Files
rui-docs/standards/数据库设计规范分析.md
vifo a7f3ee3565 refactor: 全局替换 spring-ai -> rui-framework
同步仓库名称变更,涉及 16 个文件 66 处引用:
- ai-skills: 菜单配置
- backend/guides: AI操作手册、环境配置、部署、gitnexus、opencode 工作流
- backend: 模块创建规则、通信规范、协作工作流、实施规范
- frontend: 收银设计、管理后台实施计划
- standards: 数据库设计规范
2026-06-08 12:56:39 +08:00

42 KiB
Raw Permalink Blame History

数据库设计规范分析报告

基于对当前 rui-framework 项目数据库设计的全面审查,本报告列出所有不合理之处及专业改进方案。 注意:本报告仅做分析,不做任何代码实施。


一、当前表清单(12张表)

序号 SQL 表名 实体类 服务模块 状态
1 rui_system_oauth2_client SystemOAuth2Client system 实体与SQL不一致
2 rui_system_tenant SystemTenant system 实体与SQL不一致
3 rui_user_credential UserCredential user 实体与SQL不一致
4 rui_user_info UserInfo user 一致
5 rui_user_level UserLevel user 一致
6 rui_user_level_log UserLevelLog user 一致
7 rui_user_role 无实体类 user 缺失实体
8 rui_system_menu 无实体类 system 缺失实体
9 rui_system_role 无实体类 system 缺失实体
10 rui_system_role_menu 无实体类 system 缺失实体
11 rui_system_dict 无实体类 system 缺失实体
12 rui_system_config 无实体类 system 缺失实体

二、严重问题(必须修改)

2.1 【致命】实体类表名与 SQL 表名严重不一致

问题描述

SQL 表名:              rui_system_oauth2_client
实体 @TableName:       auth_oauth2_client
keepGlobalPrefix=true  → 实际查找表: rui_auth_oauth2_client
结果:                   ❌ 找不到表!

SQL 表名:              rui_system_tenant
实体 @TableName:       auth_tenant
keepGlobalPrefix=true  → 实际查找表: rui_auth_tenant
结果:                   ❌ 找不到表!

SQL 表名:              rui_user_credential
实体 @TableName:       auth_user
keepGlobalPrefix=true  → 实际查找表: rui_auth_user
结果:                   ❌ 找不到表!

影响

  • 程序运行时无法找到正确的表,导致查询失败
  • 表前缀 rui_ 与模块前缀 system_/user_ 混合使用,逻辑混乱

专业方案

方案A:统一表前缀(推荐)
- 全局表前缀: rui_
- SQL表名: rui_oauth2_client / rui_tenant / rui_user
- 实体 @TableName: oauth2_client / tenant / user
- keepGlobalPrefix=true → rui_ + value = 正确

方案B:分模块前缀
- SQL表名保持: rui_system_oauth2_client / rui_user_credential
- 实体 @TableName: system_oauth2_client / user_credential
- keepGlobalPrefix=true → rui_ + value = 正确

方案C:去掉 keepGlobalPrefix,显式写全表名
- 实体 @TableName: rui_system_oauth2_client(不推荐,硬编码前缀)

推荐采用方案A,理由:

  1. 表前缀仅用于标识项目/公司(rui_),不包含模块信息
  2. 模块信息体现在表名本身(oauth2_client 在 system 服务下)
  3. 与全局配置 mybatis-plus.global-config.db-config.table-prefix: rui_ 一致
  4. 租户过滤时 normalizeTableName 剥离 rui_ 后得到正确表名

2.2 【严重】缺少 6 个实体类

问题描述:以下表在 SQL 中已定义,但没有对应的 Java 实体类

表名 用途 影响
rui_user_role 用户角色关联 无法通过 MyBatis Plus 操作
rui_system_menu 菜单管理 无法通过 MyBatis Plus 操作
rui_system_role 角色管理 无法通过 MyBatis Plus 操作
rui_system_role_menu 角色菜单关联 无法通过 MyBatis Plus 操作
rui_system_dict 数据字典 无法通过 MyBatis Plus 操作
rui_system_config 系统配置 无法通过 MyBatis Plus 操作

专业方案

  • 为每张表创建对应的 Entity、Mapper、Service、Controller
  • 或者至少创建 Entity + Mapper 用于基础 CRUD

2.3 【严重】主键策略不统一

问题描述

UserCredential:    @TableId(type = IdType.ASSIGN_ID)  // 雪花算法
其他所有实体:       @TableId(type = IdType.AUTO)       // 数据库自增

SQL 中的问题

-- 有 AUTO_INCREMENT
rui_system_tenant: id BIGINT NOT NULL AUTO_INCREMENT

-- 没有 AUTO_INCREMENT
rui_user_credential: id BIGINT NOT NULL  -- ❌ 缺少 AUTO_INCREMENT
rui_user_info: id BIGINT NOT NULL        -- ❌ 缺少 AUTO_INCREMENT
rui_user_level: id BIGINT NOT NULL       -- ❌ 缺少 AUTO_INCREMENT

专业方案

推荐方案:统一使用 ASSIGN_ID(雪花算法)
理由:
1. 分布式环境下自增ID存在冲突风险
2. 雪花算法ID有序且唯一,适合分库分表
3. 无需依赖数据库 AUTO_INCREMENT
4. 支持批量插入时提前知道ID

SQL调整:
- 去掉所有 AUTO_INCREMENT
- id BIGINT NOT NULL 即可
- Java实体统一使用 @TableId(type = IdType.ASSIGN_ID)

2.4 【严重】BaseEntity 设计缺陷

当前设计

@Data
public class BaseEntity implements Serializable {
    private Long id;                          // ❌ 缺少 @TableId
    private LocalDateTime createdAt;          // ❌ 与 SQL created_at 映射
    private LocalDateTime updatedAt;          // ❌ 与 SQL updated_at 映射
    private Integer deleted;                  // ❌ 缺少 @TableLogic
    private Long tenantId;                    // ❌ 缺少默认值
}

问题分析

  1. 缺少 @TableId:子类必须重复定义 id + @TableId,违反 DRY 原则
  2. 缺少 @TableLogic:子类需要手动添加,容易遗漏
  3. 缺少 @TableField(fill = FieldFill.INSERT/UPDATE):无法自动填充
  4. tenantId 无默认值SQL 中 DEFAULT 0,但 Java 中为 null,插入时可能报错
  5. deleted 为 IntegerMyBatis Plus 的 @TableLogic 推荐配合 Integer,但需要确认数据库 TINYINT 兼容性

专业方案

@Data
public class BaseEntity implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createdAt;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;

    @TableLogic
    @TableField(fill = FieldFill.INSERT)
    private Integer deleted;

    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}

SQL 默认值调整

-- 统一默认值
`deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除 0:正常 1:删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户ID 0:系统',

三、表结构设计问题

3.1 数据字典表设计不合理

当前设计(单表)

CREATE TABLE rui_system_dict (
    id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    dict_code VARCHAR(100) NOT NULL,      -- 字典编码(如:gender, status
    dict_value VARCHAR(200) NOT NULL,     -- 字典值(如:0, 1
    label VARCHAR(200) NOT NULL,          -- 标签(如:男, 女)
    sort_order INT DEFAULT 0,
    status TINYINT DEFAULT 1,
    deleted TINYINT DEFAULT 0,
    ...
)

问题

  1. 单表存储所有字典项,数据冗余大
  2. 无法扩展字典属性(如颜色、图标、备注等)
  3. 无法支持树形字典(如地区、部门层级)
  4. 字典编码 dict_code 无索引,查询效率低
  5. 缺少 dict_type(字典类型)表,无法分组管理

专业方案(两表设计)

-- 字典类型表
CREATE TABLE rui_dict_type (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    dict_code VARCHAR(100) NOT NULL COMMENT '字典编码(唯一标识)',
    dict_name VARCHAR(200) NOT NULL COMMENT '字典名称',
    description VARCHAR(500) DEFAULT NULL COMMENT '描述',
    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:禁用 1:启用',
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_dict_code (dict_code),
    INDEX idx_tenant (tenant_id)
) COMMENT='字典类型';

-- 字典项表
CREATE TABLE rui_dict_item (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    dict_type_id BIGINT NOT NULL COMMENT '字典类型ID',
    item_code VARCHAR(100) NOT NULL COMMENT '项编码',
    item_label VARCHAR(200) NOT NULL COMMENT '项标签',
    item_value VARCHAR(200) NOT NULL COMMENT '项值',
    sort_order INT NOT NULL DEFAULT 0 COMMENT '排序',
    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_dict_type (dict_type_id),
    INDEX idx_tenant (tenant_id),
    UNIQUE KEY uk_dict_type_code (dict_type_id, item_code)
) COMMENT='字典项';

3.2 系统配置表缺少作用域和加密支持

当前设计

CREATE TABLE rui_system_config (
    id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    config_key VARCHAR(200) NOT NULL,
    config_value TEXT NOT NULL,
    description VARCHAR(500) DEFAULT NULL,
    deleted TINYINT DEFAULT 0,
    ...
)

问题

  1. 缺少 config_type 字段,无法区分 STRING/JSON/NUMBER/BOOLEAN/ENCRYPTED
  2. 缺少 is_system 字段,无法区分系统级配置和租户级配置
  3. 缺少 is_encrypted 字段,敏感配置(如密钥)无法加密存储
  4. config_value 用 TEXT 不合理,大部分配置值很短
  5. 缺少 sort_order,无法对配置项排序展示
  6. 缺少 group_code,无法分组管理(如:oss, sms, email

专业方案

CREATE TABLE rui_config (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    config_group VARCHAR(100) NOT NULL DEFAULT 'default' COMMENT '配置分组(oss/sms/email',
    config_key VARCHAR(200) NOT NULL COMMENT '配置键',
    config_value VARCHAR(2000) NOT NULL COMMENT '配置值',
    config_type VARCHAR(20) NOT NULL DEFAULT 'STRING' COMMENT '值类型 STRING/JSON/NUMBER/BOOLEAN/ENCRYPTED',
    is_system TINYINT NOT NULL DEFAULT 0 COMMENT '是否系统级 0:租户 1:系统',
    is_encrypted TINYINT NOT NULL DEFAULT 0 COMMENT '是否加密 0:明文 1:密文',
    description VARCHAR(500) DEFAULT NULL,
    sort_order INT NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_config_key (tenant_id, config_key),
    INDEX idx_group (config_group),
    INDEX idx_tenant (tenant_id)
) COMMENT='系统配置';

3.3 用户凭证表与用户详情表分离但字段重复

当前设计

-- 凭证表
rui_user_credential: id, username, password, nickname, email, phone, avatar, status

-- 详情表
rui_user_info: id, username, nickname, real_name, email, phone, avatar, gender, birthday, status

问题

  1. username/nickname/email/phone/avatar/status 在两张表中重复
  2. 数据一致性难以保证(更新时容易遗漏)
  3. 违背了数据库设计第三范式(3NF

专业方案(合并为单表 + 扩展表)

-- 用户主表(核心字段,登录、认证用)
CREATE TABLE rui_user (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    username VARCHAR(100) NOT NULL COMMENT '用户名',
    password VARCHAR(255) NOT NULL COMMENT '密码(BCrypt加密)',
    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:禁用 1:启用',
    user_type TINYINT NOT NULL DEFAULT 1 COMMENT '用户类型 1:普通用户 2:管理员 3:系统用户',
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_username (tenant_id, username),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户';

-- 用户详情表(扩展字段,不经常变更)
CREATE TABLE rui_user_detail (
    id BIGINT NOT NULL,
    user_id BIGINT NOT NULL COMMENT '用户ID',
    tenant_id BIGINT NOT NULL DEFAULT 0,
    nickname VARCHAR(100) DEFAULT NULL COMMENT '昵称',
    real_name VARCHAR(100) DEFAULT NULL COMMENT '真实姓名',
    email VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
    phone VARCHAR(20) DEFAULT NULL COMMENT '手机号',
    avatar VARCHAR(500) DEFAULT NULL COMMENT '头像URL',
    gender TINYINT DEFAULT 0 COMMENT '性别 0:未知 1:男 2:女',
    birthday DATE DEFAULT NULL,
    id_card VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
    address VARCHAR(500) DEFAULT NULL COMMENT '地址',
    remark VARCHAR(500) DEFAULT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_user_id (user_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户详情';

或者(方案B:保留单表,使用 JSON 扩展字段)

CREATE TABLE rui_user (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    username VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    nickname VARCHAR(100) DEFAULT NULL,
    real_name VARCHAR(100) DEFAULT NULL,
    email VARCHAR(100) DEFAULT NULL,
    phone VARCHAR(20) DEFAULT NULL,
    avatar VARCHAR(500) DEFAULT NULL,
    gender TINYINT DEFAULT 0,
    birthday DATE DEFAULT NULL,
    extra JSON DEFAULT NULL COMMENT '扩展字段(JSON格式)',
    status TINYINT NOT NULL DEFAULT 1,
    user_type TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_username (tenant_id, username),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户';

推荐方案A,理由:

  1. 用户主表(rui_user)只保留认证相关字段,查询高效
  2. 详情表(rui_user_detail)按需加载,减少不必要的 JOIN
  3. 符合微服务设计理念:认证服务和用户信息服务可以分离
  4. 支持用户详情的多租户隔离(如不同租户有不同的详情字段)

3.4 菜单表缺少关键字段

当前设计

CREATE TABLE rui_system_menu (
    id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    parent_id BIGINT DEFAULT 0,
    name VARCHAR(100) NOT NULL,
    permission VARCHAR(200) DEFAULT NULL,
    path VARCHAR(200) DEFAULT NULL,
    component VARCHAR(200) DEFAULT NULL,
    icon VARCHAR(100) DEFAULT NULL,
    sort_order INT DEFAULT 0,
    type TINYINT DEFAULT 0 COMMENT '0:目录 1:菜单 2:按钮',
    visible TINYINT DEFAULT 1,
    status TINYINT DEFAULT 1,
    deleted TINYINT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_tenant (tenant_id),
    INDEX idx_parent (parent_id)
)

问题

  1. 缺少 code 字段,菜单编码是权限控制的关键标识
  2. 缺少 target 字段(_self/_blank),无法控制外链打开方式
  3. 缺少 keep_alive 字段,无法控制页面缓存
  4. 缺少 is_external 字段,无法区分内部路由和外部链接
  5. 缺少 description 字段,菜单说明
  6. permission 字段使用 VARCHAR(200),权限标识可能更长
  7. 缺少 levelancestors 字段,树形查询效率低
  8. sort_order 应改为 sort_nosort,更简洁

专业方案

CREATE TABLE rui_menu (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    parent_id BIGINT NOT NULL DEFAULT 0 COMMENT '父菜单ID 0:顶级',
    ancestors VARCHAR(500) DEFAULT '' COMMENT '祖级ID列表 如: 0,1,5,',
    menu_code VARCHAR(100) NOT NULL COMMENT '菜单编码(唯一标识)',
    menu_name VARCHAR(100) NOT NULL COMMENT '菜单名称',
    menu_type TINYINT NOT NULL DEFAULT 1 COMMENT '类型 1:目录 2:菜单 3:按钮',
    icon VARCHAR(100) DEFAULT NULL COMMENT '图标',
    path VARCHAR(200) DEFAULT NULL COMMENT '路由路径',
    component VARCHAR(200) DEFAULT NULL COMMENT '组件路径',
    permission VARCHAR(200) DEFAULT NULL COMMENT '权限标识 如: user:list',
    is_external TINYINT NOT NULL DEFAULT 0 COMMENT '是否外链 0:否 1:是',
    target VARCHAR(20) DEFAULT '_self' COMMENT '打开方式 _self/_blank',
    keep_alive TINYINT NOT NULL DEFAULT 0 COMMENT '是否缓存 0:否 1:是',
    visible TINYINT NOT NULL DEFAULT 1 COMMENT '是否显示 0:隐藏 1:显示',
    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:禁用 1:启用',
    sort_no INT NOT NULL DEFAULT 0 COMMENT '排序号',
    remark VARCHAR(500) DEFAULT NULL,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_menu_code (tenant_id, menu_code),
    INDEX idx_parent (parent_id),
    INDEX idx_ancestors (ancestors(100)),
    INDEX idx_tenant (tenant_id)
) COMMENT='菜单';

3.5 角色表设计不完善

当前设计

CREATE TABLE rui_system_role (
    id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    parent_id BIGINT DEFAULT 0 COMMENT '上级角色',
    name VARCHAR(100) NOT NULL,
    code VARCHAR(100) NOT NULL,
    description VARCHAR(500) DEFAULT NULL,
    status TINYINT DEFAULT 1,
    deleted TINYINT DEFAULT 0,
    ...
)

问题

  1. 缺少 role_type 字段(系统角色/租户角色/自定义角色)
  2. 缺少 data_scope 字段(数据权限范围:全部/本部门/本部门及子部门/仅本人/自定义)
  3. parent_id 实现角色层级,但没有 ancestors 字段,查询效率低
  4. 缺少 sort_no 字段,无法排序
  5. code 字段应加租户级唯一索引

专业方案

CREATE TABLE rui_role (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    parent_id BIGINT NOT NULL DEFAULT 0,
    ancestors VARCHAR(500) DEFAULT '' COMMENT '祖级ID列表',
    role_code VARCHAR(100) NOT NULL COMMENT '角色编码',
    role_name VARCHAR(100) NOT NULL COMMENT '角色名称',
    role_type TINYINT NOT NULL DEFAULT 1 COMMENT '类型 1:系统角色 2:租户角色 3:自定义',
    data_scope TINYINT NOT NULL DEFAULT 1 COMMENT '数据范围 1:全部 2:本部门 3:本部门及子部门 4:仅本人 5:自定义',
    description VARCHAR(500) DEFAULT NULL,
    sort_no INT NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_role_code (tenant_id, role_code),
    INDEX idx_parent (parent_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='角色';

3.6 关联表设计不规范

当前设计

-- 用户角色关联
CREATE TABLE rui_user_role (
    user_id BIGINT NOT NULL,
    role_id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    PRIMARY KEY (user_id, role_id),
    INDEX idx_tenant (tenant_id)
);

-- 角色菜单关联
CREATE TABLE rui_system_role_menu (
    role_id BIGINT NOT NULL,
    menu_id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    PRIMARY KEY (role_id, menu_id),
    INDEX idx_tenant (tenant_id)
);

问题

  1. 没有自增 ID,不利于后续扩展(如增加有效期、创建人等字段)
  2. 缺少 created_at 字段,无法追踪关联建立时间
  3. 缺少单独的索引用于反向查询(如根据 role_id 查所有 user
  4. 表名应统一为 rui_user_rolerui_role_menu(去掉 system 模块前缀)

专业方案

-- 用户角色关联
CREATE TABLE rui_user_role (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT NOT NULL,
    role_id BIGINT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_user_role (tenant_id, user_id, role_id),
    INDEX idx_user (user_id),
    INDEX idx_role (role_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户角色关联';

-- 角色菜单关联
CREATE TABLE rui_role_menu (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    role_id BIGINT NOT NULL,
    menu_id BIGINT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_role_menu (tenant_id, role_id, menu_id),
    INDEX idx_role (role_id),
    INDEX idx_menu (menu_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='角色菜单关联';

3.7 等级表缺少业务关联

当前设计

CREATE TABLE rui_user_level (
    id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    name VARCHAR(100) NOT NULL,
    code VARCHAR(100) NOT NULL,
    min_score INT DEFAULT 0,
    max_score INT DEFAULT 0,
    icon VARCHAR(500) DEFAULT NULL,
    benefits JSON DEFAULT NULL,
    status TINYINT DEFAULT 1,
    deleted TINYINT DEFAULT 0,
    ...
)

问题

  1. min_score/max_score 设计不合理,等级晋升应该是累计积分达到阈值
  2. 缺少 level 字段(数字等级,如 1, 2, 3...),用于快速比较等级高低
  3. benefits 用 JSON 是好的,但缺少 benefits_type 字段说明权益类型
  4. 缺少 upgrade_type 字段(自动升级/手动审核)
  5. 缺少 expire_days 字段,等级有效期

专业方案

CREATE TABLE rui_user_level (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    level_code VARCHAR(100) NOT NULL COMMENT '等级编码',
    level_name VARCHAR(100) NOT NULL COMMENT '等级名称',
    level_no INT NOT NULL DEFAULT 1 COMMENT '等级序号(数字越大等级越高)',
    min_score INT NOT NULL DEFAULT 0 COMMENT '最低积分要求',
    icon VARCHAR(500) DEFAULT NULL COMMENT '等级图标',
    benefits JSON DEFAULT NULL COMMENT '权益配置(JSON',
    upgrade_type TINYINT NOT NULL DEFAULT 1 COMMENT '升级方式 1:自动 2:手动审核',
    expire_days INT DEFAULT 0 COMMENT '有效期(天) 0:永久',
    status TINYINT NOT NULL DEFAULT 1,
    sort_no INT NOT NULL DEFAULT 0,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_level_code (tenant_id, level_code),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户等级';

3.8 等级日志表设计不足

当前设计

CREATE TABLE rui_user_level_log (
    id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    from_level_id BIGINT DEFAULT NULL,
    to_level_id BIGINT NOT NULL,
    reason VARCHAR(500) DEFAULT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    ...
)

问题

  1. 缺少 change_type 字段(升级/降级/手动调整/过期)
  2. 缺少 operator_id 字段,无法追踪操作人
  3. 缺少 operator_type 字段(系统/管理员/用户)
  4. from_level_id 为 NULL 时无法表达"初始等级"
  5. 缺少 score_change 字段,记录积分变化

专业方案

CREATE TABLE rui_user_level_log (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT NOT NULL COMMENT '用户ID',
    change_type TINYINT NOT NULL DEFAULT 1 COMMENT '变更类型 1:升级 2:降级 3:手动调整 4:过期',
    from_level_id BIGINT DEFAULT NULL COMMENT '原等级ID NULL:初始',
    to_level_id BIGINT NOT NULL COMMENT '新等级ID',
    score_before INT DEFAULT NULL COMMENT '变更前积分',
    score_after INT DEFAULT NULL COMMENT '变更后积分',
    reason VARCHAR(500) DEFAULT NULL COMMENT '变更原因',
    operator_id BIGINT DEFAULT NULL COMMENT '操作人ID',
    operator_type TINYINT NOT NULL DEFAULT 1 COMMENT '操作人类型 1:系统 2:管理员 3:用户',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_user (user_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='用户等级变更记录';

3.9 OAuth2 客户端表字段过长且缺少索引

当前设计

CREATE TABLE rui_system_oauth2_client (
    id VARCHAR(100) NOT NULL,
    tenant_id BIGINT DEFAULT 0,
    client_id VARCHAR(100) NOT NULL,
    client_id_issued_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
    client_secret VARCHAR(200) DEFAULT NULL,
    client_secret_expires_at TIMESTAMP DEFAULT NULL,
    client_name VARCHAR(200) NOT NULL,
    client_authentication_methods VARCHAR(1000) NOT NULL,  -- ❌ 过长
    authorization_grant_types VARCHAR(1000) NOT NULL,      -- ❌ 过长
    redirect_uris VARCHAR(1000) DEFAULT NULL,              -- ❌ 过长
    post_logout_redirect_uris VARCHAR(1000) DEFAULT NULL,  -- ❌ 过长
    scopes VARCHAR(1000) NOT NULL,                         -- ❌ 过长
    client_settings VARCHAR(2000) NOT NULL,                -- ❌ 过长
    token_settings VARCHAR(2000) NOT NULL,                 -- ❌ 过长
    PRIMARY KEY (id),
    INDEX idx_tenant (tenant_id)
)

问题

  1. 多个 VARCHAR(1000/2000) 字段不合理,应使用 TEXT
  2. 缺少 client_id 的唯一索引
  3. id 使用 VARCHAR(100),不如使用 BIGINT + ASSIGN_ID
  4. 缺少 status 字段,无法禁用客户端
  5. 缺少 description 字段
  6. 时间字段使用 TIMESTAMP,不如使用 DATETIME

专业方案

CREATE TABLE rui_oauth2_client (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    client_id VARCHAR(100) NOT NULL COMMENT '客户端ID',
    client_secret VARCHAR(255) DEFAULT NULL COMMENT '客户端密钥',
    client_name VARCHAR(200) NOT NULL COMMENT '客户端名称',
    client_type TINYINT NOT NULL DEFAULT 1 COMMENT '客户端类型 1:Web 2:App 3:小程序',
    logo_url VARCHAR(500) DEFAULT NULL COMMENT 'Logo',
    description VARCHAR(500) DEFAULT NULL,
    authentication_methods VARCHAR(500) NOT NULL COMMENT '认证方式',
    grant_types VARCHAR(500) NOT NULL COMMENT '授权类型',
    redirect_uris TEXT DEFAULT NULL COMMENT '回调地址(逗号分隔)',
    scopes VARCHAR(500) NOT NULL COMMENT '授权范围',
    access_token_ttl INT NOT NULL DEFAULT 7200 COMMENT '访问令牌有效期(秒)',
    refresh_token_ttl INT NOT NULL DEFAULT 604800 COMMENT '刷新令牌有效期(秒)',
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_client_id (tenant_id, client_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='OAuth2客户端';

说明

  • client_settingstoken_settings 不建议用 JSON/VARCHAR 存储,应在代码中配置模板
  • redirect_uris 使用 TEXT,因为可能有多个URL
  • client_id_issued_at/client_secret_expires_at 去掉,实际业务中很少用到
  • post_logout_redirect_uris 去掉,OAuth2 退出回调通常不需要配置

3.10 租户表缺少关键字段

当前设计

CREATE TABLE rui_system_tenant (
    id BIGINT NOT NULL AUTO_INCREMENT,
    tenant_code VARCHAR(50) NOT NULL COMMENT '租户编码',
    tenant_name VARCHAR(200) NOT NULL COMMENT '租户名称',
    contact_name VARCHAR(100) DEFAULT NULL,
    contact_phone VARCHAR(20) DEFAULT NULL,
    contact_email VARCHAR(100) DEFAULT NULL,
    domain VARCHAR(200) DEFAULT NULL,
    status TINYINT DEFAULT 1,
    deleted TINYINT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_tenant_code (tenant_code)
)

问题

  1. 缺少 tenant_type 字段(企业/个人/试用)
  2. 缺少 expire_time 字段,租户有效期
  3. 缺少 max_user_count 字段,最大用户数限制
  4. 缺少 logo 字段,租户 Logo
  5. 缺少 package_id 字段,关联套餐/版本
  6. domain 应支持多个域名(用逗号分隔或单独表)
  7. 缺少 super_admin_id 字段,记录租户创建人/超管

专业方案

CREATE TABLE rui_tenant (
    id BIGINT NOT NULL,
    tenant_code VARCHAR(50) NOT NULL COMMENT '租户编码',
    tenant_name VARCHAR(200) NOT NULL COMMENT '租户名称',
    tenant_type TINYINT NOT NULL DEFAULT 1 COMMENT '类型 1:企业 2:个人 3:试用',
    tenant_level TINYINT NOT NULL DEFAULT 1 COMMENT '等级 1:基础版 2:专业版 3:旗舰版',
    logo_url VARCHAR(500) DEFAULT NULL COMMENT 'Logo',
    contact_name VARCHAR(100) DEFAULT NULL,
    contact_phone VARCHAR(20) DEFAULT NULL,
    contact_email VARCHAR(100) DEFAULT NULL,
    domains VARCHAR(500) DEFAULT NULL COMMENT '绑定域名(逗号分隔)',
    max_user_count INT NOT NULL DEFAULT 100 COMMENT '最大用户数',
    expire_time DATETIME DEFAULT NULL COMMENT '过期时间 NULL:永久',
    super_admin_id BIGINT DEFAULT NULL COMMENT '超管用户ID',
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_tenant_code (tenant_code),
    INDEX idx_status (status)
) COMMENT='租户';

四、缺少的关键表

4.1 操作日志表

必要性:审计、追踪、安全

CREATE TABLE rui_oper_log (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    oper_type TINYINT NOT NULL DEFAULT 1 COMMENT '操作类型 1:新增 2:修改 3:删除 4:查询 5:导出 6:登录 7:登出',
    title VARCHAR(200) NOT NULL COMMENT '操作模块',
    method VARCHAR(500) DEFAULT NULL COMMENT '请求方法',
    request_url VARCHAR(500) DEFAULT NULL COMMENT '请求URL',
    request_method VARCHAR(10) DEFAULT NULL COMMENT '请求方式 GET/POST/PUT/DELETE',
    request_params TEXT DEFAULT NULL COMMENT '请求参数',
    response_data TEXT DEFAULT NULL COMMENT '响应数据',
    user_id BIGINT DEFAULT NULL COMMENT '操作用户ID',
    user_name VARCHAR(100) DEFAULT NULL COMMENT '操作用户名',
    oper_ip VARCHAR(128) DEFAULT NULL COMMENT '操作IP',
    oper_location VARCHAR(255) DEFAULT NULL COMMENT '操作地点',
    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
    error_msg TEXT DEFAULT NULL COMMENT '错误消息',
    cost_time BIGINT DEFAULT 0 COMMENT '耗时(ms)',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_user (user_id),
    INDEX idx_tenant (tenant_id),
    INDEX idx_created (created_at)
) COMMENT='操作日志';

4.2 登录日志表

必要性:安全审计、异常登录检测

CREATE TABLE rui_login_log (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT DEFAULT NULL,
    username VARCHAR(100) DEFAULT NULL,
    login_type TINYINT NOT NULL DEFAULT 1 COMMENT '登录类型 1:密码 2:短信 3:微信 4:支付宝',
    client_id VARCHAR(100) DEFAULT NULL COMMENT '客户端ID',
    ip VARCHAR(128) DEFAULT NULL,
    location VARCHAR(255) DEFAULT NULL,
    browser VARCHAR(200) DEFAULT NULL,
    os VARCHAR(200) DEFAULT NULL,
    status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
    msg VARCHAR(500) DEFAULT NULL COMMENT '消息',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_user (user_id),
    INDEX idx_tenant (tenant_id),
    INDEX idx_created (created_at)
) COMMENT='登录日志';

4.3 部门/组织表

必要性:组织架构、数据权限

CREATE TABLE rui_dept (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    parent_id BIGINT NOT NULL DEFAULT 0,
    ancestors VARCHAR(500) DEFAULT '' COMMENT '祖级ID列表',
    dept_code VARCHAR(100) NOT NULL COMMENT '部门编码',
    dept_name VARCHAR(100) NOT NULL COMMENT '部门名称',
    leader_id BIGINT DEFAULT NULL COMMENT '负责人ID',
    phone VARCHAR(20) DEFAULT NULL,
    email VARCHAR(100) DEFAULT NULL,
    sort_no INT NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_dept_code (tenant_id, dept_code),
    INDEX idx_parent (parent_id),
    INDEX idx_tenant (tenant_id)
) COMMENT='部门';

-- 用户部门关联表
CREATE TABLE rui_user_dept (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT NOT NULL,
    dept_id BIGINT NOT NULL,
    is_main TINYINT NOT NULL DEFAULT 1 COMMENT '是否主部门 0:否 1:是',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_user_dept (tenant_id, user_id, dept_id),
    INDEX idx_user (user_id),
    INDEX idx_dept (dept_id)
) COMMENT='用户部门关联';

4.4 岗位表

必要性:职位体系、审批流

CREATE TABLE rui_post (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    post_code VARCHAR(100) NOT NULL COMMENT '岗位编码',
    post_name VARCHAR(100) NOT NULL COMMENT '岗位名称',
    sort_no INT NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    deleted TINYINT NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_post_code (tenant_id, post_code),
    INDEX idx_tenant (tenant_id)
) COMMENT='岗位';

-- 用户岗位关联表
CREATE TABLE rui_user_post (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT NOT NULL,
    post_id BIGINT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_user_post (tenant_id, user_id, post_id),
    INDEX idx_user (user_id)
) COMMENT='用户岗位关联';

4.5 用户权限直接关联表(可选)

必要性:支持用户直接拥有权限(不通过角色)

CREATE TABLE rui_user_permission (
    id BIGINT NOT NULL,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    user_id BIGINT NOT NULL,
    permission VARCHAR(200) NOT NULL COMMENT '权限标识',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_user_permission (tenant_id, user_id, permission),
    INDEX idx_user (user_id)
) COMMENT='用户权限关联(直接授权)';

五、索引设计问题

5.1 当前索引缺陷

表名 当前索引 问题
rui_user_credential uk_username 未包含 tenant_id,多租户下会冲突
rui_user_info idx_username 未加唯一约束,用户名可重复
rui_system_role uk_code 未包含 tenant_id,多租户下会冲突
rui_system_config uk_config_key 未包含 tenant_id,多租户下会冲突
rui_user_role PRIMARY (user_id, role_id) 缺少反向索引(根据 role_id 查 user

5.2 索引设计原则

1. 所有唯一索引必须包含 tenant_id(多租户环境)
   错误: UNIQUE KEY uk_code (code)
   正确: UNIQUE KEY uk_code (tenant_id, code)

2. 外键关联表必须建双向索引
   错误: 只有 PRIMARY KEY (user_id, role_id)
   正确: + INDEX idx_role (role_id)

3. 时间字段建索引用于分页查询
   INDEX idx_created (created_at)

4. 状态字段建索引用于筛选
   INDEX idx_status (status)

5. 组合索引遵循最左前缀原则
   正确: INDEX idx_tenant_status (tenant_id, status)
   错误: INDEX idx_status_tenant (status, tenant_id)  -- status 区分度低

六、字段命名规范问题

6.1 当前不一致之处

位置 命名方式 示例
SQL 下划线命名 created_at, updated_at
Java BaseEntity 驼峰命名 createdAt, updatedAt
Java 部分实体 驼峰命名 realName, tenantCode
表名 rui_前缀 + 模块_表名 rui_system_tenant
实体 @TableName 无 rui_前缀 + 不一致前缀 auth_tenant, user_info

6.2 推荐规范

SQL 层:
  - 表名: 小写下划线,项目前缀 + 表名(如: rui_user, rui_menu
  - 字段名: 小写下划线(如: user_name, created_at
  - 索引名: uk_字段名 / idx_字段名

Java 层:
  - 类名: 大驼峰(如: User, Menu
  - 属性名: 小驼峰(如: userName, createdAt
  - @TableName: 不包含前缀(如: "user", "menu"
  - keepGlobalPrefix: true(自动加 rui_ 前缀)

七、时间字段设计

7.1 当前问题

  • 使用 DATETIME 类型(无精度)
  • 无统一命名规范
  • 部分表缺少 updated_at

7.2 专业方案

-- 推荐: DATETIME(3) 支持毫秒精度
-- 或: TIMESTAMP(3) 支持毫秒且自动时区转换

-- 统一时间字段
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',

-- 如果需要删除时间(用于回收站功能)
`deleted_at` DATETIME(3) DEFAULT NULL COMMENT '删除时间',

注意

  • 使用 DATETIME(3) 而非 TIMESTAMP,因为 TIMESTAMP 有 2038 年问题
  • MySQL 5.6.4+ 支持小数秒精度
  • Java 对应 LocalDateTimeJDBC 自动处理精度

八、数据类型规范

8.1 当前问题

字段 当前类型 问题
status TINYINT 合理,但建议 NOT NULL DEFAULT 1
deleted TINYINT 合理,但建议 NOT NULL DEFAULT 0
tenant_id BIGINT DEFAULT 0 建议 NOT NULL DEFAULT 0
avatar VARCHAR(500) URL 长度可能不够,建议 VARCHAR(1000)
password VARCHAR(500) BCrypt 密码固定 60 字符,VARCHAR(255) 足够
id BIGINT NOT NULL 建议统一,部分表缺少 AUTO_INCREMENT 或主键策略
JSON 字段 JSON 使用正确,但需确认 MySQL 版本支持

8.2 推荐类型映射

业务类型 MySQL 类型 Java 类型 说明
主键 BIGINT Long 雪花算法生成
状态/枚举 TINYINT NOT NULL DEFAULT x Integer 0:禁用 1:启用
租户ID BIGINT NOT NULL DEFAULT 0 Long 0:系统
字符串(短) VARCHAR(50-200) String 用户名、编码
字符串(中) VARCHAR(500) String 名称、标题
字符串(长) VARCHAR(2000) String 描述、备注
文本 TEXT String 内容、日志
JSON JSON String/Object 配置、扩展字段
金额 DECIMAL(19,4) BigDecimal 精确计算
时间 DATETIME(3) LocalDateTime 毫秒精度
日期 DATE LocalDate 生日、有效期
IP VARCHAR(128) String IPv6 兼容
URL VARCHAR(1000) String 头像、链接

九、总结:核心问题清单

🔴 致命问题(必须修改)

  1. 实体类表名与 SQL 表名不一致SystemOAuth2Client, SystemTenant, UserCredential
  2. BaseEntity 缺少关键注解@TableId, @TableLogic, @TableField
  3. 主键策略不统一ASSIGN_ID vs AUTO
  4. 6 张表缺少实体类user_role, system_menu, system_role, system_role_menu, system_dict, system_config
  5. 关联表缺少自增 IDuser_role, role_menu

🟡 严重问题(建议修改)

  1. 字典表应拆分为 dict_type + dict_item
  2. 用户凭证表与用户详情表字段重复,应合并或拆分
  3. 系统配置表缺少作用域、加密、分组支持
  4. 菜单表缺少 code、target、keep_alive 等关键字段
  5. 角色表缺少 data_scope、role_type 字段
  6. OAuth2 客户端表字段过长,应优化
  7. 租户表缺少 tenant_type、expire_time、max_user_count 字段
  8. 等级表设计不合理(min_score/max_score

🟢 优化问题(可选修改)

  1. 缺少操作日志表、登录日志表
  2. 缺少部门表、岗位表
  3. 索引未包含 tenant_id(多租户冲突)
  4. 时间字段未使用 DATETIME(3) 精度
  5. 字段命名未完全统一

十、推荐的数据库设计规范(新增规则)

## 数据库设计规范

### 命名规范
1. 表名: `rui_` + 业务表名(小写下划线),如: `rui_user`, `rui_menu`
2. 字段名: 小写下划线,如: `user_name`, `created_at`
3. 索引名: `uk_字段名`(唯一), `idx_字段名`(普通)
4. 实体类名: 大驼峰,如: `User`, `Menu`
5. 实体属性: 小驼峰,如: `userName`, `createdAt`
6. @TableName: 不包含 `rui_` 前缀,如: `"user"`, `"menu"`

### 字段规范
1. 每张表必须包含: id, tenant_id, deleted, created_at, updated_at
2. id: BIGINT, 统一使用雪花算法(@TableId(type = IdType.ASSIGN_ID)
3. tenant_id: BIGINT NOT NULL DEFAULT 0, 0 表示系统级
4. deleted: TINYINT NOT NULL DEFAULT 0, 逻辑删除标志
5. created_at: DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
6. updated_at: DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
7. status: TINYINT NOT NULL DEFAULT 1, 0:禁用 1:启用

### 索引规范
1. 主键: 单列 BIGINT,雪花算法生成
2. 唯一索引: 必须包含 tenant_id,如: `UNIQUE KEY uk_code (tenant_id, code)`
3. 外键关联表: 建双向索引(如 user_role 表需 idx_user 和 idx_role
4. 时间字段: 建索引支持分页查询
5. 状态字段: 建索引支持筛选

### 关联表规范
1. 必须包含自增 ID(雪花算法)
2. 必须包含 tenant_id
3. 必须包含 created_at
4. 联合字段建唯一索引: `UNIQUE KEY uk_rel (tenant_id, from_id, to_id)`

### 数据类型规范
1. 状态/枚举: TINYINT NOT NULL DEFAULT x
2. 字符串(短): VARCHAR(50-200)
3. 字符串(中): VARCHAR(500)
4. 字符串(长): VARCHAR(2000)
5. 文本内容: TEXT
6. JSON: JSON 类型(MySQL 5.7+
7. 金额: DECIMAL(19,4)
8. 时间: DATETIME(3)
9. URL: VARCHAR(1000)

### 多租户规范
1. 所有业务表必须包含 tenant_id 字段
2. 系统级表(如字典类型)可不含 tenant_id
3. 租户过滤使用 MyBatis Plus TenantLineInnerInterceptor
4. 系统租户(ID=1)对某些表有特权访问

文档版本: v1.0 分析日期: 2026-05-28 分析范围: init-database.sql + 所有 Entity 实体类 状态: 仅分析,未实施任何修改