约束
约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。
约束分类
听名字就知道,约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。
在MySQL中,通常有这几种约束:
约束类型: | 主键 | 默认值 | 唯一 | 外键 | 非空 |
---|---|---|---|---|---|
关键字: | PRIMARY KEY | DEFAULT | UNIQUE | FOREIGN KEY | NOT NULL |
建立含约束的表
为了方便介绍这几种约束,先建立一个数据库:
新建一个数据库 mysql_ldl
,然后在其中创建三张表 department
,employee
,project
,它们包含了各种约束。
在这里我已经提前准备好一个包含新建一个数据库的代码文件,所以可以通过加载文件中的数据,直接建立好一个数据库
加载文件中的数据,需要在 MySQL 控制台中输入命令:
source /home/ldl/MySQL.sql;
查看一下这个数据库,输入命令 show tables;
,可见:
主键
主键 (PRIMARY KEY)是用于约束表中的一行,作为这一行的唯一标识符,在一张表中通过主键就能准确定位到一行,主键用来表示一个特定的行,没有主键,更新或删除表中特定的行很困难,因此主键十分重要。主键不能有重复且不能为空。
在 MySQL.sql
中,这里有主键:
列名id那一行最后的PRIMARY KEY是主键,这是定义主键的一种方法
定义主键的第二种方法:
上面图片中最后一行为定义主键的语句,其中dpt_p为主键名字(自定义),PRIMARY KEY后面括号里限定了所要定义主键的列名)
还有一种特殊的主键——复合主键。主键不仅可以是表中的一列,也可以由表中的两列或多列来共同标识,比如:
proj_pk 是主键名字(自定义)PRIMARY KEY后面括号里为限定多列列名)
默认值约束
默认值约束 (DEFAULT) 规定,当有 DEFAULT 约束的列,插入数据为空时,将使用默认值。
在 MySQL.sql
中,这段代码包含了 DEFAULT 约束:
DEFAULT 约束只会在使用 INSERT 语句时体现出来,INSERT语句中,如果被 DEFAULT 约束的位置没有值,那么这个位置将会被 DEFAULT 的值填充,如语句:
# 正常插入数据
INSERT INTO department(dpt_name,people_num) VALUES('dpt1',11);
#插入新的数据,people_num 为空,使用默认值
INSERT INTO department(dpt_name) VALUES('dpt2');
输入命令 SELECT * FROM department;
,可见表中第二行的people_num 被 DEFAULT 的值 (10) 填充:
唯一约束
唯一约束 (UNIQUE) 比较简单,它规定一张表中指定的一列的值必须不能有重复值,即这一列每个值都是唯一的。
当 INSERT 语句新插入的数据和已有数据重复的时候,如果有 UNIQUE约束,则 INSERT 失败,比如:
INSERT INTO employee VALUES(01,'Tom',25,3000,110110,'dpt1');
INSERT INTO employee VALUES(02,'Jack',30,3500,110110,'dpt2');
结果如图:
因为第二次输入的数据中的phone项和以前数据库中有的项内容重复,所以报错。
外键约束
外键 (FOREIGN KEY) 既能确保数据完整性,也能表现表之间的关系。
一个表可以有多个外键,每个外键必须 REFERENCES (参考) 另一个表的主键,被外键约束的列,取值必须在它参考的列中有对应值。
在 INSERT 时,如果被外键约束的值没有在参考列中有对应,比如以下命令,参考列 (department 表的 dpt_name) 中没有dpt3,则INSERT 失败:
INSERT INTO employee VALUES(02,'Jack',30,3500,114114,'dpt3');
非空约束
非空约束 (NOT NULL),听名字就能理解,被非空约束的列,在插入值时必须非空。
在MySQL中违反非空约束,不会报错,只会有警告,比如以下语句:
#INSERT 成功 age 为空,因为没有非空约束,表中显示 NULL
INSERT INTO employee(id,name,salary,phone,in_dpt) VALUES(03,'Jim',3400,119119,'dpt2');
#警告 salary 被非空约束,值为空,表中显示0
INSERT INTO employee(id,name,age,phone,in_dpt) VALUES(04,'Bob',23,123456,'dpt1');
结果如图,出现警告,但还是插入数据成功,5.6
版本以上的 MySQL 会报错,禁止插入不符合非空约束的数据: