<p><strong><strong>前言</strong></strong></p><p>數據在實際工作中應用非常廣泛,數據庫的產品也比較多,oracle、DB2、SQL2000、mySQL;基于嵌入式linux的數據庫主要有SQLite, Firebird, Berkeley DB, eXtremeDB。</p><p>本文主要講解數據庫SQLite,通過這個開源的小型的嵌入式數據庫帶領大家掌握一些基本的數據庫操作,這些操作在很多系統中都是通用的,可謂學一通百。</p><p><strong><strong>SQLite</strong></strong></p><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-dbc0c7525cfae188.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>SQLite,是一款輕型的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對小的C庫中。</p><p><strong><strong>作者D.RichardHipp</strong></strong></p><p>2000年1月,Hipp開始和一個同事討論關于創建一個簡單的嵌入式SQL數據庫的想法,這個數據庫將使用GNU
DBM哈希庫(gdbm)做后臺,同時這個數據庫將不需要安裝和管理支持。后來,一有空閑時間,Hipp就開始實施這項工作,2000年8月,SQLite
1.0版發布了。【在此向大神獻上我的膝蓋!】</p><p>它的設計目標是嵌入式的,而且已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如
Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源的世界著名數據庫管理系統來講,它的處理速度比他們都快。</p><p><strong><strong>SQLite特性</strong></strong></p><ol><li><p>零配置一無需安裝和管理配置;</p></li><li><p>儲存在單一磁盤文件中的一個完整的數據庫;</p></li><li><p>數據庫文件可以在不同字節順序的機器間自由共享;</p></li><li><p>支持數據庫大小至2TB;</p></li><li><p>足夠小,全部源碼大致3萬行c代碼,250KB;</p></li><li><p>比目前流行的大多數數據庫對數據的操作要快。</p></li></ol><p><strong><strong>安裝</strong></strong></p><p>現在運行的主要是sqlite3版本,在ubuntu下安裝也非常方便。</p><pre>sudo?apt-get?install?sqlite?sqlite3???安裝應用程序
sudo?apt-get?install?libsqlite3-dev???安裝庫+頭文件,用代碼操作數據庫必須安裝</pre><p>查看版本號: 輸入命令 sqlite3進入操作界面,輸入命令.version,即可查看詳細版本號。</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-5b76265622e87398.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>也可以使用下面命令,安裝圖形化操作工具:</p><pre>sudo?apt-get?install?sqlitebrowser????圖形化工具建立數據庫</pre><p>除此之外,還可以部署在windows下,本文只討論ubtuntu下,采用命令行方式來操作數據庫。</p><p><strong><strong>數據類型</strong></strong></p><p>操作數據庫,主要就是操作表,表的每一列內容都有一定數據類型,比如整型值、字符串、布爾型等。</p><p><strong>Sqlite3主要數據類型如下:</strong></p><p>ble d<strong>at</strong>a-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"></p><p>同時sqlite3也接受如下的數據類型:</p><p>ble d<strong>at</strong>a-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"></p><p><strong><strong>約束</strong></strong></p><p>表的每一列都有一些限制屬性,比如有的列的數據不能重復,有的則限制數據范圍等,約束就是用來進一步描述每一列數據屬性的。 SQLite 數據庫常用約束如下:</p><p>ble<strong> d</strong>ata-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"></p><p><strong><strong>非空 NOT NULL</strong></strong></p><p>有一些字段我們可能一時不知到該填些什么,同時它也沒設定默認值,
當添加數據時,我們把這樣的字段空著不填,系統認為他是 NULL 值。但是還有另外一類字段,必須被填上數據,如果不填,系統就會報錯。
這樣的字段被稱為 NOT NULL 非空字段,需要在定義表的時候事先聲明。</p><p><strong><strong>唯一 UNIQUE</strong></strong></p><p>除了主列以為,還有一些列也不能有重復值。</p><p><strong><strong>主鍵 PRIMARY KEY</strong></strong></p><p>一般是整數或者字符串,只要保證唯一就行。 在 SQLite 中,主鍵如果是整數類型,該列的值可以自動增長。</p><p><strong><strong>外鍵 FOREIGN KEY</strong></strong></p><p>我們的數據庫中已經有
Teachers 表了,假如我們再建立一個 Students 表, 要求 Students 表中的每一個學生都對應一個 Teachers
表中的教師。 很簡單,只需要在 Students 表中建立一個 TeacherId 字段,保存對應教師的 Id 號,
這樣,學生和教師之間就建立了關系。 問題是:我們有可能給學生存入一個不在 Teachers 表中的 TeacherId 值,
而且發現不了這個錯誤。 這種情況下,可以把 Students 表中 TeacherId 字段聲明為一個外鍵, 讓它的值對應到 Teachers
表中的 Id 字段上。 這樣,一旦在 Students 表中存入一個不存在的教師 Id ,系統就會報錯。</p><p><strong><strong>默認值 DEFAULT</strong></strong></p><p>有一些特別的字段列,在每一條記錄中,他的值基本上都是一樣的。只是在個別情況下才改為別的值,這樣的字段列我們可以給他設一個默認值。</p><p><strong><strong>條件檢查 CHECK</strong></strong></p><p>某些值必須符合一定的條件才允許存入,這是就需要用到這個 CHECK 約束。</p><p><strong><strong>常用命令</strong></strong></p><p>下面介紹Shell模式中的各常用命令的使用。</p><p>ble<strong> d</strong>ata-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"></p><p>【注意】sqlite的命令都是.開頭的,操作語句前面是沒有.的。</p><p><strong><strong>使用實例</strong></strong></p><p>數據庫的操作語句主要是增刪改查,下面我們通過一些實例讓大家了解數據庫的這些基本操作。</p><p><strong><strong>表類型</strong></strong></p><p>假設我們要創建一個教學管理的數據庫jxgl.db,數據庫中要保存學生表STUDENT。</p><p>ble <strong>data-</strong>d<strong>raft</strong>-<strong>node</strong>=<strong>"bloc</strong>k" data-draft-type="table" data-size="normal" data-row-style="normal"></p><p>根據我們的常識,可知每一列的數據有以下特性:</p><ul><li><p>sno ? ? ?學號:整型值,每個人學號是唯一的,學校一般用學號來區分所有的學生,而且一般學號是遞增的,所以我們設置sno為primary key;</p></li><li><p>sname 姓名:一般是字符串,可以重復,但是不能為空;</p></li><li><p>ssex ? ?性別:字符串,可以為空;</p></li><li><p>sage ? 年齡:整型值,假定年齡要大于14;</p></li><li><p>sdept ?專業:字符串,可以為空,此處我們默認為'CS'。</p></li></ul><p>下面我們一步步實現這個數據庫的所有操作。</p><p><strong><strong>創建教學管理“jxgl”數據庫</strong></strong></p><p>數據庫的打開和退出,使用如下命令。</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-38cd11a9d6e97280.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>
</p><p><strong><strong>創建表:</strong></strong></p><pre>CREATE?TABLE?IF?NOT?EXISTS?STUDENT(Sno?integer?primary?key,???Sname?text?not?null,???Ssex?text,Sage?integer?check(Sage>14),Sdept?text?default?'CS');</pre><p>該表的屬性就是按照上一節表屬性 執行結果:</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-c3c0ed8784fcc581.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>
</p><p><strong><strong>查看表:</strong></strong></p><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-84bb2c0c3b99875e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>看到STUDENT,說明該表創建好了。 【注意】</p><ol><li><p>操作語句不是命令,前面不要加. ;</p></li><li><p>操作語句后面一定要;結尾,如果漏掉了,一定要補上分號;</p></li><li><p>操作語句對字母的全角半角很敏感,所有的符號都要用半角。</p></li></ol><p><strong><strong>插入數據</strong></strong></p><p>插入數據采用insert into語句來實現,如下所示:</p><pre>INSERT?INTO?STUDENT?VALUES('95001','李勇','M',20,'CS');
INSERT?INTO?STUDENT?VALUES('95002','劉晨','F',19,'IS');
INSERT?INTO?STUDENT?VALUES('95003','王敏','F',18,'MA');
INSERT?INTO?STUDENT?VALUES('95004','張立','M',18,'IS');</pre><p>執行結果如下:</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-25aeacd50b14c74e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>插入的數據只初始化部分值</strong></strong></p><p>設置了not null那一列 必須要賦值,而且表名字不區分大小寫。</p><pre>insert?into?student(sname,sage)?values?('一口',19);</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-63abca97f378156e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>查看表</strong></strong></p><p>用SELECT語句查看表中的內容:</p><pre>SELECT??FROM?STUDENT;</pre><p>其中的 * 表示查看所有的數據信息。</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-b4625506bcf2faa1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>有沒有看到,結果看起來不舒服啊,下面我們來調整下顯示格式:</p><pre>sqlite>?.headers?on??????????顯示列名
sqlite>?.mode?column?????????列對齊</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-a3284a8f12977ba4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>刪除一行信息</strong></strong></p><pre>delete?from?student?where?sname='一口';</pre><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-1a2fadd6483b0de3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>由上圖可見,名字為“一口”的那條記錄被刪除了。</p><p><strong><strong>修改一條記錄的某個內容</strong></strong></p><pre>UPDATE?student?SET?sage=29?WHERE?sname='張立';</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-0f80cf02282b9a64.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>修改數據表結構。</strong></strong></p><p>修改表結構,需要用到語句ALTER TABLE。 下面我們向STUDENT表增加“spwd”列,其數據類型為TEXT型,用SELECT命令查看表中內容。</p><pre>ALTER?TABLE?STUDENT?ADD?spwd?TEXT?default?'123456';</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-e1f5c71ea118bf3c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>修改表名字</strong></strong></p><pre>alter?table?student?rename?to?stu;</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-f40fa302ea13127c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>刪除數據表。</strong></strong></p><pre>DROP?TABLE?STUDENT;</pre><p><strong><strong>刪除列</strong></strong></p><p>sqlite3沒有實現刪除一列的命令,要實現這個操作,需要先將該表拷貝到一個新表,但是只集成需要的列,要刪除的列不繼承過來。 可以 用以下方式操作刪除一列:</p><pre>sqlite>?create?table?test?as?select?sno,?sname,ssex,sage,sdept??from?stu;
sqlite>?drop?table?stu;
sqlite>?alter?table?test?rename?to?stu;</pre><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-d6d152bdfbb3a850.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>由上圖可知,我們剛才增加的列spwd被刪除了。</p><p><strong><strong>sqlite進階</strong></strong></p><p><strong><strong>where子句</strong></strong></p><p>如果我不想查看所有的數據,而指向查看某一個人的信息要怎么操作呢? 我們就要借助where子句來實現。 where子句可以結合操作語句來進程增刪改查,是最常用的一個子句。</p><p><strong>根據姓名查找記錄:</strong></p><pre>Select??from?student?where?sname='一口';</pre><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-36984f460a69be0e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong>根據學號查找記錄:</strong></p><pre>Select??from?student?where?sno=95001;</pre><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-36da245acc748f08.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong>根據姓名和年齡同時查找記錄:</strong></p><pre>select?from?student?where?sname='一口'?and?sage=19;</pre><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-ece728ad9dee12dc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong>顯示某兩列的數據</strong></p><pre>select?sno,sname?from?student?;</pre><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/23850874-f8adcf4d8e58c82f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong><strong>數據庫的備份和恢復</strong></strong></p><p>現在我們假設要將表foods備份出為foodsdb.sql,并用命令回復該數據庫。 按照以下步驟操作即可。</p><pre>sqlite>.dump???????--把創建表及向表中插入記錄的所有SQL語句顯示在屏幕上
sqlite>.output??foodsdb.sql?--指定dump命令輸出到文件的文件名
sqlite>.dump????????--輸出創建并插入數據到基本表的SQL語句到output指定的文件
sqlite>.output?stdout??--恢復輸出內容到標準輸出設備(屏幕)
sqlite>.dump???????????--此時輸出的SQL語句轉回到屏幕?
sqlite>Drop?table?foods;?--刪除foods表語句說明:</pre><p>上述Drop為SQL語句,用于刪除指定的表。因為是SQL語句,因此以“;”結尾</p><pre>sqlite>.read?foodsdb.sql????--執行foodsdb.sql中的包含的所有SQL語句,用來重建剛刪除的4張表及相關數據</pre><p>好了,跟著一口君一步步操作,基本上sqlite3的增刪改查操作,相信各位應該沒什么問題了,sqlite還有其他一些子句以及函數的用法,留待下一篇繼續介紹。</p><p>獲取更多關于Linux的資料,請關注公眾號「一口Linux」</p><p>
</p>