MySQL建表考虑的方面

1. 基础设置与规范

  • 存储引擎的选择:
    • InnoDB: 在95%以上的场景下,我会选择它。因为它支持事务(ACID)行级锁 (高并发写入的关键)、以及外键崩溃恢复能力。
    • MyISAM: 只有在极特殊的只读场景,或者需要全文索引且不在意数据一致性时才会考虑(不过MySQL 5.6以后InnoDB也支持全文索引了)。
  • 字符集的选择:
    • 我通常会选择 utf8mb4 。因为传统的 utf8 字符集在MySQL中最多支持3个字节,无法存储emoji表情和一些生僻的中文字符。utf8mb4 是真正的4字节UTF-8编码,是兼容性最好的方案。
    • 排序规则一般选择 utf8mb4_general_ciutf8mb4_unicode_ci,后者在排序上更准确一些。

2. 字段数据类型的选择

这里的原则是:"在满足业务需求的条件下,尽可能选择占用存储空间小的、简洁的数据类型"。这能显著提升查询效率。

  • 整型:
    • 根据值的范围选择 TINYINTSMALLINTMEDIUMINTINTBIGINT。比如 age 字段用 TINYINT UNSIGNED 就足够了,不需要用 INT
  • 字符型:
    • CHARVARCHAR CHAR 适合定长的字段(如MD5加密后的密码、身份证号),因为它是定长的,存取速度快。VARCHAR 适合可变长度的字段(如用户名、地址),可以节省空间。注意不要为了省事把所有字符串都定义成 VARCHAR(255)

3. 约束与规范

  • 主键设计:
    • 必须要有主键。 InnoDB是索引组织表,必须要有主键。
    • 推荐使用自增ID雪花算法生成的分布式ID
    • 不建议使用业务主键(如身份证号),因为业务可能会变,而且长度通常比自增ID长,会导致辅助索引占用空间变大。
    • 不建议使用UUID,因为UUID是无序的,在插入时会导致页分裂,影响写入性能。(簇索引数据会按主键顺序排好)
  • 避免NULL:
    • 我通常会尽量给字段设置 NOT NULL ,并配合 DEFAULT 值(如空字符串或0)。
    • 原因:NULL值占用更多存储空间(标志位),对索引的维护也更复杂,而且在 COUNT()!= 等运算中容易出错。

4. 索引设计

参考其中的索引优化部分

在建表初期,至少要先把基础的索引设计好。

  • 根据查询设计索引:
    • WHERE 条件、ORDER BYGROUP BY 中频繁出现的字段,需要考虑建立索引。
  • 区分度:
    • 对于性别这种区分度极低的字段,建立索引意义不大(除非是组合索引的前导列)。
  • 联合索引:
    • 遵循最左前缀原则。我会把区分度高的字段放在左边。
    • 尽量通过联合索引做 "索引覆盖"(即索引中已经包含了需要查询的所有字段),减少"回表"查询。
  • 控制索引数量:
    • 索引不是越多越好。虽然能加速查询,但会拖慢 INSERTUPDATEDELETE 的速度,因为索引也需要维护。

5. 扩展性与冗余字段

  • 范式与反范式:
    • 在数据量大的时候,为了减少表连接,我会适度地做反范式设计。例如在订单表里冗余一份商品名称,这样查询订单详情时就不用再去关联商品表,但代价是如果商品名称修改了,可能需要去同步更新历史订单(业务通常不允许修改历史订单,所以这一点刚好适用)。

6. 核心字段建议

基于实际开发经验,几乎每张表我都会建议包含以下三个字段,这在很多框架中也是标配:

  • id: BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY (主键)
  • create_time: datetime NOT NULL DEFAULT CURRENT_TIMESTAMP (创建时间)
  • update_time: datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP (更新时间) ------ 这样在更新数据时,时间戳会自动刷新,对排查数据变更非常有帮助。
相关推荐
静水楼台x3 分钟前
spring security
java·数据库·spring
深度研习笔记17 分钟前
OpenCV工业视觉进阶14|SQLite违规数据库存储+历史记录查询+Excel报表导出,完成项目商用数据闭环(验收必备)
数据库·opencv·sqlite
要开心吖ZSH3 小时前
一文搞懂:JDK 21 虚拟线程 vs N种异步方案,到底该怎么选?
java·数据库·jdk·虚拟线程
guodingdingh7 小时前
软件开发工作问题总结0718
java·开发语言·数据库
GuWenyue9 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
Miao1213111 小时前
某海外住宿平台如何在大规模场景下实现指标一致性:Minerva 指标平台实践
大数据·数据库·人工智能
CodexDave11 小时前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
碎光拾影11 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
曾阿伦11 小时前
MongoDB 查询语句备忘手册
数据库·mongodb
一叶龙洲11 小时前
wslg打开Ubuntu24.04默认打开图形界面
linux·服务器·数据库·ubuntu