MySQL建表考虑的方面

1. 基础设置与规范

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

2. 字段数据类型的选择

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

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

3. 约束与规范

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

4. 索引设计

参考其中的索引优化部分

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

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

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 (更新时间) ------ 这样在更新数据时,时间戳会自动刷新,对排查数据变更非常有帮助。
相关推荐
IvorySQL1 小时前
PostgreSQL 日报|修复截断 zstd 备份检测(10 月 9 日)
数据库·postgresql
刘胡子大叔1 小时前
SQL 脚本的导入顺序
数据库·sql
代码什么用2 小时前
Spring对IoC的实现
数据库·spring
hz567894 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC4 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
程序员Sunday4 小时前
MySQL 为什么使用 B+ 树索引?把范围查询、回表和覆盖索引连起来
数据库·mysql
半杯咖啡半行码4 小时前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
Yyyyyy~4 小时前
[ Mysql ] 库的操作
mysql
小米里的大麦5 小时前
16 MySQL 事务
数据库·mysql
西柚小萌新5 小时前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库