cursor-init/prd/M2-基础用户系统-数据库设计.md
expressgy 2518986557 feat(docs): 完成星撰平台M2基础用户系统完整设计文档体系
 新增功能设计文档:
- M2基础用户系统数据库设计(12个核心表,RBAC权限模型)
- M2基础用户系统接口设计(41个API接口,含排序功能)
- 完整的项目需求文档和开发计划

📚 核心文档结构:
- 数据库设计:支持树形结构、软删除、审计日志的完整用户权限体系
- 接口设计:包含认证、用户管理、角色权限、组织架构、字典标签等9大模块
- 排序功能:新增7个排序接口,支持拖拽和批量操作
- 项目规划:从MVP到完整生态的4阶段开发计划

🔧 技术栈确定:
- 后端:Elysia + Bun.js + MySQL + Redis + Elasticsearch
- 前端:Vue.js/React + TypeScript
- 部署:Docker + Docker Compose
- 测试:Vitest + 完整测试规范

📋 设计亮点:
- 无外键约束设计,应用层维护数据完整性
- 树形结构支持(path、level字段优化查询)
- 完整的权限继承机制和权限快照
- 支持root超级管理员和多级角色体系
- 标签系统和智能推荐功能
- 统一的响应格式和错误码规范

🎯 覆盖功能:
- 用户认证与管理(注册、登录、权限控制)
- RBAC角色权限体系(树形角色、权限继承)
- 组织架构管理(多级组织、人员分配)
- 数据字典与标签系统
- 完整的排序和数据导入导出功能

📈 文档规模:
- 数据库设计:38KB,922行
- 接口设计:55KB,3024行
- 总计:约100KB的详细技术文档

🔄 配套更新:
- 更新Elysia后端开发规范
- 完善健康检查控制器
- 统一项目代码规范和注释规范
2025-06-29 03:11:35 +08:00

38 KiB
Raw Blame History

M2 - 基础用户系统 - 数据库设计文档

1. 概述

本文档为星撰个人综合平台的基础用户系统M2阶段提供详细的数据库设计方案。设计遵循以下原则

  • 无外键约束:所有关联关系通过应用层代码维护,提高性能和灵活性
  • 软删除机制:所有业务表支持软删除,保留数据历史
  • 树形结构支持:角色、组织、权限、字典等支持无限层级的树形结构
  • 审计追踪:完整的创建、修改记录
  • 高性能:合理的索引设计,支持大数据量查询
  • 扩展性:预留扩展字段,支持未来功能演进

2. 数据库 ER 图

erDiagram
    %% 用户相关
    sys_users {
        bigint id PK "主键雪花ID"
        varchar(50) username UK "用户名"
        varchar(100) email UK "邮箱"
        varchar(20) mobile "手机号"
        varchar(255) password_hash "密码哈希"
        varchar(255) avatar "头像URL"
        varchar(100) nickname "昵称"
        varchar(20) status "状态:字典[user_status]"
        tinyint gender "性别0未知,1男,2女"
        date birthday "生日"
        varchar(500) bio "个人简介"
        int login_count "登录次数"
        datetime last_login_at "最后登录时间"
        varchar(45) last_login_ip "最后登录IP"
        int failed_attempts "失败尝试次数"
        datetime locked_until "锁定截止时间"
        boolean is_root "是否超级管理员"
        json extra "扩展信息JSON"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
        int version "乐观锁版本号"
    }

    %% 角色相关
    sys_roles {
        bigint id PK "主键"
        varchar(50) code UK "角色代码"
        varchar(100) name "角色名称"
        text description "角色描述"
        bigint pid "父角色ID"
        varchar(500) path "层级路径,如:/1/2/3/"
        int level "层级深度"
        int sort_order "排序号"
        varchar(20) status "状态:字典[role_status]"
        boolean is_system "是否系统角色"
        json permissions_snapshot "权限快照"
        json extra "扩展信息"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
        int version "版本号"
    }

    %% 权限相关
    sys_permissions {
        bigint id PK "主键"
        varchar(100) code UK "权限代码"
        varchar(100) name "权限名称"
        varchar(20) type "类型menu,button,api,data"
        varchar(50) resource "资源标识"
        varchar(50) action "操作read,write,delete等"
        text description "权限描述"
        bigint pid "父权限ID"
        varchar(500) path "层级路径"
        int level "层级深度"
        int sort_order "排序号"
        varchar(20) status "状态"
        json meta "元数据"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
    }

    %% 组织架构
    sys_organizations {
        bigint id PK "主键"
        varchar(100) code UK "组织代码"
        varchar(200) name "组织名称"
        varchar(200) full_name "组织全称"
        text description "组织描述"
        bigint pid "父组织ID"
        varchar(500) path "层级路径"
        int level "层级深度"
        varchar(20) type "类型:字典[org_type]"
        varchar(20) status "状态:字典[org_status]"
        int sort_order "排序号"
        varchar(100) leader_id "负责人ID"
        varchar(200) address "地址"
        varchar(50) phone "电话"
        json extra "扩展信息"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
        int version "版本号"
    }

    %% 字典管理
    sys_dict_types {
        bigint id PK "主键"
        varchar(50) code UK "字典类型代码"
        varchar(100) name "字典类型名称"
        text description "描述"
        bigint pid "父字典类型ID"
        varchar(500) path "层级路径"
        int level "层级深度"
        varchar(20) status "状态active,inactive"
        boolean is_system "是否系统字典"
        int sort_order "排序号"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
    }

    sys_dict_items {
        bigint id PK "主键"
        bigint type_id "字典类型ID"
        varchar(50) item_key "字典项键"
        varchar(200) item_value "字典项值"
        varchar(100) label "显示标签"
        varchar(200) label_en "英文标签"
        text description "描述"
        bigint pid "父字典项ID"
        varchar(500) path "层级路径"
        int level "层级深度"
        int sort_order "排序号"
        varchar(20) status "状态"
        varchar(50) css_class "样式类"
        varchar(50) color "颜色值"
        json extra "扩展属性"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        bigint updated_by "更新人"
        datetime updated_at "更新时间"
        datetime deleted_at "删除时间"
    }

    %% 标签管理
    sys_tags {
        bigint id PK "主键"
        varchar(50) name UK "标签名称"
        varchar(50) type "标签类型user,role,content"
        varchar(50) color "标签颜色"
        text description "描述"
        int usage_count "使用次数"
        bigint created_by "创建人"
        datetime created_at "创建时间"
        datetime deleted_at "删除时间"
    }

    %% 关联表
    sys_user_roles {
        bigint id PK "主键"
        bigint user_id "用户ID"
        bigint role_id "角色ID"
        datetime expired_at "过期时间"
        bigint created_by "创建人"
        datetime created_at "创建时间"
    }

    sys_role_permissions {
        bigint id PK "主键"
        bigint role_id "角色ID"
        bigint permission_id "权限ID"
        boolean is_half "是否半选(树形权限)"
        bigint created_by "创建人"
        datetime created_at "创建时间"
    }

    sys_user_organizations {
        bigint id PK "主键"
        bigint user_id "用户ID"
        bigint organization_id "组织ID"
        boolean is_primary "是否主组织"
        varchar(100) position "职位"
        datetime joined_at "加入时间"
        bigint created_by "创建人"
        datetime created_at "创建时间"
    }

    sys_user_tags {
        bigint id PK "主键"
        bigint user_id "用户ID"
        bigint tag_id "标签ID"
        bigint created_by "创建人"
        datetime created_at "创建时间"
    }

    %% 操作日志
    sys_operation_logs {
        bigint id PK "主键"
        bigint user_id "用户ID"
        varchar(100) username "用户名"
        varchar(50) module "模块"
        varchar(50) action "操作"
        varchar(200) target "操作对象"
        bigint target_id "对象ID"
        text request_data "请求数据"
        text response_data "响应数据"
        varchar(20) status "状态success,fail"
        varchar(45) ip "IP地址"
        varchar(200) user_agent "用户代理"
        bigint duration "耗时(ms)"
        text error_msg "错误信息"
        datetime created_at "创建时间"
    }

    %% 关系定义
    sys_users ||--o{ sys_user_roles : "拥有"
    sys_roles ||--o{ sys_user_roles : "被分配"
    sys_roles ||--o{ sys_role_permissions : "拥有"
    sys_permissions ||--o{ sys_role_permissions : "被分配"
    sys_users ||--o{ sys_user_organizations : "属于"
    sys_organizations ||--o{ sys_user_organizations : "包含"
    sys_users ||--o{ sys_user_tags : "拥有"
    sys_tags ||--o{ sys_user_tags : "被使用"
    sys_dict_types ||--o{ sys_dict_items : "包含"
    sys_roles ||--o| sys_roles : "继承自"
    sys_organizations ||--o| sys_organizations : "隶属于"
    sys_permissions ||--o| sys_permissions : "包含"
    sys_dict_items ||--o| sys_dict_items : "子项"
    sys_dict_types ||--o| sys_dict_types : "包含"

3. 表结构详细设计

3.1 用户表 (sys_users)

用户系统的核心表,存储用户基本信息和认证信息。

-- 表结构
CREATE TABLE `sys_users` (
  `id` BIGINT NOT NULL COMMENT '主键雪花ID',
  `username` VARCHAR(50) NOT NULL COMMENT '用户名,唯一',
  `email` VARCHAR(100) NOT NULL COMMENT '邮箱,唯一',
  `mobile` VARCHAR(20) NULL COMMENT '手机号',
  `password_hash` VARCHAR(255) NOT NULL COMMENT '密码哈希值',
  `avatar` VARCHAR(255) NULL COMMENT '头像URL',
  `nickname` VARCHAR(100) NULL COMMENT '昵称',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态active-正常,inactive-未激活,locked-锁定,disabled-禁用',
  `gender` TINYINT NULL DEFAULT 0 COMMENT '性别0-未知,1-男,2-女',
  `birthday` DATE NULL COMMENT '生日',
  `bio` VARCHAR(500) NULL COMMENT '个人简介',
  `login_count` INT NOT NULL DEFAULT 0 COMMENT '登录次数',
  `last_login_at` DATETIME NULL COMMENT '最后登录时间',
  `last_login_ip` VARCHAR(45) NULL COMMENT '最后登录IP',
  `failed_attempts` INT NOT NULL DEFAULT 0 COMMENT '连续失败尝试次数',
  `locked_until` DATETIME NULL COMMENT '锁定截止时间',
  `is_root` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否超级管理员',
  `extra` JSON NULL COMMENT '扩展信息JSON格式',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间,软删除标记',
  `version` INT NOT NULL DEFAULT 1 COMMENT '乐观锁版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

-- 索引设计
CREATE UNIQUE INDEX `uk_username` ON `sys_users` (`username`, `deleted_at`);
CREATE UNIQUE INDEX `uk_email` ON `sys_users` (`email`, `deleted_at`);
CREATE INDEX `idx_mobile` ON `sys_users` (`mobile`);
CREATE INDEX `idx_status` ON `sys_users` (`status`);
CREATE INDEX `idx_created_at` ON `sys_users` (`created_at`);
CREATE INDEX `idx_deleted_at` ON `sys_users` (`deleted_at`);
CREATE INDEX `idx_is_root` ON `sys_users` (`is_root`);
CREATE INDEX `idx_last_login` ON `sys_users` (`last_login_at`);

3.2 角色表 (sys_roles)

支持树形结构的角色管理表,实现角色继承。

-- 表结构
CREATE TABLE `sys_roles` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `code` VARCHAR(50) NOT NULL COMMENT '角色代码,唯一',
  `name` VARCHAR(100) NOT NULL COMMENT '角色名称',
  `description` TEXT NULL COMMENT '角色描述',
  `pid` BIGINT NULL DEFAULT 0 COMMENT '父角色ID0表示顶级',
  `path` VARCHAR(500) NULL COMMENT '层级路径,如:/1/2/3/',
  `level` INT NOT NULL DEFAULT 1 COMMENT '层级深度',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '同级排序号',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态active-启用,inactive-禁用',
  `is_system` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否系统内置角色',
  `permissions_snapshot` JSON NULL COMMENT '权限快照,用于优化查询',
  `extra` JSON NULL COMMENT '扩展信息',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  `version` INT NOT NULL DEFAULT 1 COMMENT '版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';

-- 索引设计
CREATE UNIQUE INDEX `uk_code` ON `sys_roles` (`code`, `deleted_at`);
CREATE INDEX `idx_name` ON `sys_roles` (`name`);
CREATE INDEX `idx_pid` ON `sys_roles` (`pid`);
CREATE INDEX `idx_path` ON `sys_roles` (`path`);
CREATE INDEX `idx_status` ON `sys_roles` (`status`);
CREATE INDEX `idx_deleted_at` ON `sys_roles` (`deleted_at`);
CREATE INDEX `idx_is_system` ON `sys_roles` (`is_system`);
CREATE INDEX `idx_sort` ON `sys_roles` (`pid`, `sort_order`);

3.3 权限表 (sys_permissions)

细粒度的权限定义表,支持多种权限类型。

-- 表结构
CREATE TABLE `sys_permissions` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `code` VARCHAR(100) NOT NULL COMMENT '权限代码,唯一',
  `name` VARCHAR(100) NOT NULL COMMENT '权限名称',
  `type` VARCHAR(20) NOT NULL COMMENT '权限类型menu-菜单,button-按钮,api-接口,data-数据',
  `resource` VARCHAR(50) NULL COMMENT '资源标识user,role,post',
  `action` VARCHAR(50) NULL COMMENT '操作标识read,create,update,delete',
  `description` TEXT NULL COMMENT '权限描述',
  `pid` BIGINT NULL DEFAULT 0 COMMENT '父权限ID',
  `path` VARCHAR(500) NULL COMMENT '层级路径',
  `level` INT NOT NULL DEFAULT 1 COMMENT '层级深度',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序号',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态',
  `meta` JSON NULL COMMENT '元数据,如:图标、路由等',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限表';

-- 索引设计
CREATE UNIQUE INDEX `uk_code` ON `sys_permissions` (`code`, `deleted_at`);
CREATE INDEX `idx_type` ON `sys_permissions` (`type`);
CREATE INDEX `idx_resource_action` ON `sys_permissions` (`resource`, `action`);
CREATE INDEX `idx_pid` ON `sys_permissions` (`pid`);
CREATE INDEX `idx_deleted_at` ON `sys_permissions` (`deleted_at`);
CREATE INDEX `idx_status` ON `sys_permissions` (`status`);
CREATE INDEX `idx_sort` ON `sys_permissions` (`pid`, `sort_order`);

3.4 组织架构表 (sys_organizations)

支持多级组织结构,用于用户归属管理。

-- 表结构
CREATE TABLE `sys_organizations` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `code` VARCHAR(100) NOT NULL COMMENT '组织代码,唯一',
  `name` VARCHAR(200) NOT NULL COMMENT '组织名称',
  `full_name` VARCHAR(200) NULL COMMENT '组织全称',
  `description` TEXT NULL COMMENT '组织描述',
  `pid` BIGINT NULL DEFAULT 0 COMMENT '父组织ID',
  `path` VARCHAR(500) NULL COMMENT '层级路径',
  `level` INT NOT NULL DEFAULT 1 COMMENT '层级深度',
  `type` VARCHAR(20) NULL COMMENT '组织类型company,department,team',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序号',
  `leader_id` BIGINT NULL COMMENT '负责人ID',
  `address` VARCHAR(200) NULL COMMENT '地址',
  `phone` VARCHAR(50) NULL COMMENT '联系电话',
  `extra` JSON NULL COMMENT '扩展信息',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  `version` INT NOT NULL DEFAULT 1 COMMENT '版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='组织架构表';

-- 索引设计
CREATE UNIQUE INDEX `uk_code` ON `sys_organizations` (`code`, `deleted_at`);
CREATE INDEX `idx_name` ON `sys_organizations` (`name`);
CREATE INDEX `idx_pid` ON `sys_organizations` (`pid`);
CREATE INDEX `idx_path` ON `sys_organizations` (`path`);
CREATE INDEX `idx_type` ON `sys_organizations` (`type`);
CREATE INDEX `idx_leader_id` ON `sys_organizations` (`leader_id`);
CREATE INDEX `idx_deleted_at` ON `sys_organizations` (`deleted_at`);
CREATE INDEX `idx_status` ON `sys_organizations` (`status`);
CREATE INDEX `idx_sort` ON `sys_organizations` (`pid`, `sort_order`);

3.5 字典类型表 (sys_dict_types)

管理系统中的各类数据字典,支持树形结构。

-- 表结构
CREATE TABLE `sys_dict_types` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `code` VARCHAR(50) NOT NULL COMMENT '字典类型代码,唯一',
  `name` VARCHAR(100) NOT NULL COMMENT '字典类型名称',
  `description` TEXT NULL COMMENT '描述',
  `pid` BIGINT NULL DEFAULT 0 COMMENT '父字典类型ID支持字典分类',
  `path` VARCHAR(500) NULL COMMENT '层级路径',
  `level` INT NOT NULL DEFAULT 1 COMMENT '层级深度',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态active-启用,inactive-禁用',
  `is_system` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否系统内置',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序号',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='字典类型表';

-- 索引设计
CREATE UNIQUE INDEX `uk_code` ON `sys_dict_types` (`code`, `deleted_at`);
CREATE INDEX `idx_name` ON `sys_dict_types` (`name`);
CREATE INDEX `idx_pid` ON `sys_dict_types` (`pid`);
CREATE INDEX `idx_path` ON `sys_dict_types` (`path`);
CREATE INDEX `idx_status` ON `sys_dict_types` (`status`);
CREATE INDEX `idx_deleted_at` ON `sys_dict_types` (`deleted_at`);
CREATE INDEX `idx_is_system` ON `sys_dict_types` (`is_system`);
CREATE INDEX `idx_sort` ON `sys_dict_types` (`pid`, `sort_order`);

3.6 字典项表 (sys_dict_items)

存储具体的字典数据,支持树形结构。

-- 表结构
CREATE TABLE `sys_dict_items` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `type_id` BIGINT NOT NULL COMMENT '字典类型ID',
  `item_key` VARCHAR(50) NOT NULL COMMENT '字典项键',
  `item_value` VARCHAR(200) NOT NULL COMMENT '字典项值',
  `label` VARCHAR(100) NOT NULL COMMENT '显示标签',
  `label_en` VARCHAR(200) NULL COMMENT '英文标签',
  `description` TEXT NULL COMMENT '描述',
  `pid` BIGINT NULL DEFAULT 0 COMMENT '父字典项ID支持树形字典',
  `path` VARCHAR(500) NULL COMMENT '层级路径',
  `level` INT NOT NULL DEFAULT 1 COMMENT '层级深度',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序号',
  `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态',
  `css_class` VARCHAR(50) NULL COMMENT 'CSS样式类',
  `color` VARCHAR(50) NULL COMMENT '颜色值,如:#FF0000',
  `extra` JSON NULL COMMENT '扩展属性',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_by` BIGINT NULL COMMENT '更新人ID',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='字典项表';

-- 索引设计
CREATE UNIQUE INDEX `uk_type_key` ON `sys_dict_items` (`type_id`, `item_key`, `deleted_at`);
CREATE INDEX `idx_type_id` ON `sys_dict_items` (`type_id`);
CREATE INDEX `idx_pid` ON `sys_dict_items` (`pid`);
CREATE INDEX `idx_status` ON `sys_dict_items` (`status`);
CREATE INDEX `idx_deleted_at` ON `sys_dict_items` (`deleted_at`);
CREATE INDEX `idx_sort` ON `sys_dict_items` (`type_id`, `sort_order`);
CREATE INDEX `idx_key` ON `sys_dict_items` (`item_key`);

3.7 标签表 (sys_tags)

灵活的标签系统,可用于用户、内容等多种场景。

-- 表结构
CREATE TABLE `sys_tags` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `name` VARCHAR(50) NOT NULL COMMENT '标签名称',
  `type` VARCHAR(50) NULL DEFAULT 'user' COMMENT '标签类型user-用户标签,role-角色标签,content-内容标签',
  `color` VARCHAR(50) NULL COMMENT '标签颜色,如:#FF0000',
  `description` TEXT NULL COMMENT '描述',
  `usage_count` INT NOT NULL DEFAULT 0 COMMENT '使用次数统计',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `deleted_at` DATETIME NULL COMMENT '删除时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='标签表';

-- 索引设计
CREATE UNIQUE INDEX `uk_name_type` ON `sys_tags` (`name`, `type`, `deleted_at`);
CREATE INDEX `idx_type` ON `sys_tags` (`type`);
CREATE INDEX `idx_usage_count` ON `sys_tags` (`usage_count` DESC);
CREATE INDEX `idx_deleted_at` ON `sys_tags` (`deleted_at`);
CREATE INDEX `idx_name` ON `sys_tags` (`name`);

3.8 用户角色关联表 (sys_user_roles)

-- 表结构
CREATE TABLE `sys_user_roles` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `user_id` BIGINT NOT NULL COMMENT '用户ID',
  `role_id` BIGINT NOT NULL COMMENT '角色ID',
  `expired_at` DATETIME NULL COMMENT '过期时间NULL表示永久',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';

-- 索引设计
CREATE UNIQUE INDEX `uk_user_role` ON `sys_user_roles` (`user_id`, `role_id`);
CREATE INDEX `idx_user_id` ON `sys_user_roles` (`user_id`);
CREATE INDEX `idx_role_id` ON `sys_user_roles` (`role_id`);
CREATE INDEX `idx_expired_at` ON `sys_user_roles` (`expired_at`);
CREATE INDEX `idx_created_at` ON `sys_user_roles` (`created_at`);

3.9 角色权限关联表 (sys_role_permissions)

-- 表结构
CREATE TABLE `sys_role_permissions` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `role_id` BIGINT NOT NULL COMMENT '角色ID',
  `permission_id` BIGINT NOT NULL COMMENT '权限ID',
  `is_half` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否半选状态(树形权限)',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色权限关联表';

-- 索引设计
CREATE UNIQUE INDEX `uk_role_permission` ON `sys_role_permissions` (`role_id`, `permission_id`);
CREATE INDEX `idx_role_id` ON `sys_role_permissions` (`role_id`);
CREATE INDEX `idx_permission_id` ON `sys_role_permissions` (`permission_id`);
CREATE INDEX `idx_is_half` ON `sys_role_permissions` (`is_half`);

3.10 用户组织关联表 (sys_user_organizations)

-- 表结构
CREATE TABLE `sys_user_organizations` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `user_id` BIGINT NOT NULL COMMENT '用户ID',
  `organization_id` BIGINT NOT NULL COMMENT '组织ID',
  `is_primary` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否主组织',
  `position` VARCHAR(100) NULL COMMENT '职位',
  `joined_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '加入时间',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户组织关联表';

-- 索引设计
CREATE UNIQUE INDEX `uk_user_org` ON `sys_user_organizations` (`user_id`, `organization_id`);
CREATE INDEX `idx_user_id` ON `sys_user_organizations` (`user_id`);
CREATE INDEX `idx_organization_id` ON `sys_user_organizations` (`organization_id`);
CREATE INDEX `idx_is_primary` ON `sys_user_organizations` (`is_primary`);
CREATE INDEX `idx_joined_at` ON `sys_user_organizations` (`joined_at`);

3.11 用户标签关联表 (sys_user_tags)

-- 表结构
CREATE TABLE `sys_user_tags` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `user_id` BIGINT NOT NULL COMMENT '用户ID',
  `tag_id` BIGINT NOT NULL COMMENT '标签ID',
  `created_by` BIGINT NULL COMMENT '创建人ID',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户标签关联表';

-- 索引设计
CREATE UNIQUE INDEX `uk_user_tag` ON `sys_user_tags` (`user_id`, `tag_id`);
CREATE INDEX `idx_user_id` ON `sys_user_tags` (`user_id`);
CREATE INDEX `idx_tag_id` ON `sys_user_tags` (`tag_id`);
CREATE INDEX `idx_created_at` ON `sys_user_tags` (`created_at`);

3.12 操作日志表 (sys_operation_logs)

记录所有重要操作,用于审计和问题追踪。

-- 表结构
CREATE TABLE `sys_operation_logs` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `user_id` BIGINT NULL COMMENT '操作用户ID',
  `username` VARCHAR(100) NULL COMMENT '操作用户名',
  `module` VARCHAR(50) NOT NULL COMMENT '操作模块',
  `action` VARCHAR(50) NOT NULL COMMENT '操作类型',
  `target` VARCHAR(200) NULL COMMENT '操作对象描述',
  `target_id` BIGINT NULL COMMENT '操作对象ID',
  `request_data` TEXT NULL COMMENT '请求数据',
  `response_data` TEXT NULL COMMENT '响应数据',
  `status` VARCHAR(20) NOT NULL COMMENT '操作状态success-成功,fail-失败',
  `ip` VARCHAR(45) NULL COMMENT 'IP地址',
  `user_agent` VARCHAR(200) NULL COMMENT '用户代理',
  `duration` BIGINT NULL COMMENT '操作耗时(毫秒)',
  `error_msg` TEXT NULL COMMENT '错误信息',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志表';

-- 索引设计
CREATE INDEX `idx_user_id` ON `sys_operation_logs` (`user_id`);
CREATE INDEX `idx_module_action` ON `sys_operation_logs` (`module`, `action`);
CREATE INDEX `idx_target` ON `sys_operation_logs` (`target_id`);
CREATE INDEX `idx_status` ON `sys_operation_logs` (`status`);
CREATE INDEX `idx_created_at` ON `sys_operation_logs` (`created_at`);
CREATE INDEX `idx_ip` ON `sys_operation_logs` (`ip`);
-- 分区建议:按月分区
ALTER TABLE `sys_operation_logs` PARTITION BY RANGE (YEAR(created_at) * 100 + MONTH(created_at)) (
    PARTITION p202401 VALUES LESS THAN (202402),
    PARTITION p202402 VALUES LESS THAN (202403),
    -- 继续添加更多分区...
    PARTITION p_future VALUES LESS THAN MAXVALUE
);

4. 设计特点说明

4.1 软删除机制

  • 所有业务表都包含 deleted_at 字段
  • 删除操作只更新 deleted_at 为当前时间
  • 唯一索引都包含 deleted_at,确保已删除数据不影响唯一性
  • 查询时默认过滤 deleted_at IS NULL
  • 提供回收站功能,可恢复误删数据

4.2 树形结构支持

  • 使用 pid 存储父节点ID0或NULL表示顶级节点
  • path 字段存储完整路径(如:/1/2/3/),便于查询所有子节点
  • level 记录层级深度,优化层级查询
  • 支持无限层级嵌套
  • 提供递归查询的存储过程优化性能

4.3 审计追踪

  • 所有表包含 created_bycreated_atupdated_byupdated_at
  • 重要操作记录到 sys_operation_logs
  • 支持数据变更历史追踪
  • 可配置敏感操作的详细日志记录

4.4 性能优化

  • 合理的索引设计,覆盖常用查询场景
  • 使用JSON字段存储扩展信息减少表结构变更
  • 权限快照机制,避免复杂的联表查询
  • 日志表按月分区,提高查询效率
  • 高频查询数据缓存到Redis

4.5 扩展性设计

  • 预留 extra JSON字段支持灵活扩展
  • 版本号字段支持乐观锁
  • 标签系统支持多种业务场景
  • 字典系统支持动态配置
  • 支持插件化扩展新功能

4.6 数据完整性

  • 虽然不使用外键,但通过应用层保证引用完整性
  • 删除操作需级联处理关联数据
  • 使用事务保证操作原子性
  • 定期数据一致性检查任务

4.7 安全性设计

  • 密码使用bcrypt算法加密成本因子不低于12
  • 登录失败次数限制,防止暴力破解
  • 操作日志记录IP和UserAgent便于审计
  • 敏感数据(如手机号)部分存储时脱敏
  • SQL注入防护通过参数化查询实现

5. 初始化数据

5.1 系统初始用户

-- 创建root超级管理员
INSERT INTO `sys_users` (`id`, `username`, `email`, `password_hash`, `nickname`, `is_root`, `status`) 
VALUES (1, 'root', 'root@system.local', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewYpfQaXUIkRrPJK', '超级管理员', TRUE, 'active');

-- 创建系统管理员
INSERT INTO `sys_users` (`id`, `username`, `email`, `password_hash`, `nickname`, `status`) 
VALUES (2, 'admin', 'admin@system.local', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewYpfQaXUIkRrPJK', '系统管理员', 'active');

5.2 系统初始角色

-- 超级管理员角色
INSERT INTO `sys_roles` (`id`, `code`, `name`, `description`, `is_system`, `status`) 
VALUES (1, 'super_admin', '超级管理员', '拥有系统所有权限', TRUE, 'active');

-- 系统管理员角色
INSERT INTO `sys_roles` (`id`, `code`, `name`, `description`, `is_system`, `status`, `pid`, `path`, `level`) 
VALUES (2, 'admin', '系统管理员', '负责系统配置和用户管理', TRUE, 'active', 1, '/1/2/', 2);

-- 普通用户角色
INSERT INTO `sys_roles` (`id`, `code`, `name`, `description`, `is_system`, `status`) 
VALUES (3, 'user', '普通用户', '普通注册用户默认角色', TRUE, 'active');

-- 分配角色
INSERT INTO `sys_user_roles` (`user_id`, `role_id`) VALUES (1, 1);
INSERT INTO `sys_user_roles` (`user_id`, `role_id`) VALUES (2, 2);

5.3 基础字典数据

-- 字典分类
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`) VALUES
(1, 'system', '系统字典', TRUE),
(2, 'business', '业务字典', TRUE);

-- 用户状态字典
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(10, 'user_status', '用户状态', TRUE, 1, '/1/10/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `color`, `sort_order`) VALUES
(10, 'active', 'active', '正常', '#52c41a', 1),
(10, 'inactive', 'inactive', '未激活', '#faad14', 2),
(10, 'locked', 'locked', '锁定', '#ff4d4f', 3),
(10, 'disabled', 'disabled', '禁用', '#d9d9d9', 4);

-- 组织类型字典
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(11, 'org_type', '组织类型', TRUE, 1, '/1/11/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `sort_order`) VALUES
(11, 'company', 'company', '公司', 1),
(11, 'department', 'department', '部门', 2),
(11, 'team', 'team', '团队', 3),
(11, 'group', 'group', '小组', 4);

-- 性别字典
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(12, 'gender', '性别', TRUE, 1, '/1/12/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `sort_order`) VALUES
(12, '0', '0', '未知', 1),
(12, '1', '1', '男', 2),
(12, '2', '2', '女', 3);

-- 权限类型字典
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(13, 'permission_type', '权限类型', TRUE, 1, '/1/13/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `color`, `sort_order`) VALUES
(13, 'menu', 'menu', '菜单', '#1890ff', 1),
(13, 'button', 'button', '按钮', '#52c41a', 2),
(13, 'api', 'api', '接口', '#fa8c16', 3),
(13, 'data', 'data', '数据', '#722ed1', 4);

-- 标签类型字典
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(14, 'tag_type', '标签类型', TRUE, 1, '/1/14/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `sort_order`) VALUES
(14, 'user', 'user', '用户标签', 1),
(14, 'role', 'role', '角色标签', 2),
(14, 'content', 'content', '内容标签', 3);

-- 地区字典(示例)
INSERT INTO `sys_dict_types` (`id`, `code`, `name`, `is_system`, `pid`, `path`) VALUES
(20, 'region', '地区', TRUE, 2, '/2/20/');

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `sort_order`) VALUES
(20, 'CN', 'CN', '中国', 1);

INSERT INTO `sys_dict_items` (`type_id`, `item_key`, `item_value`, `label`, `pid`, `path`, `sort_order`) VALUES
(20, 'CN_BJ', 'CN_BJ', '北京', (SELECT id FROM sys_dict_items WHERE item_key = 'CN'), NULL, 1),
(20, 'CN_SH', 'CN_SH', '上海', (SELECT id FROM sys_dict_items WHERE item_key = 'CN'), NULL, 2);

5.4 基础权限数据

-- 系统管理权限
INSERT INTO `sys_permissions` (`id`, `code`, `name`, `type`, `resource`, `action`) VALUES
(1, 'system:manage', '系统管理', 'menu', 'system', 'manage'),
(2, 'user:read', '查看用户', 'api', 'user', 'read'),
(3, 'user:create', '创建用户', 'api', 'user', 'create'),
(4, 'user:update', '更新用户', 'api', 'user', 'update'),
(5, 'user:delete', '删除用户', 'api', 'user', 'delete'),
(6, 'role:read', '查看角色', 'api', 'role', 'read'),
(7, 'role:create', '创建角色', 'api', 'role', 'create'),
(8, 'role:update', '更新角色', 'api', 'role', 'update'),
(9, 'role:delete', '删除角色', 'api', 'role', 'delete');

-- 为超级管理员角色分配所有权限
INSERT INTO `sys_role_permissions` (`role_id`, `permission_id`) 
SELECT 1, id FROM `sys_permissions`;

5.5 初始组织架构

-- 创建顶级组织
INSERT INTO `sys_organizations` (`id`, `code`, `name`, `type`, `status`) VALUES
(1, 'ROOT', '星撰集团', 'company', 'active');

-- 创建部门
INSERT INTO `sys_organizations` (`id`, `code`, `name`, `type`, `pid`, `path`, `level`, `status`) VALUES
(2, 'TECH', '技术部', 'department', 1, '/1/2/', 2, 'active'),
(3, 'PRODUCT', '产品部', 'department', 1, '/1/3/', 2, 'active'),
(4, 'OPERATE', '运营部', 'department', 1, '/1/4/', 2, 'active');

5.6 示例标签数据

-- 用户标签
INSERT INTO `sys_tags` (`name`, `type`, `color`, `description`) VALUES
('VIP', 'user', '#ff4d4f', 'VIP用户'),
('活跃用户', 'user', '#52c41a', '经常登录的用户'),
('内容创作者', 'user', '#1890ff', '发布优质内容的用户'),
('新用户', 'user', '#faad14', '注册不满30天的用户');

-- 角色标签
INSERT INTO `sys_tags` (`name`, `type`, `color`, `description`) VALUES
('核心角色', 'role', '#ff4d4f', '系统核心角色'),
('业务角色', 'role', '#1890ff', '业务相关角色');

6. 注意事项

  1. ID生成策略建议使用雪花算法生成分布式ID避免自增ID的局限性
  2. 密码存储必须使用bcrypt或类似的强哈希算法成本因子不低于12
  3. 并发控制使用version字段实现乐观锁防止并发更新冲突
  4. 查询优化对于树形结构的查询优先使用path字段而非递归查询
  5. 数据归档:日志表建议定期归档,避免单表数据量过大
  6. 缓存策略权限、字典等数据变更不频繁建议缓存到Redis
  7. 批量操作大批量数据操作时使用批量SQL避免循环单条执行
  8. 索引维护:定期分析索引使用情况,删除无用索引,优化查询性能

7. 性能优化建议

7.1 查询优化

  • 使用覆盖索引减少回表查询
  • 合理使用联合索引,注意索引顺序
  • 避免在WHERE子句中对字段进行函数操作
  • 使用EXPLAIN分析SQL执行计划

7.2 树形结构查询优化

-- 查询所有子节点使用path
SELECT * FROM sys_roles WHERE path LIKE '/1/2/%' AND deleted_at IS NULL;

-- 查询直接子节点
SELECT * FROM sys_roles WHERE pid = 2 AND deleted_at IS NULL ORDER BY sort_order;

-- 递归查询所有子节点MySQL 8.0+
WITH RECURSIVE role_tree AS (
    SELECT * FROM sys_roles WHERE id = 1
    UNION ALL
    SELECT r.* FROM sys_roles r 
    INNER JOIN role_tree rt ON r.pid = rt.id
)
SELECT * FROM role_tree;

7.3 权限查询优化

-- 使用权限快照避免多表联查
SELECT permissions_snapshot FROM sys_roles WHERE id = ?;

-- 获取用户所有权限(包括角色继承)
SELECT DISTINCT p.*
FROM sys_permissions p
JOIN sys_role_permissions rp ON p.id = rp.permission_id
JOIN sys_user_roles ur ON rp.role_id = ur.role_id
WHERE ur.user_id = ? 
  AND ur.expired_at IS NULL OR ur.expired_at > NOW()
  AND p.deleted_at IS NULL;

8. 后续扩展建议

  1. 多租户支持预留tenant_id字段支持SaaS化部署
  2. 数据权限:扩展权限表,支持行级数据权限控制
  3. 审批流程:增加工作流相关表,支持复杂的审批场景
  4. 消息通知:增加消息表,支持站内信、邮件、短信等通知
  5. 登录日志:独立的登录日志表,记录所有登录尝试
  6. 配置管理:系统配置表,支持动态配置管理
  7. 定时任务:任务调度表,支持定时任务管理
  8. 数据字典缓存:实现字典数据的多级缓存机制

9. 安全建议

  1. SQL注入防护使用参数化查询避免拼接SQL
  2. XSS防护:对用户输入进行转义处理
  3. CSRF防护使用Token机制防止跨站请求伪造
  4. 敏感数据加密:对敏感字段进行加密存储
  5. 访问控制:实施最小权限原则
  6. 审计日志:记录所有敏感操作
  7. 数据备份:定期备份,异地容灾
  8. 安全扫描:定期进行安全漏洞扫描