数据持久化与缓存 / 技术笔记

MySQL 表结构设计

从业务需求开始,理解一张表为什么这样拆、字段为什么这样选,以及约束如何保护数据。

内容章节
6 节
阅读重点
建模与约束
示例语言
SQL

数据库表看起来很像电子表格,但两者的目标不同。电子表格方便人临时整理信息,数据库表需要长期、稳定地保存业务事实。

文本示意

text

用户有唯一邮箱订单一定属于某个用户价格不能是负数

好的表结构会把这些规则明确表达出来。

设计表结构,本质上是在决定系统允许保存什么样的数据。

1. 表结构承载业务规则

建表之前,先找业务中的对象和关系。电商系统可能有用户、商品、订单和订单项。

文本示意

text

用户 1 对多 订单订单 1 对多 订单项商品 1 对多 订单项

每张表应该表达一种清楚的事实。不要把用户、商品和订单全部塞进一张“万能表”,否则重复数据和空字段会越来越多。

2. 主键应该怎样选择

主键用来稳定地识别一行数据。姓名、手机号和邮箱都会改变,不适合承担这个职责。

SQL 示例

sql

CREATE TABLE users (    id BIGINT PRIMARY KEY AUTO_INCREMENT,    email VARCHAR(255) NOT NULL UNIQUE,    nickname VARCHAR(80) NOT NULL);

业务字段仍然可以加唯一约束,但内部关系通常引用不会变化的主键。

3. 字段类型会影响什么

字段类型同时影响取值范围、存储空间、比较方式和索引效率。

SQL 示例

sql

price DECIMAL(10, 2) NOT NULL,status VARCHAR(24) NOT NULL,created_at DATETIME NOT NULL

金额通常使用 DECIMAL,避免浮点数精度误差。时间需要先约定时区。文本长度也应该根据真实业务范围设置,统一使用无限长类型会增加存储和索引成本。

4. 一对多和多对多怎样落表

一对多关系通常把外键放在“多”的一侧。

SQL 示例

sql

CREATE TABLE orders (    id BIGINT PRIMARY KEY,    user_id BIGINT NOT NULL,    FOREIGN KEY (user_id) REFERENCES users(id));

多对多关系需要一张中间表。例如文章和标签:

SQL 示例

sql

CREATE TABLE article_tags (    article_id BIGINT NOT NULL,    tag_id BIGINT NOT NULL,    PRIMARY KEY (article_id, tag_id));

中间表不仅连接两边,也可以保存关系自己的信息,例如添加时间和排序。

5. 约束为什么比应用判断可靠

应用代码可能有多个入口,也可能因为 Bug 跳过检查。数据库约束是所有写入最终都必须经过的防线。

SQL 示例

sql

CREATE TABLE products (    id BIGINT PRIMARY KEY,    sku VARCHAR(64) NOT NULL UNIQUE,    price DECIMAL(10, 2) NOT NULL,    CHECK (price >= 0));

NOT NULLUNIQUE、外键和检查约束,分别保护完整性、唯一性和关系正确性。

6. 从需求到表结构的完整过程

设计表结构可以按这个顺序进行:

文本示意

text

阅读业务需求识别实体和关系确定每张表的职责选择主键和字段类型添加唯一、非空和关系约束根据查询方式设计索引用真实场景验证结构

表结构会随着业务持续演进。每次变化都应该留下迁移记录,并且能够对应到清楚的业务规则。