import{_ as t,o as i,c as a,a2 as e}from"./chunks/framework.BbmSSMjL.js";const c=JSON.parse('{"title":"4.9 数据库设计","description":"","frontmatter":{},"headers":[],"relativePath":"zh/architecture/database-design.md","filePath":"zh/architecture/database-design.md"}'),d={name:"zh/architecture/database-design.md"};function n(l,s,h,p,r,k){return i(),a("div",null,[...s[0]||(s[0]=[e(`

4.9 数据库设计 ​

概述

项目支持 MySQL、PostgreSQL、SQL Server、Oracle、SQLite 五种数据库,通过 .env 的 DB_CONNECTION 一键切换,document/ 下提供五套初始化脚本。所有数据库共用同一套代码,无需修改业务逻辑。本章涵盖命名规范、表结构设计、字段说明、索引策略和多数据库适配。

命名规范 ​

对象规范示例
表名不含前缀的业务名 + DB_PREFIX(默认 laravel_)laravel_user、laravel_article
模型 $table不含前缀protected $table = 'user'
字段名小写下划线create_time、user_name
主键统一 id,INT 自增id INT PRIMARY KEY
外键表名_iduser_id、role_id
索引idx_字段名idx_status、idx_tenant_id
唯一索引uk_含义(常含 is_delete 协同)uk_tenant_username

公共字段 ​

所有业务表必须包含以下公共字段,由模型 Trait 自动维护:

sql
-- MySQL 格式
id              INT PRIMARY KEY AUTO_INCREMENT  COMMENT '主键',
is_delete       TINYINT(1) DEFAULT 0            COMMENT '软删除 0=正常 1=已删除',
create_user     VARCHAR(50) DEFAULT ''           COMMENT '创建人',
create_time     DATETIME                         COMMENT '创建时间',
update_user     VARCHAR(50) DEFAULT ''           COMMENT '更新人',
update_time     DATETIME                         COMMENT '更新时间'
字段自动维护方说明
is_deleteSoftDeletesByFlagsoftDelete() 设置为 1,SoftDeleteFlagScope 全局过滤
create_userHasAuditColumns creating 事件取 Auth::username(),已传入则不覆盖
create_timeHasAuditColumns creating 事件取 now(),已传入则不覆盖
update_userHasAuditColumns updating 事件取 Auth::username()
update_timeHasAuditColumns updating 事件始终覆盖为当前时间

核心表清单(25 张) ​

用户与权限(5 张) ​

表名说明Service 基类
laravel_user用户表BaseTenantService
laravel_user_role用户角色关联表(N:N 中间表)—
laravel_role角色表BaseTenantService
laravel_role_menu角色菜单关联表(N:N 中间表)—
laravel_menu菜单/权限表(菜单即权限)BaseService

关联关系:

text
laravel_user ──┐
               │ N:N (laravel_user_role)
laravel_role ──┤
               │ N:N (laravel_role_menu)
laravel_menu ──┘

laravel_dept   ←── laravel_user.dept_id
laravel_tenant ←── laravel_user.tenant_id

组织架构(3 张) ​

表名说明Service 基类
laravel_dept部门表(树形,parent_id)BaseTenantService
laravel_position岗位表BaseTenantService
laravel_level职级表BaseTenantService

租户(1 张) ​

表名说明Service 基类
laravel_tenant租户表(状态、过期时间、用户数限制)BaseService

系统配置(5 张) ​

表名说明Service 基类
laravel_dict字典表BaseService
laravel_dict_item字典项表BaseService
laravel_config配置组表BaseService
laravel_config_item配置项表BaseService
laravel_param系统参数表BaseService

关联关系:

text
laravel_dict   ←── laravel_dict_item.dict_id
laravel_config ←── laravel_config_item.config_id

内容管理(4 张) ​

表名说明Service 基类
laravel_article文章表BaseTenantService
laravel_category文章分类表(树形)BaseTenantService
laravel_link友情链接表BaseTenantService
laravel_notice通知公告表BaseTenantService

日志审计(2 张) ​

表名说明Service 基类
laravel_login_log登录日志表BaseService
laravel_operation_log操作日志表BaseService

定时任务(2 张) ​

表名说明Service 基类
laravel_job定时任务表BaseService
laravel_job_log定时任务执行日志表BaseService

关联关系:

text
laravel_job ←── laravel_job_log.job_id

基础数据(3 张) ​

表名说明Service 基类
laravel_city城市行政区划表(树形)BaseService
laravel_file_template文件模板表BaseService
laravel_example案例演示表(生成器参考模板)BaseService

租户隔离范围

继承 BaseTenantService 的 9 个服务:User / Role / Dept / Position / Level / Article / Category / Notice / Link——业务数据按租户隔离;系统共享数据(字典、配置、菜单、日志等)继承 BaseService 不隔离。

关键表字段说明 ​

laravel_user(用户表) ​

字段类型说明
idINT主键
tenant_idINT租户 ID(0=平台用户)
codeVARCHAR(100)用户编码
usernameVARCHAR(30)用户名(登录账号)
passwordVARCHAR(255)密码(bcrypt 加密)
saltVARCHAR(30)加密盐(外部盐,与 password 分离存储)
realnameVARCHAR(150)用户姓名
genderINT性别:1-男 2-女 3-保密
mobile / emailVARCHAR(30)手机号 / 邮箱
avatarVARCHAR(255)用户头像
statusINT状态:1-正常 2-禁用
dept_id / level_id / position_idINT部门 / 职级 / 岗位 ID
province_code / city_code / district_code / street_codeVARCHAR(30)省市县街道编码
city_infoVARCHAR(255)省市区信息拼接
addressVARCHAR(255)详细地址
intro / noteVARCHAR(255)个人简介 / 备注
sortINT排序
is_delete + 四个审计字段公共字段

唯一索引(与软删除协同):

sql
UNIQUE INDEX uk_tenant_username (tenant_id, username, is_delete)
UNIQUE INDEX uk_tenant_mobile   (tenant_id, mobile,   is_delete)
UNIQUE INDEX uk_tenant_code     (tenant_id, code,     is_delete)

为什么唯一索引含 is_delete?

软删除的用户 is_delete=1 仍占唯一索引——把 is_delete 纳入联合唯一后,同名账号删除后可重新注册(新记录 is_delete=0 不与已删记录冲突),同时保证同租户内未删数据用户名唯一。业务层的 uniqueFields 校验与数据库索引双保险。

laravel_role(角色表) ​

字段类型说明
idINT主键
nameVARCHAR(50)角色名称
codeVARCHAR(50)角色编码
tenant_idINT租户 ID(角色按租户隔离)
statusTINYINT状态
remark / sort备注 / 排序

laravel_menu(菜单/权限表) ​

字段类型说明
idINT主键
parent_idINT父级 ID(0=顶级)
nameVARCHAR(50)菜单名称
permissionVARCHAR(100)权限标识(如 sys:user:add,菜单即权限)
typeTINYINT类型:0=菜单/目录(可导航) 1=权限节点
pathVARCHAR(200)路由路径
iconVARCHAR(100)图标
sort / status / remark排序 / 状态 / 备注

laravel_tenant(租户表) ​

字段类型说明
idINT主键
nameVARCHAR(100)租户名称
codeVARCHAR(50)租户编码(系统自动生成)
statusTINYINT状态(字典 tenant_status):0=禁用 1=启用
expire_timeDATETIME过期时间(ResolveTenant 中间件校验)
max_user_numINT最大用户数限制
contact_name / contact_phone联系人 / 联系电话

laravel_article(文章表) ​

字段类型说明
idINT主键
titleVARCHAR(200)标题
category_idINT分类 ID
coverVARCHAR(500)封面图路径
contentTEXT内容(富文本,含 [IMG_URL] 占位符)
authorVARCHAR(50)作者
statusTINYINT状态(字典 article_status)
sortINT排序
tenant_idINT租户 ID

索引策略 ​

推荐索引 ​

sql
-- 用户表:高频查询字段(联合唯一索引见上文)
ALTER TABLE laravel_user ADD INDEX idx_tenant_id (tenant_id);
ALTER TABLE laravel_user ADD INDEX idx_dept_id (dept_id);
ALTER TABLE laravel_user ADD INDEX idx_status (status);

-- 角色关联表:外键索引
ALTER TABLE laravel_user_role ADD INDEX idx_user_id (user_id);
ALTER TABLE laravel_user_role ADD INDEX idx_role_id (role_id);
ALTER TABLE laravel_role_menu ADD INDEX idx_role_id (role_id);
ALTER TABLE laravel_role_menu ADD INDEX idx_menu_id (menu_id);

-- 文章表:常用过滤字段
ALTER TABLE laravel_article ADD INDEX idx_category_id (category_id);
ALTER TABLE laravel_article ADD INDEX idx_status (status);
ALTER TABLE laravel_article ADD INDEX idx_tenant_id (tenant_id);

-- 日志表:按时间查询
ALTER TABLE laravel_login_log ADD INDEX idx_create_time (create_time);
ALTER TABLE laravel_operation_log ADD INDEX idx_create_time (create_time);
ALTER TABLE laravel_job_log ADD INDEX idx_job_id (job_id);

-- 菜单表:树形查询
ALTER TABLE laravel_menu ADD INDEX idx_parent_id (parent_id);

-- 字典项表:按字典 ID 查询
ALTER TABLE laravel_dict_item ADD INDEX idx_dict_id (dict_id);
ALTER TABLE laravel_config_item ADD INDEX idx_config_id (config_id);

-- 城市表:按编码查询
ALTER TABLE laravel_city ADD INDEX idx_area_code (area_code);
ALTER TABLE laravel_city ADD INDEX idx_parent_code (parent_code);

索引设计原则 ​

原则说明
外键必加所有 _id 外键字段都应加索引
过滤字段pageEqFields 中配置的精确匹配字段应加索引
模糊搜索pageLikeFields 中的字段可考虑全文索引,但 LIKE '%xx%' 无法用普通索引
排序字段pageOrderBy 中的默认排序字段可加索引
时间字段日志表的 create_time 必加索引(按时间范围查询)
联合唯一软删除表的唯一约束必须含 is_delete(见上文)

多数据库支持 ​

支持的数据库 ​

数据库DB_CONNECTION 值默认端口PHP 扩展
MySQLmysql3306pdo_mysql
PostgreSQLpgsql5432pdo_pgsql
SQL Serversqlsrv1433pdo_sqlsrv
Oracleoracle1521pdo_oci(自定义 oci 驱动接入)
SQLitesqlite-pdo_sqlite

切换数据库 ​

只需修改 .env 文件,无需改动任何代码:

ini
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=rxthinkcmf.laravel13.naivevue
DB_USERNAME=root
DB_PASSWORD=root
DB_PREFIX=laravel_
ini
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=rxthinkcmf.laravel13.naivevue
DB_USERNAME=postgres
DB_PASSWORD=root
DB_PREFIX=laravel_
ini
DB_CONNECTION=sqlsrv
DB_HOST=127.0.0.1
DB_PORT=1433
DB_DATABASE=rxthinkcmf.laravel13.naivevue
DB_USERNAME=sa
DB_PASSWORD=root
DB_PREFIX=laravel_
ini
DB_CONNECTION=oracle
DB_HOST=127.0.0.1
DB_PORT=1521
DB_DATABASE=rxthinkcmf.laravel13.naivevue
DB_USERNAME=root
DB_PASSWORD=root
DB_PREFIX=laravel_
ini
DB_CONNECTION=sqlite
# DB_DATABASE 指向 database/database.sqlite(默认值)
DB_PREFIX=laravel_

配置文件结构 ​

php
// config/database.php
return [
    'default' => env('DB_CONNECTION', 'mysql'),
    'connections' => [
        'sqlite'  => [...],
        'mysql'   => [...],
        'pgsql'   => [...],
        'sqlsrv'  => [...],
        'oracle'  => [...],   // 自定义 oci 驱动(AppServiceProvider 注册 DB::extend)
    ],
];

Oracle 接入说明

Laravel 核心不内置 Oracle 连接器,项目通过 AppServiceProvider 中 DB::extend('oci', ...) 注册自定义驱动,配套 App\\Support\\Database\\{OracleConnection, OracleGrammar, OracleProcessor} 完成分页语法与自增主键回填适配。切换前需安装 pdo_oci 扩展(见 2.1 开发环境准备)。

字段类型映射 ​

通用类型MySQLPostgreSQLSQL ServerOracleSQLite
自增主键INT AUTO_INCREMENTSERIALINT IDENTITYNUMBER + 序列/触发器INTEGER PRIMARY KEY
字符串VARCHAR(n)VARCHAR(n)NVARCHAR(n)VARCHAR2(n)TEXT
文本TEXTTEXTNVARCHAR(MAX)CLOBTEXT
布尔TINYINT(1)BOOLEANBITNUMBER(1)INTEGER
日期时间DATETIMETIMESTAMPDATETIME2TIMESTAMPTEXT
小数DECIMAL(m,n)NUMERIC(m,n)DECIMAL(m,n)NUMBER(m,n)REAL

业务代码零修改

Eloquent 的方言层自动处理大部分 SQL 差异,切换数据库只需修改 .env 中的 DB_CONNECTION,业务代码无需任何修改。跨库 DDL 由 DbSchemaBuilder 按驱动生成(Oracle 自增序列与触发器自动创建)。

各数据库安装 ​

数据库的安装与初始化步骤已在 2.1 开发环境准备(含四平台安装命令、扩展启用、Oracle Instant Client)与 2.5 数据库初始化(建库、脚本导入、.env 配置)中完整说明,此处不再重复。

SQL 脚本 ​

项目为每种数据库提供了独立的 SQL 脚本,存放在 document/ 目录下按数据库类型分组:

text
document/
├── mysql/
│   └── rxthinkcmf.laravel13.naivevue.sql      # MySQL 版本
├── postgresql/
│   └── rxthinkcmf.laravel13.naivevue.sql      # PostgreSQL 版本
├── sqlserver/
│   └── rxthinkcmf.laravel13.naivevue.sql      # SQL Server 版本
├── oracle/
│   └── rxthinkcmf.laravel13.naivevue.sql      # Oracle 版本
└── sqlite/
    └── rxthinkcmf.laravel13.naivevue.sql      # SQLite 版本

各数据库脚本包含完整的表结构定义和初始数据(用户、角色、菜单、字典、城市行政区划等),已针对各数据库的 SQL 语法做了适配,可直接导入使用。

WARNING

本项目 database/migrations/ 为空,建表以 SQL 脚本为准,php artisan migrate 不会创建业务表。导入方法详见 2.5 数据库初始化。

慢查询排查 ​

ini
# MySQL my.cnf / my.ini
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

注意

项目所有查询都通过 Eloquent 查询构建器构建(参数绑定),不会出现原生 SQL 注入。如需排查慢查询,建议开启数据库慢查询日志,而非在代码层面埋点;同时核对 索引策略 中的推荐索引是否缺失。

`,73)])])}const F=t(d,[["render",n]]);export{c as __pageData,F as default};