MYSQL-表的约束(下)
目录
自增长
唯一键
外键
自增长
MySQL自增长(Auto-Increment) 是一种字段属性,用于为表中的记录自动生成唯一的连续整数,常作为主键或唯一标识字段使用,避免手动输入重复值。
核心特性
1. 自动赋值:插入数据时,无需指定该字段值,MySQL会自动分配比当前最大值大1的整数。
2. 唯一性保障:默认情况下,自增长值唯一(需配合主键或唯一索引使用,否则可能报错)。
3. 初始值与步长:默认从 1 开始,每次递增 1 ,也可手动修改初始值和步长。
4. 不可回滚:删除数据后,自增长值不会自动回退(如删除ID=5的记录,下次插入仍会是6而非5)。
常见使用场景与语法
1. 创建表时设置自增长(常用)
通常将自增长字段设为主键,语法如下:
CREATE TABLE 表名 (字段名 INT AUTO_INCREMENT PRIMARY KEY, -- 自增长+主键其他字段 数据类型,...
);
示例:创建“学生表”,用 student_id 作为自增长主键
CREATE TABLE students (student_id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),age INT
);
2. 插入数据(无需指定自增长字段)
INSERT INTO students (name, age) VALUES ('张三', 20), ('李四', 21);
插入后 student_id 会自动生成 1 和 2 。
3. 修改自增长初始值/步长
- 修改初始值(需确保新值大于当前最大自增长值):ALTER TABLE students AUTO_INCREMENT = 100; -- 下次插入从100开始- 修改步长(需先修改会话变量或全局变量,仅对新表生效):SET @@auto_increment_increment = 2; -- 步长改为2,下次插入依次为100、102...
注意事项
- 支持的数据类型:仅支持整数类型(如 INT 、 BIGINT ),不支持字符串、浮点型等。
- 一张表仅一个:每个表只能有一个 AUTO_INCREMENT 字段,且该字段必须是主键或唯一索引的一部分。
- 批量插入与自增长:批量插入时,自增长值会按插入条数连续分配,即使部分插入失败,已占用的自增长值也不会复用。
唯一键
MySQL唯一键(Unique Key) 是一种约束,用于确保表中指定字段或字段组合的值在所有记录中唯一不重复,但允许字段值为 NULL (且多个 NULL 值不视为重复),常用来标识非主键但需唯一的信息。
核心特性
- 唯一性约束:约束字段的所有非 NULL 值必须唯一,例如“用户表”中的“手机号”“邮箱”。
- 允许NULL值:与主键(非空+唯一)不同,唯一键字段可包含 NULL ,且一张表中同一唯一键字段可存在多个 NULL (因 NULL 在MySQL中视为“未知”,不与其他 NULL 比较)。
- 自动创建索引:MySQL会为唯一键自动创建唯一索引,提升基于该字段的查询效率,同时避免重复值插入。
- 数量无限制:一张表可创建多个唯一键(主键仅能有一个),满足多维度的唯一性需求。
常见使用场景与语法
1. 创建表时定义唯一键
可通过两种方式指定,直接在字段后加 UNIQUE ,或单独用 UNIQUE KEY 子句(适合复合唯一键)。
示例1:单一字段唯一键(如用户手机号)
CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY, -- 主键phone VARCHAR(20) UNIQUE, -- 单一字段唯一键(手机号唯一)email VARCHAR(50),UNIQUE KEY uk_email (email) -- 单独定义唯一键(邮箱唯一,指定约束名uk_email)
);
示例2:复合唯一键(多字段组合唯一,如“课程表”的“学期+课程号”)
需多字段组合才能唯一标识时使用,例如同一学期内课程号不能重复,但不同学期可重复。
CREATE TABLE courses (course_id INT AUTO_INCREMENT PRIMARY KEY,term VARCHAR(20), -- 学期(如“2024春”)course_no VARCHAR(20), -- 课程号(如“CS101”)course_name VARCHAR(50),UNIQUE KEY uk_term_course_no (term, course_no) -- 复合唯一键
);
2. 给已有表添加唯一键
通过 ALTER TABLE 语句为现有表新增唯一键:
-- 给users表的“身份证号”字段加唯一键
ALTER TABLE users ADD UNIQUE KEY uk_id_card (id_card);-- 给courses表加“学期+教师ID”的复合唯一键
ALTER TABLE courses ADD UNIQUE KEY uk_term_teacher (term, teacher_id);
3. 删除唯一键
需通过唯一键的约束名删除(若创建时未指定,可通过 SHOW CREATE TABLE 表名 查看默认名):
-- 删除users表中名为uk_email的唯一键
ALTER TABLE users DROP INDEX uk_email;
唯一键与主键的核心区别
对比维度 | 唯一键(Unique Key) | 主键(Primary Key) |
非空性 | 允许字段值为 NULL (可多个) | 不允许为 NULL (必须非空) |
数量限制 | 一张表可创建多个 | 一张表仅能有一个 |
主要作用 | 约束非主键字段的唯一性(如手机号) | 唯一标识表中每条记录(核心标识) |
索引类型 | 自动创建唯一索引 | 自动创建主键索引(查询效率更高) |
外键
一、外键是干啥的?
一句话总结:外键是“表与表之间的关联锁” ,用来约束两张表的数据必须“合理关联”,避免存一堆“无效/错误关联”的数据。
例子:
- 班级表(myclass) :存班级信息, id 是主键(比如 10 对应“c++大牛班”, 20 对应“java大神班” )。
- 学生表(stu) :存学生信息, class_id 是外键,用来关联“班级表的 id ”。
用外键约束后,学生表的 class_id 必须是班级表 id 里有的值 ,否则不让存!
二、外键怎么用?
1. 先建“主表”(被关联的表,必须有主键/唯一键)
比如先建班级表 myclass , id 是主键(主键自带“唯一、非空”约束,适合被外键关联):
create table myclass (id int primary key, -- 主键,班级唯一标识name varchar(30) not null comment '班级名'
);
2. 再建“从表”(关联主表的表,通过外键约束)
建学生表 stu 时,用 foreign key (class_id) references myclass(id) 声明:
- class_id 是外键字段,要关联 myclass 表的 id 字段。
create table stu (id int primary key,name varchar(30) not null comment '学生名',class_id int, -- 用来关联班级表的idforeign key (class_id) references myclass(id) -- 外键约束!
);
3. 插入数据,看外键咋“管事儿”
- 正常插入(主表有对应数据) :
先往班级表插班级 (10, 'c++大牛班'), (20, 'java大神班') ,再往学生表插 (100, '张三', 10), (101, '李四', 20) ,因为 class_id ( 10 、 20 )在班级表 id 里存在,所以能成功。
- 插“无效班级”(主表没对应数据) :
想插 (102, 'wangwu', 30) ,但班级表根本没有 id=30 的班级,直接报错!
(报错内容: Cannot add or update a child row: a foreign key constraint fails ,意思是“外键约束失败,不让插” )
- 插 NULL (还没分班的学生) :
外键允许 class_id 为 NULL ,所以能插 (102, 'wangwu', null) (表示学生还没分班,关联关系暂时“空着” )。
三、为啥要用外键?(解决啥问题?)
防“数据冗余 + 无效关联” !
- 不用外键的话,你可以随便往学生表插 class_id=100 (但班级表根本没这个班),时间长了数据就乱套——“学生说自己是100班的,但系统里根本没这个班” 。
- 用了外键,MySQL 会帮你“把关” :学生表的 class_id 必须在班级表 id 里存在 ,否则直接拦截,保证数据关联“合理” 。
四、外键的核心规则(必记!)
1. 主表必须有“主键/唯一键” :外键要关联的字段(比如班级表 id ),得是主键( primary key )或唯一键( unique ),保证“被关联的值是唯一的”。
2. 外键字段的值,要么在主表存在,要么为 NULL :如果不想关联任何主表数据,就设为 NULL (但字段本身得允许 NULL ,像class_id 没写 not null ,所以能插 NULL )。
3. 删主表数据要小心 :如果主表数据被从表关联(比如班级表 id=10 ,学生表有学生关联它),直接删主表数据会报错!(得先删从表关联数据,或设置“级联删除” ,简单场景先记住“主表数据被关联时不能直接删” )
一句话总结外键 :它是表与表之间的“关联保镖”,让 MySQL 帮你管着“谁能关联谁”,避免存一堆“瞎关联”的数据,让表关系更清晰、数据更靠谱!