AvenirSQL基于 Node.js 的數(shù)據(jù)庫(kù)
AvenirSQL是一個(gè)用Node.js設(shè)計(jì)的數(shù)據(jù)庫(kù),支持常見(jiàn)的SQL語(yǔ)句。
技術(shù)特點(diǎn)
- 1.支持增刪改查
- 2.精確查找支持哈希索引,范圍查找支持B+樹索引
- 3.智能緩存,提升QPS性能
- 4.提供用戶管理,cli程序(curl.js)
- 5.實(shí)現(xiàn)串行鎖功能
- 6.靈活的策略配置
具體技術(shù)實(shí)現(xiàn)
- 1.統(tǒng)一的底層錯(cuò)誤處理函數(shù),避免函數(shù)重復(fù)傳遞參數(shù)。
async response(type, client) {
let res = null;
if (typeof type == 'string') {
res = getError(type);
if (!res) {
res = unknown;
}
} else {
let code = type.code;
let data = type.data;
res = getError(code);
if (!res) {
res = unknown;
}
res.data = data;
}
client.write(JSON.stringify(res));
//如果沒(méi)有配置默認(rèn)短連接
if( ini.db.keepAlive != true) {
toLog("主動(dòng)踢掉客戶端的連接");
client.end();
}
}
2.數(shù)據(jù)庫(kù)結(jié)構(gòu)
數(shù)據(jù)庫(kù):文件夾名
表:數(shù)據(jù)文件、哈希索引文件、B+樹索引文件(聚合索引)
-
數(shù)據(jù)文件:
第一行存放表結(jié)構(gòu)定義,第二行開始第一位為壓縮的16進(jìn)制數(shù),表示該行元素是否為空,后續(xù)存儲(chǔ)按分隔符排列。
-
哈希索引:
對(duì)象,key為主鍵,value為所在文件的行號(hào)
-
B+樹索引:
存放B+樹的結(jié)構(gòu)
3.連接管理
為了區(qū)分不同的用戶對(duì)數(shù)據(jù)庫(kù)進(jìn)行的不同操作,如同一秒內(nèi)多個(gè)進(jìn)程進(jìn)行多次請(qǐng)求,AvenirSQL會(huì)生成一個(gè)簽名,用戶登錄后需使用此簽名進(jìn)行操作。
4.串行鎖
進(jìn)行操作前加鎖,操作完成后解鎖,并刷新緩存(select語(yǔ)句不會(huì)刷新緩存)
//自動(dòng)釋放鎖防止數(shù)據(jù)庫(kù)死鎖
async releaseLock() {
let now = moment().valueOf();
let releaseLockTime = ini.db.releaseLockTime;
releaseLockTime = releaseLockTime > ini.db.checkLockTime ? releaseLockTime : ini.db.checkLockTime;
for(let key in this.table) {
let tables = this.table[key];
for(let subKey in tables) {
let times = tables[subKey];
if(moment(now).diff(moment(times),'seconds') > releaseLockTime) {
delete tables[subKey];
toLog("自動(dòng)釋放了鎖 ",tables[subKey]);
}
}
}
}
5.緩存
目前共五類緩存,數(shù)據(jù)庫(kù)配置文件緩存和表結(jié)構(gòu)緩存不會(huì)刷新,哈希索引、表數(shù)據(jù)、B+樹索引緩存會(huì)定時(shí)刷新。
6.解析SQL
在此感謝阿里巴巴的sql解析器 node-sqlparser
AvenirSQL獨(dú)有的sql會(huì)先解析,除此之外的SQL會(huì)轉(zhuǎn)交給node-sqlparser。
//包含原生SQL和能夠被AvenirSQL識(shí)別的語(yǔ)句
async parse(sql, sign) {
//先解析AvenirSQL特有的語(yǔ)句 再解析原生SQL
toLog("要解析的 sql為 ", sql);
let raw = this.getArray(sql);
if (raw.length === 0 || !sql) {
throw ('SQL_PARSE_ERROR');
} else {
//AvenirSQL解析出錯(cuò)不報(bào)錯(cuò),轉(zhuǎn)給解析器解析,解析器報(bào)錯(cuò)直接throw
try {
await this.parseAvenirSql(raw, sql, sign);
} catch (error) {
//不是內(nèi)部定義的錯(cuò)誤就代表程序處理出錯(cuò)了
toLog('error = ', error);
if (error == SUCCESS || error != 'error') {
throw (error);
}
//不需要try catch了,底層會(huì)抓住錯(cuò)誤
let par = this.parseSql(sql);
await this.doSql(par, sign);
}
}
}評(píng)論
圖片
表情
