MySQL 将服务器初始化、模式定义和连接配置分离。生产环境安装应只初始化一次空数据目录,将配置存储在该目录之外,并通过平台服务管理器管理服务器。mysqld --initialize 会创建数据字典和初始管理账户,但不会配置应用程序模式或权限。
账户、授权与角色 #
MySQL 同时根据用户和主机识别账户,因此 'app'@'localhost' 与 'app'@'10.%' 是不同的身份。创建账户时应显式指定认证策略:
CREATE USER IF NOT EXISTS 'app'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'generated-secret';在 MySQL 8 中,CREATE USER 创建身份,GRANT 分配权限;GRANT 不会创建账户。主机匹配发生在认证之前,随后由角色和直接授权决定授权结果。使用 SHOW GRANTS 检查有效权限。角色将权限分组,以便在多个账户之间复用:
CREATE ROLE 'order_reader';
GRANT SELECT ON app.orders TO 'order_reader';
GRANT 'order_reader' TO 'app'@'localhost';
SET DEFAULT ROLE 'order_reader' TO 'app'@'localhost';将账户管理置于应用程序迁移表之外。应用程序模式不应依赖临时的权限变更来维持有效性。
数值类型 #
应根据取值范围而不是显示宽度选择整数类型。TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT 分别使用 1、2、3、4 和 8 字节。无符号类型会将范围调整为非负值,但会带来跨数据库可移植性问题。BOOLEAN 和 BOOL 是 TINYINT(1) 的别名。
对于货币等需要十进制运算的数量,应使用 DECIMAL(p, s)。p 是十进制总位数,s 是小数点后的位数。FLOAT 和 DOUBLE 表示二进制浮点值,可能会对十进制小数进行舍入;不要将其用于对相等性敏感的货币值。
时间类型与结构化值 #
DATE存储日历日期;TIME存储时间或持续时间。DATETIME存储字面日期和时间,不进行时区转换。TIMESTAMP以时间瞬间存储,并针对受支持的值在会话时区与 UTC 之间转换。JSON会验证 JSON 并提供 JSON 函数,但其中的值不能替代用于连接和索引的关系型列。
当值表示本地预约时,应使用 DATETIME 加上显式的业务时区。对于事件发生瞬间,应使用 UTC TIMESTAMP 或 UTC DATETIME,并明确应用程序执行转换的边界。
时间列可以声明 0 到 6 位的小数秒精度,例如 DATETIME(6)。严格 SQL 模式应拒绝无效日期;控制零日期的模式与版本有关,因此模式不应使用 '0000-00-00' 作为缺失值标记。应使用 NULL 或显式状态代替。
文本、二进制、JSON 与空间值 #
CHAR 和 VARCHAR 存储通过字符集和排序规则解释的字符串。BINARY 和 VARBINARY 存储字节字符串,而 TEXT 和 BLOB 系列提供更大的字符值和二进制值。索引宽度以字节为单位测量,因此 utf8mb4 键消耗的索引空间可能超过其字符数所暗示的大小。
MySQL 以二进制格式存储 JSON,并提供路径、提取、修改和验证函数。应通过生成列或受支持的函数索引,为经常查询的标量路径建立索引。POINT、LINESTRING 和 POLYGON 等空间类型承载几何数据;当具有地理意义时,应声明并验证空间参考系。
模式检查与限制 #
使用 SHOW CREATE TABLE 检查表的有效 DDL,使用 INFORMATION_SCHEMA 执行可移植的元数据查询:
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'app' AND table_name = 'orders'
ORDER BY ordinal_position;存储限制取决于存储引擎、页面大小、行格式、字符集和 MySQL 版本。SHOW ENGINES、SHOW TABLE STATUS 和 SHOW CREATE TABLE 可以显示有效的引擎和表属性。应验证已部署版本的行限制和索引限制,而不是将固定假设编码到模式生成器中。相关设计细节请参阅MySQL 字符串类型与字符集、MySQL 索引和MySQL 表与视图。
评论
在 GitHub 上阅读或评论(发表评论需要登录)