mysql唯一约束
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql唯一约束相关的知识,希望对你有一定的参考价值。
参考技术A 唯一约束 unique特征:
1.不允许有重复的值,保证数据的唯一性。
2.可以有空值
3.在一个表中,可以有多个唯一约束
4.默认情况下,唯一约束的名字和列名保持一致
5.添加唯一约束的列,系统也会默认给这个列添加一个唯一索引
索引:等同于书本的目录,将来能够加快数据的查询速度。
如何添加唯一约束
1.创建表的同时创建唯一约束 UN_列名
格式一:
create table 表名(
列名1 数据类型,
列名2 数据类型,
constraint 唯一约束的名字 unique(列名1),
constraint 唯一约束的名字 unique(列名2)
);
格式二:
create table 表名(
列名1 数据类型 unique,
列名2 数据类型 unique,
列名3 数据类型
);
一个表中是可以存在多个约束的
2.针对已经存在的表,添加唯一约束
格式:
alter table 表名 add unique(列名[,列名2]);
3.删除唯一约束
格式:
alter table 表名 drop index 唯一约束的名字;
Linux学习-MySQL约束
MySQL约束
MySQL约束为保证数据记录完整性定义的一系列规则、限定。
约束分类
| 唯一性约束 | UNIQUE KEY |
|主键约束| PRIMARY KEY|
|非空约束| NOT NULL|
|自增列| AUTO_INCREMENT|
|外键约束| FOREIGN KEY|
|默认值约束| DEFAULT|
|检查约束| check|
UNIQUE唯一性约束
唯一性约束:列值必须唯一,但可以为空值(空值可以重复)
1. 添加唯一性约束的列上会自动创建唯一索引
2. 删除唯一性约束只能通过删除唯一索引的方式删除
3. 删除时需要指定唯一索引名称,唯一索引名称同唯一约束名
4. 如果创建唯一约束时未指定名称,如果是单列,默认名称同列名,如组合列,默认与()中排第一的列值相同,也可以自定义唯一约束名称。
PRIMARY KEY主键约束
主键约束:用于唯一标识表中的一行记录,唯一约束+非空约束的组合
1. 一个表中最多只能有一个主键约束,建立主键约束可以在列级别,也可在表级别
2. 主键约束对应着表中的一列或多列(复合主键)
3. 如果多列组合复合主键约束,那么这些列都不允许为空,并且组合的值不能重复
4. MySQL主键名是PRIMARY
5. 当创建主键约束时,系统默认会在所在的列或列组合上建立对应的主键索引(主键查询效率更高),主键约束删除,对应的索引也自动删除
6. 不要修改主键字段的值,因为主键是数据记录的唯一标识,如果修改了主键的值,就可能破坏数据的完整性
#创建列级主键约束
mysql> create table test3(id int primary key,last_name varchar(20),email varchar(25),salary decimal(10,2));
Query OK, 0 rows affected (0.01 sec)
mysql> desc test3;
+-----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| last_name | varchar(20) | YES | | NULL | |
| email | varchar(25) | YES | | NULL | |
| salary | decimal(10,2) | YES | | NULL | |
+-----------+---------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
mysql> select * from information_schema.table_constraints where table_name='test3';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def | dbtest13 | PRIMARY | dbtest13 | test3 | PRIMARY KEY | YES |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
1 row in set (0.01 sec)
mysql> show index from test3;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| test3 | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | YES | NULL |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.01 sec)
#创建表级主键约束
mysql> create table test5(id int,last_name varchar(20),email varchar(25),salary decimal(10,2),primary key(id));
Query OK, 0 rows affected (0.01 sec)
mysql> desc test5;
+-----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| last_name | varchar(20) | YES | | NULL | |
| email | varchar(25) | YES | | NULL | |
| salary | decimal(10,2) | YES | | NULL | |
+-----------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> select * from information_schema.table_constraints where table_name='test5';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def | dbtest13 | PRIMARY | dbtest13 | test5 | PRIMARY KEY | YES |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
1 row in set (0.00 sec)
AUTO_INCREMENT自增
自增:某个字段的值自增
1. 一个表最多只能有一个自增长列
2. 当需要产生唯一标识符或顺序值时,可设置自增长
3. 自增长列约束必须是键值(主键列,唯一键列)
4. 自增约束的列数据类型必须为整型
5. 如果自增列指定了0和NULL,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值
#通过修改MySQL变量可以变更自增值
mysql> set auto_increment_increment=4;
#当像含有AUTO_INCREMENT的字段上添加0或null时,实际上会自动往上添加指定的值,在开发中向含有AUTO_INCREMENT的字段上插入数据时,不需要向此列中赋值。
#注:
(MySQL5.7)AUTO_INCREMENT在内存中维护着一个值,删除数据后,重启服务器后,会根据数据库表中的记录重新生成值
MySQL8.0将自增的计数器持久化到重做日志中,每次计数发生改变,都会将其写入重做日志中,如果数据库重启,InnoDB会根据重做日志中的信息来初使化计数器的内存值。
FOREIGN KEY外键约束
外键约束:限定某个表的某个字段的引用完整性
1. 主表(父表):被引用的表,被参考的表
2. 从表(子表):引用别人的表,参考别人的表
3. 从表的外键列必须引用/参考主表的主键或唯一约束列
4. 在创建外键约束时,如果不给外键约束命名,默认不是列名,而是自动产生一个外键名,也可以指定外键约束名
5. 创建表时指定外键约束的话,需先创建主表,再创建从表
6. 删除表时,先删除从表(或先删除外键约束),再删除从表
7. 当主表的记录被从表参照时,主表记录将不允许删除,如果要删除数据,需先删除从表中依赖该记录的数据,然后才可以删除主表的数据
8. 在从表中指定外键约束,并且一个表可以建立多个外键约束
9. 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致,如果类型不一样,创建了表时会报错
10.当创建外键约束时,系统默认会在所在列上建立对应的普通索引,但索引名是列名,不是外键的约束名(外键查询效率高)
11.删除外键约束后,必须手动删除对应的索引
#如员工表的员工所在的部门这个字段的值要参考部门表:部门表是主表,员工表是从表
#创建主表dep1
mysql> create table dep1(dept_id int,dept_name varchar(15));
Query OK, 0 rows affected (0.02 sec)
#因为主表中没有创建主键或唯一键,会报错
mysql> create table emp1(emp_id int primary key auto_increment,emp_name varchar(15),department_id int,constraint fk_emp1_dept_id foreign key(department_id) references dep1(dept_id));
ERROR 1822 (HY000): Failed to add the foreign key constraint. Missing index for constraint 'fk_emp1_dept_id' in the referenced table 'dep1'
#给主表添加主键
mysql> alter table dep1 add primary key(dept_id);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create table emp1(emp_id int primary key auto_increment,emp_name varchar(15),department_id int,constraint fk_emp1_dept_id foreign key(department_id) references dep1(dept_id));
Query OK, 0 rows affected (0.02 sec)
#查看表约束
mysql> select * from information_schema.table_constraints where table_name='emp1';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def | dbtest13 | PRIMARY | dbtest13 | emp1 | PRIMARY KEY | YES |
| def | dbtest13 | fk_emp1_dept_id | dbtest13 | emp1 | FOREIGN KEY | YES |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
2 rows in set (0.00 sec)
#直接更新从表中(外键值在主表中如果不存在,则会报错)
mysql> insert into emp1 values(1001,'Tom',10);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`dbtest13`.`emp1`, CONSTRAINT `fk_emp1_dept_id` FOREIGN KEY (`department_id`) REFERENCES `dep1` (`dept_id`))
#先在主表中添加信息后,然后在从表中添加数据
mysql> insert into dep1 values(10,'IT');
Query OK, 1 row affected (0.00 sec)
mysql> insert into emp1 values(1001,'Tom',10);
Query OK, 1 row affected (0.01 sec)
#主表中删除数据前,需先删除从表中信息
mysql> delete from dep1 where dept_id=10;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`dbtest13`.`emp1`, CONSTRAINT `fk_emp1_dept_id` FOREIGN KEY (`department_id`) REFERENCES `dep1` (`dept_id`))
#约束等级
- Cascade(级联)方式:在父表update/delete记录时,同步删除从表中的记录
- Set null方式:在父表上update/delete记录时,将子表中匹配记录的列设为null,但从表的外键不能设定为not null
- No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
- Restrict方式:同no action,都是立即检查外键约束
- Set default方式,父表有变更时,子表将外键设定为一个默认的值,但innodb不能识别
- 默认等级为Restrict,对于外键约束,最好采用ON UPDATE CASCADE ON DELETE RESTRICT的方式
##在MySQL里,外键约束是有成本的,需要消耗系统资源,对于大并发的SQL操作,可能会因为外键约束的系统开销变得很慢,MySQL允许不使用自带的外键约束,在应用层面完成数据一致性的逻辑。
外键级连适合单机低并发,不适合分布式高并发环境
CHECK约束
CHECK约束:检查某个字段的值是否符合xx要求,一般指取值范围
mysql> create table test10(id int,last_name varchar(20),salary decimal(10,2),check(salary>2000));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test10 values(10,'tome',2500);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test10 values(10,'tome',1500);
ERROR 3819 (HY000): Check constraint 'test10_chk_1' is violated.
DEFAULT约束
问:为什么建表时,加not null default ''或default 0
不想让表出现null值
问:为什么不想要null值
1. 不好比较,null是一种特殊值,比较时需使用函数 is null 或not is null,使用运算符则返回null
2. 效率不高,影响索引效果
问:带AUTO_INCREMENT约束的字段是从1开始的吗
在MySQL中,默认AUTO_INCREMENT的初使值是1,每新增一条记录,字段值自动加1,设置了AUTO_INCREMENT的时候,可以提前插入一条记录如(自增字段)id=5,则下一条记录则会从6开始
问:并不是每个表都可以任意选择存储引擎
外键约束不能跨引擎使用
MySQL支持多种存储引擎,每一个表可以指定不同的存储引擎,外键约束是保证数据的参照完整性的,如表之间需要关联外键,却指定了不同存储引擎,那么表之间不能创建外键约束,所以存储引擎选择不是随意的。
以上是关于mysql唯一约束的主要内容,如果未能解决你的问题,请参考以下文章
mysql中唯一约束、key和索引的区别,unique key 就是唯一约束吗,新手麻烦指点,谢谢