AvenirSQL —— 基于 Node.js 的数据库
AvenirSQL是一个用Node.js设计的数据库,支持常见的SQL语句。
技术特点
- 1.支持增删改查
- 2.精确查找支持哈希索引,范围查找支持B+树索引
- 3.智能缓存,提升QPS性能
- 4.提供用户管理,cli程序(curl.js)
- 5.实现串行锁功能
- 6.灵活的策略配置
具体技术实现
- 1.统一的底层错误处理函数,避免函数重复传递参数。
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));
//如果没有配置默认短连接
if( ini.db.keepAlive != true) {
toLog("主动踢掉客户端的连接");
client.end();
}
}
2.数据库结构
数据库:文件夹名
表:数据文件、哈希索引文件、B+树索引文件(聚合索引)
-
数据文件:
第一行存放表结构定义,第二行开始第一位为压缩的16进制数,表示该行元素是否为空,后续存储按分隔符排列。
-
哈希索引:
对象,key为主键,value为所在文件的行号
-
B+树索引:
存放B+树的结构
3.连接管理
为了区分不同的用户对数据库进行的不同操作,如同一秒内多个进程进行多次请求,AvenirSQL会生成一个签名,用户登录后需使用此签名进行操作。
4.串行锁
进行操作前加锁,操作完成后解锁,并刷新缓存(select语句不会刷新缓存)
//自动释放锁防止数据库死锁
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("自动释放了锁 ",tables[subKey]);
}
}
}
}
5.缓存
目前共五类缓存,数据库配置文件缓存和表结构缓存不会刷新,哈希索引、表数据、B+树索引缓存会定时刷新。
6.解析SQL
在此感谢阿里巴巴的sql解析器 node-sqlparser
AvenirSQL独有的sql会先解析,除此之外的SQL会转交给node-sqlparser。
//包含原生SQL和能够被AvenirSQL识别的语句
async parse(sql, sign) {
//先解析AvenirSQL特有的语句 再解析原生SQL
toLog("要解析的 sql为 ", sql);
let raw = this.getArray(sql);
if (raw.length === 0 || !sql) {
throw ('SQL_PARSE_ERROR');
} else {
//AvenirSQL解析出错不报错,转给解析器解析,解析器报错直接throw
try {
await this.parseAvenirSql(raw, sql, sign);
} catch (error) {
//不是内部定义的错误就代表程序处理出错了
toLog('error = ', error);
if (error == SUCCESS || error != 'error') {
throw (error);
}
//不需要try catch了,底层会抓住错误
let par = this.parseSql(sql);
await this.doSql(par, sign);
}
}
}