系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 数据库 > 其它 > 详细页面

mysql完整性约束实例详解

时间:2020-01-03来源:系统城作者:电脑系统城

本文实例讲述了mysql完整性约束。分享给大家供大家参考,具体如下:

主要内容

  • not null 与 default
  • unique
  • primary
  • auto_increment
  • foreign key

约束条件作用:用于保证数据的完整性和一致性

主要分为

PRIMARY KEY (PK)    #标识该字段为该表的主键,可以唯一的标识记录
FOREIGN KEY (FK)    #标识该字段为该表的外键
NOT NULL    #标识该字段不能为空
UNIQUE KEY (UK)    #标识该字段的值是唯一的,
AUTO_INCREMENT    #标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT    #为该字段设置默认值
UNSIGNED #无符号
ZEROFILL #使用0填充

unique

在mysql中称为单列唯一

 

 
  1. #例子1:
  2. create table department(
  3. id int,
  4. name char(10) unique
  5. );
  6. mysql> insert into department values(1,'it'),(2,'it');
  7. ERROR 1062 (23000): Duplicate entry 'it' for key 'name'
  8. #例子2:
  9. create table department(
  10. id int unique,
  11. name char(10) unique
  12. );
  13. insert into department values(1,'it'),(2,'sale');
  14. #第二种创建unique的方式
  15. create table department(
  16. id int,
  17. name char(10) ,
  18. unique(id),
  19. unique(name)
  20. );
  21. insert into department values(1,'it'),(2,'sale');
  22.  

联合唯一:只要两列记录,有一列不同,既符合联合唯一的约束


 
  1. # 创建services表
  2. mysql> create table services(
  3. -> id int,
  4. -> ip char(15),
  5. -> port int,
  6. -> unique(id),
  7. -> unique(ip,port)
  8. -> );
  9. Query OK, 0 rows affected (0.05 sec)
  10. mysql> desc services;
  11. +-------+----------+------+-----+---------+-------+
  12. | Field | Type | Null | Key | Default | Extra |
  13. +-------+----------+------+-----+---------+-------+
  14. | id | int(11) | YES | UNI | NULL | |
  15. | ip | char(15) | YES | MUL | NULL | |
  16. | port | int(11) | YES | | NULL | |
  17. +-------+----------+------+-----+---------+-------+
  18. 3 rows in set (0.01 sec)
  19. #联合唯一,只要两列记录,有一列不同,既符合联合唯一的约束
  20. mysql> insert into services values
  21. -> (1,'192,168,11,23',80),
  22. -> (2,'192,168,11,23',81),
  23. -> (3,'192,168,11,25',80);
  24. Query OK, 3 rows affected (0.01 sec)
  25. Records: 3 Duplicates: 0 Warnings: 0
  26. mysql> select * from services;
  27. +------+---------------+------+
  28. | id | ip | port |
  29. +------+---------------+------+
  30. | 1 | 192,168,11,23 | 80 |
  31. | 2 | 192,168,11,23 | 81 |
  32. | 3 | 192,168,11,25 | 80 |
  33. +------+---------------+------+
  34. 3 rows in set (0.00 sec)
  35. mysql> insert into services values (4,'192,168,11,23',80);
  36. ERROR 1062 (23000): Duplicate entry '192,168,11,23-80' for key 'ip'
  37.  

auto_increment

约束:约束的字段为自动增长,约束的字段必须同时被key约束

不指定id,则自动增长


 
  1. # 创建student
  2. create table student(
  3. id int primary key auto_increment,
  4. name varchar(20),
  5. sex enum('male','female') default 'male'
  6. );
  7.  
  8. mysql> desc student;
  9. +-------+-----------------------+------+-----+---------+----------------+
  10. | Field | Type | Null | Key | Default | Extra |
  11. +-------+-----------------------+------+-----+---------+----------------+
  12. | id | int(11) | NO | PRI | NULL | auto_increment |
  13. | name | varchar(20) | YES | | NULL | |
  14. | sex | enum('male','female') | YES | | male | |
  15. +-------+-----------------------+------+-----+---------+----------------+
  16. rows in set (0.17 sec)
  17. #插入记录
  18. mysql> insert into student(name) values ('老白'),('小白');
  19. Query OK, 2 rows affected (0.01 sec)
  20. Records: 2 Duplicates: 0 Warnings: 0
  21. mysql> select * from student;
  22. +----+--------+------+
  23. | id | name | sex |
  24. +----+--------+------+
  25. | 1 | 老白 | male |
  26. | 2 | 小白 | male |
  27. +----+--------+------+
  28. rows in set (0.00 sec)
  29.  

指定id的情况


 
  1. mysql> insert into student values(4,'asb','female');
  2. Query OK, 1 row affected (0.00 sec)
  3. mysql> insert into student values(7,'wsb','female');
  4. Query OK, 1 row affected (0.01 sec)
  5. mysql> select * from student;
  6. +----+--------+--------+
  7. | id | name | sex |
  8. +----+--------+--------+
  9. | 1 | 老白 | male |
  10. | 2 | 小白 | male |
  11. | 4 | asb | female |
  12. | 7 | wsb | female |
  13. +----+--------+--------+
  14. rows in set (0.00 sec)
  15. # 再次插入一条不指定id的记录,会在之前的最后一条记录继续增长
  16. mysql> insert into student(name) values ('大白');
  17. Query OK, 1 row affected (0.00 sec)
  18. mysql> select * from student;
  19. +----+--------+--------+
  20. | id | name | sex |
  21. +----+--------+--------+
  22. | 1 | 老白 | male |
  23. | 2 | 小白 | male |
  24. | 4 | asb | female |
  25. | 7 | wsb | female |
  26. | 8 | 大白 | male |
  27. +----+--------+--------+
  28. rows in set (0.00 sec)
  29.  

对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长


 
  1. mysql> delete from student;
  2. Query OK, 5 rows affected (0.00 sec)
  3. mysql> select * from student;
  4. Empty set (0.00 sec)
  5. mysql> select * from student;
  6. Empty set (0.00 sec)
  7. mysql> insert into student(name) values('ysb');
  8. Query OK, 1 row affected (0.01 sec)
  9. mysql> select * from student;
  10. +----+------+------+
  11. | id | name | sex |
  12. +----+------+------+
  13. | 9 | ysb | male |
  14. +----+------+------+
  15. row in set (0.00 sec)
  16. #应该用truncate清空表,比起delete一条一条地删除记录,truncate是直接清空表,在删除大表时用它
  17. mysql> truncate student;
  18. Query OK, 0 rows affected (0.03 sec)
  19. mysql> insert into student(name) values('xiaobai');
  20. Query OK, 1 row affected (0.00 sec)
  21. mysql> select * from student;
  22. +----+---------+------+
  23. | id | name | sex |
  24. +----+---------+------+
  25. | 1 | xiaobai | male |
  26. +----+---------+------+
  27. row in set (0.00 sec)
  28. mysql>
  29. auto_increment_increment和 auto_increment_offset
  30.  

查看可用的 开头auto_inc的词


 
  1. mysql> show variables like 'auto_inc%';
  2. +--------------------------+-------+
  3. | Variable_name | Value |
  4. +--------------------------+-------+
  5. | auto_increment_increment | 1 |
  6. | auto_increment_offset | 1 |
  7. +--------------------------+-------+
  8. rows in set (0.02 sec)
  9.  

 
  1. # 步长auto_increment_increment,默认为1
  2. # 起始的偏移量auto_increment_offset, 默认是1
  3. # 设置步长 为会话设置,只在本次连接中有效
  4. set session auto_increment_increment=5;
  5. #全局设置步长 都有效。
  6. set global auto_increment_increment=5;
  7. # 设置起始偏移量
  8. set global auto_increment_offset=3;
  9.  

强调:If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 
翻译:如果auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略 

设置完起始偏移量和步长之后,再次执行show variables like'auto_inc%';

发现跟之前一样,必须先exit,再登录才有效。


 
  1. mysql> show variables like'auto_inc%';
  2. +--------------------------+-------+
  3. | Variable_name | Value |
  4. +--------------------------+-------+
  5. | auto_increment_increment | 5 |
  6. | auto_increment_offset | 3 |
  7. +--------------------------+-------+
  8. rows in set (0.00 sec)
  9. #因为之前有一条记录id=1
  10. mysql> select * from student;
  11. +----+---------+------+
  12. | id | name | sex |
  13. +----+---------+------+
  14. | 1 | xiaobai | male |
  15. +----+---------+------+
  16. row in set (0.00 sec)
  17. # 下次插入的时候,从起始位置3开始,每次插入记录id+5
  18. mysql> insert into student(name) values('ma1'),('ma2'),('ma3');
  19. Query OK, 3 rows affected (0.00 sec)
  20. Records: 3 Duplicates: 0 Warnings: 0
  21. mysql> select * from student;
  22. +----+---------+------+
  23. | id | name | sex |
  24. +----+---------+------+
  25. | 1 | xiaobai | male |
  26. | 3 | ma1 | male |
  27. | 8 | ma2 | male |
  28. | 13 | ma3 | male |
  29. +----+---------+------+
  30.  

清空表区分delete和truncate的区别:

delete from t1; #如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。

truncate table t1;数据量大,删除速度比上一条快,且直接从零开始。

foreign key

理解foreign key

 

如上图如果一个公司有很多员工,每个员工都对应一个部门,在填表的时候就会重复写这些部门,太冗余了

我们可以将它们分离

 

此时有两张表,一张是employee表,简称emp表(关联表,也就从表)。一张是department表,简称dep表(被关联表,也叫主表)。


 
  1. #1.创建表时先创建被关联表,再创建关联表
  2. # 先创建被关联表(dep表)
  3. create table dep(
  4. id int primary key,
  5. name varchar(20) not null,
  6. descripe varchar(20) not null
  7. );
  8. #再创建关联表(emp表)
  9. create table emp(
  10. id int primary key,
  11. name varchar(20) not null,
  12. age int not null,
  13. dep_id int,
  14. constraint fk_dep foreign key(dep_id) references dep(id) //创建约束
  15. );
  16. #2.插入记录时,先往被关联表中插入记录,再往关联表中插入记录
  17. insert into dep values
  18. (1,'IT','IT技术有限部门'),
  19. (2,'销售部','销售部门'),
  20. (3,'财务部','花钱太多部门');
  21. insert into emp values
  22. (1,'zhangsan',18,1),
  23. (2,'lisi',19,1),
  24. (3,'egon',20,2),
  25. (4,'yuanhao',40,3),
  26. (5,'alex',18,2);
  27.  

3.删除表


 
  1. #按道理来说,删除了部门表中的某个部门,员工表的有关联的记录相继删除。
  2. mysql> delete from dep where id=3;
  3. ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db5`.`emp`, CONSTRAINT `fk_name` FOREIGN KEY (`dep_id`) REFERENCES `dep`(`id`))
  4. #但是先删除员工表的记录之后,再删除当前部门就没有任何问题
  5. mysql> delete from emp where dep_id =3;
  6. Query OK, 1 row affected (0.00 sec)
  7. mysql> select * from emp;
  8. +----+----------+-----+--------+
  9. | id | name | age | dep_id |
  10. +----+----------+-----+--------+
  11. | 1 | zhangsan | 18 | 1 |
  12. | 2 | lisi | 18 | 1 |
  13. | 3 | egon | 20 | 2 |
  14. | 5 | alex | 18 | 2 |
  15. +----+----------+-----+--------+
  16. 4 rows in set (0.00 sec)
  17. mysql> delete from dep where id=3;
  18. Query OK, 1 row affected (0.00 sec)
  19. mysql> select * from dep;
  20. +----+-----------+----------------------+
  21. | id | name | descripe |
  22. +----+-----------+----------------------+
  23. | 1 | IT | IT技术有限部门 |
  24. | 2 | 销售部 | 销售部门 |
  25. +----+-----------+----------------------+
  26. 2 rows in set (0.00 sec)
  27.  

上面的删除表记录的操作比较繁琐,按道理讲,裁掉一个部门,该部门的员工也会被裁掉。其实呢,在建表的时候还有个很重要的内容,叫同步删除,同步更新

on delete cascade #同步删除
on update cascade #同步更新


 
  1. create table emp(
  2. id int primary key,
  3. name varchar(20) not null,
  4. age int not null,
  5. dep_id int,
  6. constraint fk_dep foreign key(dep_id) references dep(id)
  7. on delete cascade #同步删除
  8. on update cascade #同步更新
  9. );
  10.  

 
  1. #再去删被关联表(dep)的记录,关联表(emp)中的记录也跟着删除
  2. mysql> delete from dep where id=3;
  3. Query OK, 1 row affected (0.00 sec)
  4. mysql> select * from dep;
  5. +----+-----------+----------------------+
  6. | id | name | descripe |
  7. +----+-----------+----------------------+
  8. | 1 | IT | IT技术有限部门 |
  9. | 2 | 销售部 | 销售部门 |
  10. +----+-----------+----------------------+
  11. 2 rows in set (0.00 sec)
  12. mysql> select * from emp;
  13. +----+----------+-----+--------+
  14. | id | name | age | dep_id |
  15. +----+----------+-----+--------+
  16. | 1 | zhangsan | 18 | 1 |
  17. | 2 | lisi | 19 | 1 |
  18. | 3 | egon | 20 | 2 |
  19. | 5 | alex | 18 | 2 |
  20. +----+----------+-----+--------+
  21. 4 rows in set (0.00 sec)
  22. #再去更改被关联表(dep)的记录,关联表(emp)中的记录也跟着更改
  23. mysql> update dep set id=222 where id=2;
  24. Query OK, 1 row affected (0.02 sec)
  25. Rows matched: 1 Changed: 1 Warnings: 0
  26. # 赶紧去查看一下两张表是否都被删除了,是否都被更改了
  27. mysql> select * from dep;
  28. +-----+-----------+----------------------+
  29. | id | name | descripe |
  30. +-----+-----------+----------------------+
  31. | 1 | IT | IT技术有限部门 |
  32. | 222 | 销售部 | 销售部门 |
  33. +-----+-----------+----------------------+
  34. 2 rows in set (0.00 sec)
  35. mysql> select * from emp;
  36. +----+----------+-----+--------+
  37. | id | name | age | dep_id |
  38. +----+----------+-----+--------+
  39. | 1 | zhangsan | 18 | 1 |
  40. | 2 | lisi | 19 | 1 |
  41. | 3 | egon | 20 | 222 |
  42. | 5 | alex | 18 | 222 |
  43. +----+----------+-----+--------+
  44. 4 rows in set (0.00 sec)
  45.  

更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL查询技巧大全》、《MySQL常用函数大汇总》、《MySQL日志操作技巧大全》、《MySQL事务操作技巧汇总》、《MySQL存储过程技巧大全》及《MySQL数据库锁相关技巧汇总》

分享到:

相关信息

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载