MySQL 核心知识点精讲:约束、索引、存储过程与触发器
·
在 MySQL 数据库开发与设计中,主键、外键、索引是保障数据完整性和查询性能的基础,CHECK 约束用于精细化数据校验,存储过程和触发器则能实现 SQL 逻辑的封装与自动化执行。
前置准备:创建测试库与表
首先创建测试数据库和数据表,后续所有案例均基于这两张表:
-- 创建数据库
create database jx character set utf8;
use jx;
-- 创建用户表 users
CREATE TABLE users (
id INT AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
-- 创建订单表 orders
CREATE TABLE orders (
order_id INT AUTO_INCREMENT,
user_id INT,
owner VARCHAR(50) NOT NULL,
level INT NOT NULL,
age INT,
PRIMARY KEY (order_id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 查看表结构
desc users;
desc orders;
一、主键(Primary Key)
主键是表的唯一标识,是关系型数据库的核心基础。
核心特性
- 唯一标识单条记录,无重复值
- 一张表只能有一个主键
- 支持单列 / 多列组合主键
- 自动强制为
NOT NULL
核心作用
- 唯一标识数据,精准定位记录
- 保障数据唯一性,避免脏数据
- 自带索引,大幅提升主键查询速度
- 作为外键关联的基础,建立表间关系
常用语法
-- 1. 创建表时定义主键
CREATE TABLE users (
id INT AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
-- 2. 删除主键
ALTER TABLE users DROP PRIMARY KEY;
-- 3. 新增主键
ALTER TABLE users ADD PRIMARY KEY (id);
二、外键(Foreign Key)
外键用于关联两张表,强制数据的参照完整性(子表数据必须在父表中存在)。
核心特性
- 子表外键列 = 父表主键列
- 防止产生孤立、无效的关联数据
- 支持级联更新 / 删除
核心作用
- 维护多表数据一致性
- 规范表与表之间的关联关系
- 避免非法数据插入
常用语法
-- 1. 创建表时定义外键
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 2. 删除外键(需先查看外键名)
ALTER TABLE orders DROP FOREIGN KEY orders_ibfk_1;
-- 3. 新增外键(自定义约束名,推荐)
ALTER TABLE orders ADD CONSTRAINT fk_user_id
FOREIGN KEY (user_id) REFERENCES users(id);
语法解析
ADD CONSTRAINT:添加约束并自定义名称FOREIGN KEY (user_id):指定子表外键列REFERENCES users(id):指定关联的父表 + 主键
三、索引(Index)
索引是提升查询速度的核心工具,本质是优化数据查找结构的目录。
核心特性
- 快速定位数据,减少全表扫描
- 分为唯一索引 / 普通索引
- 索引会占用存储空间,写入数据时会有性能损耗
索引分类(高频实用版)
1. 按数据结构分类
- B+tree 索引:MySQL 默认索引,支持范围查询 / 排序,适用绝大多数场景
- Hash 索引:仅支持等值查询,速度极快,Memory 引擎适用
- Fulltext 索引:全文检索,用于文本模糊搜索
2. 按物理存储分类
- 聚簇索引:数据和索引存在一起,主键默认就是聚簇索引,一张表仅一个
- 二级索引:辅助索引,叶子节点存储主键值,需回表查询
3. 按字段特性分类
- 主键索引:主键自动生成,唯一 + 非空
- 普通索引:最基础索引,允许重复值
- 前缀索引:对字符串前 N 个字符建索引,节省空间
4. 按字段个数分类
- 单列索引:单个字段建索引
- 联合索引:多个字段组合建索引,遵循最左匹配原则
常用语法
-- 1. 创建普通索引
CREATE INDEX idx_username ON users(username);
-- 2. 创建联合索引
CREATE INDEX orders_index ON orders(owner, level);
-- 3. 查看索引
show index from users;
-- 4. 删除索引
DROP INDEX idx_username ON users;
-- 5. 强制使用索引
select * from users force index (idx_username) where username='tom';
执行计划分析(EXPLAIN)
使用EXPLAIN追踪索引是否生效,是 SQL 优化必备工具:
explain select id from users;
关键字段解析
type:查询性能(最优→最差:const > ref > range > index > ALL)key:实际使用的索引rows:扫描的行数(越小越好)Extra:额外优化信息(Using index代表索引高效命中)
四、CHECK 约束
MySQL 8.0.16+ 正式支持CHECK约束,用于自定义数据校验规则,在数据库层面拦截非法数据。
核心特性
- 自定义列数据规则(数值范围、字符串格式等)
- 插入 / 更新数据时自动校验
核心作用
- 数据合法性验证
- 统一业务规则,避免应用层重复校验
- 保障数据质量
常用语法
-- 1. 给用户名添加格式约束(字母开头,长度≥3)
ALTER TABLE users ADD CONSTRAINT chk_username_format
CHECK (username REGEXP '^[a-zA-Z][a-zA-Z0-9_]{2,}$');
-- 2. 查看约束
select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='users'\G;
-- 3. 删除约束
ALTER TABLE users DROP CONSTRAINT chk_username_format;
实战应用场景
-- 限制年龄 18-60 岁
CREATE TABLE employees (
id INT PRIMARY KEY,
age INT CHECK (age >= 18 AND age <= 60)
);
-- 限制订单金额必须大于0
ALTER TABLE orders ADD CHECK (total_amount > 0);
五、存储过程(Stored Procedure)
存储过程是预先编译并存储在数据库中的 SQL 集合,可重复调用,封装业务逻辑。
核心优点
- 预编译,执行速度快
- 减少网络传输,仅传调用命令
- 统一业务逻辑,便于维护
- 提升数据安全性
常用语法
-- 1. 创建存储过程(查询所有用户)
DELIMITER // -- 临时修改语句结束符
CREATE PROCEDURE GetAllUsers()
BEGIN
SELECT * FROM jx.users;
END //
DELIMITER ; -- 恢复结束符
-- 2. 带参数的存储过程(根据ID查询用户)
DELIMITER //
CREATE PROCEDURE get_user_info(IN user_id INT)
BEGIN
SELECT * FROM users WHERE id = user_id;
END //
DELIMITER ;
-- 3. 调用存储过程
CALL GetAllUsers();
CALL get_user_info(1);
-- 4. 查看存储过程
SHOW PROCEDURE status where Db='jx'\G;
-- 5. 删除存储过程
DROP PROCEDURE IF EXISTS GetAllUsers;
适用场景
- 复杂多表查询 / 数据统计
- 固定业务逻辑封装(如订单结算)
- 定时数据处理任务
六、触发器(Trigger)
触发器是与表绑定的自动执行的存储过程,在INSERT/UPDATE/DELETE时自动触发。
核心特性
- 自动触发,无需手动调用
- 分为
BEFORE(执行前)和AFTER(执行后) - 可使用
NEW(新数据)、OLD(旧数据)操作数据
核心概念
- 触发时间
BEFORE:操作前执行,用于数据校验 / 预处理AFTER:操作后执行,用于日志记录 / 关联操作
- NEW/OLD
NEW:代表插入 / 更新后的新数据OLD:代表更新 / 删除前的旧数据
常用语法
-- 1. 插入订单前,自动设置订单日期
ALTER TABLE orders ADD COLUMN order_date DATE;
DELIMITER //
CREATE TRIGGER set_order_date_before_insert
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
SET NEW.order_date = CURDATE();
END //
DELIMITER ;
-- 2. 删除用户后,自动删除关联订单
DELIMITER //
CREATE TRIGGER delete_order_after_user
AFTER DELETE ON users
FOR EACH ROW
BEGIN
DELETE FROM orders WHERE user_id = OLD.id;
END //
DELIMITER ;
-- 3. 查看触发器
show triggers\G;
-- 4. 删除触发器
DROP TRIGGER set_order_date_before_insert;
总结
本文覆盖了 MySQL 最核心的六大知识点,总结如下:
- 主键 / 外键:保障数据唯一性和表关联完整性
- 索引:优化查询速度,
EXPLAIN是索引优化神器 - CHECK 约束:数据库层自定义数据校验规则
- 存储过程:封装 SQL 逻辑,复用性强、性能高
- 触发器:自动化执行 SQL,适配数据联动场景
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)