# 数据库设计规? > **版本?* v2.0 > **最后更新:** 2025-11-06 > **数据库:** PostgreSQL 15+ > **ORM?* Prisma > **适用范围?* 平台?+ 能力?+ 业务模块? --- ## 📋 核心原则 本规范是所有模块数据库设计的基础规范,必须严格遵守? **设计原则?* - ?遵循第三范式?NF? - ?使用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创建 ```sql -- 创建Schema CREATE SCHEMA IF NOT EXISTS platform_schema; CREATE SCHEMA IF NOT EXISTS asl_schema; CREATE SCHEMA IF NOT EXISTS aia_schema; -- ...其他Schema ``` ### 跨Schema依赖规则 ?必须遵守 **允许的依赖:** ```sql -- ?允许:业务模块引用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, ... ); ``` **禁止的依赖:** ```sql -- ?禁止:业务模块之间互相引? 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字符? - 在表中存储其他模块的业务ID(VARCHAR? - 不建立外键关? - 在应用层验证ID的有效? ``` --- ## 📝 命名规范 ### 表命? **规则?* - 小写字母 - 下划线分? - 复数形式 - Schema前缀(查询时使用? **示例?* ```sql -- ?正确 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 (...); -- 使用连字? ``` ### 字段命名 **规则?* - 小写字母 - 下划线分? - 语义清晰 **示例?* ```sql -- ?正确 user_id created_at project_name is_active -- ?错误 userId -- 驼峰 createdat -- 没有下划? prjName -- 缩写不清? ``` ### 索引命名 **规则?* `idx_表名_字段名` **示例?* ```sql -- ?正确 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_表名_关联表名` **示例?* ```sql -- ?正确 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 ... -- 太长 ``` --- ## 📊 通用字段 ?必须包含 ### 所有表必须包含 ```sql CREATE TABLE xxx_schema.table_name ( -- 主键(必须) id SERIAL PRIMARY KEY, -- 业务字段 ... -- 时间戳(必须? created_at TIMESTAMP DEFAULT NOW() NOT NULL, updated_at TIMESTAMP DEFAULT NOW() NOT NULL ); ``` ### 重要表应包含(软删除? ```sql 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; ``` ### 用户关联表必须包? ```sql 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. 主键** ```sql -- 自动创建,无需手动添加 id SERIAL PRIMARY KEY ``` **2. 外键字段** ```sql -- 必须添加,提高JOIN性能 CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id); ``` **3. 常用查询字段** ```sql -- 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. 唯一约束字段** ```sql -- email等唯一字段 CREATE UNIQUE INDEX idx_users_email ON platform_schema.users(email); ``` ### 复合索引 **规则?* - 高频组合查询使用复合索引 - 最常查询的字段放在前面 - 复合索引最?个字? **示例?* ```sql -- ?正确: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策略 **规则?* ```sql -- 用户删除时,级联删除关联数据 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; -- 有子记录时禁止删? ``` ### 外键索引 **规则?* 所有外键必须添加索? ```sql -- 创建外键 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万记? ```sql -- 按月分区(如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'); ``` ### 数据归档策略 ```sql -- 历史数据归档(如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'; ``` --- ## 🔒 安全规范 ### 敏感字段加密 ```sql -- 密码字段 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) -- 身份证号加密 ``` ### 数据脱敏 ```sql -- 日志中不记录敏感字段 -- 开?测试环境使用脱敏数据 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 | 支持索引,性能更好 | ### 字段长度建议 ```sql -- 短文? 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 -- 内容 ``` --- ## ?检查清? **设计新表时必须检查:** - [ ] 表名符合命名规范(小?下划?复数? - [ ] 使用正确的Schema(platform/aia/asl/pkb等) - [ ] 包含id主键(SERIAL PRIMARY KEY? - [ ] 包含created_at和updated_at时间? - [ ] 用户关联表包含user_id外键 - [ ] 所有外键都有ON DELETE策略 - [ ] 所有外键都添加了索? - [ ] 常用查询字段添加了索? - [ ] 外键约束符合跨Schema依赖规则 - [ ] 敏感字段已加密存? --- ## 🔗 相关文档 **总览?* - [数据库全局视图](./03-数据库全局视图.md) ?查看所有Schema和表 **模板?* - [数据库设计模板](../_templates/数据库设?模板.md) **各模块设计:** - [平台基础层](../01-平台基础?README.md) - [通用能力层](../02-通用能力?README.md) - [业务模块层](../03-业务模块/README.md) --- **最后更新:** 2025-11-06 **维护人:** 技术架构师 **版本?* v2.0