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

把 TEXT 当万能字符串类型用
很多工程师一遇到“字段可能很长”就直接上 TEXT,尤其在 MySQL 中。但 TEXT 类型不支持默认值、不能建普通索引(只能前缀索引)、无法参与内存临时表排序(ORDER BY 或 GROUP BY 时容易触发磁盘临时表),性能隐患明显。
实操建议:
- 优先用
VARCHAR(255)或VARCHAR(1024)—— 大多数业务场景(如标题、摘要、URL)完全够用,且支持索引和默认值 - 只有真实需要存 >64KB 内容(比如富文本正文、日志快照)才考虑
TEXT,并明确加注释说明用途 - 若需全文检索,别只靠
TEXT+LIKE,应搭配FULLTEXT索引或外部搜索引擎
外键约束被当成“数据一致性保险”
外键看起来很安全,但实际在线上高并发写入场景中,它会成为锁竞争热点。比如订单表 order 关联用户表 user 的 user_id,每次插入订单都要校验 user 表主键是否存在 —— 这个校验会持读锁,可能阻塞用户信息更新。
更麻烦的是,跨库、分库、读写分离后,外键根本不可用。很多团队后期不得不删掉所有外键,靠应用层兜底。
实操建议:
- 新项目初期可保留外键,用于开发阶段快速暴露数据逻辑错误(如误删父记录)
- 上线前评估写入压力:若单表 QPS > 500,或存在批量导入/定时任务高频写入,建议去掉外键,改用应用层校验 + 定期对账脚本
- 用
NOT NULL+CHECK约束替代部分业务规则(如状态值限定),比外键轻量且可控
时间字段全用 DATETIME 不区分场景
DATETIME 和 TIMESTAMP 在 MySQL 中行为差异极大:TIMESTAMP 自动转时区、范围小(1970–2038)、占 4 字节;DATETIME 无时区转换、范围大(1000–9999)、占 8 字节。但很多人图省事,一律用 DATETIME,结果埋下两个坑:一是日志类时间(如 created_at)本该统一 UTC,却因时区不一致导致排查困难;二是存储空间翻倍,对亿级表的 I/O 和备份影响不小。
天龙企业网站管理系统,基于.net2.0+access开发,系统架构采用MVC设计模式,是一个十分优秀的.net企业管理系统。其中包括产品发布,新闻发布,企业简价,企业文化,下载中心,客户留言等功能。在V2.0 sp2 基础上再次升级: 1、修正了前台的投票调查功能。 2、增强系统安全性,增加了防SQL注入功能 3、修补了后台漏洞 4、增加了前台游客留言的字符过滤,自动过滤html格式以增强系统安
实操建议:
-
created_at/updated_at用TIMESTAMP(配合DEFAULT CURRENT_TIMESTAMP),确保写入即固化为 UTC - 业务意义明确带本地时区的时间(如“用户预约的明天下午三点”)才用
DATETIME,并额外存timezone_offset字段 - 避免在 WHERE 条件里对时间字段做函数操作,例如
WHERE DATE(created_at) = '2024-01-01'会导致索引失效
索引设计只盯着 WHERE 条件
索引不是光让 WHERE 快就行。如果 SELECT 列太多、ORDER BY 字段没覆盖、或者 JOIN 条件没走索引,照样慢。典型例子:查询“最近 10 条订单”,写成 SELECT * FROM order WHERE user_id = ? ORDER BY created_at DESC LIMIT 10,但只给 user_id 建了单列索引 —— 数据库得先扫出所有该用户的订单,再内存排序,效率极低。
实操建议:
- 复合索引要按「等值查询字段 → 排序字段 → 覆盖查询字段」顺序组织,例如
(user_id, created_at)可支撑上面那个查询 - 用
EXPLAIN看key_len和Extra(尤其是Using filesort或Using temporary)来验证索引是否生效 - 避免过度索引:每多一个索引,写入就多一次 B+ 树维护,对高频更新表,索引总数建议控制在 5 个以内
架构设计里最危险的不是不知道怎么做,而是用“看起来合理”的方案跳过权衡——比如选类型时没想清楚读写比例,建索引时没模拟真实查询路径。这些细节不会报错,但会在流量上来时悄悄拖垮系统。









