Files
AIclinicalresearch/docs/04-开发规范/01-数据库设计规范.md
HaHafeng 3634933ece refactor(asl): ASL frontend architecture refactoring with left navigation
- feat: Create ASLLayout component with 7-module left navigation
- feat: Implement Title Screening Settings page with optimized PICOS layout
- feat: Add placeholder pages for Workbench and Results
- fix: Fix nested routing structure for React Router v6
- fix: Resolve Spin component warning in MainLayout
- fix: Add QueryClientProvider to App.tsx
- style: Optimize PICOS form layout (P+I left, C+O+S right)
- style: Align Inclusion/Exclusion criteria side-by-side
- docs: Add architecture refactoring and routing fix reports

Ref: Week 2 Frontend Development
Scope: ASL module MVP - Title Abstract Screening
2025-11-18 21:51:51 +08:00

11 KiB
Raw Blame History

数据库设计规范

版本: v2.0
最后更新: 2025-11-06
数据库: PostgreSQL 15+
ORM Prisma
适用范围: 平台层 + 能力层 + 业务模块层


📋 核心原则

本规范是所有模块数据库设计的基础规范,必须严格遵守。

设计原则:

  • 遵循第三范式3NF
  • 使用SERIAL作为主键整数自增性能更好
  • 所有表包含created_at和updated_at时间戳
  • 重要表使用软删除保留deleted_at字段
  • 外键约束使用ON DELETE CASCADE
  • 敏感字段加密存储密码使用bcrypt

🏗️ Schema隔离策略 最重要

为什么需要Schema隔离

核心原因:

  1. 模块独立性每个业务模块有独立的Schema
  2. 支持独立部署:可以单独导出某个模块的数据
  3. 支持独立销售:可以单独交付某个模块
  4. 权限隔离可以为不同Schema设置不同权限
  5. 避免命名冲突:不同模块可以有相同的表名

Schema命名规范

platform_schema       # 平台基础层(全局共享)
aia_schema           # AI智能问答
asl_schema           # AI智能文献
pkb_schema           # 个人知识库
dc_schema            # 数据清洗整理
ssa_schema           # 智能统计分析
st_schema            # 统计分析工具
rvw_schema           # 稿件审查系统

Schema创建

-- 创建Schema
CREATE SCHEMA IF NOT EXISTS platform_schema;
CREATE SCHEMA IF NOT EXISTS asl_schema;
CREATE SCHEMA IF NOT EXISTS aia_schema;
-- ...其他Schema

跨Schema依赖规则 必须遵守

允许的依赖:

-- ✅ 允许业务模块引用platform_schema
CREATE TABLE asl_schema.literature_projects (
  id SERIAL PRIMARY KEY,
  user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE,
  ...
);

-- ✅ 允许通用能力引用platform_schema
CREATE TABLE platform_schema.llm_usage (
  id SERIAL PRIMARY KEY,
  user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE,
  ...
);

禁止的依赖:

-- ❌ 禁止:业务模块之间互相引用
CREATE TABLE ssa_schema.analysis_projects (
  id SERIAL PRIMARY KEY,
  -- 错误!不能引用其他业务模块
  literature_project_id INTEGER REFERENCES asl_schema.literature_projects(id)
);

-- ❌ 禁止platform_schema反向依赖业务模块
CREATE TABLE platform_schema.users (
  id SERIAL PRIMARY KEY,
  -- 错误platform_schema不能依赖业务模块
  current_project_id INTEGER REFERENCES asl_schema.literature_projects(id)
);

正确做法:

跨模块数据关联在应用层处理,不在数据库层!

方式1通过user_id关联
- 两个模块都引用platform_schema.users
- 在应用层通过user_id查询两个模块的数据
- 在应用层组装数据

方式2存储业务ID字符串
- 在表中存储其他模块的业务IDVARCHAR
- 不建立外键关系
- 在应用层验证ID的有效性

📝 命名规范

表命名

规则:

  • 小写字母
  • 下划线分隔
  • 复数形式
  • Schema前缀查询时使用

示例:

-- ✅ 正确
CREATE TABLE asl_schema.literature_projects (...);
CREATE TABLE platform_schema.users (...);
CREATE TABLE pkb_schema.knowledge_bases (...);

-- ❌ 错误
CREATE TABLE ASLSchema.LiteratureProject (...);  -- 驼峰
CREATE TABLE asl_schema.project (...);           -- 单数
CREATE TABLE literature-projects (...);          -- 使用连字符

字段命名

规则:

  • 小写字母
  • 下划线分隔
  • 语义清晰

示例:

-- ✅ 正确
user_id
created_at
project_name
is_active

-- ❌ 错误
userId        -- 驼峰
createdat     -- 没有下划线
prjName       -- 缩写不清晰

索引命名

规则: idx_表名_字段名

示例:

-- ✅ 正确
CREATE INDEX idx_users_email ON platform_schema.users(email);
CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id);
CREATE INDEX idx_projects_user_status ON asl_schema.literature_projects(user_id, status);

-- ❌ 错误
CREATE INDEX user_email_idx ...        -- 顺序错误
CREATE INDEX index_on_email ...        -- 名称不清晰

外键命名

规则: fk_表名_关联表名

示例:

-- ✅ 正确
CONSTRAINT fk_projects_users 
  FOREIGN KEY (user_id) REFERENCES platform_schema.users(id);

CONSTRAINT fk_items_projects
  FOREIGN KEY (project_id) REFERENCES asl_schema.literature_projects(id);

-- ❌ 错误
CONSTRAINT user_fk ...                -- 名称不清晰
CONSTRAINT foreign_key_users ...      -- 太长

📊 通用字段 必须包含

所有表必须包含

CREATE TABLE xxx_schema.table_name (
  -- 主键(必须)
  id SERIAL PRIMARY KEY,
  
  -- 业务字段
  ...
  
  -- 时间戳(必须)
  created_at TIMESTAMP DEFAULT NOW() NOT NULL,
  updated_at TIMESTAMP DEFAULT NOW() NOT NULL
);

重要表应包含(软删除)

CREATE TABLE xxx_schema.important_table (
  id SERIAL PRIMARY KEY,
  
  -- 业务字段
  ...
  
  -- 软删除字段(可选,重要表建议添加)
  deleted_at TIMESTAMP,
  
  -- 时间戳(必须)
  created_at TIMESTAMP DEFAULT NOW() NOT NULL,
  updated_at TIMESTAMP DEFAULT NOW() NOT NULL
);

-- 查询时过滤已删除数据
SELECT * FROM xxx_schema.important_table WHERE deleted_at IS NULL;

用户关联表必须包含

CREATE TABLE xxx_schema.user_related_table (
  id SERIAL PRIMARY KEY,
  
  -- 用户外键(必须)
  user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE NOT NULL,
  
  -- 业务字段
  ...
  
  -- 时间戳(必须)
  created_at TIMESTAMP DEFAULT NOW() NOT NULL,
  updated_at TIMESTAMP DEFAULT NOW() NOT NULL
);

🔍 索引设计规范

必须添加索引的字段

1. 主键

-- 自动创建,无需手动添加
id SERIAL PRIMARY KEY

2. 外键字段

-- 必须添加提高JOIN性能
CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id);

3. 常用查询字段

-- status状态字段常用于WHERE
CREATE INDEX idx_projects_status ON asl_schema.literature_projects(status);

-- created_at时间字段常用于排序
CREATE INDEX idx_projects_created_at ON asl_schema.literature_projects(created_at DESC);

4. 唯一约束字段

-- email等唯一字段
CREATE UNIQUE INDEX idx_users_email ON platform_schema.users(email);

复合索引

规则:

  • 高频组合查询使用复合索引
  • 最常查询的字段放在前面
  • 复合索引最多3个字段

示例:

-- ✅ 正确user_id + status 组合查询
CREATE INDEX idx_projects_user_status 
  ON asl_schema.literature_projects(user_id, status);

-- 可以优化以下查询:
-- WHERE user_id = ? AND status = ?
-- WHERE user_id = ?  (只用前缀)

-- ❌ 错误:字段过多
CREATE INDEX idx_projects_complex
  ON asl_schema.literature_projects(user_id, status, created_at, updated_at);

🔗 外键约束规范

ON DELETE策略

规则:

-- 用户删除时,级联删除关联数据
FOREIGN KEY (user_id) 
  REFERENCES platform_schema.users(id) 
  ON DELETE CASCADE;

-- 父记录删除时,级联删除子记录
FOREIGN KEY (project_id) 
  REFERENCES asl_schema.literature_projects(id) 
  ON DELETE CASCADE;

-- 特殊情况:不能删除
FOREIGN KEY (parent_id) 
  REFERENCES xxx_schema.parent_table(id) 
  ON DELETE RESTRICT;  -- 有子记录时禁止删除

外键索引

规则: 所有外键必须添加索引

-- 创建外键
ALTER TABLE asl_schema.literature_items
  ADD CONSTRAINT fk_items_projects
  FOREIGN KEY (project_id) REFERENCES asl_schema.literature_projects(id)
  ON DELETE CASCADE;

-- 必须添加索引
CREATE INDEX idx_items_project_id ON asl_schema.literature_items(project_id);

性能优化规范

大表分区(可选)

适用场景: 年增长 > 100万记录

-- 按月分区如llm_usage表
CREATE TABLE platform_schema.llm_usage (
  id SERIAL,
  user_id INTEGER NOT NULL,
  created_at TIMESTAMP NOT NULL,
  ...
) PARTITION BY RANGE (created_at);

-- 创建分区
CREATE TABLE platform_schema.llm_usage_2025_11 
  PARTITION OF platform_schema.llm_usage
  FOR VALUES FROM ('2025-11-01') TO ('2025-12-01');

数据归档策略

-- 历史数据归档如1年前的日志
CREATE TABLE platform_schema.admin_logs_archive (
  LIKE platform_schema.admin_logs INCLUDING ALL
);

-- 定期归档
INSERT INTO platform_schema.admin_logs_archive
SELECT * FROM platform_schema.admin_logs
WHERE created_at < NOW() - INTERVAL '1 year';

DELETE FROM platform_schema.admin_logs
WHERE created_at < NOW() - INTERVAL '1 year';

🔒 安全规范

敏感字段加密

-- 密码字段
password VARCHAR(255) NOT NULL  -- 使用bcrypt加密存储哈希值

-- API Key字段
api_key_encrypted TEXT NOT NULL  -- 使用AES-256加密

-- 个人敏感信息
phone_encrypted VARCHAR(255)     -- 手机号加密
id_card_encrypted VARCHAR(255)   -- 身份证号加密

数据脱敏

-- 日志中不记录敏感字段
-- 开发/测试环境使用脱敏数据
UPDATE platform_schema.users 
SET 
  email = CONCAT('user', id, '@example.com'),
  phone = '138****0000'
WHERE environment = 'development';

📋 数据类型选择

常用字段类型

用途 推荐类型 说明
主键 SERIAL 整数自增
外键 INTEGER 与主键类型一致
短文本 VARCHAR(N) N<500如姓名、标题
长文本 TEXT 无长度限制,如描述、内容
布尔值 BOOLEAN true/false
日期时间 TIMESTAMP 精确到毫秒
金额 DECIMAL(10,2) 避免精度问题
JSON JSONB 支持索引,性能更好

字段长度建议

-- 短文本
name VARCHAR(100)           -- 姓名
title VARCHAR(200)          -- 标题
email VARCHAR(255)          -- 邮箱
phone VARCHAR(20)           -- 手机号

-- 状态枚举
status VARCHAR(20)          -- active, inactive, deleted
role VARCHAR(20)            -- user, admin

-- 长文本
description TEXT            -- 描述
content TEXT               -- 内容

检查清单

设计新表时必须检查:

  • 表名符合命名规范(小写+下划线+复数)
  • 使用正确的Schemaplatform/aia/asl/pkb等
  • 包含id主键SERIAL PRIMARY KEY
  • 包含created_at和updated_at时间戳
  • 用户关联表包含user_id外键
  • 所有外键都有ON DELETE策略
  • 所有外键都添加了索引
  • 常用查询字段添加了索引
  • 外键约束符合跨Schema依赖规则
  • 敏感字段已加密存储

🔗 相关文档

总览:

模板:

各模块设计:


最后更新: 2025-11-06
维护人: 技术架构师
版本: v2.0