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 (更新时间) ------ 这样在更新数据时,时间戳会自动刷新,对排查数据变更非常有帮助。
相关推荐
Mr_sst1 分钟前
文件上传并发控制:为什么选Redisson可过期信号量?(避坑指南)
网络·数据库·redis·分布式·安全架构
四维迁跃2 分钟前
JavaScript中Object-defineProperties批量设置属性
jvm·数据库·python
qq_283720054 分钟前
Python3 模块精讲:psycopg2(第三方)- 连接 PostgreSQL
数据库·postgresql
倚楼盼风雨4 分钟前
Redis 为什么快
数据库·redis·缓存
2501_901200534 分钟前
CSS如何让响应式字体在断点处平滑切换_使用clamp函数计算
jvm·数据库·python
xiaoliuliu123457 分钟前
redis-windows-7.2.3安装步骤详解(附Redis配置与Windows服务注册)
数据库·windows·redis
dFObBIMmai9 分钟前
如何应对高级SQL注入_配置数据库审计实时监控流量
jvm·数据库·python
Elastic 中国社区官方博客11 分钟前
通过受管控的控制平面加速商品陈列优化
大数据·数据库·人工智能·elasticsearch·搜索引擎·平面·ai
郝开13 分钟前
Spring Cloud Gateway 3.5.14 使用手册
java·数据库·spring boot·gateway
troyqu19 分钟前
Mysql(四)InnoDB怎么确保RR下的数据一致性
数据库·后端·mysql