MySQL 不是只会增删改查就够了。真正做后端项目时,最重要的是能把业务对象设计成合理的数据表。本文从表、行、列、主键、外键、字段类型、范式和项目建模讲起。

【一、MySQL 在后端项目中负责什么】

MySQL 是关系型数据库,适合长期、稳定地保存结构化数据。

在 Python 后端项目中,MySQL 常用于保存:

- 用户账号

- 角色权限

- 商品信息

- 订单记录

- 支付流水

- 文章内容

- 任务状态

- 文件元数据

- AI 调用日志

- 知识库文档信息

Redis 更像高速缓存,MySQL 更像正式账本。

【二、表、行、列怎么理解】

可以把 MySQL 表理解成 Excel。

表 table:一类数据,比如 users

行 row:一条记录,比如一个用户

列 column:一个字段,比如 email、password_hash

例子:

sql

CREATE TABLE users (

  id BIGINT PRIMARY KEY AUTO_INCREMENT,

  username VARCHAR(50) NOT NULL,

  email VARCHAR(255) NOT NULL UNIQUE,

  password_hash VARCHAR(255) NOT NULL,

  created_at DATETIME NOT NULL

);

这里的 `users` 是用户表,每一行是一个用户,每一列是用户的一个属性。

【三、主键怎么设计】

主键是每条记录的唯一标识。

常见选择:

id BIGINT PRIMARY KEY AUTO_INCREMENT

为什么不用用户名或邮箱做主键?

因为用户名和邮箱属于业务字段,未来可能修改;主键最好稳定,不随业务变化而变化。

常见主键方案:

- 自增整数 id:简单、查询快,适合多数单体项目。

- UUID:分布式系统更方便,但长度更大,索引成本更高。

- 雪花 ID:适合分布式高并发业务。

初学项目用自增 id 就够了。

【四、外键是什么】

外键用来表达表和表之间的关系。

比如一个用户可以有多个订单:

sql

CREATE TABLE orders (

  id BIGINT PRIMARY KEY AUTO_INCREMENT,

  user_id BIGINT NOT NULL,

  total_amount DECIMAL(10, 2) NOT NULL,

  status VARCHAR(20) NOT NULL,

  created_at DATETIME NOT NULL,

  FOREIGN KEY (user_id) REFERENCES users(id)

);

`orders.user_id` 指向 `users.id`,表示这个订单属于哪个用户。

真实项目里,有些团队不强制使用数据库外键,而是在业务代码里维护关系。但逻辑上你必须知道:谁属于谁,谁关联谁。

【五、字段类型怎么选】

常见字段类型:

| 类型 | 用途 |

|---|---|

| INT / BIGINT | 数字 id、数量 |

| VARCHAR | 用户名、邮箱、标题 |

| TEXT | 长文本内容 |

| DECIMAL | 金额 |

| DATETIME | 创建时间、更新时间 |

| BOOLEAN / TINYINT | 是否启用、是否删除 |

| JSON | 半结构化配置,不适合滥用 |

金额不要用 FLOAT,因为浮点数有精度问题。金额一般用 `DECIMAL(10,2)`。

【六、常见通用字段】

后端项目里的核心表通常会加:

created_at DATETIME NOT NULL,

updated_at DATETIME NOT NULL,

deleted_at DATETIME NULL

或者:

is_deleted TINYINT NOT NULL DEFAULT 0

作用:

- `created_at`:什么时候创建。

- `updated_at`:什么时候更新。

- `deleted_at` / `is_deleted`:软删除,保留历史记录。

订单、支付、日志这类数据通常不能随便物理删除。

【七、范式是什么】

范式可以简单理解成“减少重复数据,保证数据关系清楚”的设计原则。

例如不要在订单表里直接保存用户所有信息:

orders 表:

id, user_id, username, user_email, user_address, ...

更合理的是:

users 表保存用户信息

orders 表保存订单信息,并用 user_id 关联 users

但也不是范式越高越好。真实项目中,为了查询效率,可能会做适当冗余。

比如订单表保存 `receiver_name`、`receiver_phone`、`receiver_address` 是合理的,因为下单后收货信息应该固化,不能因为用户后来改地址就影响历史订单。

【八、表设计的思考步骤】

设计表时先问:

1. 系统有哪些核心对象?

2. 每个对象有哪些字段?

3. 对象之间是什么关系?

4. 哪些字段必须唯一?

5. 哪些字段经常用于查询?

6. 哪些操作需要事务?

7. 哪些数据不能物理删除?

比如 RAG 知识库项目:

users:用户

knowledge_bases:知识库

documents:文档

document_chunks:文档切片

chat_sessions:对话会话

chat_messages:消息

llm_call_logs:模型调用日志

这就比只建一张 `data` 表清晰得多。

【九、常见坑】

- 所有字段都用 VARCHAR。

- 金额用 FLOAT。

- 没有创建时间和更新时间。

- 该唯一的字段没有加唯一约束,比如邮箱。

- 表之间关系不清楚,到处重复存数据。

- 业务状态用中文字符串,后期维护困难。

- 物理删除重要业务数据,无法审计。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐