wordpress所有頁面溫州網(wǎng)站建設(shè)優(yōu)化
數(shù)據(jù)庫的概念
SQL(Structured Query Language)是一種專門用來與數(shù)據(jù)庫進(jìn)行交互的編程語言,它允許用戶查詢、更新和管理關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)。關(guān)系型數(shù)據(jù)庫是基于表(Table)的數(shù)據(jù)庫,其中表由行(Row)和列(Column)組成,每一行代表一個(gè)記錄(Record),每一列代表一個(gè)字段(Field)。
非關(guān)系型數(shù)據(jù)庫MongoDB
? ? ??
1、分類: 大型 ? ?中型 ? ??? ??? ?小型
?? ??? ? ORACLE ? MYSQL/MSSQL ? SQLITE ?DBII powdb
?? ??? ?關(guān)系型數(shù)據(jù)庫 ? ? ? ?
2、名詞:
?? ??? ?DB?? ??? ?數(shù)據(jù)庫 select update database
?? ??? ?DBMS?? ?數(shù)據(jù)庫管理系統(tǒng)
?? ??? ?MIS ? ? 管理信息系統(tǒng)
?? ??? ?OA ? ? ?辦公自動(dòng)化
3、嵌入式數(shù)據(jù)庫:
?? ??? ?sqlite3 ? ?www.sqlite.org ?www.kernal.org
?? ?GNU ??
?? ?特點(diǎn):
?? ??? ? ?1、開源 ?C語言開發(fā)
?? ??? ? ?2、代碼量少 1萬行左右,總大小10M以內(nèi)
?? ??? ? ?3、綠色軟件無需安裝
?? ??? ? ?4、文件型數(shù)據(jù)庫,可以移動(dòng)。
?? ??? ? ?5、數(shù)據(jù)容量最大 2T ??
4、sqlite3的安裝: LTS long term support?
??? ?1、在線安裝 :
?? ??? ??? ??? ?sudo apt-get install sqlite3?
?? ??? ??? ??? ?sudo apt-get install libsqlite3-dev
?? ?
?? ??? ?gcc test.c -lsqlite3 -lpthread
?? ??? ?
?? ?2、驗(yàn)證是否安裝成功:
?? ??? ?sqlite3 --version
?? ??? ?sqlite3 --help
5、sqlite3的使用:
?? ?0、啟動(dòng)sqlite3?
?? ??? ??? ?sqlite3 xxx.db ?
?? ??? ??? ?===>用sqlite3 來打開一個(gè)名稱為test.db的本地?cái)?shù)據(jù)庫。
?? ??? ??? ?出現(xiàn)如下提示符:表明數(shù)據(jù)庫管理系統(tǒng)啟動(dòng)。
?? ??? ??? ?sqlite>?
?? ? ??? ??? ?退出數(shù)據(jù)庫:?
?? ? ? ?? ??? ?.q 命令
?? ??? ??? ?
?? ??? ??? ?注意:如果一直出現(xiàn)如下符號(hào):
?? ??? ??? ?...> ??
?? ??? ??? ?則寫';'結(jié)束。
sql命令
以下所有命令必須在 sqlite> 后執(zhí)行。
?? ?創(chuàng)建一個(gè)數(shù)據(jù)庫:
?? ??? ?1、touch ?xxx.db
?? ??? ?2、sqlite3 xxx.db
? ? ? ? 系統(tǒng)維護(hù)命令:===> .help
?? ??? ?出現(xiàn)所有相關(guān)的系統(tǒng)維護(hù)命令,都是以 "."開頭。
?? ??? ?.database ?列出當(dāng)前庫和系統(tǒng)中那個(gè)文件在關(guān)聯(lián)
?? ??? ?.tables ? ?列出當(dāng)期數(shù)據(jù)庫中的所有表
?? ??? ?.schema xxx 列出當(dāng)前指定的xxx表結(jié)構(gòu)
?? ??? ?.dump user ? ===>導(dǎo)出數(shù)據(jù)庫
?? ??? ?重定向
?? ??? ?sqlite3 test.db .dump > 123.sql
?? ??? ?sqlite3 xxx.db < test.sql ===>導(dǎo)入數(shù)據(jù)庫
?? ??? ?
sql語句
? 標(biāo)準(zhǔn)SQL語句:===》通用語法在其他平臺(tái)可以直接使用。struct query language;
?? ??? ?注意:所有的sql語句都以';'結(jié)尾。
?? ??? ?創(chuàng)建一個(gè)表:ddl
?? ??? ?create table ?表名(表字段1,表字段2,...);
?? ??? ?eg: create table user(id,name,age); ? ? ? ? char?
?? ??? ?注意:以上表的表字段,支持如下數(shù)據(jù)類型。int text real blob
?? ??? ??? ? ?默認(rèn)是text類型。char
;
?? ??? ?create table 表名 (表字段 類型,表字段 類型,。。。。);
?? ??? ?eg:
?? ??? ?create table user(id int ?,name char,age int);
?? ??? ?刪除一個(gè)表:
?? ??? ?drop table ?表名;
?? ??? ?eg:drop table user;
?? ? ? 數(shù)據(jù)庫常規(guī)操作: 增加 刪除 修改 查詢
?? ? ? 向表中增加數(shù)據(jù):
?? ? ? insert into 表名 (字段名稱 ) values (值名稱);
?? ? ? eg:insert into user (id,age) values (1,10);
?? ? ? insert into user values(3,"wang",11);
?? ? ? insert into user (age) values ( 12);
?? ? ? 查詢表中的數(shù)據(jù):
?? ? ? select 列名 from 表名 ?條件;
?? ? ? eg:select * from user ;
?? ? ? ? ? select id from user;
?? ??? ? ? select id,name from user where not ?age <30
?? ??? ? ? where name ? like '三一' ? % _ 通配符
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ? asc
?? ??? ? ? select *from user where age>20 or age<50 order by age desc limit 2 ;
?? ??? ? ? && ?||
?? ? ? 修改表中數(shù)據(jù):
?? ? ? update 表名 set 表字段 = 值 ?滿足條件:
?? ? ? eg: update user set id = 1 where name = 'li';
?? ? ? update user set id = 1 where name = "li" and passwd = "123";
?? ? ? update user set id = 2 where name = "li" or ?name = "zhao";
?? ??
?? ? ? 刪除表中數(shù)據(jù):
?? ? ? delete from 表名 ?滿足條件:
?? ? ? eg:delete from user ; ?///刪除表中所有數(shù)據(jù)
?? ? ? ?? ? ? delete from user where id ?= 1; ///刪除id=1 的數(shù)據(jù);
?? ??? ? ? delete from user where id =1 and name = "zhang";
?? ??? ? ? delete from user where id = 1 or id ?= 2;
>2022-1-1 and <2018-12-31
插入時(shí)間列 int int;
?? ?unicode
?? ?CREATE TABLE user1(id int,name char,age int,dt datetime);'2022-07-01 19:00:00'
?? ?insert into user1 values (2,'張三',23,datetime('now','+8 hours'));
自動(dòng)增長(zhǎng)列
?? ?sqlite> CREATE TABLE user3(id INTEGER PRIMARY KEY ASC,name char,age int,dt datetime); ?主鍵?
sqlite> insert into user3 (NULL,'李四',23,datetime('now')); ? (void*)0
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?asc?
?? ?where (group by having) order by [desc] limit;
?? ?select * from user where id<10 order by id limit 2; ?
?
維護(hù)命令:
1、數(shù)據(jù)的導(dǎo)出:
?? ??? ?sqlite3 xxx.db .dump > xxx.sql
?? ?//將數(shù)據(jù)庫名稱為xxx的數(shù)據(jù)庫整體導(dǎo)出到腳本中。
?? ?
2、數(shù)據(jù)的導(dǎo)入:
?? ??? ?sqlite3 xxx.db < xxx.sql
3、可視化工具安裝:
?? ?sudo apt-get install sqlitebrowser?
?
sqlite3 數(shù)據(jù)庫編程接口:
1、需要的頭文件
?? ??? ?sqlite3.h
2、編譯過程
?? ??? ?-lsqlite3
3、編程框架:
打開數(shù)據(jù)庫 ==》讀寫數(shù)據(jù)庫(增,刪,改,查) ==》關(guān)閉數(shù)據(jù)庫
sqlite3.h
3.1 打開數(shù)據(jù)庫: sqlite3_open
? ? int sqlite3_open(char * path,sqlite3 ** db);
?? ?功能:打開指定path路徑+文件名稱的數(shù)據(jù)庫,并將
?? ??? ? ?打開的地址指向db變量的句柄。
?? ?參數(shù):path 要打開的數(shù)據(jù)庫路徑+名稱
?? ??? ? ?db ?要打開的數(shù)據(jù)庫地址指針
?? ?返回值:成功 ?0
?? ??? ??? ?失敗 ?-1;
3.2 關(guān)閉數(shù)據(jù)庫: sqlite3_close
?? ?int sqlite3_close(sqlite3 *db);
?? ?功能:關(guān)閉指定的數(shù)據(jù)庫
?? ?參數(shù):要關(guān)閉的數(shù)據(jù)庫地址
?? ?返回值:成功 ?0
?? ??? ??? ?失敗 ?-1;
3.3 數(shù)據(jù)庫操作:
?? ?查詢操作:sqlite3_get_table(); ?select?
?? ?int sqlite3_get_table(sqlite3 *db,char *sql,
?? ??? ??? ??? ??? ?char *** rest,int *nrow,int *ncol,
?? ??? ??? ??? ??? ?char ** errmsg);
?? ?功能:在db數(shù)據(jù)庫上執(zhí)行sql查詢語句,并將執(zhí)行的
?? ??? ? ?結(jié)果集返回到rest地址上,同時(shí)返回查詢的行和列。
?? ?參數(shù):db 要執(zhí)行查詢語句的數(shù)據(jù)庫
?? ? ? ? ?sql ?要執(zhí)行的select查詢語句
?? ??? ? ?rest 查詢的結(jié)果集是一個(gè)三級(jí)指針
?? ??? ? ?nrow 查詢的結(jié)果的行數(shù)
?? ??? ? ?ncol 查詢的結(jié)果的列數(shù)
?? ??? ? ?errmsg 如果執(zhí)行有錯(cuò)誤,則存儲(chǔ)錯(cuò)誤。
?? ?返回值:成功 0
?? ??? ??? ?失敗 非0;
?? ?執(zhí)行sql語句:sqlite3_exec(); ? insert delete update
?? ?int sqlite3_exec(sqlite3 *db,char *sql,callback fun,
?? ??? ??? ??? ??? ?void * arg,char ** errmsg);
?? ?功能:在db數(shù)據(jù)庫上執(zhí)行sql 非查詢語句。
?? ??? ? ?并將結(jié)果返回。
?? ?參數(shù):db 要執(zhí)行sql的數(shù)據(jù)庫
?? ??? ? ?sql ?要執(zhí)行的非查詢sql語句。
?? ??? ? ?fun ?如果該函數(shù)要執(zhí)行查詢語句,則該回調(diào)函數(shù)
?? ??? ? ??? ? ? 用來回收查詢的結(jié)果。
?? ??? ? ?arg ?回調(diào)函數(shù)的參數(shù),如果沒有回調(diào)函數(shù)則該參數(shù)為NULL;
?? ??? ? ?errmsg ?執(zhí)行過程中的錯(cuò)誤信息。
?? ?返回值:執(zhí)行成功 ?0
?? ??? ??? ?失敗 ?非0 ;
?? ?int fun(void *arg ,int f_num,char ** f_value,
?? ? ? ? ? ?char ** f_name)
?? ?
?? ?功能:該函數(shù)用于sqlite3_exec執(zhí)行select語句的
?? ??? ? ?結(jié)果集返回?cái)?shù)據(jù)。
?? ?參數(shù):arg 由sqlite3_exec傳入的參數(shù)
?? ??? ? ?f_num 執(zhí)行該命令所返回測(cè)結(jié)果集的字段個(gè)數(shù)。
?? ??? ? ?f_value 查詢結(jié)果集中的字段的值。
?? ??? ? ?f_name ?查詢結(jié)果集中的字段的名稱。
?? ?返回值:成功 0
?? ??? ??? ?失敗 非0
?? ?注意:該回調(diào)函數(shù)必須有返回值,否則可能導(dǎo)致查詢異常。
使用:打印一張表
#include <stdio.h>
#include <sqlite3.h>
int show(void*arg,int col,char**result,char**title)
{static int flag = 0;int i = 0 ;if(0 == flag){for(i = 0 ;i<col;i++){printf("%s\t",title[i]);}printf("\n");flag = 1;}for(i = 0 ;i<col;i++){printf("%s\t",result[i]);}printf("\n");return 0;
}
int main()
{sqlite3* db=NULL;int ret = sqlite3_open("/home/linux/20240812/sec4/aaa.db",&db);if(SQLITE_OK!=ret){fprintf(stderr,"cant opendb,%s\n",sqlite3_errstr(ret));sqlite3_close(db);return 1;}char sql_cmd[128]="select * from user;";char * errmsg=NULL;ret = sqlite3_exec(db,sql_cmd,show,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}sqlite3_close(db);printf("Hello World!\n");return 0;
}
提升插入速度
在SQLite3中,提升數(shù)據(jù)插入速度的方法主要包括以下幾個(gè)方面:
1. 使用事務(wù)(Transaction)
事務(wù)可以將多個(gè)插入操作組合在一起,從而減少每次插入操作的開銷。在SQLite中,每調(diào)用一次sqlite3_exec()
函數(shù),就會(huì)隱式地開啟一個(gè)事務(wù)。如果插入一條數(shù)據(jù)就調(diào)用一次該函數(shù),事務(wù)會(huì)被反復(fù)地開啟和關(guān)閉,這會(huì)增大IO量。因此,在插入數(shù)據(jù)前顯式開啟事務(wù),并在插入完成后一起提交,可以顯著提高IO效率,進(jìn)而加快數(shù)據(jù)插入速度。
#include <stdio.h>
#include <sqlite3.h>
#include <string.h>
int main()
{char * errmsg=NULL;sqlite3* db=NULL;int ret = sqlite3_open("/home/linux/20240812/sec4/aaa.db",&db);if(SQLITE_OK!=ret){fprintf(stderr,"cant opendb,%s\n",sqlite3_errstr(ret));sqlite3_close(db);return 1;}char sql_cmd[1024]={0};sprintf(sql_cmd,"create table if not exists dict""(x INTEGER PRIMARY KEY ASC,word char,mean text);");ret = sqlite3_exec(db,sql_cmd,NULL,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error create table,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}bzero(sql_cmd,sizeof(sql_cmd));sprintf(sql_cmd,"delete from dict");ret = sqlite3_exec(db,sql_cmd,NULL,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error create table,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}FILE* fp = fopen("/home/linux/dict.txt","r");if(NULL == fp){perror("fopen");return 1;}// BEGIN TRANSACTION;bzero(sql_cmd,sizeof(sql_cmd));sprintf(sql_cmd,"BEGIN TRANSACTION;");ret = sqlite3_exec(db,sql_cmd,NULL,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error create table,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}while(1){//char sql_cmd[128]="insert into user values(7,'bbb',11);";char line[512]={0};if(NULL == fgets(line,sizeof(line),fp)){break;}char* word = strtok(line," ");char *mean = strtok(NULL,"\r");bzero(sql_cmd,sizeof(sql_cmd));sprintf(sql_cmd,"insert into dict values(NULL,\"%s\",\"%s\");",word,mean);ret = sqlite3_exec(db,sql_cmd,NULL,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}}bzero(sql_cmd,sizeof(sql_cmd));sprintf(sql_cmd,"COMMIT;");ret = sqlite3_exec(db,sql_cmd,NULL,NULL,&errmsg);if(SQLITE_OK!=ret){fprintf(stderr,"exec error create table,%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}sqlite3_close(db);printf("Hello World!\n");return 0;
}
2. 關(guān)閉寫同步(Synchronous OFF)
SQLite的synchronous
模式控制數(shù)據(jù)寫入物理存儲(chǔ)的同步方式。該模式有三種可選狀態(tài):full
、normal
、off
。其中,full
寫入速度最慢但保證數(shù)據(jù)安全性,而off
可以加速數(shù)據(jù)庫操作,但在系統(tǒng)崩潰或斷電時(shí)可能會(huì)導(dǎo)致數(shù)據(jù)庫損毀。如果應(yīng)用場(chǎng)景允許少量數(shù)據(jù)丟失,可以將synchronous
設(shè)置為OFF
以提升插入速度。
通過設(shè)置PRAGMA synchronous = OFF;
,可以關(guān)閉數(shù)據(jù)庫的同步寫入功能,這將允許SQLite在將數(shù)據(jù)傳遞給操作系統(tǒng)后不等待磁盤寫入完成就繼續(xù)執(zhí)行,從而提高插入速度。但請(qǐng)注意,這可能會(huì)增加數(shù)據(jù)丟失的風(fēng)險(xiǎn)。
#include <stdio.h>
#include <sqlite3.h>
#include <string.h> int main()
{ char *errmsg = NULL; sqlite3 *db = NULL; int ret = sqlite3_open("/home/linux/20240812/sec4/aaa.db", &db); if (SQLITE_OK != ret) { fprintf(stderr, "cant open db, %s\n", sqlite3_errstr(ret)); return 1; } // 關(guān)閉同步 char *pragma_cmd = "PRAGMA synchronous = OFF;"; ret = sqlite3_exec(db, pragma_cmd, NULL, NULL, &errmsg); if (SQLITE_OK != ret) { fprintf(stderr, "exec error setting synchronous, %s\n", errmsg); sqlite3_free(errmsg); sqlite3_close(db); return 1; } // ... (其他數(shù)據(jù)庫操作,如創(chuàng)建表、插入數(shù)據(jù)等) sqlite3_close(db); printf("Hello World!\n"); return 0;
}