# M2 - 基础用户系统 - 数据库设计文档 ## 1. 概述 本文档为星撰个人综合平台的基础用户系统(M2阶段)提供详细的数据库设计方案。设计遵循以下原则: - **无外键约束**:所有关联关系通过应用层代码维护,提高性能和灵活性 - **软删除机制**:所有业务表支持软删除,保留数据历史 - **树形结构支持**:角色、组织、权限、字典等支持无限层级的树形结构 - **审计追踪**:完整的创建、修改记录 - **高性能**:合理的索引设计,支持大数据量查询 - **扩展性**:预留扩展字段,支持未来功能演进 ## 2. 数据库 ER 图 ```mermaid 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) 用户系统的核心表,存储用户基本信息和认证信息。 ```sql -- 表结构 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) 支持树形结构的角色管理表,实现角色继承。 ```sql -- 表结构 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) 细粒度的权限定义表,支持多种权限类型。 ```sql -- 表结构 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) 支持多级组织结构,用于用户归属管理。 ```sql -- 表结构 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) 管理系统中的各类数据字典,支持树形结构。 ```sql -- 表结构 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) 存储具体的字典数据,支持树形结构。 ```sql -- 表结构 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) 灵活的标签系统,可用于用户、内容等多种场景。 ```sql -- 表结构 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) ```sql -- 表结构 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) ```sql -- 表结构 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) ```sql -- 表结构 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) ```sql -- 表结构 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) 记录所有重要操作,用于审计和问题追踪。 ```sql -- 表结构 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 系统初始用户 ```sql -- 创建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 系统初始角色 ```sql -- 超级管理员角色 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 基础字典数据 ```sql -- 字典分类 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 基础权限数据 ```sql -- 系统管理权限 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 初始组织架构 ```sql -- 创建顶级组织 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 示例标签数据 ```sql -- 用户标签 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 树形结构查询优化 ```sql -- 查询所有子节点(使用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 权限查询优化 ```sql -- 使用权限快照避免多表联查 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. **安全扫描**:定期进行安全漏洞扫描