赞
踩
作用:
在一个table中,标识一行记录的唯一性。
语法:
create table时,可以紧随列属性声明的后面,如id int primary key
,也可以单独成一行,如下:
mysql> show create table student \G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int(3) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`gender` enum('男','女') DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
表已存在,添加主键
alter table 表名 add primary key (已存在的字段列表);
删除主键
alter table 表名 drop primary key;
复合主键:
mysql> show create table t3 \G
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE `t3` (
`course` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`gender` enum('男','女') DEFAULT NULL,
PRIMARY KEY (`course`,`name`) #括号里面以逗号区分复合主键的每一个成分
) ENGINE=InnoDB DEFAULT CHARSET=utf8
多个属性组合为一个整体,以标识数据记录的唯一性,就是复合主键。要将复合主键看作一个整体,即复合主键也只是一个主键,只不过包含了多个属性。
作用:
保证同一张table内,多条数据的某个字段的唯一性。
语法(和定义主键的语法差不多):
mysql> show create table student \G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int(3) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`gender` enum('男','女') DEFAULT NULL,
`telephone` char(11) DEFAULT NULL,
`wechat` varchar(15) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `telephone` (`telephone`),
UNIQUE KEY `wechat` (`wechat`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
添加唯一键
alter table 表名 add unique key (已存在的字段列表);
复合唯一键:
道理和复合主键类似,也支持整合多个字段为一个唯一键(如下,创建一个学生信息表,以’班级-班内编号’作为一个复合唯一键)
mysql> show create table t4 \G
*************************** 1. row ***************************
Table: t4
Create Table: CREATE TABLE `t4` (
`id` int(3) unsigned zerofill NOT NULL,
`name` varchar(20) NOT NULL,
`class` char(10) DEFAULT NULL,
`classid` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `in_class` (`class`,`classid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> select * from t4;
+-----+--------+------------+---------+
| id | name | class | classid |
+-----+--------+------------+---------+
| 001 | 张三 | 2021200101 | 1 |
| 002 | 李四 | 2021200103 | 1 |
| 008 | 老刘 | 2021200103 | 2 |
+-----+--------+------------+---------+
每个学生的class可以相同,classid可以相同,但是class-classid组合起来就必须是唯一的。
The difference between primary key and unique key:
tips
作用:
在表与表之间建立联系,使彼此的增删查改操作受到另一方一定的影响。在foreign key的语境中,会有一张主表和一张从表,外键约束主要定义在从表上,主表则必须是有主键约束或唯一键约束,从表可以引用主表的primary key或unique key作为自己的外键,以此建立与主表的联系。
Demo场景:学生与班级的关系,学生一定从属于某个存在的班级。
从表指定外键的语法
foreign key (字段名) references 主表名(字段名)
建立主表class
mysql> show create table class \G *************************** 1. row *************************** Table: class Create Table: CREATE TABLE `class` ( `id` tinyint(3) unsigned zerofill NOT NULL, `type` enum('实验班','普通班') DEFAULT '普通班', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 mysql> desc class; +-------+-------------------------------+------+-----+-----------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------------------------+------+-----+-----------+-------+ | id | tinyint(3) unsigned zerofill | NO | PRI | NULL | | | type | enum('实验班','普通班') | YES | | 普通班 | | +-------+-------------------------------+------+-----+-----------+-------+
建立从表student
mysql> show create table student \G *************************** 1. row *************************** Table: student Create Table: CREATE TABLE `student` ( `id` int(3) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `gender` enum('男','女') DEFAULT NULL, `telephone` char(11) DEFAULT NULL, `wechat` varchar(15) DEFAULT NULL, `class_id` tinyint(3) unsigned zerofill DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `telephone` (`telephone`), UNIQUE KEY `wechat` (`wechat`), KEY `class_id` (`class_id`), CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`) #重点在这里 ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> desc student; +-----------+------------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------------------+------+-----+---------+----------------+ | id | int(3) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | | gender | enum('男','女') | YES | | NULL | | | telephone | char(11) | YES | UNI | NULL | | | wechat | varchar(15) | YES | UNI | NULL | | | class_id | tinyint(3) unsigned zerofill | YES | MUL | NULL | | +-----------+------------------------------+------+-----+---------+----------------+
实际场景中,学生的信息在student表中存储,由于学生必然从属于某个班级,因此还需要存储学生班级的信息,由于多个学生可能共属于同一个班级,如果直接在student表中增加班级属性的列(如班级编号、班级类型等),会使student表的数据冗余。因此可以用另一个表class存储班级信息,再将class表作为主表,student表作为从表,建立外键联系。student表的class_id
指的是学生的班级id,而这个class_id
与class表的字段id
建立了外键联系,这样在student表中,每个学生只需要存储一个class_id,就可以到class表中找到对应的班级信息,减少数据冗余。
试着向两个表插入一些数据!
mysql> select * from class; +-----+-----------+ | id | type | +-----+-----------+ | 001 | 普通班 | | 002 | 实验班 | +-----+-----------+ 2 rows in set (0.00 sec) mysql> select * from student; +----+--------+--------+-------------+--------+----------+ | id | name | gender | telephone | wechat | class_id | +----+--------+--------+-------------+--------+----------+ | 1 | 张伟 | 男 | 12345678910 | 5555 | 001 | | 2 | 一菲 | 女 | 11233113344 | 6666 | 002 | +----+--------+--------+-------------+--------+----------+ 6 rows in set (0.00 sec)
如果向student表中插入在class表中不存在的class_id,MySQL会拦截
mysql> insert into student (name, gender, telephone, wechat, class_id) values ('小贤','男',11111111222,7777, 3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ckf_d3`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
如果从class表中删除了在student中已经存在的class_id,MySQL也不允许这样做
mysql> delete from class where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`ckf_d3`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
建立外键约束的本质其实就是把表与表之间逻辑上的相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。