什么是约束
约束:constraint
MySQL中的约束,实则是对数据表中数据的限制条件
约束的作用
约束保证数据的完整性和一致性
- 比如:设计数据表时,要求username字段不允许重复,这时候就需要在CREATE数据表时加入相应的约束。再比如注册时候必须填写邮箱、性别等。
约束的分类
按约束定义的位置可分
- 列级约束
- 表级约束
按约束的作用可分
主键 约束 | PRIMARY KEY | |
---|---|---|
外键 约束 | FOREIGN KEY | |
非空 约束 | NOT NULL | |
唯一 约束 | UNIQUE KEY | |
默认 约束 | DEFAULT |
列级约束、表级约束
区别
列级约束:只能应用于一列上。
表级约束:可以应用于一列上,也可以应用在一个表中的多个列上。即:如果你创建的约束涉及到该表的多个属性列,则必须创建的是表级约束(必须定义在表级上);否则既可以定义在列级上也可以定义在表级上此时只是SQL语句格式不同而已。
列级约束:包含在列定义中,直接跟在该列的其它定义之后 ,用空格分隔;不必指定列名。
表级约束:与列定义相互独立,不包含在列定义中;与定义用‘,’分隔;必须指出要约束的列的名称。注:因为在创建列级约束时,只需将创建列约束的语句添加到该字段(列)的定义子句后面;而在创建表级约束时,需要将创建表级约束的语句添加到各个字段(列)定义语句的后面,因为并不是每个定义的字段都要创建约束,所以必须指明需要创建的约束的列名。
举例说明
1 | Create Table project( |
分析:“项目编号”字段设置为主键,主键约束名为pk_pno,此主键约束为列主键约束。“项目名称”和“项目负责人”的组合字段设置唯一性约束,此约束为表级约束)
具体说明
一:既可以创建列级约束又可以创建表级约束的:
1、主键约束(primary key constraint):
(1)定义列约束:CONSTRAINT <约束名> PRIMARY KEY
(2)定义表约束:[CONSTRAINT <约束名>] PRIMARY KEY( <列名> [{<列名>}])
2、唯一性约束(unique key constraint):
(1)定义列约束:[CONSTRAINT <约束名>] UNIQUE [KEY]
(2)定义表约束:CONSTRAINT <约束名> UNIQUE [KEY] ( <列名> [{<列名>}])
3、外键约束(foreign key constraint):
定义 列级约束:[CONSTRAINT <约束名>] FOREIGN KEY REFERENCES <外表名>
定义表级约束:[CONSTRAINT <约束名>] FOREIGN KEY REFERENCES <外表名>( <列名> [{<列名>}])
二:只能创建列级约束的:
1,缺省约束(default constraint):
[CONSTRAINT <约束名>] DEFAULT 约束条件
2,NULL 约束:
[CONSTRAINT <约束名>] [NULL | NOT NULL]
主键约束 PRIMARY KEY
“主键(PRIMARY KEY)”的完整称呼是“主键约束”。MySQL 主键约束是一个列或者列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可以强制表的实体完整性。
涉及术语
- 主键约束
- 主键字段
- 主键值
三种术语的关系:
表中的某个字段添加主键约束后,该字段为主键字段,主键字段中出现的每一个数据都称为主键值
特点
- 保证数据的实体完整性
要求
一张表应该有主键字段,如果没有,表示该表无效
- 主键值:是当前行数据的唯一标识、是当前行数据的身份证号
- 即使表中两行记录相关数据相同,但由于主键值不同,所以也认为是两行不同的记录
按主键约束的字段数量分类
在MySQL的一个表中只有唯一的一个主键,不能有多列主键,但可以有复合主键。一个表中可以:单列做主键、多列做主键(复合主键)。
- 单一主键:给一个字段添加主键约束
- 复合主键:给多个字段联合添加一个主键约束(只能用表级定义)
单一主键(列级定义)
1 | mysql> create table t_user( |
单一主键(表级定义)
1 | mysql> create table t_user( |
复合主键(表级定义)
一定要在表级定义。
1 | mysql> create table t_user( |
配合AUTO_INCREMENT
在MySQL数据库提供了一个自增的数字,专门用来自动生成主键值,主键值不用用户维护,自动生成,自增数从1开始,以1递增(auto_increment)
1 | mysql> create table t_user( |
外键约束 FOREIGN KEY
外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接,它可以是一列或者多列。一个表可以有一个或多个外键。
外键的主要作用是保持数据的一致性、完整性。例如,部门表 tb_dept 的主键是 id,在员工表 tb_emp5 中有一个键 deptId 与这个 id 关联。
- 主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表。
- 从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的表就是从表。
快速理解
之前创建表的时候都是在一张表中添加记录,比如如下表:
公司有3个部门,但是有1个亿的员工,那意味着部门这个字段需要重复存储,部门名字越长,越浪费。这个时候,解决方法:我们完全可以定义一个部门表,然后让员工信息表关联该表,如何关联,即foreign key。
我们可以将上表改为如下结构:
涉及到的术语
- 外键约束
- 外键字段
- 外键值
三种术语的关系:
某个字段添加外键约束之后,该字段称为外键字段,外键字段中每个数据都是外键值
特点
- 保持数据的一致性
- 完整性
- 实现一对一或者一对多关系
这也是为什么称为MySQL关系型数据库的原因
要求
- ★父表(子表所参照的表)和子表(具有外键列的表)必须使用使用相同的存储引擎,而且禁止使用临时表。
- ★外键对应的是参照完整性,一个表的外键可以为NULL,若不为空值,则每一个外键的值必须等于另一个表中主键的某个值。
- ★定义外键时,创建先创建父表。定义外键后,插入先插入父表数据,同理,删除先删除子表数据。
- 数据表的存储引擎只能为InnoDB。(编辑数据库的默认存储引擎,修改完需要重启MySQL服务)
- 外键列(加FOREIGN KEY关键词的一列)和参照列(外键列参照的一列)必须具有相似的数据类型,如果是数字数据类型,则数字长度或者是否有符号位必须相同;如果为字符数据类型长度可以不同。
- ★外键列和参照列(主键在创建的同时,会自动创建索引seq_in_index)必须创建索引。如果外键列不存在索引的话,MySQL将自动创建。
与主键的区别
一张表可以有多个外键,但是主键最多只有一个。
按外键约束的字段数量分类
单一外键:给一个字段添加外键约束
复合外键:给多个字段联合添加一个外键约束
表复合外键(表级定义)
1 | FOREIGN KEY(classno) REFERENCES t_class(cno); |
非空约束
用NOT NULL约束的字段不能为NULL值,必须给定具体的数据。
注意的是
NULL,表示空,并不是字符串中的空。两者需要区分开。
实例
1 | mysql> CREATE TABLE t12(id INT NOT NULL); #设置字段id不为空 |
验证
1 | mysql> INSERT INTO t12 VALUES(); #不能插入空 |
唯一约束
UNIQUE约束的字段,具有唯一性,不可重复,但可以为NULL。
列级约束
1 | mysql> create table t_user( |
表级约束
1 | mysql> create table t_user( |
如果插入相同email会报错
1 | mysql> insert into t_user(id,name,email) values(1,'xlj','932834897@qq.com'); |
扩展:联合唯一约束
1 | # 创建services表 |
更多可参考 mysql 给表添加唯一约束、联合唯一约束,指定唯一约束的名字
默认约束
为某一字段提供默认值。
创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
实例
1 | create table tb1( |
验证
1 | mysql> insert into tb1(id) values(1); #给t11表插一个空的值 |
主要文献:
[部分概念来自C语言中文网] http://c.biancheng.net/view/2440.html
[大部分案例的代码块来自CSDN] https://blog.csdn.net/w_linux/article/details/79655073
注:案例中的SQL语句并非作者写的,存在规范问题,但不影响阅读。