# 数据库规则 > **入口**: [_index.md](_index.md) --- ## 1. 表命名规范 ### 1.1 基本规则 | 规则 | 说明 | |------|------| | **表前缀** | 所有表必须以 `cf_` 开头 | | **命名格式** | `cf_{模块}_{实体}` 如 `cf_product`, `cf_order_item` | | **禁止** | 无前缀、其他前缀 | ### 1.2 示例 ```sql -- ✅ 正确 CREATE TABLE cf_product (...); CREATE TABLE cf_order_item (...); CREATE TABLE cf_inventory_log (...); -- ❌ 错误 CREATE TABLE product (...); CREATE TABLE order_items (...); ``` --- ## 2. 字段类型规范 ### 2.1 金额字段 | 规则 | 说明 | |------|------| | **类型** | `decimal(10,2)` | | **禁止** | `float`, `double` | | **原因** | 精度问题会导致金额计算错误 | ```sql -- ✅ 正确 price DECIMAL(10,2) NOT NULL, total_amount DECIMAL(10,2) NOT NULL, -- ❌ 错误 price FLOAT, total_amount DOUBLE, ``` ### 2.2 物理属性单位 | 属性 | 单位 | 字段类型 | |------|------|---------| | 长度 | cm | `decimal(10,2)` | | 重量 | kg | `decimal(10,2)` | | 体积 | m³ | `decimal(10,4)` | ### 2.3 JSON 字段 | 规则 | 说明 | |------|------| | **存储** | JSON 字段入库前序列化 | | **读取** | 出库后解析 | | **适用** | images, skus, attributes, params 等 | --- ## 3. 数据完整性 ### 3.1 唯一约束 ```sql -- 商品表:平台+商品ID唯一 ALTER TABLE cf_product ADD UNIQUE KEY uk_platform_product (platform, product_id); -- 店铺表:租户+店铺ID唯一 ALTER TABLE cf_shop ADD UNIQUE KEY uk_tenant_shop (tenant_id, shop_id); ``` ### 3.2 幂等性保证 所有建表语句必须使用 `db.schema.hasTable` 前置校验: ```typescript // ✅ 正确 if (!(await db.schema.hasTable('cf_product'))) { await db.schema.createTable('cf_product', (table) => { table.increments('id').primary(); // ... }); } // ❌ 错误 await db.schema.createTable('cf_product', (table) => { // 可能重复创建导致错误 }); ``` --- ## 4. 索引规范 ### 4.1 必须索引 | 字段类型 | 索引要求 | |---------|---------| | `tenant_id` | 必须索引 | | `shop_id` | 必须索引 | | `created_at` | 必须索引 | | 状态字段 | 按查询频率决定 | | 外键 | 必须索引 | ### 4.2 复合索引顺序 ```sql -- 按查询频率和选择性排序 -- 高选择性在前,常用查询条件在前 CREATE INDEX idx_tenant_shop_status ON cf_order (tenant_id, shop_id, status); ``` ### 4.3 索引验证 复杂查询必须通过 `EXPLAIN` 校验: ```sql EXPLAIN SELECT * FROM cf_order WHERE tenant_id = 'xxx' AND status = 'PENDING'; ``` --- ## 5. 禁止操作 | 操作 | 说明 | |------|------| | `DROP TABLE` | 禁止在代码中执行 | | `TRUNCATE` | 禁止在代码中执行 | | `DELETE` 全表 | 必须带 WHERE 条件 | | 直接修改生产数据 | 必须通过迁移脚本 | --- ## 6. 迁移规范 ### 6.1 迁移文件命名 ``` {timestamp}_{action}_{table}.ts 示例: 20260322000001_create_cf_product.ts 20260322000002_add_price_index_to_cf_product.ts ``` ### 6.2 迁移模板 ```typescript import { Knex } from 'knex'; export async function up(knex: Knex): Promise { if (!(await knex.schema.hasTable('cf_product'))) { await knex.schema.createTable('cf_product', (table) => { table.increments('id').primary(); table.string('tenant_id', 50).notNullable(); table.string('shop_id', 50).notNullable(); table.string('product_id', 100).notNullable(); table.string('platform', 20).notNullable(); table.decimal('price', 10, 2).notNullable(); table.timestamps(true, true); table.index(['tenant_id', 'shop_id']); table.unique(['platform', 'product_id']); }); } } export async function down(knex: Knex): Promise { await knex.schema.dropTableIfExists('cf_product'); } ``` --- ## 7. 五元组字段 所有业务表必须包含以下追踪字段: | 字段 | 类型 | 说明 | |------|------|------| | `tenant_id` | VARCHAR(50) | 租户ID | | `shop_id` | VARCHAR(50) | 店铺ID | | `task_id` | VARCHAR(50) | 任务ID(可选) | | `trace_id` | VARCHAR(50) | 链路追踪ID | | `business_type` | VARCHAR(10) | TOC/TOB | ```sql tenant_id VARCHAR(50) NOT NULL, shop_id VARCHAR(50) NOT NULL, task_id VARCHAR(50), trace_id VARCHAR(50) NOT NULL, business_type VARCHAR(10) NOT NULL, ``` --- *最后更新: 2026-03-22*