✨ 新增功能设计文档: - 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后端开发规范 - 完善健康检查控制器 - 统一项目代码规范和注释规范
38 KiB
38 KiB
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 '父角色ID,0表示顶级',
`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
存储父节点ID,0或NULL表示顶级节点 path
字段存储完整路径(如:/1/2/3/),便于查询所有子节点level
记录层级深度,优化层级查询- 支持无限层级嵌套
- 提供递归查询的存储过程优化性能
4.3 审计追踪
- 所有表包含
created_by
、created_at
、updated_by
、updated_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. 注意事项
- ID生成策略:建议使用雪花算法生成分布式ID,避免自增ID的局限性
- 密码存储:必须使用bcrypt或类似的强哈希算法,成本因子不低于12
- 并发控制:使用version字段实现乐观锁,防止并发更新冲突
- 查询优化:对于树形结构的查询,优先使用path字段而非递归查询
- 数据归档:日志表建议定期归档,避免单表数据量过大
- 缓存策略:权限、字典等数据变更不频繁,建议缓存到Redis
- 批量操作:大批量数据操作时使用批量SQL,避免循环单条执行
- 索引维护:定期分析索引使用情况,删除无用索引,优化查询性能
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. 后续扩展建议
- 多租户支持:预留tenant_id字段,支持SaaS化部署
- 数据权限:扩展权限表,支持行级数据权限控制
- 审批流程:增加工作流相关表,支持复杂的审批场景
- 消息通知:增加消息表,支持站内信、邮件、短信等通知
- 登录日志:独立的登录日志表,记录所有登录尝试
- 配置管理:系统配置表,支持动态配置管理
- 定时任务:任务调度表,支持定时任务管理
- 数据字典缓存:实现字典数据的多级缓存机制
9. 安全建议
- SQL注入防护:使用参数化查询,避免拼接SQL
- XSS防护:对用户输入进行转义处理
- CSRF防护:使用Token机制防止跨站请求伪造
- 敏感数据加密:对敏感字段进行加密存储
- 访问控制:实施最小权限原则
- 审计日志:记录所有敏感操作
- 数据备份:定期备份,异地容灾
- 安全扫描:定期进行安全漏洞扫描