feat: 建立 MySQL 8 数据库基础 (#78)

This commit is contained in:
chengma
2026-08-10 01:22:22 +08:00
parent 93bbca88a8
commit 7e74bf210d
12 changed files with 623 additions and 41 deletions
+13 -5
View File
@@ -1,8 +1,9 @@
# 03 Admin 数据模型
- 文档状态:基线草案,待数据评审
- 数据库:SQLite(驱动 `modernc.org/sqlite`,纯 Go 免 cgo)
- 位置:`data/admin.db`,见 [02 架构](02-architecture.md) §6
- 生产数据库:MySQL 8.4(驱动 `go-sql-driver/mysql` v1.9.2)
- 位置:与 Admin 同机的 `127.0.0.1:3307`,使用独立数据库和最小权限账号
- 历史数据库:`data/admin.db` 只作为 SQLite → MySQL 单向迁移来源和回退备份
本文档中 `[必须]` / `[建议]` / `[待定]` 的含义见 [文档索引](../README.md#文档标注说明)。
没有标注的默认是 `[必须]`。看不懂的词查 [术语表](00-glossary.md)。
@@ -19,6 +20,13 @@
## 2. 建库与迁移
生产 MySQL 使用 `schema_migrations` 记录追加版本。MySQL DDL 会隐式提交,
因此每条 DDL 必须可重放;整版全部执行、通过表和关键列自检后才记录版本。
连接会话固定 UTC,字符集固定 `utf8mb4`,业务 ID 使用二进制排序规则保持大小写精确。
下面的 PRAGMA 和 `user_version` 章节是历史 SQLite 迁移规则,只供单向迁移工具维护,
不得重新接入生产运行时。
### 2.1 PRAGMA 必须写在 DSN 里
`[必须]` 三条设置通过**连接串**传入,**不要**用 `db.Exec("PRAGMA ...")`:
@@ -444,7 +452,7 @@ CREATE INDEX idx_syb_orders_list ON syb_orders(updated_at DESC, syb_id DESC);
- `price_twd_cent` 是**台币分**,是蝦皮那边的售价,
和采购任务的人民币价格上限**没有换算关系**,不要互相赋值。
- `image_url` 存 URL。`[必须]` 不要把图片二进制存进 SQLite。
- `image_url` 存 URL。`[必须]` 不要把图片二进制存进数据库。
- `shopee_sku_id` **直接对应 `shopee_skus.sku_id`**,编号格式一致,不需要额外转换。
`[必须]` 但**不要加外键约束**。理由:蝦皮报表不是全量目录(样本里平均每商品仅 1.17 个 SKU),
@@ -713,7 +721,7 @@ users(采购员)──1:N 当前归属──────────┘
## 11. 与 Client 数据模型的关系
Admin 和 Client **各有一个 SQLite,互不相通**,只通过接口交换数据。
Admin 使用集中 MySQL 8.4,Client 仍使用各自的本地 SQLite;两者只通过接口交换数据。
| 概念 | Admin 这边 | Client 那边 |
|---|---|---|
@@ -744,7 +752,7 @@ CREATE TABLE users (
- `password_hash` 只保存成熟密码哈希算法的结果,绝不保存或记录明文密码。
- 用户不做物理删除;离职或停用改为 `disabled`,保留任务和操作记录的可追溯性。
- 首次初始化必须在写事务中再次确认 `users` 为空;SQLite 同一时刻只有一个写事务,
- 首次初始化必须在 InnoDB 写事务中锁定初始化保护记录并再次确认 `users` 为空,
并发提交最多一个成功。即使所有账号都被禁用,初始化入口也不能重新开放。
- 系统不能禁用最后一个有效管理员。