Files
makemd/docs/RULES/database.md
wurenzhi 2b86715c09 refactor: 优化代码结构并修复类型问题
- 移除未使用的TabPane组件
- 修复类型定义和导入方式
- 优化mock数据源的环境变量判断逻辑
- 更新文档结构并归档旧文件
- 添加新的UI组件和Memo组件
- 调整API路径和响应处理
2026-03-23 12:41:35 +08:00

4.3 KiB
Raw Permalink Blame History

数据库规则

入口: _index.md


1. 表命名规范

1.1 基本规则

规则 说明
表前缀 所有表必须以 cf_ 开头
命名格式 cf_{模块}_{实体}cf_product, cf_order_item
禁止 无前缀、其他前缀

1.2 示例

-- ✅ 正确
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
原因 精度问题会导致金额计算错误
-- ✅ 正确
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)
体积 decimal(10,4)

2.3 JSON 字段

规则 说明
存储 JSON 字段入库前序列化
读取 出库后解析
适用 images, skus, attributes, params 等

3. 数据完整性

3.1 唯一约束

-- 商品表:平台+商品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 前置校验:

// ✅ 正确
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 复合索引顺序

-- 按查询频率和选择性排序
-- 高选择性在前,常用查询条件在前
CREATE INDEX idx_tenant_shop_status ON cf_order (tenant_id, shop_id, status);

4.3 索引验证

复杂查询必须通过 EXPLAIN 校验:

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 迁移模板

import { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
  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<void> {
  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
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