当前位置: 首页 > news >正文

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 帮你管着“谁能关联谁”,避免存一堆“瞎关联”的数据,让表关系更清晰、数据更靠谱!

http://www.dtcms.com/a/348612.html

相关文章:

  • 数据建模怎么做?一文讲清数据建模全流程
  • 设备管理与策略
  • UE5.5 C++ 增强输入 快速上手
  • nginx部署goaccess监控
  • JdbcTemplate和MyBatis的区别
  • 《支付回调状态异常的溯源与架构级修复》
  • 学习制作记录(选项UI以及存档系统)8.24
  • KVM虚拟化
  • Vue3 setup代替了vue2的哪些功能
  • 分布式事务的两种解决方案
  • MYSQL(DDL)
  • 前端 vs 后端请求:核心差异与实战对比
  • Qt——网络通信(UDP/TCP/HTTP)
  • 【Unity开发】Unity核心学习(二)
  • PAT 1081 Rational Sum
  • 【机器学习】8 Logistic regression
  • Power BI切片器自定义顺序
  • 智能油脂润滑系统:给设备一份 “私人定制” 的保养方案
  • Linux 学习笔记 - 集群管理篇
  • 【大模型LLM学习】Data Agent学习笔记
  • C++算法学习专题:二分查找
  • Kubernetes部署Prometheus+Grafana 监控系统NFS存储方案
  • Socket some functions
  • 让机器人“想象”未来?VLN导航迎来“理解力”新升级
  • 每日算法刷题Day64:8.24:leetcode 堆6道题,用时2h30min
  • 解密 Spring Boot 自动配置:原理、流程与核心组件协同
  • 人形机器人——电子皮肤技术路线:压电式电子皮肤及一种超越现有电子皮肤NeuroDerm的设计
  • 深度学习:CUDA、PyTorch下载安装
  • Leetcode 3659. Partition Array Into K-Distinct Groups
  • sqlite创建数据库,创建表,插入数据,查询数据的C++ demo