已经一个星期没更了,因为过年嘛,比较忙,我玩心也大,就没继续更新,在这里给大家道歉,也祝大家新的一年快快乐乐,新年快乐。
为防止数据表中插入错误的数据,MySQL定义了一些规则维护数据库中数据的完整性和有效性,这些规则即表的约束。常见的约束有非空约束、唯一约束、主键约束、外键约束和默认值约束,其中外键约束涉及多表操作,将在后面进行讲解。接下来针对外键约束之外的其他约束进行讲解。
非空约束用于确保插入字段中值的非空性。如果没有对字段设置约束,字段默认允许插入NULL值。如果数据表中的字段设置了非空约束,那么该字段中存放的值必须是NULL值之外的其他具体值。
例如,在企业的员工管理系统中,如果HR在新增员工信息时没有填写员工姓名等必填信息,系统却允许新增,那么所新增的员工信息没有使用价值。一般情况下,员工管理系统的数据表中都会为必填项信息对应的字段设置非空约束,以确保数据的完整性。为数据表的字段设置非空约束后,如果往该字段中插入的内容为NULL,则所执行的插入操作会报错。
接下来,对设置和删除非空约束进行讲解和演示。
在MySQL中,非空约束通过NOT NULL进行限定,在数据表中可以为多个字段同时设置非空约束。字段的非空约束可以在创建数据表时进行设置,也可以在修改数据表时进行添加,具体实现如下。
(1)创建数据表时设置非空约束。
如果是创建数据表时给字段设置非空约束,只需要在字段的数据类型后面追加NOT NULL即可。可以在数据表中设置多个非空约束,但是不能设置非空约束为表级约束。
接下来,通过一个案例演示创建数据表时设置非空约束。
创建表时设置非空约束,创建一个部门表dept01:
mysql> create table dept01(
-> deptno int,
-> dname varchar(14),
-> local varchar(13) NOT NULL
-> );
Query OK, 0 rows affected (0.03 sec)
从创建语句可以看出我在local这个字段后面设置了非空约束,也就是添加了NOT NULL。
使用DESC语句查询一下表的结构:
mysql> desc dept01;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| deptno | int | YES | | NULL | |
| dname | varchar(14) | YES | | NULL | |
| local | varchar(13) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从结果我们可以看到NULL下面为NO,意思就是是否允许空字段的存在,NO就是不允许。
如果需要在已经存在的列表中添加非空约束,可以在ALTER TABLE语句中通过使用MODIFY或CHANGE重新定义字段的方式添加非空约束,这两种方式的效果都一样。
接下来通过一个案例演示修改数据表时使用MODIFY添加非空约束。
接上面创建的部门表dept01,这次设置dname字段为非空约束:
mysql> ALTER TABLE dept01 MODIFY dname VARCHAR(14) NOT NULL;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
语句执行成功后使用DESC语句查看表的结构:
mysql> DESC dept01;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| deptno | int | YES | | NULL | |
| dname | varchar(14) | NO | | NULL | |
| local | varchar(13) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从上面的执行结果就可以看出语句修改成功了,现在dname字段也是非空约束。
非空约束的删除也是通过ALTER TABLE 语句进行的,使用MODIFY或CHANGE方法重新定义字段来实现删除。
具体SQL语句及执行结果如下:
mysql> ALTER TABLE dept01 MODIFY dname VARCHAR(16);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC dept01;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| deptno | int | YES | | NULL | |
| dname | varchar(16) | YES | | NULL | |
| local | varchar(13) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从操作流程来看和定义字段非空约束差不多的。结果显而易见也是成功删除了,其实删除和添加都是通过重新定义的方法来实现的。
我在演示一下通过CHANGE方法来添加非空约束:
mysql> ALTER TABLE dept01 CHANGE dname dname VARCHAR(14) NOT NULL;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC dept01;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| deptno | int | YES | | NULL | |
| dname | varchar(14) | NO | | NULL | |
| local | varchar(13) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
结果也是成功的添加了,这个CHANGE方法和之前讲的用法一样。
数据表中默认可以保存相同的值,唯一约束用于确保字段中值的唯一性。如果数据表中的字段设置了唯一约束,那么该数据表的这个字段中存放的值不能重复出现。
例如,在企业的员工管理系统中,如果HR在新增员工信息时允许新增员工的企业邮箱重复,那么邮箱信息的有效性会受到很大影响(例如,发送给某位员工的邮件可能会有多名员工收到)。一般情况下,数据表中需要为内容必须保证不重复的字段设置唯一约束,以确保数据的唯一性。为字段设置唯一约束后,如果往该字段中插入已经存在的值,所执行的插入操作会报错。
接下来,对设置和删除唯一约束进行讲解。
在MySQL中,唯一约束通过关键字UNIQUE进行设置。设置时,可以在数据表中设置1个或多个唯一约束。字段的唯一约束可以在创建数据表时进行设置,也可以在修改数据表时进行添加,具体如下。
(1)创建数据表时设置唯一约束。
创建数据表时设置唯一约束的方式有两种:一种是设置列级约束;另一种是设置表级约束。列级约束紧跟在字段的数据类型之后,只对该字段起约束作用;表级约束独立于字段,可以对数据表的单个或多个字段起约束作用。如果表级约束对多个字段同时约束,只有当这几个字段的值相同时才视为重复记录,此时约束也称为联合约束或复合约束。
接下来,通过一个案例演示创建数据表时设置唯一约束。
例如,在数据库中创建一个用于存放员工信息的员工表tb_emp01,要求员工表中员工工号不能重复;相同部门中不能包含相同的员工姓名;员工职位不能为NULL值。
员工表的结构如下图:
具体SQL语句及执行结果如下:
mysql> CREATE TABLE tb_emp01(
-> deptname VARCHAR(16),
-> empno INT UNIQUE,
-> ename VARCHAR(16),
-> job VARCHAR(16) NOT NULL,
-> email VARCHAR(30),
-> UNIQUE (deptname,ename)
-> );
Query OK, 0 rows affected (0.02 sec)
从上述执行结果的提示信息可以看出,CREATE TABLE语句成功执行。如果想验证字段是否按要求设置约束,可以使用DESC语句查看tb_emp01数据表的表结构信息,具体SQL语句及执行结果如下。
mysql> DESC tb_emp01;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| deptname | varchar(16) | YES | MUL | NULL | |
| empno | int | YES | UNI | NULL | |
| ename | varchar(16) | YES | | NULL | |
| job | varchar(16) | NO | | NULL | |
| email | varchar(30) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
从上述执行结果可以看出,字段deptname的Key列为MUL,说明该字段是非唯一索引的第1列,此时字段deptname的值可以重复,字段deptname和字段ename共同的值用于唯一性判断;字段empno的Key列为UNI,说明创建数据表时empno字段成功设置了唯一索引。设置唯一约束成功后Key列的值会有变化,是因为字段设置唯一约束时,系统会自动为对应的字段设置唯一索引,即UNI。
如果是修改数据表时设置唯一约束,可以在ALTER TABLE语句中通过使用MODIFY或CHANGE重新定义字段的方式添加,也可以通过ALTER TABLE语句中的ADD添加。使用ADD的方式语法更简洁,通常添加唯一约束时会选择使用这种方式。
接下来,通过一个案例演示修改数据表时使用ADD添加唯一约束。
例如,为数据表tb_emp01中的email字段添加唯一约束,具体SQL语句及执行结果如下。
mysql> ALTER TABLE tb_emp01 ADD UNIQUE(email);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果的提示信息可以看出,上述命令成功执行。如果想验证email字段是否成功添加唯一约束,可以使用DESC语句查看数据表tb_emp01的表结构信息,具体SQL语句及执行结果如下。
mysql> DESC tb_emp01;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| deptname | varchar(16) | YES | MUL | NULL | |
| empno | int | YES | UNI | NULL | |
| ename | varchar(16) | YES | | NULL | |
| job | varchar(16) | NO | | NULL | |
| email | varchar(30) | YES | UNI | NULL | |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
从上述执行结果可以看出,email字段的Key列为UNI,说明email字段成功添加了唯一约束。
创建唯一约束时,系统也同时创建了对应的唯一索引。删除唯一索引时,会将对应的唯一约束同时删除。默认情况下所创建的索引名和字段名一致,如果想要删除字段中已有的唯一约束,可以通过ALTER TABLE语句中的“DROP索引名”实现。
接下来,通过一个案例演示使用DROP删除唯一约束。
例如,将数据表tb_emp01中的empno字段的唯一约束删除,具体SQL语句及执行结果如下:
mysql> ALTER TABLE tb_emp01 DROP INDEX empno;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
从结果可以看出ALTER TABLE 语句执行成功,接下来使用DESC语句查看empno字段的唯一约束是否成功删除:
mysql> DESC tb_emp01;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| deptname | varchar(16) | YES | MUL | NULL | |
| empno | int | YES | | NULL | |
| ename | varchar(16) | YES | | NULL | |
| job | varchar(16) | NO | | NULL | |
| email | varchar(30) | YES | UNI | NULL | |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
从上述执行结果的empno字段对应的Key列信息可以看出,empno字段的唯一约束已经删除成功。
在MySQL中,为快速查找到表中的某条记录,可以通过设置主键约束来实现。主键约束相当于非空约束和唯一约束的组合,要求被约束字段中的值不允许重复,也不允许出现NULL值。
例如,在企业内部的员工管理系统中需要高频率地使用员工表中的工号字段,如果允许员工工号重复或者是NULL值,管理员工信息时就会出现混乱,系统也没有任何有效性可言,这时就可以为员工工号设置主键约束。为员工工号设置主键约束后,如果往该字段中插入已经存在的值或NULL值,所执行的插入操作会报错。
在MySQL中,主键约束是通过PRIMARY KEY进行设置,每个数据表中最多只能设置一个主键约束。设置主键约束的方式有两种,分别为创建数据表时设置主键约束和修改数据表时添加主键约束,具体如下。
(1)创建数据表时设置主键约束。
与设置唯一约束一样,可以在创建数据表时设置列级或表级的主键约束,区别在于列级只能对单字段设置主键约束,表级可以对单字段或多字段设置主键约束。
接下来我们通过一个案例演示创建数据表时设置主键约束
首先我们先在数据库中创建一个class表,设置id、name、age这三个字段,一般来说id是唯一的且不能是空的,因此我们设置为主键约束,name可能会有重复的设置非空即可。具体SQL语句即执行结果如下:
mysql> CREATE TABLE class(
-> id INT PRIMARY KEY,
-> name VARCHAR(12) NOT NULL,
-> age INT
-> );
Query OK, 0 rows affected (0.01 sec)
CREATE 语句创建成功,接下来查看表的结构,是否成功设置主键约束:
mysql> DESC class;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(12) | NO | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从执行结果可以看出id字段对应的key列的信息为PRI,说明创建表时的id字段成功设置了主键约束。
如果数据表创建成功后,想要为表添加主键约束,则与修改数据表时添加唯一约束类似,可以在ALTER TABLE语句中通过使用MODIFY或CHANGE重新定义字段的方式添加,也可以通过ALTER TABLE语句中的ADD添加。不同的是,添加主键约束之前需要确保数据表中不存在主键约束,否则会添加失败。
在前面我设置非空约束时创建了一个dept01的数据表,不知道大家是否还记得,这里呢我们就使用这个数据表添加主键约束:
mysql> ALTER TABLE dept01 ADD PRIMARY KEY(deptno);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
修改语句执行成功,接下来使用DESC语句查看数据表的结构:
mysql> DESC dept01;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| deptno | int | NO | PRI | NULL | |
| dname | varchar(14) | NO | | NULL | |
| local | varchar(13) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从上述执行结果可以看出,字段deptno的Key列为PRI,说明字段的主键约束添加成功。
不知道你们在了解主键约束时发现没有主键约束就是唯一约束和非空约束的结合,那么我们在同一个字段上同时设置唯一约束和非空约束是否就是主键约束呢?下面来让我们实验一下:
实验的对象是设置唯一约束时的tb_emp01这个部门表:
mysql> ALTER TABLE tb_emp01 MODIFY ename VARCHAR(16) UNIQUE NOT NULL;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
修改语句成功了,接下来查看Key列下面ename有没有PRI:
mysql> DESC tb_emp01;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| deptname | varchar(16) | YES | MUL | NULL | |
| empno | int | YES | | NULL | |
| ename | varchar(16) | NO | PRI | NULL | |
| job | varchar(16) | NO | | NULL | |
| email | varchar(30) | YES | UNI | NULL | |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
从结果中可以看到ename字段后面的Key列下面有PRI。说明我们的猜想成功了。主键约束就是唯一约束与非空约束的结合。
对于设置错误或者不再需要的主键约束,可以通过ALTER TABLE语句中的DROP进行删除。由于主键约束在数据表中只能有一个,因此不需要指定主键约束对应的字段名称,直接删除即可。删除主键约束时,也会自动删除主键索引。
删除class表中的主键约束:
mysql> ALTER TABLE class DROP PRIMARY KEY;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
语句执行成功,接下来使用DESC语句检查是否删除成功:
mysql> DESC class;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | | NULL | |
| name | varchar(12) | NO | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从上述执行结果可以看出,id字段的Key列没有内容了,但是Null列还是显示NO,说明删除主键约束时自动将主键索引删除了,但字段的非空约束并没有被同时删除。如果想要删除字段的非空约束,可以参考前面说的删除非空约束的方法。
默认值约束用于给数据表中的字段指定默认值,即当在表中插入一条新记录时,如果没有给这个字段赋值,那么数据库系统会自动为这个字段插入指定的默认值。
例如,在企业的员工管理系统中需要记录每个员工的在职状态,以确定员工当前是否在职。如果每次办理员工入职时需要手动设置在职状态,则显得比较烦琐。这时就可以为员工状态设置默认值约束,这样新增员工信息时,即使不填写员工在职状态,数据库也会为员工在职状态插入设置的默认值。
接下来,对设置和删除默认值约束进行讲解。
字段的默认值约束可以在创建数据表时进行设置,也可以在修改数据表时进行添加,具体如下。
(1)创建数据表时设置默认值约束。
如果创建数据表时给字段设置默认值约束,只需要在定义字段时使用如下格式即可。
<字段名><数据类型>DEFAULT<默认值>;
接下来,通过一个案例演示创建数据表时设置默认值约束。
例如,创建一个存放学生信息的班级表class01,学生年龄的默认值设置为18
具体SQL语句及执行结果如下:
mysql> CREATE TABLE class01(
-> id int primary key,
-> name varchar(16) not null,
-> age int DEFAULT 18
-> );
Query OK, 0 rows affected (0.02 sec)
创建语句执行成功,使用DESC语句检查默认约束是否执行成功:
mysql> DESC class01;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(16) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从执行结果中可以看出age字段中的Default列下面对应的信息为18,说明我们设置默认值成功了。
修改数据表时添加默认值约束与修改数据表时添加非空约束类似,可以在ALTER TABLE语句中通过使用MODIFY或CHANGE重新定义字段的方式添加默认值约束。
接下来修改class01中id字段的默认值,默认值为1,具体SQL语句及执行结果如下:
mysql> ALTER TABLE class01 MODIFY id int DEFAULT 1;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
创建语句执行成功后使用DESC语句查看设置默认约束是否成功:
mysql> DESC class01;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | 1 | |
| name | varchar(16) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从上述语句执行结果可以看出,id字段的默认值为1,说明默认约束设置成功了。
当数据表的某列不需要默认约束时,可以通过修改表的语句删除默认值约束。删除默认约束也是通过ALTER TABLE语句中的MODIFY或CHANGE重新定义字段的方式来实现。
删除id字段的默认约束:
mysql> ALTER TABLE class01 MODIFY id INT;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
删除语句执行成功,使用DESC语句查看是否成功删除:
mysql> DESC class01;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(16) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
从结果中可以看到id字段没有了默认约束,成功删除了默认约束。
在企业开发中,有时想要数据表为插入的新记录自动生成唯一的ID。例如,在员工管理系统中,当公司HR每次添加员工信息时,如果都需要手动填写员工工号,则会导致新增之前还需要想办法查询最新的工号是多少,也有可能查询出最新工号再进行手动插入时,发现该工号已被其他HR提前添加。此时,可以使用AUTO_INCREMENT解决这类问题,AUTO_INCREMENT可以为新行自动生成唯一标识。
在字段中设置AUTO_INCREMENT的基本语法格式如下。
字段名 数据类型 AUTO_INCREMENT;
使用AUTO_INCREMENT时,需要注意以下4点。
(1)一个数据表中只能有一个字段设置AUTO_INCREMENT,设置AUTO_INCREMENT字段的数据类型可以是整数和浮点类型,并且该字段必须定义为键,如UNIQUE、PRIMARY KEY。
(2)如果为自动增长字段插入NULL,则该字段会自动增长值;如果插入的是一个具体值,则不会自动增长值。
(3)默认情况下,设置AUTO_INCREMENT的字段的值是从1开始自增。如果插入一个大于自动增长值的具体值,则下次自动增长的值为字段中的最大值加1。
(4)使用DELETE删除记录时,自动增长值不会减少或填补空缺。
下面通过班级表class01为大家演示自增约束:
class01中的id字段是有主键约束的,因此是有键的存在的,可以设置自增约束
具体SQL语句及执行结果如下:
mysql> ALTER TABLE class01 MODIFY id int AUTO_INCREMENT;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
这是通过重新定义的方式来添加自增约束,使用DESC语句检查是否添加成功:
mysql> DESC class01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
在上述执行结果中,id字段中Extra列对应的信息可以看出,我们成功的给id字段添加了自增约束。
我们还可以在创建数据表的时候给字段设置自动增长,只需要在你要设置自动增长的字段的数据类型后面添加AUTO_INCREMENT就可以了。我就不在演示了。
在MySQL中,如果你想要删除一个字段的自动增长(AUTO_INCREMENT)属性,你可以使用ALTER TABLE语句来修改这个字段。MODIFY方法和CHANGE方法都可以。我演示使用的是MODIFY方法。具体SQL语句及执行结果如下。
mysql> ALTER TABLE class01 MODIFY id int;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC class01;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(16) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+-------+
从执行结果来看自动增长已经成功的删除了
过年耽误了几天,连夜补出来的,感谢大家的支持,大家新年快乐啊。