文章目录
- [1. SQL 语言概述](#1. SQL 语言概述)
-
- [1.1 SQL 的核心定位](#1.1 SQL 的核心定位)
- [1.2 SQL 的常用版本标准](#1.2 SQL 的常用版本标准)
- [1.3 SQL 语句的规则与规范](#1.3 SQL 语句的规则与规范)
-
- [1.3.1 核心语法规则(必须遵守,违反则执行报错)](#1.3.1 核心语法规则(必须遵守,违反则执行报错))
- [1.3.2 通用编写规范(建议遵守,提升可读性/可维护性)](#1.3.2 通用编写规范(建议遵守,提升可读性/可维护性))
- [1.3.3 总结](#1.3.3 总结)
- [2. SQL 语句分类](#2. SQL 语句分类)
- [3. SQL 语句操作前置内容](#3. SQL 语句操作前置内容)
-
- [3.1 数据库服务字符集设置](#3.1 数据库服务字符集设置)
-
- [3.1.1 字符集设置的目的](#3.1.1 字符集设置的目的)
- [3.1.2 核心技术操作](#3.1.2 核心技术操作)
-
- [① 查看字符集信息](#① 查看字符集信息)
- [② 设置字符集](#② 设置字符集)
- [③ 乱码修复](#③ 乱码修复)
- [3.2 数据库服务校对规则设置](#3.2 数据库服务校对规则设置)
-
- [3.2.1 校对规则设置的目的](#3.2.1 校对规则设置的目的)
- [3.2.2 核心技术操作](#3.2.2 核心技术操作)
-
- [① 查看校对规则](#① 查看校对规则)
- [② 常用校对规则说明](#② 常用校对规则说明)
- [③ 设置校对规则](#③ 设置校对规则)
- [3.2.3 校对规则选择建议](#3.2.3 校对规则选择建议)
- [3.3 数据的数据类型设置](#3.3 数据的数据类型设置)
-
- [3.3.1 数据类型设置的目的](#3.3.1 数据类型设置的目的)
- [3.3.2 常用数据类型及场景](#3.3.2 常用数据类型及场景)
-
- [① 数值类型(存储数字、编号等)](#① 数值类型(存储数字、编号等))
- [② 字符串类型(存储名称、文本、标识等)](#② 字符串类型(存储名称、文本、标识等))
- [③ 时间类型(存储日期、时间、时间戳)](#③ 时间类型(存储日期、时间、时间戳))
- [④ 特殊数据类型(实战高频场景)](#④ 特殊数据类型(实战高频场景))
- [3.3.3 数据类型选择原则](#3.3.3 数据类型选择原则)
- [3.4 数据表的约束与属性设置](#3.4 数据表的约束与属性设置)
-
- [3.4.1 约束与属性设置的目的](#3.4.1 约束与属性设置的目的)
- [3.4.2 约束设置(保证数据完整性、唯一性,优化索引)](#3.4.2 约束设置(保证数据完整性、唯一性,优化索引))
- [3.4.3 属性设置(辅助约束,优化数据存储)](#3.4.3 属性设置(辅助约束,优化数据存储))
- [3.5 数据库数据模式(sql_mode)](#3.5 数据库数据模式(sql_mode))
-
- [3.5.1 数据库数据模式设置的目的](#3.5.1 数据库数据模式设置的目的)
- [3.5.2 常用 sql_mode 参数说明](#3.5.2 常用 sql_mode 参数说明)
- [3.5.3 核心应用场景](#3.5.3 核心应用场景)
-
- [① 数据迁移(低版本 MySQL → 高版本 MySQL)](#① 数据迁移(低版本 MySQL → 高版本 MySQL))
- [② 主从同步故障排查](#② 主从同步故障排查)
- [4. 数据库标识符](#4. 数据库标识符)
-
- [4.1 常见标识符类型](#4.1 常见标识符类型)
- [4.2 数据库对象命名与设计规范](#4.2 数据库对象命名与设计规范)
-
- [4.2.1 基础规则(默认遵循,无需特殊处理)](#4.2.1 基础规则(默认遵循,无需特殊处理))
- [4.2.2 特殊规则(使用特殊字符时需适配)](#4.2.2 特殊规则(使用特殊字符时需适配))
- [4.2.3 命名规范(企业实战推荐)](#4.2.3 命名规范(企业实战推荐))
- [4.2.4 关键注意事项](#4.2.4 关键注意事项)
SQL(结构化查询语言)是关系型数据库的标准交互语言,覆盖数据库全生命周期管理,是数据相关岗位的核心技能。本文将梳理 SQL 语言的定位、版本及语句分类,并解析数据库字符集、校对规则、数据类型、约束属性及 SQL 模式等前置配置,为高效使用 SQL 奠定基础。
1. SQL 语言概述
SQL (英文全称:Structured Query Language,中文译名:结构化查询语言 ),是一门专用于关系型数据库的编程语言,同时也是被行业广泛认可的工业标准语言,几乎所有主流关系型数据库(如 MySQL、Oracle、SQL Server、PostgreSQL 等)均支持 SQL 语法的核心使用。
1.1 SQL 的核心定位
SQL 作为关系型数据库的专属编程语言,其核心定位是 「关系型数据库的全流程管理工具」 ------ 覆盖了数据库从结构定义、数据操作到权限管控和数据查询的完整生命周期,是连接用户与关系型数据库的标准化交互入口。
-
功能维度:一站式数据库管理能力:同时具备**数据定义(建库/表)、数据操作(增删改)、权限控制(用户/权限)、事务管理(提交/回滚)**等全链路功能,无需依赖其他工具即可完成数据库的从0到1搭建与日常运维。
-
标准维度:关系型数据库的通用交互语言 :工业级标准语言,几乎所有主流关系型数据库(MySQL、Oracle、SQL Server等)均兼容其核心语法,同一套基础操作(如
SELECT查数据、CREATE建表)可跨数据库复用,仅存在少量厂商专属扩展语法,大幅降低了跨库操作的学习与迁移成本。 -
场景维度:多角色的通用协作工具:既是开发人员实现业务数据存储、查询的核心工具,也是运维/DBA人员进行数据库部署、权限管控、性能优化的必备技能,是技术团队中"开发-运维-数据"角色间的通用协作语言。
1.2 SQL 的常用版本标准
SQL语言在发展过程中形成了多个主流版本标准,这些标准定义了SQL的核心语法、功能边界,是不同数据库厂商实现SQL支持的参考依据,其中最具代表性的版本如下:
| 版本标准 | 核心特点 | 应用价值 |
|---|---|---|
| SQL 89 | 早期基础版本,奠定了SQL的核心语法框架(如SELECT查询、INSERT新增等基础操作),功能相对简单 |
是SQL语言的"雏形",为后续版本提供了底层语法基础 |
| SQL 92 | 应用最广泛的经典版本,完善了查询语法(如多表连接、条件筛选),强化了语法的通用性与兼容性 | 成为行业主流的"基准版本",绝大多数数据库的核心语法均基于SQL 92实现,学习成本低、适配性强 |
| SQL 99 | 功能大幅扩展,新增面向对象特性(如自定义类型)、复杂查询支持(如子查询嵌套、窗口函数)、事务优化等 | 满足了更复杂的业务场景需求,是现代SQL功能的"扩展起点" |
| SQL 03 | 在SQL 99基础上优化,强化了事务管理、数据类型(如新增XML类型)、安全控制等能力 | 进一步提升了SQL的实用性与安全性,适配了互联网时代的复杂数据场景 |
这些版本的迭代逻辑是 "向下兼容核心语法,向上扩展新功能" ------即高版本标准会保留低版本的核心语法,同时新增更丰富的功能,因此学习SQL时,通常以SQL 92为基础,再拓展高版本的新增特性即可覆盖绝大多数场景。
了解:
- MySQL(5.5 及以上版本)、Oracle(9i 及以上版本)、SQL Server(2005 及以上版本)就核心兼容了SQL99版本标准;
- MySQL(8.0 及以上版本)、Oracle(10g 及以上版本)、SQL Server(2008 及以上版本)就核心兼容了SQL03版本。
1.3 SQL 语句的规则与规范
1.3.1 核心语法规则(必须遵守,违反则执行报错)
- 基础语法约束
- 语句书写与结束 :SQL 可单行/多行书写,关键字不可缩写、不可分行;每条命令必须以
;、\g或\G结束。- 标点符号要求 :所有
()、单引号'、双引号"必须成对结束;仅使用英文半角标点;字符串/日期时间类型数据用单引号'包裹;列别名建议用双引号"包裹且不省略AS。- 大小写底层规则:Windows 环境下 MySQL 大小写不敏感;Linux 环境下数据库名、表名、表别名、变量名严格区分大小写,关键字、函数名、列名/列别名忽略大小写。
- 标识符引用 :标识符默认仅允许使用英文字母、数字、下划线,长度默认最大64个字符;与保留字(如
desc/range/select)冲突、含空格/特殊符号的标识符,需用反引号 ````` 包裹;多表关联时需用表别名/表名限定字段,避免冲突。- 数据格式规则 :字符/日期型值用单引号包裹,数值型无需引号;含单引号的字符需转义(
'李''四'或'李\'四')。
- 命名底层约束
- 基础限制:标识符不能以数字开头;对象名中间无空格。
- 唯一性要求:同一数据库中库名不重复,同一库中表名不重复,同一表中字段名不重复。
- 字段一致性 :字段名和数据类型需保持一致性(如某表
user_id为 INT,其他表也需为 INT)。
- 函数与表达式规则
- 函数参数类型需匹配(如
TIMESTAMPDIFF第一个参数必须是时间单位);- 算术表达式需避免除数为 0;
- 计算列表达式不可引用子查询、其他计算列或自定义函数(UDF)。
1.3.2 通用编写规范(建议遵守,提升可读性/可维护性)
- SQL语句格式与大小写规范
- 统一大小写:标识符全部使用小写字母,避免跨环境大小写问题;SQL 关键字、函数名、绑定变量全部大写。
- 排版要求:各子句分行书写,关联/嵌套逻辑缩进(2/4 个空格);批量操作(如
INSERT多值)分行书写,便于核对。
- 注释规范:使用统一注释格式
sql
-- 单行注释:-- 后必须加空格(通用标准)
# 单行注释:MySQL (特有方式)
/* 多行注释:适用于大段逻辑说明 */
- 执行规范
- 权限最小化:业务账号仅授予必要权限,禁止高权限(如
DROP/ALTER);- 测试先行:生产环境执行 SQL 前,先在测试库验证语法、结果、性能;
- 低峰期操作:DDL/批量 DML 操作在业务低峰期执行,减少线上影响;
- 日志留存:重要 SQL 操作记录日志(执行人、时间、语句),便于追溯。
1.3.3 总结
- 规则是强制约束:违反会导致 SQL 执行报错,核心覆盖语法、标点、命名底层约束、语句专属要求等;
- 规范是最佳实践:不影响执行,但遵守可大幅提升 SQL 可读性、可维护性,降低协作与运维成本。
2. SQL 语句分类
根据企业实际应用的操作场景,SQL 可细分为以下四类,各类型对应不同的功能、语句及适用人群:
- DDL------Data Definition Language(数据定义语言)
- 核心功能 :管理数据库的基础结构(不修改表内数据),如创建/删除库、表、索引,管理用户等;
- 常用语句 :
CREATE(创建)、ALTER(修改)、DROP(删除);- 查看帮助 :在MySQL中执行
mysql> ? Data Definition,可查看所有DDL操作命令;- 适用人群:运维、数据库人员、开发人员均需掌握。
- DCL------Data Control Language(数据控制语言)
- 核心功能 :定义数据库、表、用户的访问权限与安全级别;
- 常用语句 :
GRANT(用户授权)、REVOKE(权限回收)、COMMIT(事务提交)、ROLLBACK(事务回滚);- 查看帮助 :在MySQL中执行
mysql> ? Account Management,可查看所有DCL操作命令;- 适用人群:运维、数据库人员需熟练掌握。
- DML------Data Manipulation Language(数据操作语言)
- 核心功能 :操作数据库表内的数据记录(增/删/改);
- 常用语句 :
INSERT(新增)、DELETE(删除)、UPDATE(修改);- 查看帮助 :在MySQL中执行
mysql> ? Data Manipulation,可查看所有DML操作命令;- 适用人群:开发人员需熟练掌握,运维人员需熟悉。
- DQL------Data Query Language(数据查询语言)
- 核心功能 :查询数据库表内的数据记录;
- 常用语句 :
SELECT(查询),基本结构由SELECT(查询字段)、FROM(目标表)、WHERE(筛选条件)子句组成;- 适用人群:运维、开发人员均需熟练掌握。
3. SQL 语句操作前置内容
3.1 数据库服务字符集设置
3.1.1 字符集设置的目的
字符集设置的核心目的是 保证数据库中字符数据(尤其是中文、特殊符号如 emoji)的正确存储、传输与展示,避免出现乱码问题,同时确保跨系统、跨版本的数据兼容性与一致性。
- 系统字符编码的核心逻辑
计算机无法直接存储文字,所有字符(包括中文、英文、数字)最终都会被转换为二进制数据存储和处理。字符编码本质就是"字符与二进制的映射规则"------比如用特定的二进制组合代表"a""中"等字符,不同编码规则的映射关系不同,这也是中文乱码的核心诱因。
- 常见字符编码规则解析
- ASCII码:由美国制定,用1个字节(8位二进制)表示一个字符,最多可表示256个字符,仅能覆盖英文、数字和少量特殊符号。由于不支持中文,直接存储中文会因无对应映射规则导致乱码。
- ANSI编码 :为解决本国语言显示问题,各国在ASCII码基础上进行扩展,用2个字节(16位二进制)表示本国字符,最多可表示65536个字符:
- 中国的ANSI编码为GB2312(简体中文),收录6763个常用汉字及600多个特殊符号;
- 后续扩展出GBK编码,新增罕见汉字、古汉语汉字等,共收录约2.1万个汉字;
- 日本对应JIS编码,中国台湾对应BIG5(繁体中文)编码。
但是这种"各自扩展"的模式导致跨语言兼容性差,比如GB2312编码的中文在JIS编码环境中会显示乱码。
- Unicode编码:为统一全球语言编码,推出的通用编码标准,用4个字节(32位二进制)表示一个字符,可覆盖所有人类语言文字。但缺点是效率极低------比如英文"a"用ASCII码1个字节即可存储,Unicode却需4个字节,造成极大的空间浪费。
- UTF-8编码:基于Unicode的优化编码方案,核心是"变长存储":根据字符类型自动调整字节长度,英文用1个字节(兼容ASCII)、中文用2-3个字节、特殊符号(如emoji)用4个字节。它既解决了Unicode的空间浪费问题,又实现了全球语言兼容,是目前开发中的首选编码。
- 中文乱码的核心原因
中文乱码的本质是 "字符编码与解码规则不匹配":
- 数据库默认编码为ASCII、Latin1等不支持中文的编码时,输入的中文会因无对应映射规则,被错误转换为无效二进制数据;
- 客户端(如应用程序、数据库连接工具)与数据库服务端编码不一致(比如客户端用UTF-8,服务端用GB2312),中文数据在传输和存储过程中会因"编码-解码"规则冲突导致乱码;
- 数据库、数据表的字符编码未统一(如库用UTF-8,表用Latin1),中文存储时会出现编码转换失败,最终显示为"???"等乱码形式。
因此,为避免中文乱码,需统一客户端、数据库服务端、数据表的字符编码(优先选择utf8或utf8mb4),确保中文数据的 "编码-传输-存储-解码" 全流程规则一致。
3.1.2 核心技术操作
① 查看字符集信息
sql
-- 1)查看数据库服务全局默认字符集
mysql> show variables like '%char_set%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.03 sec)
-- 2)查看指定数据库字符集,通过查看库的创建语句来看
show create database 库名;
-- 3)查看指定数据表字符集,通过查看表的创建语句来看
show create table 表名;
-- 4)查看数据库支持的所有字符集,用于确认字符集是否可以使用
show charset;
show character set; -- 等价
② 设置字符集
在 MySQL 8.0 版本以前,MySQL 的默认字符集是 latin1,而且 utf8 字符集实际上指向的是 utf8mb3。在数据库设计阶段,开发人员通常会将编码设置为 utf8 字符集,但如果疏忽了修改默认编码,就极易出现乱码问题。
从 MySQL 8.0 版本起,数据库的默认编码变更为 utf8mb4,这一改变有效避免了上述潜在的乱码问题,让数据库在处理字符时更加稳定和可靠。
- 全局默认字符集(实例层面,修改配置文件,永久生效)
bash
# 编辑 MySQL 配置文件
vim /etc/my.cnf
# 服务端字符集配置([mysqld] 段)
[mysqld]
character-set-server=utf8mb4
# 客户端字符集配置([mysql] 段)
[mysql]
default-character-set=utf8mb4
# 重启服务使配置生效
systemctl restart mysqld
- 数据库/数据表级字符集(按需单独设置)
sql
-- 创建数据库时指定字符集
CREATE DATABASE 库名 CHARACTER SET utf8mb4;
-- 修改已有数据库字符集
ALTER DATABASE 库名 CHARACTER SET utf8mb4;
-- 创建数据表时指定字符集
CREATE TABLE 表名 (
字段1 类型1 约束1,
字段2 类型2 约束2
) CHARACTER SET utf8mb4;
-- 修改已有数据表字符集
ALTER TABLE 表名 CHARACTER SET utf8mb4;
③ 乱码修复
若数据库 / 表刚创建,未存储数据,可以直接统一编码为 utf8/utf8mb4 防止乱码,但是若表中已存储数据,直接修改表编码会导致历史数据乱码,则需按以下步骤安全修复:
sql
-- 步骤1:逻辑备份表中数据(避免修复时数据丢失)
mysqldump -uroot -p 库名 表名 > /backup/table_bak.sql;
-- 步骤2:清空表中乱码数据
DELETE FROM 表名;
-- 步骤3:修改数据库/数据表字符集为 utf8mb4
ALTER DATABASE 库名 CHARACTER SET utf8mb4;
ALTER TABLE 表名 CHARACTER SET utf8mb4;
-- 步骤4:重新导入备份数据
source /backup/table_bak.sql;
注意:字符集转换需确保目标字符集是原字符集的超集(如 GBK → UTF-8mb4 可行,反之可能丢失数据)。
3.2 数据库服务校对规则设置
校对规则(Collation)是数据库字符集的配套规则,核心作用是定义字符的比较逻辑和排序标准 ------ 它不会改变字符的存储方式,只会影响数据查询匹配(如是否区分大小写)和排序输出(如字母 / 中文的排列顺序),是数据库字符处理的重要补充。
3.2.1 校对规则设置的目的
校对规则(排序规则)设置的核心目的是 定义字符的比较逻辑与排序规则,确保数据库中字符数据的查询匹配、排序输出符合业务需求,同时保证数据比较的准确性和一致性。
- 规范字符比较逻辑 :控制字符比较时是否区分大小写、是否忽略特殊字符差异(如重音符号)。例如,设置
utf8mb4_bin时区分大小写('a'≠'A'),设置utf8mb4_general_ci时不区分大小写('a'='A'),适配不同业务场景的查询匹配需求。 - 统一数据排序效果:明确字符数据的排序依据(按字符编码值或 Unicode 标准排序)。例如,中文按拼音排序、英文按字母顺序排序,避免因排序规则不明确导致的结果混乱(如相同数据集在不同规则下排序顺序不一致)。
- 保障跨场景兼容性 :确保数据库在查询过滤(如
WHERE条件匹配)、分组统计(如GROUP BY)、排序展示(如ORDER BY)等操作中,结果符合业务预期和用户习惯,同时适配多语言、多字符集的应用场景。
3.2.2 核心技术操作
① 查看校对规则
sql
-- 1)查看指定数据库的校对规则,通过查看库的创建语句来看
show create database 库名;
-- 2)查看指定数据表的校对规则,通过查看表的创建语句来看
show create table 表名;
-- 3)查看数据库支持的所有校对规则
show collation; -- 所有
show collation like 'utf8mb4%'; -- 按照字符集筛选
② 常用校对规则说明
所有校对规则名称均遵循"字符集前缀 + 排序逻辑 + 特性后缀 "的格式,以utf8mb4字符集为例:
- 前缀 :
utf8mb4(表示适配utf8mb4字符集,不可修改); - 中间 :
general(通用排序,基于字符编码)、unicode(按Unicode标准排序)、0900(适配Unicode 9.0标准,MySQL 8.0+新增)等,代表排序逻辑; - 后缀 :
ci(Case Insensitive,不区分大小写)、cs(Case Sensitive,区分大小写)、bin(Binary,按二进制编码比较),代表字符比较特性。
例如:utf8mb4_general_ci → 适配utf8mb4字符集、通用排序、不区分大小写。
utf8mb4是MySQL推荐的主流字符集(支持中文、emoji及全球语言),其常用校对规则及差异如下:
| 校对规则 | 核心特性 | 适用场景 | 优势与注意事项 |
|---|---|---|---|
utf8mb4_general_ci |
1. 不区分大小写('a'='A')、不区分重音; 2. 基于字符编码值排序,速度快; 3. 排序精度一般(如部分欧洲语言字符排序略有偏差) | 中文/英文业务(如电商商品查询、用户昵称匹配)、追求查询效率的场景 | 优势:排序速度快,兼容大多数日常场景; 注意:多语言(德、法、俄语)场景可能出现排序偏差。 |
utf8mb4_unicode_ci |
1. 不区分大小写、不区分重音; 2. 基于Unicode标准排序,精度高; 3. 支持多语言精准排序(如德语ß、法语é的正确排序) | 多语言业务(如跨境平台、国际资讯网站)、需精准排序的场景 | 优势:排序精度高,适配多语言; 注意:排序速度略慢于general_ci,中文/英文场景差异不明显。 |
utf8mb4_0900_ai_ci |
1. MySQL 8.0默认规则,基于Unicode 9.0标准; 2. 不区分大小写(ai=Accent Insensitive,不区分重音); 3. 兼容general_ci与unicode_ci的优点,支持emoji排序 |
新业务系统、需兼容emoji/特殊字符的场景(如社交平台、内容社区) | 优势:兼顾效率与精度,支持emoji等4字节字符排序; 注意:仅MySQL 8.0+支持,低版本需升级。 |
utf8mb4_0900_as_cs |
1. 区分大小写('a'≠'A')、区分重音('é'≠'e'); 2. 基于Unicode 9.0标准,排序精度高 | 需严格区分大小写的场景(如邮箱登录、文件名称匹配、敏感数据校验) | 优势:匹配与排序严格,避免数据混淆; 注意:需业务明确要求区分大小写,否则易导致查询漏数据。 |
utf8mb4_bin |
1. 按字符二进制编码值比较,严格区分大小写('a'(0x61)≠'A'(0x41)); 2. 不涉及语言逻辑,仅按编码值排序 | 需精准二进制匹配的场景(如密码校验、唯一标识对比、二进制数据存储) | 优势:匹配逻辑最简单、速度最快,无语言依赖; 注意:排序结果可能不符合人类语言习惯(如大写字母排在小写前)。 |
除utf8mb4外,GBK、latin1等字符集的校对规则逻辑与上述一致,仅前缀不同,核心规则如下:
gbk_chinese_ci:不区分大小写,适配中文排序(按拼音排序),适用于纯中文场景;gbk_bin:按GBK二进制编码比较,区分大小写,适用于中文精准匹配场景。latin1_swedish_ci:Latin1默认规则,不区分大小写,适配英文/西欧语言;latin1_bin:二进制比较,区分大小写,适用于英文精准匹配场景。
③ 设置校对规则
sql
-- 创建数据库时指定字符集+校对规则
CREATE DATABASE 库名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 修改已有数据库的校对规则
ALTER DATABASE 库名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 创建数据表时指定字符集+校对规则
CREATE TABLE 表名 (
字段1 类型1 约束1
) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 修改已有数据表的校对规则
ALTER TABLE 表名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3.2.3 校对规则选择建议
- 优先选择
utf8mb4_0900_ai_ci:MySQL 8.0+新业务首选,兼顾效率、精度与emoji支持,适配绝大多数场景; - 中文/英文老系统 :若使用MySQL 5.7及以下,选择
utf8mb4_general_ci(效率优先)或utf8mb4_unicode_ci(精度优先); - 严格区分场景 :邮箱、密码、唯一标识等需精准匹配的场景,选择
utf8mb4_0900_as_cs或utf8mb4_bin; - 多语言场景 :跨境业务、国际平台需支持德、法、俄语等,选择
utf8mb4_unicode_ci或utf8mb4_0900_ai_ci; - 一致性原则 :同一业务的数据库、数据表、字段需使用相同校对规则,避免查询/排序结果不一致(如库用
general_ci,表用bin会导致逻辑混乱)。
3.3 数据的数据类型设置
3.3.1 数据类型设置的目的
数据类型设置的核心目的是 规范数据的存储格式、约束数据范围、优化存储与查询性能,确保数据库中数据的有效性、完整性和高效性,为后续数据操作(增删改查)和业务逻辑提供可靠支撑。
- 保证数据有效性与合理性 :通过指定数据类型(如整数、字符串、日期),限制字段只能存储符合类型定义的数据(如年龄用
tinyint,避免存储负数或超长文本),杜绝无效数据(如用date类型禁止存储"2024-13-01"这类非法日期)。 - 优化存储效率 :不同数据类型占用磁盘空间不同(如
tinyint占1字节,int占4字节),合理选择类型可减少存储空间浪费(如用tinyint存储年龄而非bigint),降低磁盘IO压力。 - 提升查询与运算性能:合适的数据类型能优化索引结构(如数值类型索引比字符串索引查询更快),加速数据检索和运算(如日期类型支持直接排序、数值类型运算无需类型转换)。
- 保障数据完整性与一致性 :数据类型是约束(如非空、唯一)和属性(如自增、默认值)的基础,只有明确类型,才能配合约束规则避免数据重复、缺失(如用
char(11)存储手机号,配合唯一约束防止重复)。
3.3.2 常用数据类型及场景
以下是实际中最常用的数据类型,结合业务场景、存储特点及使用注意事项详细说明。
① 数值类型(存储数字、编号等)
- 整数类型(精准存储整数,无小数部分)
| 数据类型 | 占用字节 | 取值范围(有符号) | 取值范围(无符号) | 核心场景 | 注意事项 |
|---|---|---|---|---|---|
| tinyint | 1 | -128~127 | 0~255 | 年龄(0~120)、状态值(0=禁用/1=启用)、性别编码 | 常用unsigned(非负)属性,避免负数 |
| smallint | 2 | -32768~32767 | 0~65535 | 班级人数(0~50)、区县编码、小范围计数 | 适合中等规模整数存储,比int更省空间 |
| int | 4 | -2147483648~2147483647 | 0~4294967295 | 用户ID、订单号、手机号(纯数字存储时)、大数量计数 | 企业最常用整数类型,兼顾范围与效率 |
| bigint | 8 | ±9.22×10¹⁸ | 0~1.84×10¹⁹ | 海量数据ID(如千万级用户ID)、时间戳(毫秒级) | 仅当int范围不足时使用,避免空间浪费 |
- 小数类型(存储金额、比例等带小数的数据)
| 数据类型 | 存储精度 | 占用字节 | 核心场景 | 注意事项 |
|---|---|---|---|---|
| float(m,d) | 单精度(约7位有效数字) | 4 | 温度(25.5℃)、体重(62.3kg)等非精准小数 | 精度有限,不适合金额等精准场景 |
| double(m,d) | 双精度(约15位有效数字) | 8 | 产品评分(4.8分)、比例(33.33%) | 精度高于float,但仍可能存在小数误差 |
| decimal(m,d) | 定点数(精准存储) | - | 金额(199.99元)、汇率(6.9258)、税率 | m=总位数,d=小数位数(如decimal(10,2)存储万元内金额),无精度损失,优先选择 |
② 字符串类型(存储名称、文本、标识等)
- 短字符串类型(长度固定/可变,适合短文本)
| 数据类型 | 存储特点 | 长度限制 | 核心场景 | 注意事项 |
|---|---|---|---|---|
| char(n) | 定长存储(不足n位补空格) | 0~255字符 | 手机号(11位)、身份证号(18位)、学号(固定长度标识) | 适合长度固定的字符串,查询速度比varchar快 |
| varchar(n) | 变长存储(按实际长度存储) | 0~65535字符 | 用户名(2~20位)、地址(不超过100字)、产品名称、备注(短文本) | 企业最常用字符串类型,省空间,长度n建议按需设置(如用户名varchar(20)) |
- 长文本类型(存储大段文本)
| 数据类型 | 长度限制 | 核心场景 | 注意事项 |
|---|---|---|---|
| text | 0~65535字符 | 文章内容(短博文)、商品详情(简短描述)、备注(长文本) | 不适合作为查询条件(效率低),避免存储超长篇文本 |
| mediumtext | 0~16MB | 长篇文章、产品说明书 | 仅当text长度不足时使用,查询性能较差 |
| longtext | 0~4GB | 超大文本(如合同文件、日志全文) | 尽量避免使用,优先考虑文件存储(如OSS)+ 路径存储 |
- 特殊字符串类型
| 数据类型 | 特点 | 核心场景 | 注意事项 |
|---|---|---|---|
| enum | 枚举类型(仅能选预设值之一) | 性别(男/女/未知)、订单状态(待支付/已支付/已取消) | 预设值固定(如enum('M','F','N')),查询效率高,避免无效值 |
| set | 集合类型(可选多个预设值) | 兴趣标签(篮球/足球/读书)、产品属性(红色/蓝色/黑色) | 支持多选(如set('篮球','足球','读书')),存储为整数,查询便捷 |
③ 时间类型(存储日期、时间、时间戳)
| 数据类型 | 存储格式 | 取值范围 | 占用字节 | 核心场景 | 注意事项 |
|---|---|---|---|---|---|
| date | YYYY-MM-DD | 1000-01-01~9999-12-31 | 3 | 出生日期(1990-01-15)、注册日期、到期日期 | 仅存储日期,不包含时间 |
| time | HH:MM:SS | -838:59:59~838:59:59 | 3 | 打卡时间点(09:00:00)、时长(120:30:00,即5天0时30分) | 可存储跨天时长,适合时间间隔场景 |
| datetime | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 8 | 订单创建时间(2024-05-20 14:30:00)、数据更新时间 | 取值范围广,不受时区影响,最常用时间类型 |
| timestamp | 时间戳(秒级) | 1970-01-01 00:00:00~2038-01-19 03:14:07 | 4 | 自动记录创建/修改时间(如DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) |
占用空间小,会随时区变化,注意2038年限制 |
④ 特殊数据类型(实战高频场景)
| 数据类型 | 特点 | 核心场景 | 注意事项 |
|---|---|---|---|
| json | 存储JSON格式数据 | - | 复杂属性(如产品规格{"颜色":"红色","内存":"8GB"})、非结构化数据 |
| binary(n) | 二进制存储 | 0~255字节 | 密码哈希值(如MD5加密后的数据)、二进制标识 |
3.3.3 数据类型选择原则
- 够用即好:优先选择最小能满足需求的类型(如年龄用tinyint而非int),减少存储空间和IO压力;
- 精准优先:金额、汇率等精准数据必须用decimal,避免float/double的精度误差;
- 查询友好:频繁作为查询条件的字段(如用户ID、手机号),优先选择数值类型或char(定长字符串),提升查询效率;
- 兼容扩展:预留合理长度(如用户名varchar(20)而非varchar(10)),避免后续扩展受限;
- 避免滥用:长文本优先用text而非varchar(65535),超大文本建议文件存储+路径记录,不建议用longtext。
3.4 数据表的约束与属性设置
3.4.1 约束与属性设置的目的
数据表的约束与属性设置,是保障数据库数据质量、优化存储效率、提升使用便捷性的核心配置,二者各司其职又相互配合,最终为业务系统提供稳定、高效、可靠的数据支撑。
- 约束是对字段数据的强制校验规则,核心目标是杜绝无效数据、重复数据、关联数据不一致的问题,确保数据库中数据的准确性、唯一性和参照完整性;
- 属性是字段的附加配置,不强制约束数据合法性,核心目标是优化数据存储逻辑、简化数据操作、提升数据可读性。
约束解决 "数据能不能存" 的合法性问题,属性解决 "数据怎么存更优、用起来更方便" 的优化问题,二者搭配使用
3.4.2 约束设置(保证数据完整性、唯一性,优化索引)
- 主键约束(PK:Primary Key):非空且唯一,表中仅能有一个主键,是数据行的唯一标识(便于快速查询)。
sql
-- 创建表时设置主键
CREATE TABLE student (
id INT NOT NULL,
name VARCHAR(10) NOT NULL,
PRIMARY KEY (id) -- 主键约束
);
-- 联合主键(多字段组合唯一)
CREATE TABLE score (
student_id INT NOT NULL,
course_id INT NOT NULL,
score INT,
PRIMARY KEY (student_id, course_id)
);
- 唯一约束(UK:Unique Key):字段值唯一(可允许 NULL,但仅一个 NULL),如手机号、邮箱。
sql
CREATE TABLE user (
id INT NOT NULL PRIMARY KEY,
phone CHAR(11) NOT NULL,
UNIQUE INDEX uk_phone (phone) -- 唯一约束(命名索引)
);
- 非空约束(NN:Not Null):字段不允许为空,避免关键数据缺失(如姓名、学号)。
sql
CREATE TABLE student (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(10) NOT NULL -- 非空约束
);
- 外键约束(FK:Foreign Key) :一张表的字段(子表)指向另一张表的主键(父表),实现多表数据关联约束。
- 父表:被引用的表(如班级表 class);
- 子表:设置外键的表(如学生表 student)。
sql
-- 步骤1:创建父表(班级表)
CREATE TABLE class (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL COMMENT "班级名称",
room VARCHAR(10) COMMENT "教室"
) CHARSET utf8mb4;
-- 步骤2:创建子表(学生表),设置外键
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
number CHAR(10) NOT NULL UNIQUE COMMENT "学号",
name VARCHAR(10) NOT NULL COMMENT "姓名",
c_id INT, -- 外键字段(需与父表主键类型一致)
FOREIGN KEY (c_id) REFERENCES class(id) -- 外键约束:关联班级表主键
) CHARSET utf8mb4;
约束规则:
- 插入数据先父表后子表:插入子表数据时,c_id 必须在父表中存在(如父表无班级 ID=3,子表无法插入 c_id=3);
- 删除数据先子表后父表:删除父表数据时,若该数据被子表引用(如子表有学生关联班级 ID=1),则无法直接删除(需先删子表关联数据)。
3.4.3 属性设置(辅助约束,优化数据存储)
- 自增属性(auto_increment):数值型字段自动递增(默认从 1 开始),常用于主键(如 ID 自增)。
sql
CREATE TABLE student (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 自增+主键
name VARCHAR(10) NOT NULL
);
说明:自增起点可通过
ALTER TABLE 表名 AUTO_INCREMENT=100;修改,上限为对应数值类型的最大值。
- 默认值属性(default):字段未插入值时,自动填充默认值(配合非空约束使用)。
sql
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
phone CHAR(11) NOT NULL DEFAULT '00000000000' COMMENT "手机号默认值"
);
- 非负属性(unsigned):数值型字段仅允许存储非负数(如年龄、分数)。
sql
CREATE TABLE student (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
age TINYINT UNSIGNED NOT NULL COMMENT "年龄非负"
);
- 注释属性(comment):添加字段/表的说明文档,提升可读性(企业规范必备)。
sql
CREATE TABLE student (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT "学生唯一ID",
name VARCHAR(10) NOT NULL COMMENT "学生姓名"
) COMMENT "学生信息表";
3.5 数据库数据模式(sql_mode)
数据库数据模式(以 MySQL sql_mode 为核心)是一组数据校验与 SQL 执行规则的集合,用于约束数据库的各类操作行为,是保障数据质量、规范 SQL 执行逻辑的关键配置。
sql_mode 本质上是 MySQL 的"行为开关",它既可以启用严格校验规则,从源头杜绝脏数据的产生;也可以按需放宽限制,实现对老旧系统的兼容适配,其核心作用是在数据合法性 与系统兼容性之间找到最优平衡。
3.5.1 数据库数据模式设置的目的
sql_mode 是 MySQL 核心配置项,其设置的核心目的是 通过启用严格的数据校验规则,保障数据库中数据的合法性、完整性和一致性,同时规范 SQL 语句的执行逻辑,避免无效操作、数据异常及跨版本/跨环境的兼容性问题,是数据迁移、主从同步的关键配置。
- 拦截无效数据操作:杜绝非法数据存入数据库(如无效日期、除数为0的运算、截断字符等),避免脏数据产生,保障数据质量。
- 规范 SQL 执行逻辑:约束 SQL 语句的语法和执行行为(如分组查询的字段规范),避免因宽松模式导致的执行结果异常或逻辑歧义。
- 保障跨环境兼容性:统一不同版本 MySQL(如5.7→8.0)、不同部署环境(主库/从库、测试/生产)的执行规则,减少数据迁移、主从同步中的故障风险。
3.5.2 常用 sql_mode 参数说明
sql
-- 查看当前 sql_mode 配置(8.0.36)
mysql> select @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MySQL(5.7+ 及 8.0 版本)默认启用的 严格模式 sql_mode 核心参数组合,也是生产环境首选配置,每个参数各司其职,共同实现严格的数据校验与规范的 SQL 执行逻辑。关键参数解读:
| 参数名称 | 核心功能解读 |
|---|---|
ONLY_FULL_GROUP_BY |
规范 GROUP BY 分组查询逻辑,要求 SELECT 后查询的字段,要么在 GROUP BY 中分组,要么是聚合函数(SUM/COUNT/MAX 等),杜绝分组查询的结果歧义,避免数据统计异常。 |
STRICT_TRANS_TABLES |
严格模式的核心参数,开启后拦截各类无效数据操作: 1. 字段类型不匹配时直接报错(而非静默转换); 2. 字符长度超出字段限制时报错(而非静默截断); 3. 非空字段插入 NULL 值时报错,从源头杜绝脏数据。 |
NO_ZERO_IN_DATE |
禁止插入"月"或"日"为 0 的无效日期,仅允许年份为 0(如 0000-01-01 合法,2024-00-10、2024-12-00 非法),保障日期数据的有效性。 |
NO_ZERO_DATE |
禁止插入 0000-00-00 这类空日期(无效日期),强制存储合法的日期格式,避免时间数据混乱。 |
ERROR_FOR_DIVISION_BY_ZERO |
当 SQL 中出现除数为 0 的运算时,直接触发报错(而非静默返回 NULL),及时发现业务逻辑中的运算异常(如金额分摊、数据统计时的逻辑漏洞)。 |
NO_ENGINE_SUBSTITUTION |
创建数据表时,若指定的存储引擎(如 InnoDB)不被 MySQL 支持,直接报错提示,而非自动替换为默认引擎(如 MyISAM),避免因引擎不兼容导致功能缺失(如事务、外键失效)。 |
MySQL 的
sql_mode主要分为宽松模式 和严格模式,二者核心差异在于校验强度与兼容性,具体简单介绍如下:
- 严格模式:校验规则严苛,无静默容错,遇到无效数据(如非法日期)或不规范 SQL(如字段不匹配的分组查询)会直接报错并终止操作。能够从源头杜绝脏数据,保障数据完整性和 SQL 执行规范性。适用于生产环境、新业务系统(尤其是金融、电商等对数据质量要求高的场景)等。
- 宽松模式:校验规则宽松,对无效操作采取静默处理(如自动截断超长字符、除数为0返回 NULL),不触发报错。能够高度兼容老旧系统的不规范 SQL 和历史数据,无需大规模改造,但是也容易产生脏数据,后期排查问题难度大。适用于老旧系统维护、历史数据迁移过渡期、测试环境临时调试。
宽松模式的典型配置:
- 空值:无任何校验参数,MySQL 5.6 及以下默认配置,是最宽松的配置,不启用任何数据校验和 SQL 规范约束,对所有无效操作均做静默处理。
- 仅启用
NO_ENGINE_SUBSTITUTION:仅保留引擎兼容性校验,防止存储引擎自动替换,其余无校验规则,兼顾基础兼容性与极致宽松。
3.5.3 核心应用场景
① 数据迁移(低版本 MySQL → 高版本 MySQL)
- 问题:低版本 MySQL(如 5.6)默认采用宽松的 sql_mode 配置,校验规则简单;而高版本 MySQL(如 8.0)默认启用严格模式,校验规则更为严苛。若直接将低版本数据库的数据导入高版本,会因历史无效数据(如非法日期、截断字符)或不规范 SQL 触发校验报错,导致数据迁移失败。
- 解决方案:
sql
-- 迁移期间临时关闭严格模式(快速兼容,仅临时使用)
set global sql_mode='';
-- 长期永久配置(修改配置文件,重启 MySQL 服务后生效)
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION
② 主从同步故障排查
- 常见原因:主库配置宽松的 sql_mode,允许插入无效数据或执行不规范 SQL;而从库启用严格 sql_mode,在同步主库数据和操作时,会因校验不通过触发报错,导致主从同步中断,数据一致性受损。
- 解决方案:统一主库与从库的 sql_mode 配置(推荐双方均启用严格模式),消除规则差异,避免同步校验冲突,保障主从同步稳定运行。
4. 数据库标识符
数据库标识符是用于命名数据库对象的唯一标识,通俗来说就是数据库、数据表、字段、索引、视图等数据库对象的"名字",是操作和区分各类数据库对象的核心依据。
4.1 常见标识符类型
日常使用中高频的数据库标识符主要包括:
- 库级标识符 :数据库名称(如
user_db、order_db) - 表级标识符 :数据表名称(如
student、user_info) - 字段级标识符 :表中字段名称(如
id、user_name、phone) - 其他标识符 :索引名称(如
uk_phone)、视图名称(如v_student_score)、存储过程名称等
4.2 数据库对象命名与设计规范
4.2.1 基础规则(默认遵循,无需特殊处理)
- 允许使用英文字母(默认不区分大小写,如
User和user视为同一表)、数字(0-9)、下划线(_) - 标识符长度限制:默认最大64个字符(超出会被截断,建议简洁明了)
- 不能以数字开头(如
123_user非法,user_123合法) - 不能使用 MySQL 保留字(如
select、table、where等,避免语法冲突)
4.2.2 特殊规则(使用特殊字符时需适配)
若标识符中需要包含空格、特殊符号(如 -、#)或 MySQL 保留字,必须用反引号(`) 包裹,否则会报错:
sql
-- 非法:表名包含空格,未用反引号
CREATE TABLE user info (id INT);
-- 合法:用反引号包裹特殊标识符
CREATE TABLE `user info` (id INT);
-- 合法:用反引号包裹保留字作为标识符
CREATE TABLE `select` (`where` INT);
4.2.3 命名规范(企业实战推荐)
为提升可读性和团队协作效率,行业内有统一的命名规范(大厂中也会有自己的一些标准):
- 小写优先 :标识符全部使用小写字母,避免大小写混淆(如
user_info而非UserInfo); - 下划线分隔 :多单词用下划线连接(蛇形命名法),如
order_detail、product_category,可读性优于驼峰命名; - 简洁表意 :见名知意,避免无意义缩写(如
phone而非ph,student_score而非s_s); - 统一前缀/后缀 :特殊对象添加固定标识,如索引(
uk_唯一索引、idx_普通索引)、视图(v_)、分区表(_p); - 避免特殊字符 :尽量不使用空格、
-等特殊符号,减少反引号的使用,简化 SQL 编写。
4.2.4 关键注意事项
- 大小写敏感性:MySQL 标识符的大小写敏感由操作系统决定(Linux 区分大小写,Windows 不区分),建议统一小写避免跨环境问题。
- 保留字规避:尽量不使用 MySQL 保留字作为标识符,若必须使用,务必用反引号包裹。
- 长度控制:标识符不宜过长,建议控制在30个字符以内,便于记忆和编写 SQL。
综上所述,SQL作为关系型数据库的通用语言,其概述内容与字符集、校对规则、数据类型、约束属性及sql_mode等核心前置配置,共同构成了数据库操作的基础框架。掌握这些知识,既能规避乱码、数据异常等问题,也能为规范、高效的数据库设计与操作提供支撑。实际应用中,需结合业务场景灵活配置,让理论落地于实践,提升数据管理质量。