失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 数据库——MySQL——完整性约束

数据库——MySQL——完整性约束

时间:2018-06-29 01:40:31

相关推荐

数据库——MySQL——完整性约束

约束,就是用来保证数据完整性和一致性的。

常见的约束分为:

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

下面会说其中的一部分

unique 唯一索引

使用方式

============设置唯一约束 UNIQUE===============方法一:create table department1(id int,name varchar(20) unique,comment varchar(100));方法二:create table department2(id int,name varchar(20),comment varchar(100),constraint uk_name unique(name));mysql> insert into department1 values(1,'IT','技术');Query OK, 1 row affected (0.00 sec)mysql> insert into department1 values(1,'IT','技术');ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'

如果是not null和unique进行组合的话,会变成主键

mysql> create table t1(id int not null unique);Query OK, 0 rows affected (0.02 sec)mysql> desc t1;+-------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+---------+------+-----+---------+-------+| id | int(11) | NO | PRI | NULL | |+-------+---------+------+-----+---------+-------+row in set (0.00 sec)

create table service(id int primary key auto_increment,name varchar(20),host varchar(15) not null,port int not null,unique(host,port) #联合唯一);mysql> insert into service values-> (1,'nginx','192.168.0.10',80),-> (2,'haproxy','192.168.0.20',80),-> (3,'mysql','192.168.0.30',3306)-> ;Query OK, 3 rows affected (0.01 sec)Records: 3 Duplicates: 0 Warnings: 0mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80);ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'联合唯一

联合唯一

primary key主键

从约束角度看primary key字段的值不为空且唯一,那我们直接使用not null+unique不就可以了吗,要它干什么?

innodb称之为索引组织表,一张表中必须有且只有一个主键。主键primary key是innodb存储引擎组织数据的依据。

一个表中可以有两种形式:

单列做主键多列做主键(复合主键)

============单列做主键===============#方法一:not null+uniquecreate table department1(id int not null unique, #主键name varchar(20) not null unique,comment varchar(100));mysql> desc department1;+---------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+--------------+------+-----+---------+-------+| id| int(11)| NO | PRI | NULL | || name | varchar(20) | NO | UNI | NULL | || comment | varchar(100) | YES || NULL | |+---------+--------------+------+-----+---------+-------+rows in set (0.01 sec)#方法二:在某一个字段后用primary keycreate table department2(id int primary key, #主键name varchar(20),comment varchar(100));mysql> desc department2;+---------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+--------------+------+-----+---------+-------+| id| int(11)| NO | PRI | NULL | || name | varchar(20) | YES || NULL | || comment | varchar(100) | YES || NULL | |+---------+--------------+------+-----+---------+-------+rows in set (0.00 sec)#方法三:在所有字段后单独定义primary keycreate table department3(id int,name varchar(20),comment varchar(100),constraint pk_name primary key(id); #创建主键并为其命名pk_namemysql> desc department3;+---------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+--------------+------+-----+---------+-------+| id| int(11)| NO | PRI | NULL | || name | varchar(20) | YES || NULL | || comment | varchar(100) | YES || NULL | |+---------+--------------+------+-----+---------+-------+rows in set (0.01 sec)

单列主键

==================多列做主键================create table service(ip varchar(15),port char(5),service_name varchar(10) not null,primary key(ip,port));mysql> desc service;+--------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+-------------+------+-----+---------+-------+| ip | varchar(15) | NO | PRI | NULL | || port | char(5)| NO | PRI | NULL | || service_name | varchar(10) | NO || NULL | |+--------------+-------------+------+-----+---------+-------+rows in set (0.00 sec)mysql> insert into service values-> ('172.16.45.10','3306','mysqld'),-> ('172.16.45.11','3306','mariadb')-> ;Query OK, 2 rows affected (0.00 sec)Records: 2 Duplicates: 0 Warnings: 0mysql> insert into service values ('172.16.45.10','3306','nginx');ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'多列主键

多列主键

auto_increment自增

这里对使用自增做几点说明

给字段设置自增之后,还是可以给该字段赋值的如果用delete删除了记录后,再插入值,该字段仍按照删除前的位置继续增长truncate是清空表,而delete是一条条的删记录,当用truncate清空表中之后,设置的自增的字段重新从1开始自增。

# auto_increment_increment这是自增长的步长。# auto_increment_offset这是自增长开始的值#基于会话级别#比如:set session auth_increment_increment=2 #修改会话级别的步长#基于全局级别的#比如:set global auth_increment_increment=2 #修改全局级别的步长(所有会话都生效)mysql> set global auto_increment_increment=5;Query OK, 0 rows affected (0.00 sec)mysql> set global auto_increment_offset=3;Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'auto_incre%'; #需要退出重新登录+--------------------------+-------+| Variable_name | Value |+--------------------------+-------+| auto_increment_increment | 1|| auto_increment_offset | 1|+--------------------------+-------+

例子

foreign key 外键

为什么会产生外键,举个例子:

员工信息表有三个字段:工号 姓名 部门

公司有3个部门,但是有1个亿的员工,那意味着部门这个字段需要重复存储,部门名字越长,越浪费

解决方法:

我们完全可以定义一个部门表

然后让员工信息表关联该表,如何关联,即foreign key

使用外键要注意的:

表的类型必须是innodb存储引擎被关联的字段,也就是另一个表中的字段,必须保证唯一。

外键的定义语法:

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)REFERENCES tbl_name (index_col_name, ...)[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}][ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

说明:

该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,

CONSTRAINT symbol,是给这个约束增加一个名字,如果不指定MYSQL会自动生成一个名字。

ON DELETE、ON UPDATE表示事件触发限制,可设参数:

RESTRICT(限制外表中的外键改动)

CASCADE(跟随外键改动)

SET NULL(设空值)

SET DEFAULT(设默认值)

NO ACTION(无动作,默认的)

例子:

说明,这个例子是在网上看到的,虽然有些说明不好,但比较有条理而且易于理解的,原文地址为:/wolf/articles/69089.html

# 创建两张表,一个是大哥表,一个小弟表,大哥表的id是小弟表的外键。CREATE TABLE `dage` (`id` int(11) NOT NULL auto_increment,`name` varchar(32) default '',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;CREATE TABLE `xiaodi` (`id` int(11) NOT NULL auto_increment,`dage_id` int(11) default NULL,`name` varchar(32) default '',PRIMARY KEY (`id`),KEY `dage_id` (`dage_id`),CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;# 大哥表中插入一个记录mysql> insert into dage(name) values('铜锣湾');Query OK, 1 row affected (0.01 sec)mysql> select * from dage;+----+--------+| id | name |+----+--------+| 1 | 铜锣湾 |+----+--------+1 row in set (0.00 sec)# 小弟表中插入一个记录mysql> insert into xiaodi(dage_id,name) values(1,'铜锣湾_小弟A');Query OK, 1 row affected (0.02 sec)mysql> select * from xiaodi;+----+---------+--------------+| id | dage_id | name |+----+---------+--------------+| 1 | 1 | 铜锣湾_小弟A |+----+---------+--------------+# 想要删除大哥中的一个记录,这个时候会提示,这个大哥是一个小弟的外键,不让删mysql> delete from dage where id=1;ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`))# 这个时候给大哥的外键约束增加时间触发限制mysql> show create table xiaodi;...CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)...mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1; Query OK, 1 row affected (0.04 sec)Records: 1 Duplicates: 0 Warnings: mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade;Query OK, 1 row affected (0.04 sec)Records: 1 Duplicates: 0 Warnings: 0# 然后再删大哥mysql> delete from dage where id=1;Query OK, 1 row affected (0.01 sec)mysql> select * from dage;Empty set (0.01 sec)mysql> select * from xiaodi;Empty set (0.00 sec)# 这个时候大哥和小弟就都被一套带走了。

例子

如果觉得《数据库——MySQL——完整性约束》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。