欢迎拜访:雾里看山-CSDN博客
本篇主题:【MySQL】 表的约束(下)
发布时间:2025.2.12
隶属专栏:MySQL
自增长
基本介绍
auto_increment:当对应的字段,不给值,会主动的被体系触发,体系会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配利用,作为逻辑主键。
自增长的特点:
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
案例利用
- mysql> create table if not exists t16(
- -> id int unsigned primary key auto_increment,
- -> name varchar(20) not null
- -> );
- Query OK, 0 rows affected (0.02 sec)
- mysql> desc t16;
- +-------+------------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+------------------+------+-----+---------+----------------+
- | id | int(10) unsigned | NO | PRI | NULL | auto_increment |
- | name | varchar(20) | NO | | NULL | |
- +-------+------------------+------+-----+---------+----------------+
- 2 rows in set (0.01 sec)
复制代码 自增长的值默认从 1 开始
- mysql> insert into t16 (name) values ('a');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into t16 (name) values ('b');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into t16 (name) values ('c');
- Query OK, 1 row affected (0.01 sec)
- mysql> select * from t16;
- +----+------+
- | id | name |
- +----+------+
- | 1 | a |
- | 2 | b |
- | 3 | c |
- +----+------+
- 3 rows in set (0.00 sec)
复制代码 当自增长的值被更改以后,会从最大值开始自增长
- mysql> insert into t16 (id, name) values (1000, 'd');
- Query OK, 1 row affected (0.01 sec)
- mysql> select * from t16;
- +------+------+
- | id | name |
- +------+------+
- | 1 | a |
- | 2 | b |
- | 3 | c |
- | 1000 | d |
- +------+------+
- 4 rows in set (0.00 sec)
- mysql> insert into t16 (id, name) values (1000, 'd');
- ERROR 1062 (23000): Duplicate entry '1000' for key 'PRIMARY'
- mysql> insert into t16 (name) values ('d');
- Query OK, 1 row affected (0.00 sec)
- mysql> select * from t16;
- +------+------+
- | id | name |
- +------+------+
- | 1 | a |
- | 2 | b |
- | 3 | c |
- | 1000 | d |
- | 1001 | d |
- +------+------+
- 5 rows in set (0.00 sec)
复制代码 auto_increment值的查找
查找下一次插入时的值
- mysql> show create table t16 \G
- *************************** 1. row ***************************
- Table: t16
- Create Table: CREATE TABLE `t16` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(20) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8
- 1 row in set (0.00 sec)
复制代码 查找末了一次插入时的值
- mysql> select last_insert_id();
- +------------------+
- | last_insert_id() |
- +------------------+
- | 502 |
- +------------------+
- 1 row in set (0.02 sec)
复制代码 创建表时设置 auto_increment值
- mysql> create table t17(
- -> id int unsigned primary key auto_increment,
- -> name varchar(20) not null
- -> )auto_increment=500;
- Query OK, 0 rows affected (0.02 sec)
- mysql> insert into t17 (name) values ('a');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into t17 (name) values ('b');
- Query OK, 1 row affected (0.01 sec)
- mysql> insert into t17 (name) values ('c');
- Query OK, 1 row affected (0.00 sec)
- mysql> select * from t17;
- +-----+------+
- | id | name |
- +-----+------+
- | 500 | a |
- | 501 | b |
- | 502 | c |
- +-----+------+
- 3 rows in set (0.00 sec)
复制代码 索引
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储布局,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目次,可以根据目次中的页码快速找到所需的内容。
索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序次序对这些指针排序。数据库利用索引以找到特定值,然后顺指针找到包罗该值的行。这样可以使对应于表的SQL语句实行得更快,可快速访问数据库表中的特定信息。
唯一键
介绍
一张表中有通常有很多字段必要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多个字段必要唯一性约束的题目。
唯一键的本质和主键差不多,唯一键答应为空,而且可以多个为空,空字段不做唯一性比较。
利用
- mysql> create table stu(
- -> id char(20) unique comment '这是一个学生的唯一键',
- -> name varchar(32) not null
- -> );
- Query OK, 0 rows affected (0.01 sec)
- mysql> desc stu;
- +-------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+-------+
- | id | char(20) | YES | UNI | NULL | |
- | name | varchar(32) | NO | | NULL | |
- +-------+-------------+------+-----+---------+-------+
- 2 rows in set (0.00 sec)
- mysql> insert into stu (id, name) values ('12345', '张三');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into stu (id, name) values ('12345', '李四');
- ERROR 1062 (23000): Duplicate entry '12345' for key 'id'
- mysql> insert into stu (id, name) values (NULL, '李四');
- Query OK, 1 row affected (0.01 sec)
- mysql> insert into stu (id, name) values (NULL, '王五');
- Query OK, 1 row affected (0.01 sec)
- mysql> select * from stu;
- +-------+--------+
- | id | name |
- +-------+--------+
- | 12345 | 张三 |
- | NULL | 李四 |
- | NULL | 王五 |
- +-------+--------+
- 3 rows in set (0.00 sec)
复制代码 关于唯一键和主键的区别:
我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。
- mysql> create table student(
- -> id char(20) primary key,
- -> name varchar(32) not null,
- -> telphone char(20) unique key,
- -> qq varchar(64) unique key
- -> );
- Query OK, 0 rows affected (0.02 sec)
- mysql> desc student;
- +----------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+-------------+------+-----+---------+-------+
- | id | char(20) | NO | PRI | NULL | |
- | name | varchar(32) | NO | | NULL | |
- | telphone | char(20) | YES | UNI | NULL | |
- | qq | varchar(64) | YES | UNI | NULL | |
- +----------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
- mysql> insert into student values ('12345', '张三', '1341234', '1234');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into student values ('12345', '李四', '1341234', '1234');
- ERROR 1062 (23000): Duplicate entry '12345' for key 'PRIMARY'
- mysql> insert into student values ('12346', '李四', '1341234', '1234');
- ERROR 1062 (23000): Duplicate entry '1341234' for key 'telphone'
- mysql> insert into student values ('12346', '李四', '1341235', '1234');
- ERROR 1062 (23000): Duplicate entry '1234' for key 'qq'
- mysql> insert into student values ('12346', '李四', '1341235', '1235');
- Query OK, 1 row affected (0.01 sec)
- mysql> select * from student;
- +-------+--------+----------+------+
- | id | name | telphone | qq |
- +-------+--------+----------+------+
- | 12345 | 张三 | 1341234 | 1234 |
- | 12346 | 李四 | 1341235 | 1235 |
- +-------+--------+----------+------+
- 2 rows in set (0.00 sec)
复制代码 非空唯一键
唯一键也可以设置为非空,在功能上类似于主键
- mysql> alter table student modify telphone char(20) unique not null;
- Query OK, 0 rows affected, 1 warning (0.06 sec)
- Records: 0 Duplicates: 0 Warnings: 1
- mysql> alter table student modify qq char(20) unique not null;
- Query OK, 2 rows affected, 1 warning (0.03 sec)
- Records: 2 Duplicates: 0 Warnings: 1
- mysql> desc student;
- +----------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+-------------+------+-----+---------+-------+
- | id | char(20) | NO | PRI | NULL | |
- | name | varchar(32) | NO | | NULL | |
- | telphone | char(20) | NO | UNI | NULL | |
- | qq | char(20) | NO | UNI | NULL | |
- +----------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
- mysql> insert into student values ('54321', '王五', '1234235', '12123');
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into student values ('54322', '赵六', NULL, '12124');
- ERROR 1048 (23000): Column 'telphone' cannot be null
- mysql> insert into student values ('54322', '赵六', '1234236', NULL);
- ERROR 1048 (23000): Column 'qq' cannot be null
复制代码 外键
介绍
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique 约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
语法:
foreign key (字段名) references 主表(列)
案例:
创建主表并插入数据
- mysql> create table if not exists class(
- -> id int primary key,
- -> name varchar(32) not null
- -> );
- Query OK, 0 rows affected (0.02 sec)
- mysql> desc class;
- +-------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+-------+
- | id | int(11) | NO | PRI | NULL | |
- | name | varchar(32) | NO | | NULL | |
- +-------+-------------+------+-----+---------+-------+
- 2 rows in set (0.00 sec)
- ysql> insert into class values (1,'通信101');
- Query OK, 1 row affected (0.01 sec)
- mysql> insert into class values (2,'通信102');
- Query OK, 1 row affected (0.00 sec)
- mysql> select * from class;
- +----+-----------+
- | id | name |
- +----+-----------+
- | 1 | 通信101 |
- | 2 | 通信102 |
- +----+-----------+
- 2 rows in set (0.00 sec)
复制代码 创建从表并确认从属关系
- mysql> create table student(
- -> id int unsigned primary key,
- -> name varchar(20) not null,
- -> telphone varchar(32) unique key,
- -> class_id int,
- -> foreign key(class_id) referemces class(id)
- -> );
- Query OK, 0 rows affected (0.04 sec)
- mysql> desc student;
- +----------+------------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+------------------+------+-----+---------+-------+
- | id | int(10) unsigned | NO | PRI | NULL | |
- | name | varchar(20) | NO | | NULL | |
- | telphone | varchar(32) | YES | UNI | NULL | |
- | class_id | int(11) | YES | MUL | NULL | |
- +----------+------------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
复制代码 从表的插入受主表的约束
- mysql> insert into student values (100, '张三', '12345', 1);
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into student values (101, '李四', '12346', 2);
- Query OK, 1 row affected (0.00 sec)
- mysql> insert into student values (102, '王五', '12347', 3);
- ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test_db`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
- mysql> insert into student values (102, '王五', '12347', NULL);
- Query OK, 1 row affected (0.00 sec)
- mysql> select * from student;
- +-----+--------+----------+----------+
- | id | name | telphone | class_id |
- +-----+--------+----------+----------+
- | 100 | 张三 | 12345 | 1 |
- | 101 | 李四 | 12346 | 2 |
- | 102 | 王五 | 12347 | NULL |
- +-----+--------+----------+----------+
- 3 rows in set (0.00 sec)
复制代码 主表也受从表的约束
- mysql> delete from class where id=1;
- ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test_db`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
复制代码 如何理解外键约束
首先我们认可,这个世界是数据很多都是相关性的。
理论上,上面的例子,我们不创建外键约束,就正常建立学生表,以及班级表,该有的字段我们都有。
此时,在实际利用的时间,可能会出现什么题目?
有没有可能插入的学生信息中有详细的班级,但是该班级却没有在班级表中?
比如学校只开了普通100班,普通101班,但是在上课的学生里面竟然有普通102班的学生(这个班目前并不存在),这很显着是有题目的。
因为此时两张表在业务上是有相关性的,但是在业务上没有建立约束关系,那么就可能出现题目。
解决方案就是通过外键完成的。建立外键的本质实在就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时间,mysql不答应你插入。
综合案例实现
有一个商店的数据,记录客户及购物环境,有以下三个表组成:
- 商品goods(商品编号goods_id,商品名goods_name, 单价unitprice, 商品类别category, 供应商provider)
- 客户customer(客户号customer_id,姓名name,住址address,邮箱email,性别sex,身份证card_id)
- 购买purchase(购买订单号order_id,客户号customer_id,商品号goods_id,购买数量nums)
要求:
- 每个表的主外键
- 客户的姓名不能为空值
- 邮箱不能重复
- 客户的性别(男,女)
- -- 创建数据库
- create database if not exists bit32mall
- default character set utf8 ;
- -- 选择数据库
- use bit32mall;
- -- 创建数据库表
- -- 商品
- create table if not exists goods
- (
- goods_id int primary key auto_increment comment '商品编号',
- goods_name varchar(32) not null comment '商品名称',
- unitprice int not null default 0 comment '单价,单位分',
- category varchar(12) comment '商品分类',
- provider varchar(64) not null comment '供应商名称'
- );
- -- 客户
- create table if not exists customer
- (
- customer_id int primary key auto_increment comment '客户编号',
- name varchar(32) not null comment '客户姓名',
- address varchar(256) comment '客户地址',
- email varchar(64) unique key comment '电子邮箱',
- 比特就业课
- sex enum('男','女') not null comment '性别',
- card_id char(18) unique key comment '身份证'
- );
- -- 购买
- create table if not exists purchase
- (
- order_id int primary key auto_increment comment '订单号',
- customer_id int comment '客户编号',
- goods_id int comment '商品编号',
- nums int default 0 comment '购买数量',
- foreign key (customer_id) references customer(customer_id),
- foreign key (goods_id) references goods(goods_id)
- );
复制代码 ⚠️ 写在末了:以上内容是我在学习以后得一些总结和概括,如有错误或者必要补充的地方欢迎各位大佬评论或者私信我交流!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |