自己实现基于key-value的NoSQL数据库(一)——起步,初版

写在开始
1、这是一篇简单的数据库实现,按照自己的思路来不要求效率高不要求实用性,为的是以博主这样的小白目光来琢磨数据库怎么去实现
2、博主是边写代码边写博客,从最开始的版本(可以说根本不能叫数据库的东西!)开始一步步实现到勉强能看的地步
3、基于key-value和c++,欢迎交流技术,如果喷请轻点
==================================================================================================================

其实我从大学时代就不喜欢数据库,感觉很麻烦所以不想学

最近NoSQL很火,而且感觉比传统的数据简单,尤其是key-value感觉像哈希表一样的操作非常舒服,所以尝试摸索下它的原理

首先,数据库有哪些操作呢?打开-关闭就不说了,关于数据的操作大概有:写入(包括覆写和插入)、查询、删除,其中最重要的就是查询(因为你删除和写入都要先找到原来的数据才能操作吧),所以我觉得查询的效率比较影响数据库性能。当然这些都是后话,先来一个不讲究效率的
先实现一个简单的,基于内存的数据库(比如redis)。
什么都按最简单的来不考虑性能
那么数据库该有的操作上面已经说了,先来建立一个类吧,不如叫smallsql
这个数据库只支持10240个数据,并且只支持string和int型数据
先来看看smallsql.h的定义


可能看到定义的朋友已经开始喷了,这是什么垃圾玩意,也能叫数据库,博主滚出CSDN之内的了
哈哈,不要着急嘛。前面说了这个文章是慢慢来逐步实现从最简单的开始到面前能看的样子
如果一来就是完整版,那不如找一个开源数据库大家一起分析代码来的爽快

这是打开和关闭数据库的函数
bool open(const std::string& sqlPath);
void close();

这是对数据库两种类型的读写(不同类型居然用两个不同的接口来操作,从来没看到什么数据库是这样的,我们下篇文章来解决)

std::string getStr(const std::string& key);
void setStr(const std::string& key, const std::string& value);
int getInt(const std::string& key);
void setInt(const std::string key, int value);

这是数据库的数据项(union被博主吃了吗?)

struct SqlData  
{  
   std::string key;  
   std::string value_str;  
   int value_int;  
};  

好大概是这样了,来看看具体实现的源码

bool smallsql::open(const std::string& sqlPath)  
{  
    FILE* fp = nullptr;  
    m_sqlPath = sqlPath;  
  
    fopen_s(&fp, sqlPath.c_str(), "r");  
    if (fp == nullptr)  
    {  
        return true;  
    }  
  
    int index = 0;  
  
    while (!feof(fp))  
    {  
        int key_len = 0;  
        fread_s(&key_len, 1, 1, 1, fp);  
  
        if (key_len == 0)  
        {  
            continue;  
        }  
  
        char* key = new char[key_len + 1];  
        fread_s(key, key_len, key_len, 1, fp);  
        key[key_len] = 0;  
        m_datas[index].key = std::string(key);  
        delete[] key;  
  
        int value_len = 0;  
        fread_s(&value_len, 1, 1, 1, fp);  
  
        if (value_len != 0)  
        {  
            char* value_str = new char[value_len + 1];  
            fread_s(value_str, value_len, value_len, 1, fp);  
            value_str[value_len] = 0;  
            m_datas[index].value_str = std::string(value_str);  
            delete[] value_str;  
        }  
  
        int value_int = 0;  
        fread_s(&value_int, 4, 4, 1, fp);  
        m_datas[index].value_int = value_int;  
  
        index++;  
    }  
  
    fclose(fp);  
  
    return true;  
}  

这个函数负责打开数据库,如果不是一个新的数据库(就是文件不存在)则负责读取数据到内存中,比较简单
close和这个函数基本一样,无非就是在关闭的时候得按照格式把数据库存到文件里面,就不贴代码了
接下来是getStr和setStr(int操作是一样的,就不单独说了)

std::string smallsql::getStr(const std::string& key)  
{  
    for (int i = 0; i < smallsql::Max_Data_Count; ++i)  
    {  
        if (m_datas[i].key == key)  
        {  
            return m_datas[i].value_str;  
        }  
    }  
  
    return std::string();  
}  
  
void smallsql::setStr(const std::string& key, const std::string& value)  
{  
    for (int i = 0; i < smallsql::Max_Data_Count; ++i)  
    {  
        if (m_datas[i].key == key)  
        {  
            m_datas[i].value_str = key;  
            return;  
        }  
        else if (m_datas[i].key.empty())  
        {  
            m_datas[i].key = key;  
            m_datas[i].value_str = value;  
            m_datas[i].value_int = 0;  
            return;  
        }  
    }  
}  

可以看出,函数使用了及其暴力的方法,遍历所有数据来实现数据的查找,而且存储的时候也会查找
单独说的一点,setStr中因为这个数据库没有删除操作(数据段都是连续的,不会出现中间有空),所有当读到第一个key是空的时候就可以存入了

接下来试试数据库的存储
可以看到,1W个数据的读写,分别都要花8秒左右(时间是以微秒字做单位),太慢了
做死一下,看看10W个数据呢,这里就不贴图了,负责的告诉你们也就80多秒而已,哈哈

下一篇文章中,要解决的就是数据操作的不友好,至少不能用多个API接口操作吧,而且存储方式也不行啊

写在后面
1、不用把这一篇文章实现的东西看做数据库,姑且叫做数据管理器?
2、文章的目的是告诉读者,数据库无非就是读取和保存数据的东西,如果不考虑效率大家也都能写出来嘛哈哈
3、抱着学习和娱乐的心态看这个系列吧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容