SQLite數據庫約束詳解(1)

1、約束 Constraintsweb

SQLite數據庫中存儲數據的時候,有一些數據有明顯的約束條件。 好比一所學校關於教師的數據表,其中的字段列可能有以下約束:sql

年齡 - 至少大於20歲。若是你想錄入一個小於20歲的教師,系統會報錯.數據庫

國籍 - 默認中國。所謂默認,就是若是你不填寫,系統自動填上默認值.ubuntu

姓名 - 不能爲空。每一個人都有名字嘛.命令行

員工號 - 惟一。這個可不能亂,工資發錯了就麻煩了.code

上面提到的大於、默認、不能爲空、惟一等等,就是數據的約束條件。 咱們在用CREATE TABLE 建立表的時候,就應該將每一個字段列的約束條件事先說明(若是有的話), 之後再往表裏輸入數據的時候,系統會自動爲咱們檢查是否知足約束條件,若是不知足系統會報錯。orm

SQLite 數據庫經常使用約束以下:sqlite

  • NOT NULL - 非空索引

  • UNIQUE - 惟一字符串

  • PRIMARY KEY - 主鍵

  • FOREIGN KEY - 外鍵

  • CHECK - 條件檢查

  • DEFAULT - 默認

2、主鍵 PRIMARY KEY

咱們仍是進入SQLite 命令行環境,創建一個 test.db 數據庫用來作實驗,以下

myqiao@ubuntu:~/My Documents/db$ sqlite3 test.db   -- Loading resources from /home/myqiao/.sqliterc   SQLite version 3.7.4   Enter ".help" for instructions   Enter SQL statements terminated with a ";"   sqlite> .tables   sqlite>

運行 .tables 命令沒有返回,說明數據庫是空的。若是你的數據庫裏面有內容並影響到下面的實驗, 你能夠用咱們上一篇學的 DROP TABLE 來刪除形成影響的表, 或者用ALTER TABLE ... RENAME TO ... 來更名。

下面言歸正轉,咱們來講說主鍵 PRIMARY KEY 。

首先,數據表中每一條記錄都有一個主鍵, 這就像咱們每的身份證號碼、員工號、銀行賬號; 反過來也能夠說,每個主鍵對應着一條數據記錄。 因此,主鍵必須是惟一的。

其次,通常狀況下主鍵同時也是一個索引,因此經過主鍵查找記錄速度比較快。

第三,在關係型數據庫中,一個表的主鍵能夠做爲另一個表的外鍵, 這樣,這兩個表之間就經過這個鍵創建了關係。

最後,主鍵通常是整數或者字符串,只要保證惟一就行。 在 SQLite 中,主鍵若是是整數類型,該列的值能夠自動增加。

下面咱們來作實驗:

sqlite>  sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text);   sqlite> .tables   Teachers   sqlite> INSERT INTO Teachers(Name) Values('張三');   sqlite> INSERT INTO Teachers(Name) Values('李四');   sqlite> INSERT INTO Teachers(Name) Values('王二麻子');   sqlite> SELECT * FROM Teachers;   Id Name   ---------- ----------   1 張三   2 李四   3 王二麻   sqlite> INSERT INTO Teachers(Id,Name) Values(2,'孫悟空');   Error: PRIMARY KEY must be unique   sqlite>

咱們先新建了一個 Teachers 表,並設置了兩個字段列,其中 Id 字段列爲主鍵列。 而後,咱們向其中插入三條數據並查詢,反饋一切正常。

注意:在插入前三條數據的時候,命令中並無明確指明 Id 的值,系統自動賦值,而且數值自動增加。

插入第四條數據的時候,我給了一個明確的 Id 編號爲 2,由於李四的編號已是 2 了, 因此係統提示我錯誤:主鍵必須惟一。

3、默認值 DEFAULT

有一些特別的字段列,在每一條記錄中,他的值基本上都是同樣的。只是在個別狀況下才改成別的值,這樣的字段列咱們能夠給他設一個默認值。

下面咱們來作實驗:

sqlite>  sqlite> DROP TABLE Teachers;   sqlite> .tables   sqlite>  sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text,Country text DEFAULT '中國');   sqlite> .tables   Teachers   sqlite> INSERT INTO Teachers(Name) Values('張三');   sqlite> INSERT INTO Teachers(Name) Values('李四');   sqlite> INSERT INTO Teachers(Name) Values('王二麻子');   sqlite> INSERT INTO Teachers(Name,Country) Values('孫悟空','天庭');   sqlite> SELECT * FROM Teachers;   Id Name Country   ---- --------------- ---------------   1 張三 中國   2 李四 中國   3 王二麻子 中國   4 孫悟空 天庭   sqlite>

先把以前的 Teachers 表刪除,而後從新建立。這回 Teachers 表多了一個 Country 字段, 而且設置默認值爲「中國」,而後咱們插入四條數據到 Teachers 表。

前三條數據都沒有明確指明 Country 字段的值,只有第四條數據指明瞭「孫悟空」的 Country 爲「天庭」。

查詢數據,發現前三條數據都填上了默認值,實驗成功。

數據顯示有點走樣,命令 .width 4 15 15 設置的列寬,能夠經過 .show 查看, 多是由於中文的緣由,因此沒有對齊。

4、非空 NOT NULL

有一些字段咱們可能一時不知到該填些什麼,同時它也沒設定默認值, 當添加數據時,咱們把這樣的字段空着不填,系統認爲他是 NULL 值。可是還有另一類字段,必須被填上數據,若是不填,系統就會報錯。 這樣的字段被稱爲 NOT NULL 非空字段,須要在定義表的時候事先聲明。下面咱們來作實驗:

sqlite>  sqlite> DROP TABLE Teachers;   sqlite> .tables   sqlite>  sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text,Age integer NOT NULL,City text);   sqlite> .tables   Teachers   sqlite> INSERT INTO Teachers(Name,Age) Values('Alice',23);   sqlite> INSERT INTO Teachers(Name,Age) Values('Bob',29);   sqlite> INSERT INTO Teachers(id,Name,Age) Values(6,'Jhon',36);   sqlite> SELECT * FROM Teachers;   Id Name Age City   ---- --------------- --------------- ---------------   1 Alice 23 NULL   2 Bob 29 NULL   6 Jhon 36 NULL   sqlite> INSERT INTO Teachers(Name) Values('Mary');   Error: Teachers.Age may not be NULL   sqlite>

仍是先刪除舊錶,建立新表。

這回 Teachers 表聲明瞭一個 NOT NULL 字段 Age,同時還有一個能夠爲 NULL 的字段 City。

插入前三條數據都沒有指定 City 的值,查詢能夠看到 City 字段所有爲空。

注意:這裏的 NULL 只是對「什麼都沒有」的一種顯示形式, 能夠經過 .nullvalue 命令改成別的形式。

插入第四條數據時沒有指定 Age 的值,系統就報錯了: Teachers.Age 不能爲空。

5、 惟一 UNIQUE

這一約束很好理解,除了主列覺得,還有一些列也不能有重複值。很少說,直接看代碼:

sqlite>  sqlite> DROP TABLE Teachers;   sqlite> .tables   sqlite>  sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text UNIQUE);   sqlite> .tables   Teachers   sqlite> INSERT INTO Teachers(Name) VALUES('Alice');   sqlite> INSERT INTO Teachers(Name) VALUES('Bob');   sqlite> INSERT INTO Teachers(Name) VALUES('Jane');   sqlite> INSERT INTO Teachers(Name) VALUES('Bob');   Error: column Name is not unique   sqlite>

此次的 Teachers 表只有 Name 這一列,可是 Name 列不能有重複值。能夠看到,到咱們第二次插入 Bob 時,系統就報錯了。

6、 條件檢查 CHECK

某些值必須符合必定的條件才容許存入,這是就須要用到這個 CHECK 約束。

sqlite>  sqlite> DROP TABLE Teachers;   sqlite> .tables   sqlite>  sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Age integer CHECK(Age>22));   sqlite> .tables   Teachers   sqlite> INSERT INTO Teachers(Age) VALUES(45);   sqlite> INSERT INTO Teachers(Age) VALUES(33);   sqlite> INSERT INTO Teachers(Age) VALUES(23);   sqlite> INSERT INTO Teachers(Age) VALUES(21);   Error: constraint failed   sqlite>

Age 字段要求必須大於 22,當插入的數據小於22時,系統報錯。

7、外鍵 FOREIGN KEY

如今,咱們的數據庫中已經有 Teachers 表了,假如咱們再創建一個 Students 表, 要求 Students 表中的每個學生都對應一個 Teachers 表中的教師。

很簡單,只須要在 Students 表中創建一個 TeacherId 字段,保存對應教師的 Id 號, 這樣,學生和教師之間就創建了關係。

問題是:咱們有可能給學生存入一個不在 Teachers 表中的 TeacherId 值, 並且發現不了這個錯誤。

這種狀況下,能夠把 Students 表中 TeacherId 字段聲明爲一個外鍵, 讓它的值對應到 Teachers 表中的 Id 字段上。

這樣,一旦在 Students 表中存入一個不存在的教師 Id ,系統就會報錯。

sqlite>  sqlite> .tables   Teachers   sqlite> CREATE TABLE Students (Id integer PRIMARY KEY, TeacherId integer, FOREIGN KEY(TeacherId) REFERENCES Teachers(id) );   sqlite> .tables   Students Teachers   sqlite> SELECT * FROM Teachers;   Id Age   ---- ---------------   1 40   2 33   3 23   sqlite> INSERT INTO Students(TeacherId) VALUES(1);   sqlite> INSERT INTO Students(TeacherId) VALUES(3);   sqlite> INSERT INTO Students(TeacherId) VALUES(9);   sqlite> SELECT * FROM Students;   Id TeacherId   ---- ---------------   1 1   2 3   3 9   sqlite>

這裏創建了 Students 表,而且把 TeacherId 做爲外鍵與 Teachers 表的 Id 列相對應。

關於SQLite數據庫的約束就介紹到這裏,但願能給各位帶來幫助。

相關文章
相關標籤/搜索