贝利信息

SQL 架构设计中的常见误判

日期:2026-01-23 00:00 / 作者:舞夢輝影
优先用VARCHAR而非TEXT,慎用外键,区分TIMESTAMP与DATETIME场景,复合索引需覆盖查询路径——类型、约束、时间、索引四类设计须按实际读写特征权衡,否则隐患随流量放大。

TEXT 当万能字符串类型用

很多工程师一遇到“字段可能很长”就直接上 TEXT,尤其在 MySQL 中。但 TEXT 类型不支持默认值、不能建普通索引(只能前缀索引)、无法参与内存临时表排序(ORDER BYGROUP BY 时容易触发磁盘临时表),性能隐患明显。

实操建议:

外键约束被当成“数据一致性保险”

外键看起来很安全,但实际在线上高并发写入场景中,它会成为锁竞争热点。比如订单表 order 关联用户表 useruser_id,每次插入订单都要校验 user 表主键是否存在 —— 这个校验会持读锁,可能阻塞用户信息更新。

更麻烦的是,跨库、分库、读写分离后,外键根本不可用。很多团队后期不得不删掉所有外键,靠应用层兜底。

实操建议:

时间字段全用 DATETIME 不区分场景

DATETIMETIMESTAMP 在 MySQL 中行为差异极大:TIMESTAMP 自动转时区、范围小(1970–2038)、占 4 字节;DATETIME 无时区转换、范围大(1000–9999)、占 8 字节。但很多人图省事,一律用 DATETIME,结果埋下两个坑:一是日志类时间(如 created_at)本该统一 UTC,却因时区不一致导致排查困难;二是存储空间翻倍,对亿级表的 I/O 和备份影响不小。

实操建议:

索引设计只盯着 WHERE 条件

索引不是光让 WHERE 快就行。如果 SELECT 列太多、ORDER BY 字段没覆盖、或者 JOIN 条件没走索引,照样慢。典型例子:查询“最近 10 条订单”,写成 SELECT * FROM order WHERE user_id = ? ORDER BY created_at DESC LIMIT 10,但只给 user_id 建了单列索引 —— 数据库得先扫出所有该用户的订单,再内存排序,效率极低。

实操建议:

架构

设计里最危险的不是不知道怎么做,而是用“看起来合理”的方案跳过权衡——比如选类型时没想清楚读写比例,建索引时没模拟真实查询路径。这些细节不会报错,但会在流量上来时悄悄拖垮系统。