SQLite数据库约束详解

一、约束 Constraints

SQLite数据库中存储数据的时候,有一些数据有明显的约束条件。 比如一所学校关于教师的数据表,其中的字段列可能有如下约束:

年龄 – 至少大于20岁。如果你想录入一个小于20岁的教师,系统会报错.

国籍 – 默认中国。所谓默认,就是如果你不填写,系统自动填上默认值.

姓名 – 不能为空。每个人都有名字嘛.

员工号 – 唯一。这个可不能乱,工资发错了就麻烦了.

上面提到的大于、默认、不能为空、唯一等等,就是数据的约束条件。 我们在用CREATE TABLE 创建表的时候,就应该将每个字段列的约束条件事先说明(如果有的话), 以后再往表里输入数据的时候,系统会自动为我们检查是否满足约束条件,如果不满足系统会报错。

SQLite 数据库常用约束如下:

  • NOT NULL – 非空
  • UNIQUE – 唯一
  • PRIMARY KEY – 主键
  • FOREIGN KEY – 外键
  • CHECK – 条件检查
  • DEFAULT – 默认

二、主键 PRIMARY KEY

我们还是进入SQLite 命令行环境,建立一个 test.db 数据库用来做实验,如下

 

  1. myqiao@ubuntu:~/My Documents/db$ sqlite3 test.db  
  2.  
  3. -- Loading resources from /home/myqiao/.sqliterc  
  4.  
  5. SQLite version 3.7.4  
  6.  
  7. Enter ".help" for instructions  
  8.  
  9. Enter SQL statements terminated with a ";"  
  10.  
  11. sqlite> .tables  
  12.  
  13. sqlite> 

 

运行 .tables 命令没有返回,说明数据库是空的。如果你的数据库里面有内容并影响到下面的实验, 你可以用我们上一篇学的 DROP TABLE 来删除造成影响的表, 或者用ALTER TABLE … RENAME TO … 来改名。

下面言归正转,我们来说说主键 PRIMARY KEY 。

首先,数据表中每一条记录都有一个主键, 这就像我们每的身份证号码、员工号、银行帐号; 反过来也可以说,每一个主键对应着一条数据记录。 所以,主键必须是唯一的。

其次,一般情况下主键同时也是一个索引,所以通过主键查找记录速度比较快。

第三,在关系型数据库中,一个表的主键可以作为另外一个表的外键, 这样,这两个表之间就通过这个键建立了关系。

最后,主键一般是整数或者字符串,只要保证唯一就行。 在 SQLite 中,主键如果是整数类型,该列的值可以自动增长。

下面我们来做实验:

 

  1. sqlite> 
  2.  
  3. sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text);  
  4.  
  5. sqlite> .tables  
  6.  
  7. Teachers  
  8.  
  9. sqlite> INSERT INTO Teachers(Name) Values('张三');  
  10.  
  11. sqlite> INSERT INTO Teachers(Name) Values('李四');  
  12.  
  13. sqlite> INSERT INTO Teachers(Name) Values('王二麻子');  
  14.  
  15. sqlite> SELECT * FROM Teachers;  
  16.  
  17. Id Name  
  18.  
  19. ---------- ----------  
  20.  
  21. 1 张三  
  22.  
  23. 2 李四  
  24.  
  25. 3 王二麻  
  26.  
  27. sqlite> INSERT INTO Teachers(Id,Name) Values(2,'孙悟空');  
  28.  
  29. Error: PRIMARY KEY must be unique  
  30.  
  31. sqlite> 

 

我们先新建了一个 Teachers 表,并设置了两个字段列,其中 Id 字段列为主键列。 然后,我们向其中插入三条数据并查询,反馈一切正常。

注意:在插入前三条数据的时候,命令中并没有明确指明 Id 的值,系统自动赋值,并且数值自动增长。

插入第四条数据的时候,我给了一个明确的 Id 编号为 2,因为李四的编号已经是 2 了, 所以系统提示我错误:主键必须唯一。

三、默认值 DEFAULT

有一些特别的字段列,在每一条记录中,他的值基本上都是一样的。只是在个别情况下才改为别的值,这样的字段列我们可以给他设一个默认值。

下面我们来做实验:

 

  1. sqlite> 
  2.  
  3. sqlite> DROP TABLE Teachers;  
  4.  
  5. sqlite> .tables  
  6.  
  7. sqlite> 
  8.  
  9. sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text,Country text DEFAULT '中国');  
  10.  
  11. sqlite> .tables  
  12.  
  13. Teachers  
  14.  
  15. sqlite> INSERT INTO Teachers(Name) Values('张三');  
  16.  
  17. sqlite> INSERT INTO Teachers(Name) Values('李四');  
  18.  
  19. sqlite> INSERT INTO Teachers(Name) Values('王二麻子');  
  20.  
  21. sqlite> INSERT INTO Teachers(Name,Country) Values('孙悟空','天庭');  
  22.  
  23. sqlite> SELECT * FROM Teachers;  
  24.  
  25. Id Name Country  
  26.  
  27. ---- --------------- ---------------  
  28.  
  29. 1 张三 中国  
  30.  
  31. 2 李四 中国  
  32.  
  33. 3 王二麻子 中国  
  34.  
  35. 4 孙悟空 天庭  
  36.  
  37. sqlite> 

 

先把之前的 Teachers 表删除,然后重新创建。这回 Teachers 表多了一个 Country 字段, 并且设置默认值为“中国”,然后我们插入四条数据到 Teachers 表。

前三条数据都没有明确指明 Country 字段的值,只有第四条数据指明了“孙悟空”的 Country 为“天庭”。

查询数据,发现前三条数据都填上了默认值,实验成功。

数据显示有点走样,命令 .width 4 15 15 设置的列宽,可以通过 .show 查看, 可能是因为中文的原因,所以没有对齐。

#p#

四、非空 NOT NULL

有一些字段我们可能一时不知到该填些什么,同时它也没设定默认值, 当添加数据时,我们把这样的字段空着不填,系统认为他是 NULL 值。但是还有另外一类字段,必须被填上数据,如果不填,系统就会报错。 这样的字段被称为 NOT NULL 非空字段,需要在定义表的时候事先声明。下面我们来做实验:

 

  1. sqlite> 
  2.  
  3. sqlite> DROP TABLE Teachers;  
  4.  
  5. sqlite> .tables  
  6.  
  7. sqlite> 
  8.  
  9. sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text,Age integer NOT NULL,City text);  
  10.  
  11. sqlite> .tables  
  12.  
  13. Teachers  
  14.  
  15. sqlite> INSERT INTO Teachers(Name,Age) Values('Alice',23);  
  16.  
  17. sqlite> INSERT INTO Teachers(Name,Age) Values('Bob',29);  
  18.  
  19. sqlite> INSERT INTO Teachers(id,Name,Age) Values(6,'Jhon',36);  
  20.  
  21. sqlite> SELECT * FROM Teachers;  
  22.  
  23. Id Name Age City  
  24.  
  25. ---- --------------- --------------- ---------------  
  26.  
  27. 1 Alice 23 NULL  
  28.  
  29. 2 Bob 29 NULL  
  30.  
  31. 6 Jhon 36 NULL  
  32.  
  33. sqlite> INSERT INTO Teachers(Name) Values('Mary');  
  34.  
  35. Error: Teachers.Age may not be NULL  
  36.  
  37. sqlite> 

 

还是先删除旧表,创建新表。

这回 Teachers 表声明了一个 NOT NULL 字段 Age,同时还有一个可以为 NULL 的字段 City。

插入前三条数据都没有指定 City 的值,查询可以看到 City 字段全部为空。

注意:这里的 NULL 只是对“什么都没有”的一种显示形式, 可以通过 .nullvalue 命令改为别的形式。

插入第四条数据时没有指定 Age 的值,系统就报错了: Teachers.Age 不能为空。

五、 唯一 UNIQUE

这一约束很好理解,除了主列以为,还有一些列也不能有重复值。不多说,直接看代码:

 

  1. sqlite> 
  2.  
  3. sqlite> DROP TABLE Teachers;  
  4.  
  5. sqlite> .tables  
  6.  
  7. sqlite> 
  8.  
  9. sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Name text UNIQUE);  
  10.  
  11. sqlite> .tables  
  12.  
  13. Teachers  
  14.  
  15. sqlite> INSERT INTO Teachers(Name) VALUES('Alice');  
  16.  
  17. sqlite> INSERT INTO Teachers(Name) VALUES('Bob');  
  18.  
  19. sqlite> INSERT INTO Teachers(Name) VALUES('Jane');  
  20.  
  21. sqlite> INSERT INTO Teachers(Name) VALUES('Bob');  
  22.  
  23. Error: column Name is not unique  
  24.  
  25. sqlite> 

 

这次的 Teachers 表只有 Name 这一列,但是 Name 列不能有重复值。可以看到,到我们第二次插入 Bob 时,系统就报错了。

六、 条件检查 CHECK

某些值必须符合一定的条件才允许存入,这是就需要用到这个 CHECK 约束。

 

  1. sqlite> 
  2.  
  3. sqlite> DROP TABLE Teachers;  
  4.  
  5. sqlite> .tables  
  6.  
  7. sqlite> 
  8.  
  9. sqlite> CREATE TABLE Teachers(Id integer PRIMARY KEY,Age integer CHECK(Age>22));  
  10.  
  11. sqlite> .tables  
  12.  
  13. Teachers  
  14.  
  15. sqlite> INSERT INTO Teachers(Age) VALUES(45);  
  16.  
  17. sqlite> INSERT INTO Teachers(Age) VALUES(33);  
  18.  
  19. sqlite> INSERT INTO Teachers(Age) VALUES(23);  
  20.  
  21. sqlite> INSERT INTO Teachers(Age) VALUES(21);  
  22.  
  23. Error: constraint failed  
  24.  
  25. sqlite> 

 

Age 字段要求必须大于 22,当插入的数据小于22时,系统报错。

七、外键 FOREIGN KEY

现在,我们的数据库中已经有 Teachers 表了,假如我们再建立一个 Students 表, 要求 Students 表中的每一个学生都对应一个 Teachers 表中的教师。

很简单,只需要在 Students 表中建立一个 TeacherId 字段,保存对应教师的 Id 号, 这样,学生和教师之间就建立了关系。

问题是:我们有可能给学生存入一个不在 Teachers 表中的 TeacherId 值, 而且发现不了这个错误。

这种情况下,可以把 Students 表中 TeacherId 字段声明为一个外键, 让它的值对应到 Teachers 表中的 Id 字段上。

这样,一旦在 Students 表中存入一个不存在的教师 Id ,系统就会报错。

 

  1. sqlite> 
  2.  
  3. sqlite> .tables  
  4.  
  5. Teachers  
  6.  
  7. sqlite> CREATE TABLE Students (Id integer PRIMARY KEY, TeacherId integer, FOREIGN KEY(TeacherId) REFERENCES Teachers(id) );  
  8.  
  9. sqlite> .tables  
  10.  
  11. Students Teachers  
  12.  
  13. sqlite> SELECT * FROM Teachers;  
  14.  
  15. Id Age  
  16.  
  17. ---- ---------------  
  18.  
  19. 1 40  
  20.  
  21. 2 33  
  22.  
  23. 3 23  
  24.  
  25. sqlite> INSERT INTO Students(TeacherId) VALUES(1);  
  26.  
  27. sqlite> INSERT INTO Students(TeacherId) VALUES(3);  
  28.  
  29. sqlite> INSERT INTO Students(TeacherId) VALUES(9);  
  30.  
  31. sqlite> SELECT * FROM Students;  
  32.  
  33. Id TeacherId  
  34.  
  35. ---- ---------------  
  36.  
  37. 1 1  
  38.  
  39. 2 3  
  40.  
  41. 3 9  
  42.  
  43. sqlite> 

 

这里建立了 Students 表,并且把 TeacherId 作为外键与 Teachers 表的 Id 列相对应。

关于SQLite数据库的约束就介绍到这里,希望能给各位带来帮助。

【编辑推荐】

  1. Linux平台mysql的安装配置之常用操作
  2. MySQL索引背后的数据结构及算法之基础篇
  3. 利用mysql的audit审计功能记录用户操作信息
  4. 详解Discuz_WIN7_Apache_MySQL_PHP平台搭建
  5. NaviCat通过Http方式连接服务器的MySQL数据库

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/239769.html<

(0)
运维的头像运维
上一篇2025-04-23 13:43
下一篇 2025-04-23 13:44

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注