C语言【微项目17】—DustBase微尘数据库[自制键值对数据库][超轻量]【2022-03-23】

  • 1. DustBaseShell.c
  • 2. DustBaseCore.c
  • 3. DustBaseShell模式使用截图
  • 4. DustBase典型使用流程
  • 5. DustBaseCore嵌入式使用
  • 6. DustBaseShell模式运行视频

【TDTX】
【C99】
【编译与运行环境】64位Windows操作系统,TDM-gcc 4.9.2 64bit(-std=c99)编译

项目Gitee仓库】DustBase,同时将V1.0版本也放在C语言-微项目。

【介绍】微尘数据库,一个十分简单轻量的非关系型——键值对数据库,纯C语言实现。

【使用方式】

  1. 由DustBaseShell.exe命令行交互式使用。由“.”前缀调用命令、由“$”前缀调用函数。(已实现
  2. 嵌入式使用。将DustBaseCore.c通过#include "DustBaseCore.c"的方式直接将数据库编译到用户程序中去。(已实现)
  3. 连接式用法。(待定)

【功能】
1.支持的函数

函数 作用
createDataBase 创建数据库
usingDataBase 指定要使用的数据库
clearUsingDataBase 清除使用中的数据库
deleteDataBase 删除某个未使用中的数据库
putString 存入键值对
deleteString 删除键值对
getString 获取键的值
setKeyValue 更改键的值
getKeyList 获取键名的列表

2.使用方法

  • 在DustBaseShell.exe命令行交互式环境中,使用’.'开头可以使用Shell里面的命令
  • 在DustBaseShell.exe命令行交互式环境中,使用’$'开头可以使用上述支持的函数里面的命令
  • 设置好环境变量后,DustBaseShell.exe支持带参启动!
  • 在嵌入式使用方法中,直接调用上述支持的函数即可

【版本】version 1.0

1. DustBaseShell.c

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <dirent.h>
#include "DustBaseCore.c"
char c;
int count = 0;int isLegalparameter(char c)
{//判断参数是不是合法参数字符if(c >= '0' && c <= '9'){return 1;}if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){return 1;}return 0;
}int checkParameter(char* command,int parastart,char** para)
{//command是用户输入的字符串//parastart是可能的函数参数起始位置//para将会指向合法的参数起始位置//检查单参数函数int flag = 0;for(int i = parastart;i < strlen(command);i++){if(flag == 0 && command[i] != ' ' && isLegalparameter(command[i])){//过滤参数字符串的非法前缀parastart = i;flag = 1;continue;   }if(flag == 1 && !isLegalparameter(command[i])){//找到非空参数起始位置后,检查字符合法性*para = NULL;return 0;}} //printf("start = %d\n",parastart);*para = &command[parastart];return 1;
}int checkTwoParameter(char* command,int parastart,char** ppkey,char** ppvalue)
{int secondparastart = -1;int flag = 0;for(int i = parastart;i < strlen(command);i++){//判断该参数字符串有没有空格,即是否可能输入了两个参数,而非一个if(flag == 0 && command[i] != ' '){flag = 1;}if(flag == 1 && command[i] == ' ' && i + 1 < strlen(command)){command[i] = '\0';secondparastart = i+1;}}if(secondparastart == -1){return 0;}//puts(&command[parastart]);//puts(&command[secondparastart]);int result = 0;result = checkParameter(command,parastart,ppkey);*ppvalue = &command[secondparastart];for(int i = 0;i < strlen(*ppvalue);i++){if((*ppvalue)[i] == '$'){return 0;}}return result;
}void printHello()
{puts("Welcome to DustBase v1.0.0.");puts("This is a very very lite datastore!");puts("Two type '.' and '$',$ use to function.");puts("Say \".help\" for more information.");
}
void printHelp()
{puts(".help                   Print this help message");puts(".databases              List names and files of attached databases");puts(".function               List supported features");puts(".this                   Introduce the DustBase");puts(".cls                    Clear screen");puts(".restart                Restart DustBaseShell");puts(".quit                   Quit the DustBaseShell");puts("$function parameter     For example:$createDataBase helloworld");
}
void printFunction()
{puts("----------------------+---------------------------------------"); puts("|createDataBase       |-创建数据库                           |");puts("----------------------+---------------------------------------");puts("|usingDataBase        |-指定要使用的数据库                   |");puts("----------------------+---------------------------------------");puts("|clearUsingDataBase   |-清除使用中的数据库                   |");puts("----------------------+---------------------------------------");puts("|deleteDataBase       |-删除某个未使用中的数据库             |");puts("----------------------+---------------------------------------");puts("|putString            |-存入键值对                           |");puts("----------------------+---------------------------------------");puts("|deleteString         |-删除键值对                           |");puts("----------------------+---------------------------------------");puts("|getString            |-获取键的值                           |");puts("----------------------+---------------------------------------");puts("|setKeyValue          |-更改键的值                           |");puts("----------------------+---------------------------------------");puts("|getKeyList           |-获取键名的列表                       |");puts("----------------------+---------------------------------------");puts("|getKeySeekIndex      |-获取[键的索引位置及键名组合]的列表   |");puts("----------------------+---------------------------------------");
}
void printIntroduce()
{puts("- DustBase,微尘数据库!");puts("- 一个十分简单轻量的非关系型——键值对数据库,纯C语言实现!");puts("- 作者:CSDN/Gitee:TDTX/TDTXYZHH");
}
int main(int argc,char*argv[])
{printHello();if(argc >= 2){if(argv[1] != NULL && !strcmp(".help",argv[1])){printf("DB> %s\n",argv[1]);printHelp();}if(argv[1] != NULL && !strcmp(".function",argv[1])){printf("DB> %s\n",argv[1]);printFunction();}if(argv[1] != NULL && !strcmp(".this",argv[1])){printf("DB> %s\n",argv[1]);printIntroduce();}if(argv[1] != NULL && !strcmp(".quit",argv[1])){printf("DB> %s\n",argv[1]);return 0;}}//puts("");while(1){printf("DB> ");while(1){c = fgetc(stdin);if(c == '\n'){break;}   if(c == '.' && ftell(stdin) == 1){int commandsize = 0;char* command = (char*)malloc(0);    while(1){c = fgetc(stdin);command = (char*)realloc(command,sizeof(char)*(commandsize + 1));commandsize++;if(c == '\n'){command[commandsize - 1] = '\0';break;}command[commandsize - 1] = c;}if(!strcmp("help",command)){printHelp();free(command);break;}else if(!strcmp("databases",command)){//puts("teset=====");DIR* dir = NULL;struct dirent* dt;int i = 0;dir = opendir("./");int flag = 0;puts("=====[In this folder]=====");while(dt = readdir(dir)){//print("hello");//printf("i = %d\n",i);char* filename = &(dt->d_name)[strlen(dt->d_name) - 4];if(!strcmp(filename,".tdb")){i++;printf("->%2d:%s\n",i,dt->d_name);flag = 1;}}if(flag == 0){puts("Info:NO DATABASE[.tdb]");}puts("=====[In this folder]=====");closedir(dir);free(command);break;}else if(!strcmp("function",command)){printFunction(); free(command);break;}else if(!strcmp("this",command)){printIntroduce();free(command);break;}else if(!strcmp("cls",command)){system("cls");free(command);break;}else if(!strcmp("restart",command)){char* t[] = {"DustBase",NULL};main(0,t);free(command);exit(0);break;}else if(!strcmp("quit",command)){free(command);return 0;}free(command);break;}else if(c == '$' && ftell(stdin) == 1){int commandsize = 0;char* command = (char*)malloc(0);  while(1){c = fgetc(stdin);command = (char*)realloc(command,sizeof(char)*(commandsize + 1));commandsize++;if(c == '\n'){command[commandsize - 1] = '\0';break;}command[commandsize - 1] = c;}if(strstr(command,"createDataBase") != NULL){puts("create");if(strlen(command) > 15){if(command[14] != ' '){puts("Function:createDataBase input error,need space between function and parameter!");}else{char* parameter = &command[15];int i = checkParameter(command,15,&parameter);if(i == 0){puts("Function:createDataBase input error,parameters have illegal parameter!");}else{puts(parameter);createDataBase(parameter);}  }}else{puts("Function:createDataBase input error,need parameter!");}free(command);break;}else if(strstr(command,"usingDataBase") != NULL){puts("use");if(strlen(command) > 14){if(command[13] != ' '){puts("Function:createDataBase input error,need space between function and parameter!");}else{char* parameter = &command[14];int i = checkParameter(command,14,&parameter);if(i == 0){puts("Function:createDataBase input error,parameters have illegal parameter!");}else{puts(parameter);usingDataBase(parameter);}   }}else{puts("Function:createDataBase input error,need parameter!");}free(command);break;}else if(strstr(command,"clearUsingDataBase") != NULL){puts("clearusing");if(strlen(command) == 18){clearUsingDataBase();}else{puts("Function:createDataBase input error,don't need parameter!");}free(command);break;}else if(strstr(command,"deleteDataBase") != NULL){puts("deleteDataBase");if(strlen(command) > 15){if(command[14] != ' '){puts("Function:deleteDataBase input error,need space between function and parameter!");}else{char* parameter = &command[15];int i = checkParameter(command,15,&parameter);if(i == 0){puts("Function:deleteDataBase input error,parameters have illegal parameter!");}else{puts(parameter);deleteDataBase(parameter);} }}else{puts("Function:deleteDataBase input error,need parameter!");}free(command);break;}else if(strstr(command,"putString") != NULL){puts("putString");if(strlen(command) > 10){if(command[9] != ' '){puts("Function:putString input error,need space between function and parameter!");}else{char* pkey = &command[10];char* pvalue = NULL;int result = checkTwoParameter(command,10,&pkey,&pvalue);if(result == 0){puts("Function:putString input error,parameters have illegal parameter!");}else{//puts(pkey);//puts(pvalue);putString(pkey,pvalue);}  }}else{puts("Function:putString input error,need parameter!");}free(command);break;}else if(strstr(command,"deleteString") != NULL){puts("deleteString");if(strlen(command) > 13){if(command[12] != ' '){puts("Function:deleteString input error,need space between function and parameter!");}else{char* parameter = &command[13];int i = checkParameter(command,13,&parameter);if(i == 0){puts("Function:deleteString input error,parameters have illegal parameter!");}else{puts(parameter);deleteString(parameter);} }}else{puts("Function:deleteString input error,need parameter!");}free(command);break;}else if(strstr(command,"getString") != NULL){puts("getString");if(strlen(command) > 10){if(command[9] != ' '){puts("Function:getString input error,need space between function and parameter!");}else{char* pkey = &command[10];char* pvalue = NULL;int result = checkTwoParameter(command,10,&pkey,&pvalue);if(result == 0){puts("Function:getString input error,parameters have illegal parameter!");}else{//puts(pkey);//puts(pvalue);//char* svalue = getString(pkey,pvalue);//puts(svalue);getString(pkey,pvalue);}   }}else{puts("Function:getString input error,need parameter!");}free(command);break;}else if(strstr(command,"setKeyValue") != NULL){puts("setKeyValue");if(strlen(command) > 12){if(command[11] != ' '){puts("Function:setKeyValue input error,need space between function and parameter!");}else{char* pkey = &command[12];char* pvalue = NULL;int result = checkTwoParameter(command,12,&pkey,&pvalue);if(result == 0){puts("Function:setKeyValue input error,parameters have illegal parameter!");}else{//puts(pkey);//puts(pvalue);setKeyValue(pkey,pvalue);}    }}else{puts("Function:setKeyValue input error,need parameter!");}free(command);break;}else if(strstr(command,"getKeyList") != NULL){puts("getKeyList");if(strlen(command) == 10){struct keylistinfo* keys = getKeyList();if(keys != NULL){for(int i = 0;i < keys->n;i++){if(i == 0){printf("[\"%s\"",(keys->keylist)[i]);}else{printf(",\"%s\"",(keys->keylist)[i]);}if(i == keys->n - 1){printf("]\n");}}    }}else{puts("Function:createDataBase input error,don't need parameter!");}free(command);break;}free(command);break;}}}system("pause");return 0;
}

2. DustBaseCore.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>struct keylistinfo
{char** keylist;int n;
};
char rundatabasename[37] = {'\0'};//数据库名最多32字符
char* value = NULL;
struct keylistinfo* keys = NULL;int connecDataBase();//待定
int disconnectDataBase();//待定int createDataBase(char* databasename);
int usingDataBase(char* databasename);
int clearUsingDataBase();
int deleteDataBase(char* databasename);
int putString(char* key,char* value);
int deleteString(char* key);
char* getString(char* key,char* error);
int setKeyValue(char* key,char* newvalue);
struct keylistinfo* getKeyList();int getKeySeekIndex();//暂不实现int connecDataBase()
{//待定
}
int disconnectDataBase()
{//待定
}int createDataBase(char* databasename)
{int len = strlen(databasename);if(len > 32){puts("Warning:the length of database name exceeds the limit(32)");return 0;}char name[len+5];strcpy(name,databasename);name[len] = '.';name[len+1] = 't';name[len+1+1] = 'd';name[len+1+1+1] = 'b';name[len+1+1+1+1] = '\0';//puts(name);if(!access(name,F_OK)){puts("Error:the newdatabase exist!");return -1;}FILE* database = fopen(name,"a");if(database == NULL){puts("Error:create database fail!");return -1;}fflush(database);fclose(database);puts("Info:create database success!");return 1;
}int usingDataBase(char* databasename)
{int len = strlen(databasename);if(len > 32){puts("Warning:the length of database name exceeds the limit(32)");return 0;}char name[len+5];strcpy(name,databasename);name[len] = '.';name[len+1] = 't';name[len+1+1] = 'd';name[len+1+1+1] = 'b';name[len+1+1+1+1] = '\0';//puts(name);if(access(name,F_OK)){puts("Error:the database doesn't exist!");return -1;}strcpy(rundatabasename,name);puts("Info:using database success!");char* value = (char*)malloc(0);keys = (struct keylistinfo*)malloc(sizeof(struct keylistinfo));keys->n = 0;keys->keylist = (char**)malloc(0);return 1;
}int clearUsingDataBase()
{if(strlen(rundatabasename) == 0){puts("Error:clear using databse fail,no database is using!");return 0;}rundatabasename[0] = '\0';free(value);value = NULL;for(int i = 0;i < keys->n;i++){free((keys->keylist)[i]);} free(keys->keylist);free(keys);keys = NULL;puts("Info:clear using databse success!");return 1;
}int deleteDataBase(char* databasename)
{int len = strlen(databasename);if(len > 32){puts("Warning:the length of database name exceeds the limit(32)");return 0;}char name[len+5];strcpy(name,databasename);name[len] = '.';name[len+1] = 't';name[len+1+1] = 'd';name[len+1+1+1] = 'b';name[len+1+1+1+1] = '\0';//puts(name);if(access(name,F_OK)){puts("Error:the newdatabase doesn't exist!");return -1;}if(!strcmp(rundatabasename,name)){puts("Warning:the database is using,can not delete!");return 0;}if(remove(name) != 0){puts("Error:delete databse fail!");return -1;}puts("Info:delete databse success!");return 1;
}int putString(char* key,char* value)
{if(rundatabasename[0] == '\0'){puts("Error:no database is using!");return -1;}if(strlen(key) > 32){puts("Warning:the length of key exceeds the limit(32)");return 0;}//puts(rundatabasename);for(int i = 0; i < strlen(value);i++){if(value[i] == '$'){puts("Warning:the value can not contain '$'!");return 0;}}FILE* database = fopen(rundatabasename,"a+");if(database == NULL){puts("Error:the database doesn't exist!");return -1;}char tkey[33];int cancopy = 0;int k = 0;char tc;while(1){//这里用来判断里面有没有该key,如果存在则不存入,没有则存入tc = fgetc(database);if(tc == EOF){break;}if(tc == '$'){cancopy = 1;continue;}if(cancopy == 1){if(tc == ':'){tkey[k] = '\0';k = 0;cancopy = 0;//puts(tkey);if(!strcmp(key,tkey)){fclose(database);puts("Error:the key exists!");return -1;}tkey[0] = '\0';}else{tkey[k++] = tc;continue;}}}fprintf(database,"$%s:%s\n",key,value);fflush(database);fclose(database);puts("Info:putString success!");return 1;
}int deleteString(char* key)
{if(rundatabasename[0] == '\0'){puts("Error:no database is using!");return -1;}if(strlen(key) > 32){puts("Warning:the length of key exceeds the limit(32)");return 0;}//puts(rundatabasename);FILE* database = fopen(rundatabasename,"a+");if(database == NULL){puts("Error:the database doesn't exist!");return -1;}char tkey[33];int cancopy = 0;int k = 0;char tc;int havekey = 0;int location = 0;while(1){//这里用来判断里面有没有该key,如果存在则执行删除,不存在则返回-1tc = fgetc(database);if(tc == EOF){break;}if(tc == '$'){location = ftell(database);cancopy = 1;continue;}if(cancopy == 1){if(tc == ':'){tkey[k] = '\0';k = 0;cancopy = 0;//puts(tkey);if(!strcmp(key,tkey)){havekey = 1;//puts("Error:the key exists!");break;}tkey[0] = '\0';}else{tkey[k++] = tc;continue;}}}if(havekey == 1){int flag = 0;fseek(database,0,SEEK_SET);//将文件指针定位到起始位置FILE* temp = fopen("temp.tdb","w");if(temp == NULL){puts("Error:new temp-database fail!");fclose(database);return -1;  }while(1){tc = fgetc(database);if(tc == EOF){break;}if(ftell(database) == location){flag = 1;}if(flag == 1){if((tc == '$' || tc == EOF) && ftell(database) > location){flag = 0;fputc(tc,temp);}}else{fputc(tc,temp);}}fclose(database);fclose(temp);remove(rundatabasename);rename("temp.tdb",rundatabasename);puts("Info:delete key-value success!");return 1;}else{fclose(database);puts("Error:the key doesn't exists,cannot delete key-vlaue!");return 0;}
}char* getString(char* key,char* error)
{if(rundatabasename[0] == '\0'){puts("Error:no database is using!");return error;}if(strlen(key) > 32){puts("Warning:the length of key exceeds the limit(32)");return error;}//puts(rundatabasename);FILE* database = fopen(rundatabasename,"a+");if(database == NULL){puts("Error:the database doesn't exist!");return error;}char tkey[33];int cancopy = 0;int k = 0;char tc;int havekey = 0;int location = 0;while(1){//这里用来判断里面有没有该key,如果存在则执行获取值,不存在则返回error所指字符串tc = fgetc(database);if(tc == EOF){break;}if(tc == '$'){cancopy = 1;continue;}if(cancopy == 1){if(tc == ':'){location = ftell(database);tkey[k] = '\0';k = 0;cancopy = 0;//puts(tkey);if(!strcmp(key,tkey)){havekey = 1;//puts("Error:the key exists!");break;}tkey[0] = '\0';}else{tkey[k++] = tc;continue;}}}k = 0;if(havekey == 1){fseek(database,location,SEEK_SET);while(1){tc = fgetc(database);if(tc == '$' || tc == EOF){break;}value = (char*)realloc(value,++k);value[k - 1] = tc;}value[k] = '\0';puts("value is:");puts(value);fclose(database);return value;}else{fclose(database);puts("Error:the key doesn't exists,cannot get vlaue!");return 0;}
}int setKeyValue(char* key,char* newvalue)
{if(rundatabasename[0] == '\0'){puts("Error:no database is using!");return -1;}if(strlen(key) > 32){puts("Warning:the length of key exceeds the limit(32)");return 0;}//puts(rundatabasename);for(int i = 0; i < strlen(value);i++){if(value[i] == '$'){puts("Warning:the value can not contain '$'!");return 0;}}FILE* database = fopen(rundatabasename,"a+");if(database == NULL){puts("Error:the database doesn't exist!");return -1;}char tkey[33];int cancopy = 0;int k = 0;char tc;int havekey = 0;int location = 0;while(1){//这里用来判断里面有没有该key,如果存在则执行设置该key的value,不存在则返回0tc = fgetc(database);if(tc == EOF){break;}if(tc == '$'){cancopy = 1;continue;}if(cancopy == 1){if(tc == ':'){location = ftell(database);tkey[k] = '\0';k = 0;cancopy = 0;//puts(tkey);if(!strcmp(key,tkey)){havekey = 1;//puts("Error:the key exists!");break;}tkey[0] = '\0';}else{tkey[k++] = tc;continue;}}}if(havekey == 1){int flag = 0;fseek(database,0,SEEK_SET);//将文件指针定位到起始位置FILE* temp = fopen("settemp.tdb","w");if(temp == NULL){puts("Error:new settemp-database fail!");fclose(database);return -1;  }while(1){tc = fgetc(database);if(tc == EOF){break;}if(ftell(database) == location){fputc(tc,temp);flag = 1;int len = strlen(newvalue);for(int i = 0;i < len;i++){fputc(newvalue[i],temp);}fputc('\n',temp);}if(flag == 1){if((tc == '$' || tc == EOF) && ftell(database) > location){flag = 0;fputc(tc,temp);}}else{fputc(tc,temp);}}fclose(database);fclose(temp);remove(rundatabasename);rename("settemp.tdb",rundatabasename);puts("Info:set the key's new value success!");return 1;}else{fclose(database);puts("Error:the key doesn't exists,cannot set set the key's new value!");return 0;} }struct keylistinfo* getKeyList()
{if(rundatabasename[0] == '\0'){puts("Error:no database is using!");return NULL;}//puts(rundatabasename);FILE* database = fopen(rundatabasename,"a+");if(database == NULL){puts("Error:the database doesn't exist!");return NULL;}if(keys->n != 0){for(int i = 0;i < keys->n;i++){free((keys->keylist)[i]);}keys->keylist = (char**)realloc(keys->keylist,0);keys->n = 0;   }char tkey[33];int cancopy = 0;int k = 0;char tc;int location = 0;while(1){tc = fgetc(database);if(tc == EOF){break;}if(tc == '$'){location = ftell(database);cancopy = 1;continue;}if(cancopy == 1){if(tc == ':'){tkey[k] = '\0';k = 0;cancopy = 0;//puts(tkey);keys->keylist = (char**)realloc(keys->keylist,sizeof(char*)*(keys->n + 1));(keys->n)++;char* thiskey = (char*)malloc(strlen(tkey)*sizeof(char));strcpy(thiskey,tkey);//printf("检查thiskey:%s\n",thiskey);(keys->keylist)[keys->n - 1] = thiskey;tkey[0] = '\0';}else{tkey[k++] = tc;continue;}}}fclose(database);return keys;
}int getKeySeekIndex()
{//暂不实现
}

3. DustBaseShell模式使用截图


4. DustBase典型使用流程

  1. int createDataBase(char* databasename);//创建数据库

  2. int usingDataBase(char* databasename);//使用数据库

  3. 使用下列数据库操作函数:
    int putString(char* key,char* value);
    int deleteString(char* key);
    char* getString(char* key,char* error);
    int setKeyValue(char* key,char* newvalue);
    struct keylistinfo* getKeyList();

  4. int clearUsingDataBase();//清除使用的数据库

  5. int deleteDataBase(char* databasename);//删除未使用中的数据库

5. DustBaseCore嵌入式使用

测试文件:importtest.c

#include <stdlib.h>
#include "DustBaseCore.c"
int main()
{createDataBase("useimport999");usingDataBase("useimport999");putString("godd1","dadasdhjuhfas\ndadasd\tdada8977465=");putString("peoo","dersaasdasdewqdad");putString("qdwqd","cfasdsadad");getString("godd1","error");struct keylistinfo* keys = getKeyList();if(keys != NULL){for(int i = 0;i < keys->n;i++){if(i == 0){printf("[\"%s\"",(keys->keylist)[i]);}else{printf(",\"%s\"",(keys->keylist)[i]);}if(i == keys->n - 1){printf("]\n");}} }setKeyValue("godd1","this is new value!!!!");keys = getKeyList();if(keys != NULL){for(int i = 0;i < keys->n;i++){printf("%s:%s",(keys->keylist)[i],getString((keys->keylist)[i],"error"));}  }clearUsingDataBase();system("pause");return 0;
}

运行截图:

6. DustBaseShell模式运行视频

DustBase--微尘数据库,一个十分简单轻量的非关系型——键值对数据库,纯C语言实现!

C语言【微项目17】—DustBase微尘数据库[自制键值对数据库][超轻量]【2022-03-23】相关推荐

  1. 深入探索Redis:高性能键值存储数据库

    系列文章目录 文章目录 系列文章目录 前言 一.Redis简介 1.1 为什么需要Redis 1.1.1 高性能 1.1.2 高并发 1.2 Redis的应用场景 二.Redis 下载安装 2.1 w ...

  2. 浅谈redis数据库的键值设计

    丰富的数据结构使得redis的设计非常的有趣.不像关系型数据库那样,DEV和DBA需要深度沟通,review每行sql语句,也不像memcached那样,不需要DBA的参与.redis的DBA需要熟悉 ...

  3. oracle数据库中索值,Oracle数据库中的索引详解

    Oracle数据库中的索引详解以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一 ROWID的概念 存储了row在数据文 ...

  4. mysql数据库键值对_关于数据库存储键值对的问题?

    目前的需求的是:客户可自定义Grid的表头顺序,对表头进行拖拽和排序,并且要根据当前用户的配置保存.现在系统的表头显示是根据后台的配置配置顺序显示,如:table:字段名/表头名排序... 目前的需求 ...

  5. 重新定义数据库历史的时刻——时间序列数据库Schwartz认为InfluxDB最有前途,Elasticsearch也不错...

    转自:http://www.infoq.com/cn/news/2017/04/redefine-database-history 提起VividCortex公司的创建者兼CEO Baron Schw ...

  6. C语言【微项目01】—电话号码管理系统(文件操作实现)【2021-06-29】

    C语言[微项目01]-电话号码管理系统(文件操作实现) TelSeaSys.h TelSeaSys.c main.c 运行结果示例 [TDTX] [通过文件进行增.删.查.改, 在文件中增.删.查.改 ...

  7. 音频文件 数据库存储_Apache Kafka是数据库吗?

    Apache Kafka是否可以并且应该替换数据库?我可以并且应该在Kafka中存储数据多长时间?如何在Kafka中查询和处理数据?这些是越来越多的常见问题.诸如"是"或" ...

  8. 图数据库:从传统关系型数据库说起

    1.数据库 按照早期的数据库理论,比较流行的数据库模型有三种,分别为层次式数据库.网状数据库和关系型数据库.而在当今的互联网中,最常见的数据库模型主要是两种,即SQL关系型数据库和NoSQL非关系型数 ...

  9. 键值数据库LevelDB的优缺点及性能分析

    导读:LevelDB是一种为分布式而生的键-值数据库. 作者:廖环宇 张仕华 来源:大数据DT(ID:hzdashuju) 01 LevelDB的特性 LevelDB是一个C++语言编写的高效键-值嵌 ...

  10. 【宋红康 MySQL数据库】【01】数据库概述

    持续学习&持续更新中- 学习态度:守破离 [宋红康 MySQL数据库][01]数据库概述 1. 为什么要使用数据库 2. 数据库与数据库管理系统 2.1 数据库的相关概念 2.2 数据库与数据 ...

最新文章

  1. 利用委托和泛型实现树的常用操作
  2. 架构中的一切都是权衡
  3. 第十三课.随机近似初步:蒙特卡洛方法
  4. PMCAFF问答精选 | 产品新手写PRD需要注意什么?
  5. Topshelf 学习 跨平台
  6. 【问链-EOS公开课】第十三课 EOS插件机制深入解析
  7. Mac Hadoop的安装与配置
  8. 把Hybris安装时输出的日志重定向到一个本地文件中
  9. 禁用安全模式(2k,2k3,xp)
  10. 如何解决亚稳态?(FPGA面试题)
  11. Vue cli项目开启Gzip
  12. Modal View Controllers, Not Model-View-Controller(MVC)
  13. android 多图片优化工具,总结Android App内存优化之图片优化
  14. LDA算法和PCA算法的总结(原理和思想)
  15. android外接键盘打汉字,外接键盘情况下,安卓打字不如windows
  16. 视频I帧/P帧/B帧
  17. MySQL事务隔离及锁机制
  18. Git 笔记 - git cherry-pick
  19. 【NiosII训练】第二篇、FPGA驱动AD9854高级篇
  20. openwrt mesh网络设置

热门文章

  1. 文本挖掘与matlab,文本挖掘与数据挖掘:发现差异
  2. IPv4编址;A类、B类、C类、D类、E类IP地址(IP地址;网络地址和主机地址;子网掩码;网关;广播地址;)
  3. Discuz模板安装步骤以及发生的问题
  4. 什么是Cisco ACI?
  5. 在任意位置Reset掉任意的TCP连接
  6. 20+案例教你可视化图表的设计方法
  7. python虚拟变量回归_虚拟变量提升多元线性回归模型精度(附Python代码与数据)...
  8. 【Flutter 问题系列第 26 篇】给 TextField 添加背景色,为什么没有效果 ?
  9. html实心圆圈,html5使用canvas画空心圆与实心圆
  10. element-ui 删除input框尾部默认图标和获取焦点边框高亮问题