自己實(shí)現(xiàn)基于key-value的NoSQL數(shù)據(jù)庫(kù)(一)——起步蔫磨,初版

寫(xiě)在開(kāi)始
1淘讥、這是一篇簡(jiǎn)單的數(shù)據(jù)庫(kù)實(shí)現(xiàn),按照自己的思路來(lái)不要求效率高不要求實(shí)用性堤如,為的是以博主這樣的小白目光來(lái)琢磨數(shù)據(jù)庫(kù)怎么去實(shí)現(xiàn)
2蒲列、博主是邊寫(xiě)代碼邊寫(xiě)博客,從最開(kāi)始的版本(可以說(shuō)根本不能叫數(shù)據(jù)庫(kù)的東西!)開(kāi)始一步步實(shí)現(xiàn)到勉強(qiáng)能看的地步
3搀罢、基于key-value和c++蝗岖,歡迎交流技術(shù),如果噴請(qǐng)輕點(diǎn)
==================================================================================================================

其實(shí)我從大學(xué)時(shí)代就不喜歡數(shù)據(jù)庫(kù)榔至,感覺(jué)很麻煩所以不想學(xué)

最近NoSQL很火抵赢,而且感覺(jué)比傳統(tǒng)的數(shù)據(jù)簡(jiǎn)單,尤其是key-value感覺(jué)像哈希表一樣的操作非常舒服洛退,所以嘗試摸索下它的原理

首先瓣俯,數(shù)據(jù)庫(kù)有哪些操作呢?打開(kāi)-關(guān)閉就不說(shuō)了兵怯,關(guān)于數(shù)據(jù)的操作大概有:寫(xiě)入(包括覆寫(xiě)和插入)彩匕、查詢、刪除媒区,其中最重要的就是查詢(因?yàn)槟銊h除和寫(xiě)入都要先找到原來(lái)的數(shù)據(jù)才能操作吧)驼仪,所以我覺(jué)得查詢的效率比較影響數(shù)據(jù)庫(kù)性能。當(dāng)然這些都是后話袜漩,先來(lái)一個(gè)不講究效率的
先實(shí)現(xiàn)一個(gè)簡(jiǎn)單的绪爸,基于內(nèi)存的數(shù)據(jù)庫(kù)(比如redis)。
什么都按最簡(jiǎn)單的來(lái)不考慮性能
那么數(shù)據(jù)庫(kù)該有的操作上面已經(jīng)說(shuō)了宙攻,先來(lái)建立一個(gè)類(lèi)吧奠货,不如叫smallsql
這個(gè)數(shù)據(jù)庫(kù)只支持10240個(gè)數(shù)據(jù),并且只支持string和int型數(shù)據(jù)
先來(lái)看看smallsql.h的定義


可能看到定義的朋友已經(jīng)開(kāi)始噴了座掘,這是什么垃圾玩意递惋,也能叫數(shù)據(jù)庫(kù),博主滾出CSDN之內(nèi)的了
哈哈溢陪,不要著急嘛萍虽。前面說(shuō)了這個(gè)文章是慢慢來(lái)逐步實(shí)現(xiàn)從最簡(jiǎn)單的開(kāi)始到面前能看的樣子
如果一來(lái)就是完整版,那不如找一個(gè)開(kāi)源數(shù)據(jù)庫(kù)大家一起分析代碼來(lái)的爽快

這是打開(kāi)和關(guān)閉數(shù)據(jù)庫(kù)的函數(shù)
bool open(const std::string& sqlPath);
void close();

這是對(duì)數(shù)據(jù)庫(kù)兩種類(lèi)型的讀寫(xiě)(不同類(lèi)型居然用兩個(gè)不同的接口來(lái)操作形真,從來(lái)沒(méi)看到什么數(shù)據(jù)庫(kù)是這樣的杉编,我們下篇文章來(lái)解決)

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);

這是數(shù)據(jù)庫(kù)的數(shù)據(jù)項(xiàng)(union被博主吃了嗎?)

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

好大概是這樣了,來(lái)看看具體實(shí)現(xiàn)的源碼

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;  
}  

這個(gè)函數(shù)負(fù)責(zé)打開(kāi)數(shù)據(jù)庫(kù)邓馒,如果不是一個(gè)新的數(shù)據(jù)庫(kù)(就是文件不存在)則負(fù)責(zé)讀取數(shù)據(jù)到內(nèi)存中嘶朱,比較簡(jiǎn)單
close和這個(gè)函數(shù)基本一樣,無(wú)非就是在關(guān)閉的時(shí)候得按照格式把數(shù)據(jù)庫(kù)存到文件里面绒净,就不貼代碼了
接下來(lái)是getStr和setStr(int操作是一樣的见咒,就不單獨(dú)說(shuō)了)

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;  
        }  
    }  
}  

可以看出,函數(shù)使用了及其暴力的方法挂疆,遍歷所有數(shù)據(jù)來(lái)實(shí)現(xiàn)數(shù)據(jù)的查找,而且存儲(chǔ)的時(shí)候也會(huì)查找
單獨(dú)說(shuō)的一點(diǎn)下翎,setStr中因?yàn)檫@個(gè)數(shù)據(jù)庫(kù)沒(méi)有刪除操作(數(shù)據(jù)段都是連續(xù)的缤言,不會(huì)出現(xiàn)中間有空),所有當(dāng)讀到第一個(gè)key是空的時(shí)候就可以存入了

接下來(lái)試試數(shù)據(jù)庫(kù)的存儲(chǔ)
可以看到视事,1W個(gè)數(shù)據(jù)的讀寫(xiě)胆萧,分別都要花8秒左右(時(shí)間是以微秒字做單位),太慢了
做死一下俐东,看看10W個(gè)數(shù)據(jù)呢跌穗,這里就不貼圖了,負(fù)責(zé)的告訴你們也就80多秒而已虏辫,哈哈

下一篇文章中蚌吸,要解決的就是數(shù)據(jù)操作的不友好,至少不能用多個(gè)API接口操作吧砌庄,而且存儲(chǔ)方式也不行啊

寫(xiě)在后面
1羹唠、不用把這一篇文章實(shí)現(xiàn)的東西看做數(shù)據(jù)庫(kù),姑且叫做數(shù)據(jù)管理器娄昆?
2佩微、文章的目的是告訴讀者,數(shù)據(jù)庫(kù)無(wú)非就是讀取和保存數(shù)據(jù)的東西萌焰,如果不考慮效率大家也都能寫(xiě)出來(lái)嘛哈哈
3哺眯、抱著學(xué)習(xí)和娛樂(lè)的心態(tài)看這個(gè)系列吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扒俯,隨后出現(xiàn)的幾起案子奶卓,更是在濱河造成了極大的恐慌,老刑警劉巖陵珍,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寝杖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡互纯,警方通過(guò)查閱死者的電腦和手機(jī)瑟幕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人只盹,你說(shuō)我怎么就攤上這事辣往。” “怎么了殖卑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵站削,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我孵稽,道長(zhǎng)许起,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任菩鲜,我火速辦了婚禮园细,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘接校。我一直安慰自己猛频,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蛛勉。 她就那樣靜靜地躺著鹿寻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诽凌。 梳的紋絲不亂的頭發(fā)上毡熏,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音皿淋,去河邊找鬼招刹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窝趣,可吹牛的內(nèi)容都是我干的疯暑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哑舒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼妇拯!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起洗鸵,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤越锈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后膘滨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甘凭,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年火邓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丹弱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片德撬。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖躲胳,靈堂內(nèi)的尸體忽然破棺而出蜓洪,到底是詐尸還是另有隱情,我是刑警寧澤坯苹,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布隆檀,位于F島的核電站,受9級(jí)特大地震影響粹湃,放射性物質(zhì)發(fā)生泄漏恐仑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一再芋、第九天 我趴在偏房一處隱蔽的房頂上張望菊霜。 院中可真熱鬧,春花似錦济赎、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至液南,卻和暖如春壳猜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滑凉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工统扳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人畅姊。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓咒钟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親若未。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朱嘴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 接著上節(jié) condition_varible ,本節(jié)主要介紹future的內(nèi)容粗合,練習(xí)代碼地址萍嬉。本文參考http:/...
    jorion閱讀 14,795評(píng)論 1 5
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法隙疚,內(nèi)部類(lèi)的語(yǔ)法壤追,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法供屉,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,639評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理行冰,服務(wù)發(fā)現(xiàn)溺蕉,斷路器,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,519評(píng)論 1 51
  • Adboost算法R語(yǔ)言實(shí)踐 第一步:數(shù)據(jù)集劃分訓(xùn)練集和測(cè)試集资柔,比例2:1 index<-sample(1:nro...
    bioinfo2011閱讀 863評(píng)論 0 2