STVM

基本介紹

  • 中文名:高速快取資料庫
  • 外文名:STVM
  • 1:高速離線快取資料庫
  • 2:最快快取資料庫沒有之一
STVM,定義,性能,支持語言,欄位類型,使用手冊,開發流程,創建表,操作表(查詢單記錄),操作表(查詢多條記錄),操作表(新增記錄),操作表(刪除記錄),操作表(修改記錄),

STVM

STVM(truck of Virtual memory table)是一個開源的使用ANSI C語言編寫、支持本地API調用和網路調用,全表數據基於IPC共享記憶體方式存儲,
基於C語言struck結構定義記錄行,RB-Tree和hash作為主要算法的記憶體資料庫,是一款介於SQL和NOSQL之間的一款高速快取資料庫。
由於數據全部存儲在記憶體中,相比較其他類型的快取,運行速度之快可想而知。

定義

stvm是一款其介於介於SQL和NOSQL,擁有以下主要特點
支持SQL基本語法(本版本支持insert、update、delete、select、group order、count,first,游標)功能。
支持序列
支持唯一索引、查詢索引和組合索引(組合索引不必考慮索引欄位先後)
支持條件動態查詢
內置記錄點擊量
集群、主-子分布同步。
事務功能(假性事務)
數據持久性,進程異常退出,不會導致數據丟失,除非系統宕機。
支持網路API和函式API, 支持多執行緒、多進程等等
內置數據版本,維護數據一致安全。
多機集群,數據分區
當然也有幾點缺陷,索引長度限制目前版本64位,修改長度需編譯項目、啟動後不能修改表欄位(ddl語句),不能聯表查詢。
stvm是一款高速快取資料庫,表欄位定義來源與C語言STRUCK,動態條件賦值只需要對結構體成員賦值即為查詢條件。
整個操作提供特定API訪問,減少解析SQL和欄位的時間。
全表數據分3個區(表頭區、索引區、數據區),並且全部存儲在一塊記憶體中。
每張表定義一個資料庫塊,每張表擁有自己讀寫鎖,支持執行緒。
預留拓展表空間參數,但效率會降低擴展個數倍

性能

在相同環境在,用本機API訪問對單標操作是redis的30倍以上。網路api也快1.5倍以上。
比fastdb快倍10左右。
其他沒逐一測試。

支持語言

C
C++
Java
……
支持
支持
待支持

欄位類型

欄位類型有LONG,CHAR,DOUB(對應整型、字元型、浮點型)
行記錄建議不要超過500KB
為了避免記憶體的浪費,唯一索引和查詢索引最多各一組。

使用手冊

啟動環境變數:
TVMDBD=/home/stvm/tvmdb 指向stvm工作目錄
TVMCFG=/home/stvm/tvmdb/.tvm.run 啟動參數
配置完成後,stvm -w採用預設啟動參數進去本機模式。
如果集群模式請配置 stvm.conf,然後用stvm -c stvm.conf編譯配置檔案即可。
STVM對外提供2個開發運維工具stvm和調試工具detvm。
stvm -w啟動啟動
stvm -s停止系統
STVM也提供一個類型sqlpuls類型簡單工具,輸入:stvm SQL進入SQL界面,該工具僅僅用來運維調試使用。
stvm dom --進入域的維護

開發流程

創建表

// 定義表序號
#define TBL_USER_INFO 10
必須用C定義STRUCK:
    typedef struct  __TBL_USER_INFO    {       long    acct_id;       char    user_no[21];       char    user_type[2];       char    user_nm[81];       char    user_addr[161];       char    user_phone[31];    }dbUser;
定義創建表函式
    CREATE  lCreateUserInfo()    {       DEFINE(TBL_USER_INFO, "TBL_USER_INFO", "", dbUser)       FIELD(dbUser,    acct_id,         "acct_id",       FIELD_LONG)       FIELD(dbUser,    user_no,         "user_no",       FIELD_CHAR)       FIELD(dbUser,    user_type,       "user_type",     FIELD_CHAR)       FIELD(dbUser,    user_nm,         "user_nm",       FIELD_CHAR)       FIELD(dbUser,    user_addr,       "user_addr",     FIELD_CHAR)       FIELD(dbUser,    user_phone,      "user_phone",    FIELD_CHAR)           CREATE_IDX(NORMAL)        //    創建查詢索引       IDX_FIELD(dbUser, acct_id,       FIELD_LONG)           CREATE_IDX(UNQIUE)        //    創建唯一索引       IDX_FIELD(dbUser, user_no,       FIELD_CHAR)       IDX_FIELD(dbUser, user_type,     FIELD_CHAR)           FINISH    }
調用api:
lCreateTable(pstSavm, TBL_USER_INFO, 100000, lCreateUserInfo)完成對TBL_USER_INFO表的創建。
其中pstSavm為執行緒句柄
TBL_USER_INFO 創建的表序號,
100000初始化記憶體記錄空間條數。
lCreateUserInfo創建表定義函式。
調用成功則返回RC_SUCC, 失敗返回RC_FAIL, 失敗可調用pstSavm->m_lErrno獲取處理失敗錯誤碼,sGetTError(pstSavm->m_lErrno)獲取錯誤信息。

操作表(查詢單記錄)

dbUser stUser;SATvm  *pstSavm = (SATvm *)pGetSATvm();//    初始化TBL_USER_INFO表,每張表都需要初始化一次, 對於表重建後,需要重新初始化一次。if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)){    fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno));    return ;}conditinit(pstSavm, stUser, TBL_USER_INFO);                // 綁定變數numberset(pstSavm, stUser, user_type, "1");                // 查詢條件賦值stringset(pstSavm, stUser, user_no, "20180223");           // 查詢條件賦值if(RC_SUCC != lSelect(pstSavm, (void *)&stUser))           // 單條記錄查詢{    fprintf(stderr, "Select錯誤ep:%d, err:(%d)(%s)\n", pstSavm->m_lEType, pstSavm->m_lErrno,        sGetTError(pstSavm->m_lErrno));    return ;}fprintf(stdout, "acct_id:%ld, user_no:%s, user_type:%s, user_nm:%s, user_addr:%s, user_phone:%s\n",    stUser.acct_id, stUser.user_no, stUser.user_type, stUser.user_nm, stUser.user_addr, stUser.user_phone);

操作表(查詢多條記錄)

    size_t  i = 0, lOut;    dbUser  *pstUser;    SATvm   *pstSavm = (SATvm *)pGetSATvm();//    初始化TBL_USER_INFO表,每張表都需要初始化一次, 對於表重建後,需要重新初始化一次。     if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO))    {        fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno));        return ;    }       conditinit(pstSavm, stUser, TBL_USER_INFO);    // 綁定變數    numberset(pstSavm, stUser, user_type, "1");         // 查詢條件賦值    stringset(pstSavm, stUser, user_no, "20180223");         // 查詢條件賦值            if(RC_SUCC != lQuery(pstSavm, &lOut, (void **)&pstUser))      // 批量查詢查詢      {        fprintf(stderr, "Select錯誤ep:%d, err:(%d)(%s)\n", pstSavm->m_lEType, pstSavm->m_lErrno,            sGetTError(pstSavm->m_lErrno));        return ;    }         for(i = 0; i < lOut; i ++)    {        fprintf(stdout, "acct_id:%ld, user_no:%s, user_type:%s, user_nm:%s, user_addr:%s, user_phone:%s\n",               pstUser[i].acct_id, pstUser[i].user_no, pstUser[i].user_type, pstUser[i].user_nm, pstUser[i].user_addr, pstUser[i].user_phone);    }

操作表(新增記錄)

    dbUser  stUser;    SATvm   *pstSavm = (SATvm *)pGetSATvm();    //    初始化TBL_USER_INFO表,每張表都需要初始化一次, 對於表重建後,需要重新初始化一次。     if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO))    {        fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno));        return ;    }    stUser.acct_id = 10021;                    // 對結構體賦值    strcpy(stUser.user_no, "20180223");                            // 對結構體賦值    strcpy(stUser.user_type, "1");                            // 對結構體賦值    insertinit(pstSavm, stUser, TBL_USER_INFO);               // 綁定變數    if(RC_SUCC != lInsert(pstSavm))      // 插入記錄      {        fprintf(stderr, "Select錯誤ep:%d, err:(%d)(%s)\n", pstSavm->m_lEType, pstSavm->m_lErrno,            sGetTError(pstSavm->m_lErrno));        return ;    }

操作表(刪除記錄)

    dbUser  stUser;    SATvm   *pstSavm = (SATvm *)pGetSATvm();    //    初始化TBL_USER_INFO表,每張表都需要初始化一次, 對於表重建後,需要重新初始化一次。     if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO))    {        fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno));        return ;    }    conditinit(pstSavm, stAct, TBL_USER_INFO)       // 對結構體賦值    numberset(pstSavm, stUser, user_type, "1");     // 查詢條件賦值    stringset(pstSavm, stUser, user_no, "20180223");          // 查詢條件賦值    if(RC_SUCC != lDelete(pstSavm))      // 刪除記錄      {        fprintf(stderr, "Delete err:(%d)(%s)\n", pstSavm->m_lEType, pstSavm->m_lErrno,            sGetTError(pstSavm->m_lErrno));        return ;    }

操作表(修改記錄)

    dbUser  stUser, stUpd;    SATvm       *pstSavm = (SATvm *)pGetSATvm();    if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO))    {        fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno));        return ;    }        updateinit(stUpd);        conditinit(pstSavm, stUser, TBL_USER_INFO)         // 綁定變數    numberset(pstSavm, stUser, user_type, "1");                  // 查詢條件賦值    stringset(pstSavm, stUser, user_no, "20180223");             // 查詢條件賦值    stringupd(pstSavm, stUpd, user_phone, "18691128912");    if(RC_SUCC != lUpdate(pstSavm, (void *)&stUpd))    {        fprintf(stderr, "Update err:(%d)(%s), (%ld)\n", pstSavm->m_lErrno,            sGetTError(pstSavm->m_lErrno), lGetEffect());        return ;    }
其他函式lTruncate、lCount、lExtreme、lGroup, 和網路API如lTvmDelete、lTvmInsert、lTvmSelect、lTvmUpdate、lTvmTruncate、lTvmCount、lTvmExtreme、lTvmGroup、lTvmQuery、不做一一枚舉。

相關詞條

熱門詞條

聯絡我們