MySQL 核心函数与约束详解
MySQL 核心函数与约束详解
在 MySQL 数据库操作中,函数能极大简化数据处理逻辑,约束则是保障数据完整性的关键机制。本文将系统梳理常用函数的用法与约束规则,并结合具体 SQL 语句示例,帮助开发者快速掌握核心应用场景。
一、MySQL 函数:简化数据处理的工具
函数是 MySQL 中预先定义的一段可重复调用的程序代码,用于实现特定的数据计算或转换逻辑。调用时只需传入参数(部分函数无需参数),即可返回计算结果,广泛用于 SELECT
查询、数据插入/更新等场景。
1.1 字符串函数:处理文本数据
字符串函数主要用于对字符类型数据(如 VARCHAR
、CHAR
)进行拼接、大小写转换、截取、填充等操作,是日常数据处理中最常用的函数类别之一。
函数名 | 功能描述 | 语法格式 | 示例(基于表 user ,含字段 name (值为 " Zhang San ")、age (值为 25)) |
---|---|---|---|
CONCAT | 拼接多个字符串 | CONCAT(str1, str2, ...) | 需求:拼接姓名与年龄为“姓名-年龄”格式SELECT CONCAT(TRIM(name), '-', age) AS user_info FROM user; 结果: "Zhang San-25" |
LOWER | 将字符串转为小写 | LOWER(str) | 需求:将姓名转为全小写SELECT LOWER(TRIM(name)) AS lower_name FROM user; 结果: "zhang san" |
UPPER | 将字符串转为大写 | UPPER(str) | 需求:将姓名转为全大写SELECT UPPER(TRIM(name)) AS upper_name FROM user; 结果: "ZHANG SAN" |
LPAD | 左填充:用指定字符将字符串补到指定长度 | LPAD(str, length, pad_str) | 需求:将年龄补为 3 位,不足用 0 填充SELECT LPAD(age, 3, '0') AS padded_age FROM user; 结果: "025" |
RPAD | 右填充:用指定字符将字符串补到指定长度 | RPAD(str, length, pad_str) | 需求:将姓名补为 10 位,不足用 * 填充SELECT RPAD(TRIM(name), 10, '*') AS padded_name FROM user; 结果: "Zhang San**" |
TRIM | 去除字符串首尾的空格(默认)或指定字符 | TRIM([remstr FROM] str) | 需求:去除姓名首尾的空格SELECT TRIM(name) AS trimmed_name FROM user; 结果: "Zhang San" (原 name 含首尾空格) |
SUBSTRING | 截取字符串(索引从 1 开始) | SUBSTRING(str, pos, len) | 需求:截取姓名的前 5 个字符SELECT SUBSTRING(TRIM(name), 1, 5) AS sub_name FROM user; 结果: "Zhang" |
1.2 数值函数:处理数值型数据
数值函数用于对 INT
、DECIMAL
等数值类型数据进行计算,如取整、求余、随机数生成等,常用于统计分析、数据格式化场景。
函数名 | 功能描述 | 语法格式 | 示例(基于数值 12.34、-12.34、5、3) |
---|---|---|---|
CEIL | 向上取整(返回大于等于该数的最小整数) | CEIL(num) | SELECT CEIL(12.34); → 13SELECT CEIL(-12.34); → -12 |
FLOOR | 向下取整(返回小于等于该数的最大整数) | FLOOR(num) | SELECT FLOOR(12.34); → 12SELECT FLOOR(-12.34); → -13 |
MOD | 求余(返回两数相除的余数,符号与被除数一致) | MOD(num1, num2) | SELECT MOD(5, 3); → 2(5÷3 余 2)SELECT MOD(-5, 3); → -2 |
RAND | 生成 0~1 之间的随机浮点数(每次调用结果不同) | RAND() | 需求:生成 1~100 的随机整数SELECT FLOOR(RAND() * 100 + 1) AS random_num; → 随机返回 1-100 的整数 |
ROUND | 四舍五入(保留指定小数位数,默认保留 0 位) | ROUND(num, decimals) | SELECT ROUND(12.34); → 12SELECT ROUND(12.345, 2); → 12.35 |
1.3 日期函数:处理日期与时间数据
日期函数用于对 DATE
、DATETIME
、TIME
等时间类型数据进行提取、计算、格式化,是业务系统中“时间范围查询”“有效期判断”等场景的核心工具。
函数名 | 功能描述 | 语法格式 | 示例(当前时间:2024-05-20 14:30:00) |
---|---|---|---|
CURDATE | 返回当前日期(格式:YYYY-MM-DD) | CURDATE() | SELECT CURDATE(); → 2024-05-20 |
CURTIME | 返回当前时间(格式:HH:MM:SS) | CURTIME() | SELECT CURTIME(); → 14:30:00 |
NOW | 返回当前日期时间(格式:YYYY-MM-DD HH:MM:SS) | NOW() | SELECT NOW(); → 2024-05-20 14:30:00 |
YEAR /MONTH /DAY | 提取日期中的年/月/日 | YEAR(date) MONTH(date) DAY(date) | 需求:提取当前日期的年、月、日SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW()); → 2024, 5, 20 |
DATE_ADD | 日期加法:给指定日期添加指定时间间隔 | DATE_ADD(date, INTERVAL expr unit) | 需求:计算当前日期 7 天后的日期SELECT DATE_ADD(CURDATE(), INTERVAL 7 DAY) AS next_week; → 2024-05-27 |
DATEDIFF | 计算两个日期的差值(结果为:date1 - date2,单位:天) | DATEDIFF(date1, date2) | 需求:计算“2024-06-01”与当前日期的天数差SELECT DATEDIFF('2024-06-01', CURDATE()) AS days_left; → 12(当前为 2024-05-20) |
1.4 流程函数:实现条件逻辑判断
流程函数类似编程语言中的“if-else”“switch-case”,用于根据条件返回不同结果,常用于数据分类、状态转换等场景。
函数名 | 功能描述 | 语法格式 | 示例(基于表 student ,含字段 score (分数)) |
---|---|---|---|
IF | 双分支判断:满足条件返回值 1,否则返回值 2 | IF(condition, val1, val2) | 需求:判断分数是否及格(≥60 为及格)SELECT score, IF(score >= 60, '及格', '不及格') AS status FROM student; |
IFNULL | 空值判断:若值为 NULL 则返回默认值,否则返回原值 | IFNULL(val, default_val) | 需求:若学生“备注”(remark 字段)为 NULL,显示“无备注”SELECT remark, IFNULL(remark, '无备注') AS show_remark FROM student; |
CASE | 多分支判断(两种语法:等值判断、范围判断) | 1. 等值判断:CASE col<br> WHEN val1 THEN res1<br> WHEN val2 THEN res2<br> ELSE resN<br>END 2. 范围判断: CASE<br> WHEN cond1 THEN res1<br> WHEN cond2 THEN res2<br> ELSE resN<br>END | 需求:根据分数划分等级(90+优秀,80-89良好,60-79及格,<60不及格)SELECT score, CASE<br> WHEN score >= 90 THEN '优秀'<br> WHEN score >= 80 THEN '良好'<br> WHEN score >= 60 THEN '及格'<br> ELSE '不及格'<br>END AS grade FROM student; |
二、MySQL 约束:保障数据完整性的规则
约束(Constraint)是作用在表字段上的规则,用于限制存储在表中的数据,防止无效、冗余或不一致的数据进入数据库。常见约束分为 6 类,核心目标是保证数据的实体完整性(如主键唯一)、域完整性(如字段非空)和引用完整性(如外键关联)。
2.1 约束分类与基础语法
约束类型 | 关键字 | 核心作用 | 示例(创建表时添加约束) |
---|---|---|---|
非空约束 | NOT NULL | 限制字段值不能为 NULL | 创建 student 表,name 字段非空:CREATE TABLE student (<br> id INT,<br> name VARCHAR(50) NOT NULL, -- 姓名不能为NULL<br> score INT<br>); |
唯一约束 | UNIQUE | 限制字段值在表中唯一(可包含 NULL,且允许多个 NULL) | 创建 student 表,id 字段唯一:CREATE TABLE student (<br> id INT UNIQUE, -- 学号唯一<br> name VARCHAR(50)<br>); |
主键约束 | PRIMARY KEY | 非空 + 唯一,唯一标识表中每条记录(一个表只能有一个主键) | 创建 student 表,id 为主键:CREATE TABLE student (<br> id INT PRIMARY KEY, -- 主键(非空且唯一)<br> name VARCHAR(50)<br>); |
默认约束 | DEFAULT | 字段未插入值时,自动填充默认值 | 创建 student 表,gender 默认为“男”:CREATE TABLE student (<br> id INT PRIMARY KEY,<br> name VARCHAR(50),<br> gender VARCHAR(10) DEFAULT '男' -- 默认值<br>); |
检查约束 | CHECK | 限制字段值必须满足指定条件(MySQL 8.0+ 支持) | 创建 student 表,score 必须在 0-100 之间:CREATE TABLE student (<br> id INT PRIMARY KEY,<br> name VARCHAR(50),<br> score INT CHECK (score BETWEEN 0 AND 100) -- 分数范围约束<br>); |
外键约束 | FOREIGN KEY | 建立两个表的关联,保证引用数据的一致性(子表外键关联父表主键) | 见 2.2 详细说明 |
2.2 外键约束:实现表间数据关联
外键约束是保障“多表关联数据完整性”的核心,常用于“主从表”场景(如“部门表”为父表,“员工表”为子表,员工的“部门ID”需关联部门表的“部门ID”)。
核心概念
- 父表:被引用的表(如
dept
部门表),外键关联的是父表的主键。 - 子表:添加外键的表(如
emp
员工表),外键字段(如dept_id
)的值必须在父表主键字段的取值范围内。
外键约束的添加方式
方式 1:创建表时添加外键
先创建父表(部门表 dept
),再创建子表(员工表 emp
)并关联父表主键:
-- 1. 创建父表:部门表(dept)
CREATE TABLE dept (dept_id INT PRIMARY KEY, -- 部门ID(主键)dept_name VARCHAR(50) NOT NULL -- 部门名称(非空)
);-- 2. 创建子表:员工表(emp),添加外键关联部门表的 dept_id
CREATE TABLE emp (emp_id INT PRIMARY KEY, -- 员工ID(主键)emp_name VARCHAR(50) NOT NULL, -- 员工姓名(非空)dept_id INT, -- 部门ID(外键字段)-- 声明外键:关联 dept 表的 dept_idFOREIGN KEY (dept_id) REFERENCES dept (dept_id)
);
方式 2:创建表后通过 ALTER TABLE
添加外键
若子表已创建,可通过 ALTER
语句补充外键约束:
-- 1. 先创建子表(未添加外键)
CREATE TABLE emp (emp_id INT PRIMARY KEY,emp_name VARCHAR(50) NOT NULL,dept_id INT -- 待关联的外键字段
);-- 2. 为 emp 表的 dept_id 字段添加外键,关联 dept 表的 dept_id
ALTER TABLE emp
ADD CONSTRAINT fk_emp_dept -- 外键名称(自定义,便于后续删除)
FOREIGN KEY (dept_id) REFERENCES dept (dept_id);
外键的删除与更新行为
当父表的主键值被子表引用时,删除/更新父表数据会触发外键约束,MySQL 提供 5 种行为控制该场景的处理逻辑:
行为关键字 | 中文含义 | 核心逻辑 | 示例(添加外键时指定行为) |
---|---|---|---|
NO ACTION | 无动作 | 若父表数据被引用,删除/更新操作直接报错(默认行为) | 创建外键时指定:FOREIGN KEY (dept_id) REFERENCES dept (dept_id) ON DELETE NO ACTION ON UPDATE NO ACTION; |
RESTRICT | 限制 | 与 NO ACTION 逻辑一致,仅语义差异(MySQL 中效果相同) | FOREIGN KEY (dept_id) REFERENCES dept (dept_id) ON DELETE RESTRICT ON UPDATE RESTRICT; |
CASCADE | 级联 | 父表数据删除/更新时,子表关联的外键数据同步删除/更新 | 需求:删除部门时,同步删除该部门的所有员工FOREIGN KEY (dept_id) REFERENCES dept (dept_id) ON DELETE CASCADE ON UPDATE CASCADE; |
SET NULL | 设为 NULL | 父表数据删除/更新时,子表关联的外键数据设为 NULL(需外键字段允许 NULL) | 需求:删除部门时,该部门员工的 dept_id 设为 NULLFOREIGN KEY (dept_id) REFERENCES dept (dept_id) ON DELETE SET NULL ON UPDATE SET NULL; |
SET DEFAULT | 设为默认值 | 父表数据删除/更新时,子表关联的外键数据设为默认值(需外键字段设置默认值) | 需求:删除部门时,员工 dept_id 设为默认值 0CREATE TABLE emp (<br> dept_id INT DEFAULT 0, -- 外键字段设默认值 0<br> FOREIGN KEY (dept_id) REFERENCES dept (dept_id) ON DELETE SET DEFAULT<br>); |
注意事项
- 外键字段的数据类型必须与父表主键字段完全一致(如父表
dept_id
为INT
,子表dept_id
不能为VARCHAR
)。 - 父表必须先存在,才能创建关联它的子表。
- 若需删除外键约束,需通过外键名称删除(避免误删其他约束):
-- 删除 emp 表的外键 fk_emp_dept ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept;