SQLite入门与分析(九)VACUUM命令分析
VACUUM命令是SQLite的一個(gè)擴(kuò)展功能,模仿PostgreSQL中的相同命令而來。若調(diào)用VACUUM帶一個(gè)表名或索引名, 則將整理該表或索引。在SQLite 1.0中,VACUUM命令調(diào)用 gdbm_reorganize()整理后端數(shù)據(jù)庫文件。
SQLITE 2.0.0中去掉了GDBM后端,VACUUM無效。在2.8.1版中,VACUUM被重新實(shí)現(xiàn)。現(xiàn)在索引名或表名被忽略。
當(dāng)數(shù)據(jù)庫中的一個(gè)對(duì)象(表,索引或觸發(fā)器)被撤銷,會(huì)留下空白的空間。它使數(shù)據(jù)庫比需要的大小更大,但能加快插入速度。實(shí)時(shí)的插入和刪除會(huì)使得數(shù)據(jù)庫文件結(jié)構(gòu)混亂,減慢對(duì)數(shù)據(jù)庫內(nèi)容訪問的速度。 VACUUM命令復(fù)制主數(shù)據(jù)庫文件到臨時(shí)數(shù)據(jù)庫并從臨時(shí)數(shù)據(jù)庫重新載入主數(shù)據(jù)庫,以整理數(shù)據(jù)庫文件。這將除去空白頁,使表數(shù)據(jù)彼此相鄰排列,并整理數(shù)據(jù)庫文件結(jié)構(gòu)。不能對(duì)附加數(shù)據(jù)庫文件進(jìn)行以上操作。
若當(dāng)前有活動(dòng)事務(wù),該命令無法起作用。對(duì)于in-memory數(shù)據(jù)庫,該命令無效。
SQLite3.1中,可以通過使用auto-vacuum模式取代VACUUM命令,使用 auto_vacuum pragma開啟該模式。
VACUUM的使用:VACUUM main
當(dāng)對(duì)3.4節(jié)中討論的數(shù)據(jù)進(jìn)行VACUUM操作后,頁面只剩第一個(gè)頁面。
VACUUM實(shí)現(xiàn):
代碼實(shí)現(xiàn)(vcuum.c):
intsqlite3RunVacuum(char**pzErrMsg,sqlite3*db){
///////////////////////////////////第1步////////////////////////////////////////////////
zSql=sqlite3MPrintf("ATTACH'%q'ASvacuum_db;",zTemp);
//創(chuàng)建臨時(shí)數(shù)據(jù)庫vacuum_db
rc=execSql(db,zSql);
///////////////////////////////////第2步////////////////////////////////////////////////
//開始一個(gè)事務(wù)
rc=execSql(db,"BEGINEXCLUSIVE;");
///////////////////////////////////第3步////////////////////////////////////////////////
//在vacuum_db中建立main數(shù)據(jù)庫的所有表,索引和視圖,并將main中的所有表,索引和視圖的數(shù)據(jù)插入
//到vacuum_db。即在vacuum_db建立main的鏡象。
rc=execExecSql(db,
"SELECT'CREATETABLEvacuum_db.'||substr(sql,14,100000000)"
"FROMsqlite_masterWHEREtype='table'ANDname!='sqlite_sequence'");
if(rc!=SQLITE_OK)gotoend_of_vacuum;
rc=execExecSql(db,
"SELECT'CREATEINDEXvacuum_db.'||substr(sql,14,100000000)"
"FROMsqlite_masterWHEREsqlLIKE'CREATEINDEX%'");
if(rc!=SQLITE_OK)gotoend_of_vacuum;
rc=execExecSql(db,
"SELECT'CREATEUNIQUEINDEXvacuum_db.'||substr(sql,21,100000000)"
"FROMsqlite_masterWHEREsqlLIKE'CREATEUNIQUEINDEX%'");
if(rc!=SQLITE_OK)gotoend_of_vacuum;
rc=execExecSql(db,
"SELECT'CREATEVIEWvacuum_db.'||substr(sql,13,100000000)"
"FROMsqlite_masterWHEREtype='view'"
);
rc=execExecSql(db,
"SELECT'INSERTINTOvacuum_db.'||quote(name)"
"||'SELECT*FROM'||quote(name)||';'"
"FROMsqlite_master"
"WHEREtype='table'ANDname!='sqlite_sequence';"
);
///////////////////////////////////第4步////////////////////////////////////////////////
//將vacumm_db數(shù)據(jù)庫對(duì)應(yīng)的數(shù)據(jù)文件的數(shù)據(jù)拷貝到main數(shù)據(jù)庫對(duì)應(yīng)的數(shù)據(jù)文件,一個(gè)頁面一個(gè)頁面的拷貝
rc=sqlite3BtreeCopyFile(pMain,pTemp);
///////////////////////////////////第5步////////////////////////////////////////////////
//提交事務(wù)
rc=sqlite3BtreeCommit(pTemp);
if(rc!=SQLITE_OK)gotoend_of_vacuum;
rc=sqlite3BtreeCommit(pMain);
}
總結(jié)
以上是生活随笔為你收集整理的SQLite入门与分析(九)VACUUM命令分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sqlserver 数据库安全
- 下一篇: 贝塞尔曲线(UIBezierPath)属