Files
workspace/code/fms/FMS新系统核心表结构设计.md
T
2026-08-18 22:08:49 +08:00

43 KiB
Raw Blame History

FMS 新系统核心表结构设计

1. 说明

本文档给出 FMS 新系统核心平台表的 SQL Server 建表语句,范围包括元数据中心(模块、实体、字段、关系、页面菜单、视图、表单、多语言)、Schema Compiler、权限中心、技术日志、登录日志与业务审计。

设计原则:

  • 业务实体(订舱、集装箱、发票等)由 Schema Compiler 根据 s_module_entity + s_module_field 生成真实物理表,本文档只定义平台核心表。
  • 实体是数据和字段的所有者,页面只是实体的一种展示方式;字段挂实体(s_module_entity),不挂菜单。
  • 页面和菜单合并为一条 s_module_menu 记录(导航节点 = 页面入口),用 b_menu_type 区分节点性质。
  • 元数据变更通过服务层校验后立即生效,DDL 同步执行、失败回滚,不做异步迁移任务表,也不建立配置变更集、版本快照或运行时状态表。

约定如下:

  • 所有表名以 s_ 开头,字段名以 b_ 开头。
  • 表名、字段名、索引名和约束名统一使用 snake_case。
  • 不创建物理外键,关联字段只作为逻辑外键使用。
  • 逻辑外键必须创建必要的普通索引或唯一索引。
  • 一个租户使用一个独立业务数据库,普通业务表不重复保存 b_tenant_id 或 b_org_id;集中技术日志和登录日志允许使用 b_org_id 标识日志来源。
  • 内部主键统一使用 bigint identity(1, 1),跨环境标识使用稳定的 b_*_key。
  • 同库内的逻辑关联 ID(例如 b_form_id)统一使用 bigint,不使用 uniqueidentifier。
  • 时间点统一使用 datetime2(3),应用层按 UTC 写入。
  • 稳定业务标识统一使用 b_*_key,跨环境导入导出不得依赖内部 b_id。
  • 扩展内容统一使用 nvarchar(max) 普通文本保存,由应用层按业务约定解析和校验,不使用 JSON 字段类型。
  • 原布尔语义字段统一使用 tinyint,取值约定为 0(否)或 1(是)。
  • 核心业务字段使用真实数据库列,不采用全量 EAV;不设置无业务含义的通用扩展列(如 b_bz1~n、mx_varchar_n),字段必须有明确的 b_field_key 与语义。
  • 下面的 b_*_id、b_*_key 关联均为逻辑外键,由应用服务负责校验一致性。

2. 元数据中心

2.1 模块

模块是业务能力边界,不是数据库表的别名。模块只保存身份、依赖与启用状态,不承载菜单、路由或数据源职责。

create table dbo.s_module (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_module_key nvarchar(128) not null,                -- 模块稳定业务标识(如 ocean、finance、master-data)
    b_name_key nvarchar(256) not null,                  -- 模块显示名多语言 key
    b_description nvarchar(1000) null,                  -- 模块描述
    b_origin nvarchar(32) not null                      -- 来源:platform 平台内置 / tenant 租户定制
        constraint df_s_module_origin default N'platform',
    b_enabled tinyint not null                          -- 是否启用(1启用/0停用)
        constraint df_s_module_enabled default 1,
    b_sort_no int not null                              -- 模块排序号
        constraint df_s_module_sort_no default 0,
    b_icon_key nvarchar(128) null,                      -- 模块图标 key
    b_config_text nvarchar(max) null,                   -- 模块扩展配置(应用自定义解析)
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module primary key (b_id),
    constraint ux_s_module_key unique (b_module_key)
);

create index ix_s_module_key
    on dbo.s_module (b_module_key, b_enabled);

2.2 模块依赖

模块依赖必须形成有向无环图,不允许循环依赖。

create table dbo.s_module_dependency (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_module_key nvarchar(128) not null,                -- 依赖方模块 key(如 ocean)
    b_depends_on_module_key nvarchar(128) not null,     -- 被依赖模块 key(如 master-data)
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_dependency_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_dependency primary key (b_id),
    constraint ux_s_module_dependency_key unique (
        b_module_key,
        b_depends_on_module_key
    )
);

create index ix_s_module_dependency_depends_on
    on dbo.s_module_dependency (b_depends_on_module_key);

2.3 实体

实体是数据和字段的所有者,映射一张真实物理表。页面、列表、表单都只是实体的展示方式。

create table dbo.s_module_entity (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_entity_key nvarchar(192) not null,                -- 实体稳定业务标识(如 ocean.booking)
    b_module_key nvarchar(128) not null,                -- 所属模块 key
    b_name_key nvarchar(256) not null,                  -- 实体显示名多语言 key
    b_description nvarchar(1000) null,                  -- 实体描述
    b_physical_table sysname not null,                  -- 真实物理表名(如 ocean_booking)
    b_delete_policy nvarchar(32) not null               -- 删除策略(默认 lifecycle)
        constraint df_s_module_entity_delete_policy default N'lifecycle',
    b_origin nvarchar(32) not null                      -- 来源:platform / tenant
        constraint df_s_module_entity_origin default N'platform',
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_module_entity_enabled default 1,
    b_config_text nvarchar(max) null,                   -- 实体扩展配置
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_entity_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_entity primary key (b_id),
    constraint ux_s_module_entity_key unique (b_entity_key)
);

create index ix_s_module_entity_module_key
    on dbo.s_module_entity (b_module_key, b_enabled);

删除策略取值(b_delete_policy):

restrictWhenReferenced  主数据:有引用时拒绝删除,只能停用或合并
lifecycle               业务单据:草稿且无下游时可删,正式后只能取消/作废
cascadeOwned            主表拥有的从数据:随主表同一事务级联删除
hardDelete              临时记录:校验权限后直接物理删除

2.4 字段

字段属于实体,同时携带数据库列定义、UI 行为与业务语义(供 UI 和 AI 理解)。

create table dbo.s_module_field (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_entity_key nvarchar(192) not null,                -- 所属实体 key
    b_field_key nvarchar(128) not null,                 -- 字段稳定业务标识(如 carrier_id)
    b_name_key nvarchar(256) not null,                  -- 字段显示名多语言 key
    b_label nvarchar(256) not null,                     -- 字段标签(可随时改,不改数据库)
    b_description nvarchar(1000) null,                  -- 字段描述
    b_physical_column_name sysname not null,            -- 真实数据库列名(通常与 b_field_key 相同)
    b_data_type nvarchar(64) not null,                  -- 存储数据类型(如 varchar/decimal/datetime)
    b_semantic_type nvarchar(128) null,                 -- 语义类型(如 email/money/phone,供 UI/AI 理解)
    b_write_mode nvarchar(32) not null                  -- 后端写入模式(如 direct/compute/readonly)
        constraint df_s_module_field_write_mode default N'direct',
    b_required tinyint not null                         -- 是否必填
        constraint df_s_module_field_required default 0,
    b_enabled tinyint not null                          -- 是否启用(停用则隐藏并保留数据)
        constraint df_s_module_field_enabled default 1,
    b_queryable tinyint not null                        -- 是否出现在查询条件中
        constraint df_s_module_field_queryable default 0,
    b_sortable tinyint not null                         -- 是否可排序
        constraint df_s_module_field_sortable default 0,
    b_list_visible tinyint not null                     -- 是否显示在固定列表组件
        constraint df_s_module_field_list_visible default 1,
    b_edit_visible tinyint not null                     -- 是否显示在固定编辑组件
        constraint df_s_module_field_edit_visible default 1,
    b_readonly tinyint not null                         -- 编辑组件中是否只读
        constraint df_s_module_field_readonly default 0,
    b_sort_no int not null                              -- 列表/表单默认排序
        constraint df_s_module_field_sort_no default 0,
    b_width int null,                                   -- 列表列宽(px)
    b_component_type nvarchar(64) null,                 -- 固定表单组件类型(input/select/date)
    b_auditable tinyint not null                        -- 是否记录字段级审计
        constraint df_s_module_field_auditable default 0,
    b_audit_visibility nvarchar(32) null,               -- 审计可见性(内部/客户可见)
    b_sensitive tinyint not null                        -- 是否敏感字段(涉及脱敏/导出控制)
        constraint df_s_module_field_sensitive default 0,
    b_max_length int null,                              -- 字符串最大长度
    b_numeric_precision tinyint null,                   -- 数值精度(总位数)
    b_numeric_scale tinyint null,                       -- 数值小数位
    b_temporal_type nvarchar(32) null,                  -- 时间类型(如 date/datetime)
    b_unit_key nvarchar(128) null,                      -- 计量单位 key
    b_default_value_text nvarchar(max) null,            -- 默认值(文本表达)
    b_aliases_text nvarchar(max) null,                  -- 字段别名(搜索/AI 理解用)
    b_validation_text nvarchar(max) null,               -- 校验规则(文本表达)
    b_ai_hints_text nvarchar(max) null,                 -- 给 AI 理解的提示信息
    b_origin nvarchar(32) not null                      -- 来源:platform / tenant
        constraint df_s_module_field_origin default N'platform',
    b_required_by_code tinyint not null                 -- 是否被代码强依赖
        constraint df_s_module_field_required_by_code default 0,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_field_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_field primary key (b_id),
    constraint ux_s_module_field_key unique (
        b_entity_key,
        b_field_key
    )
);

create index ix_s_module_field_entity_key
    on dbo.s_module_field (b_entity_key, b_enabled, b_sort_no, b_field_key);

create index ix_s_module_field_physical_column_name
    on dbo.s_module_field (b_entity_key, b_physical_column_name);

写入模式取值(b_write_mode):

direct      可通过 saveobjt 普通保存(如备注、ETD、件数)
createOnly  仅创建时允许写入(如来源系统、初始业务类型)
readOnly    前端和普通接口只读(如汇总金额、关联展示值)
computed    由公式或计算服务生成(如毛利、计费重量)
actionOnly  只能通过指定业务动作修改(如审核状态、确认时间)
system      仅平台内部维护(如创建人、版本、流水状态)

2.5 关系

b_relation 描述实体之间的引用与主子关系,通用运行时据此执行外键校验、主子事务、级联删除和子表区域渲染。

create table dbo.s_module_relation (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_relation_key nvarchar(192) not null,              -- 关系稳定业务标识
    b_entity_key nvarchar(192) not null,                -- 主实体 key
    b_relation_type nvarchar(32) not null,              -- 关系类型:one-to-one/one-to-many/many-to-one/many-to-many
    b_target_entity_key nvarchar(192) not null,         -- 目标实体 key
    b_ownership nvarchar(32) not null                   -- 所有权(默认 reference 引用)
        constraint df_s_module_relation_ownership default N'reference',
    b_required tinyint not null                         -- 是否必填
        constraint df_s_module_relation_required default 0,
    b_delete_policy nvarchar(32) null,                  -- 删除策略:restrict/set-null/cascade/archive
    b_save_strategy nvarchar(32) null,                  -- 保存策略:separate 独立保存 / with-parent 随主实体事务保存
    b_order_field nvarchar(256) null,                   -- 子表排序字段表达式
    b_unique_constraint tinyint not null                -- 是否唯一约束
        constraint df_s_module_relation_unique_constraint default 0,
    b_name_key nvarchar(256) not null,                  -- 关系显示名多语言 key
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_module_relation_enabled default 1,
    b_config_text nvarchar(max) null,                   -- 关系扩展配置
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_relation_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_relation primary key (b_id),
    constraint ux_s_module_relation_key unique (b_relation_key)
);

create index ix_s_module_relation_entity_key
    on dbo.s_module_relation (b_entity_key, b_enabled);

create index ix_s_module_relation_target_entity_key
    on dbo.s_module_relation (b_target_entity_key);

2.6 页面菜单入口

每条菜单记录同时代表一个导航节点和一个页面入口。directory 仅表示目录节点,page 使用固定 Vue 页面组件,data_category 表示数据目录,data 表示由通用列表与表单组件维护的数据模块,external 表示外链。

create table dbo.s_module_menu (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_menu_key nvarchar(192) not null,                  -- 菜单/页面稳定业务标识
    b_module_key nvarchar(128) null,                    -- 所属平台模块 key
    b_parent_menu_key nvarchar(192) null,               -- 父菜单 key(导航树自引用)
    b_name_key nvarchar(256) not null,                  -- 菜单显示名多语言 key
    b_menu_type nvarchar(32) not null,                  -- 菜单类型:directory/page/data_category/data/external
    b_route nvarchar(256) null,                         -- 固定页面或外链路由
    b_entity_key nvarchar(192) null,                    -- data 类型绑定的实体 key
    b_view_key nvarchar(192) null,                      -- 绑定的列表视图 key
    b_form_key nvarchar(192) null,                      -- 绑定的表单 key
    b_permission_key nvarchar(192) null,                -- 页面访问权限 key
    b_icon_key nvarchar(128) null,                      -- 菜单图标 key
    b_sort_no int not null                              -- 菜单排序号
        constraint df_s_module_menu_sort_no default 0,
    b_can_menu tinyint not null                         -- 是否显示在菜单中
        constraint df_s_module_menu_can_menu default 1,
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_module_menu_enabled default 1,
    b_config_text nvarchar(max) null,                   -- 菜单/页面扩展配置
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_menu_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_menu primary key (b_id),
    constraint ux_s_module_menu_key unique (b_menu_key)
);

create index ix_s_module_menu_module_key
    on dbo.s_module_menu (b_module_key, b_enabled);

create index ix_s_module_menu_parent_key
    on dbo.s_module_menu (b_parent_menu_key, b_sort_no, b_enabled);

create index ix_s_module_menu_route
    on dbo.s_module_menu (b_route, b_enabled);

create index ix_s_module_menu_entity_key
    on dbo.s_module_menu (b_entity_key, b_enabled);

约束由元数据校验器执行:directory 节点不能填写业务表或外链路由;page 节点必须填写 b_route,并绑定 b_view_key/b_form_key;data 节点必须填写 b_entity_key 和 b_view_key(列表)、b_form_key(表单);external 节点必须填写 b_route 和 b_permission_key。固定页面组件负责布局,表中只保存实体与视图/表单引用和导航配置。目录仅在至少存在一个可访问子页面时显示。

2.7 视图(列表)

视图定义"一个实体的一种列表展示方式",一个实体可以有多个视图。列表字段配置在 s_module_view_field。

create table dbo.s_module_view (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_view_key nvarchar(192) not null,                  -- 视图稳定业务标识(如 ocean.booking.default-list)
    b_entity_key nvarchar(192) not null,                -- 所属实体 key
    b_name_key nvarchar(256) not null,                  -- 视图显示名多语言 key
    b_queryable tinyint not null                        -- 是否提供查询条件区
        constraint df_s_module_view_queryable default 1,
    b_exportable tinyint not null                       -- 是否允许导出
        constraint df_s_module_view_exportable default 1,
    b_page_size int null,                               -- 默认分页大小
    b_config_text nvarchar(max) null,                   -- 视图扩展配置
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_module_view_enabled default 1,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_view_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_view primary key (b_id),
    constraint ux_s_module_view_key unique (b_view_key)
);

create index ix_s_module_view_entity_key
    on dbo.s_module_view (b_entity_key, b_enabled);

create table dbo.s_module_view_field (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_view_key nvarchar(192) not null,                  -- 所属视图 key
    b_field_key nvarchar(128) not null,                 -- 引用的字段 key
    b_sort_no int not null                              -- 列排序号
        constraint df_s_module_view_field_sort_no default 0,
    b_width int null,                                   -- 列宽(px)
    b_visible tinyint not null                          -- 是否显示
        constraint df_s_module_view_field_visible default 1,
    b_frozen tinyint not null                           -- 是否固定列
        constraint df_s_module_view_field_frozen default 0,
    b_align nvarchar(16) null,                          -- 对齐方式(left/center/right)
    b_format_text nvarchar(256) null,                   -- 显示格式(如日期、千分位)
    b_queryable tinyint not null                        -- 是否作为查询条件
        constraint df_s_module_view_field_queryable default 0,
    b_query_operator nvarchar(32) null,                 -- 查询运算符(eq/contains/gte/...)
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_view_field_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_view_field primary key (b_id),
    constraint ux_s_module_view_field_key unique (
        b_view_key,
        b_field_key
    )
);

create index ix_s_module_view_field_view_key
    on dbo.s_module_view_field (b_view_key, b_sort_no);

2.8 表单

表单定义"一个实体的一种编辑展示方式",一个实体可以有多个表单(默认编辑表单、详情表单)。子表区域通过 s_module_form_relation 引用关系并绑定子表视图/表单。

create table dbo.s_module_form (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_form_key nvarchar(192) not null,                  -- 表单稳定业务标识(如 ocean.booking.default-form)
    b_entity_key nvarchar(192) not null,                -- 所属实体 key
    b_name_key nvarchar(256) not null,                  -- 表单显示名多语言 key
    b_form_type nvarchar(32) not null                   -- 表单类型(默认 default)
        constraint df_s_module_form_form_type default N'default',
    b_config_text nvarchar(max) null,                   -- 表单扩展配置(控件特有属性与布局 JSON)
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_module_form_enabled default 1,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_form_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_form primary key (b_id),
    constraint ux_s_module_form_key unique (b_form_key)
);

create index ix_s_module_form_entity_key
    on dbo.s_module_form (b_entity_key, b_enabled);

create table dbo.s_module_form_field (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_form_key nvarchar(192) not null,                  -- 所属表单 key
    b_field_key nvarchar(128) not null,                 -- 引用的字段 key
    b_group_key nvarchar(128) null,                     -- 所属分组 key(逻辑分组)
    b_sort_no int not null                              -- 表单内排序号
        constraint df_s_module_form_field_sort_no default 0,
    b_required tinyint not null                         -- 是否必填(覆盖字段默认)
        constraint df_s_module_form_field_required default 0,
    b_readonly tinyint not null                         -- 是否只读(覆盖字段默认)
        constraint df_s_module_form_field_readonly default 0,
    b_visible tinyint not null                          -- 是否显示
        constraint df_s_module_form_field_visible default 1,
    b_span int null,                                    -- 布局占宽(栅格)
    b_component_type nvarchar(64) null,                 -- 控件类型(覆盖字段默认)
    b_config_text nvarchar(max) null,                   -- 控件扩展配置
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_form_field_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_form_field primary key (b_id),
    constraint ux_s_module_form_field_key unique (
        b_form_key,
        b_field_key
    )
);

create index ix_s_module_form_field_form_key
    on dbo.s_module_form_field (b_form_key, b_sort_no);

create table dbo.s_module_form_relation (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_form_key nvarchar(192) not null,                  -- 所属表单 key
    b_relation_key nvarchar(192) not null,              -- 引用的主子关系 key
    b_child_view_key nvarchar(192) null,                -- 子表列表配置 key
    b_child_form_key nvarchar(192) null,                -- 子表编辑配置 key(可选)
    b_display_mode nvarchar(16) not null                -- 子表显示模式(默认 table)
        constraint df_s_module_form_relation_display_mode default N'table',
    b_editable tinyint not null                         -- 是否可编辑
        constraint df_s_module_form_relation_editable default 1,
    b_allow_add tinyint not null                        -- 是否允许新增行
        constraint df_s_module_form_relation_allow_add default 1,
    b_allow_delete tinyint not null                     -- 是否允许删除行
        constraint df_s_module_form_relation_allow_delete default 1,
    b_allow_sort tinyint not null                       -- 是否允许排序行
        constraint df_s_module_form_relation_allow_sort default 1,
    b_sort_no int not null                              -- 子表区域排序号
        constraint df_s_module_form_relation_sort_no default 0,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_form_relation_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_form_relation primary key (b_id),
    constraint ux_s_module_form_relation_key unique (
        b_form_key,
        b_relation_key
    )
);

create index ix_s_module_form_relation_form_key
    on dbo.s_module_form_relation (b_form_key, b_sort_no);

2.9 多语言

多语言是元数据运行时的一部分,统一解析模块、菜单、实体、字段、动作和主数据的显示名称。

create table dbo.s_module_i18n (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_resource_key nvarchar(256) not null,              -- 多语言资源 key(如 nameKey)
    b_locale nvarchar(32) not null,                     -- 语言区域(如 zh-CN/en-US)
    b_resource_value nvarchar(max) not null,            -- 该语言下的显示文本
    b_source_type nvarchar(32) not null                 -- 来源类型(默认 manual 人工 / ai AI 生成)
        constraint df_s_module_i18n_source_type default N'manual',
    b_resource_status nvarchar(32) not null             -- 资源状态(默认 confirmed 已确认)
        constraint df_s_module_i18n_resource_status default N'confirmed',
    b_model_key nvarchar(128) null,                     -- 生成翻译的 AI 模型标识(追溯用)
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_module_i18n_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_module_i18n primary key (b_id),
    constraint ux_s_module_i18n_key_locale unique (
        b_resource_key,
        b_locale
    )
);

create index ix_s_module_i18n_resource_key
    on dbo.s_module_i18n (b_resource_key, b_locale);

3. Schema Compiler

元数据变更通过服务层校验后立即生效。Schema Compiler 根据 s_module_entity 的物理表配置和 s_module_field 的物理字段配置生成所需的 CREATE TABLE、ALTER TABLE、索引和约束语句,并由应用服务直接执行;执行成功后提交元数据变更,失败则回滚本次操作并返回错误。

执行机制:

  • DDL 同步执行,单租户库内加锁,同一时间只允许一个结构变更任务;其他租户不受影响。
  • 每个变更步骤记录开始时间、结束时间、checksum 和执行结果;重启或网络中断后可以从最后一个已确认步骤继续执行。
  • DDL、数据转换和结构校验全部成功后,才提交元数据变更;提交失败保持原结构,进入可修复状态。
  • 变更审计统一写入现有审计日志;本阶段不建立配置变更集、版本快照或迁移任务表,如果未来需要异步执行、失败重试、断点恢复或版本回滚,再增加专用任务表。
  • 破坏性变更(删除字段、缩短长度、改变类型)采用 expand-contract:先新增兼容结构、双写或分批迁移数据、校验新旧数据、停止写入旧结构、经过保留期后归档或删除旧结构。

4. 统一权限中心

4.1 角色与用户角色关系

create table dbo.s_auth_role (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_role_key nvarchar(128) not null,                  -- 角色稳定业务标识
    b_role_name nvarchar(256) not null,                 -- 角色名称
    b_description nvarchar(1000) null,                  -- 角色描述
    b_role_type nvarchar(32) not null                   -- 角色类型(默认 custom 自定义)
        constraint df_s_auth_role_role_type default N'custom',
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_auth_role_enabled default 1,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_auth_role_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    b_updated_at datetime2(3) null,                     -- 更新时间
    b_updated_by nvarchar(128) null,                    -- 更新人
    constraint pk_s_auth_role primary key (b_id),
    constraint ux_s_auth_role_key unique (b_role_key)
);

create table dbo.s_auth_user_role (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_user_key nvarchar(128) not null,                  -- 用户稳定 key
    b_role_key nvarchar(128) not null,                  -- 角色 key
    b_enabled tinyint not null                          -- 是否启用(该用户角色关系)
        constraint df_s_auth_user_role_enabled default 1,
    b_effective_from datetime2(3) null,                 -- 生效开始时间(可定时)
    b_effective_to datetime2(3) null,                   -- 生效结束时间(可定时)
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_auth_user_role_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_auth_user_role primary key (b_id),
    constraint ux_s_auth_user_role_key unique (b_user_key, b_role_key)
);

create index ix_s_auth_user_role_role_key
    on dbo.s_auth_user_role (b_role_key, b_enabled);

4.2 功能权限

首期只做 RBAC 功能授权(页面、实体、动作、字段)。数据范围策略(auth_data_policy)和字段查看/导出/脱敏策略(auth_field_policy)作为后续扩展,不在本版本建表。

create table dbo.s_auth_permission (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_permission_key nvarchar(192) not null,            -- 权限稳定业务标识
    b_module_key nvarchar(128) null,                    -- 所属模块 key
    b_resource_type nvarchar(32) not null,              -- 资源类型(如 menu/entity/field/action)
    b_resource_key nvarchar(256) not null,              -- 资源稳定 key(被授权的对象)
    b_action_type nvarchar(64) null,                    -- 操作类型(如 view/create/update/delete/confirm)
    b_name_key nvarchar(256) not null,                  -- 权限显示名多语言 key
    b_description nvarchar(1000) null,                  -- 权限描述
    b_enabled tinyint not null                          -- 是否启用
        constraint df_s_auth_permission_enabled default 1,
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_auth_permission_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                 -- 创建人
    constraint pk_s_auth_permission primary key (b_id),
    constraint ux_s_auth_permission_key unique (b_permission_key)
);

create table dbo.s_auth_role_permission (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_role_key nvarchar(128) not null,                  -- 角色 key
    b_permission_key nvarchar(192) not null,            -- 权限 key
    b_permission_effect nvarchar(16) not null           -- 权限效果(默认 allow 允许)
        constraint df_s_auth_role_permission_effect default N'allow',
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_auth_role_permission_created_at default sysutcdatetime(),
    b_created_by nvarchar(128) not null,                -- 创建人
    constraint pk_s_auth_role_permission primary key (b_id),
    constraint ux_s_auth_role_permission_key unique (
        b_role_key,
        b_permission_key
    )
);

create index ix_s_auth_permission_resource_key
    on dbo.s_auth_permission (b_resource_type, b_resource_key, b_enabled);

create index ix_s_auth_role_permission_permission_key
    on dbo.s_auth_role_permission (b_permission_key, b_permission_effect);

菜单显示继承页面访问权限:用户拥有 s_module_menu.b_permission_key 对应权限时菜单才显示;目录菜单在无可访问子页面时自动隐藏。前端只控制显示,后端通用数据运行时和动作引擎必须再次检查同一个权限 key。

5. 日志与审计

5.1 技术日志

技术日志主要用于请求链路、SQL、异常、性能和外部接口排查,推荐写入 Loki、OpenSearch、Elasticsearch 等日志平台。下面的表适合集中日志库或短期数据库兜底,不建议把所有高频技术日志长期写入租户业务库。

create table dbo.s_log_technical (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_occurred_at datetime2(3) not null                 -- 发生时间(UTC)
        constraint df_s_log_technical_occurred_at default sysutcdatetime(),
    b_log_level nvarchar(16) not null,                  -- 日志级别(如 INFO/WARN/ERROR)
    b_log_category nvarchar(64) not null,               -- 日志分类(如 sql/exception/performance)
    b_operation nvarchar(192) not null,                 -- 操作名(如 loadData/saveObject)
    b_org_id nvarchar(128) null,                        -- 租户/组织 ID(日志来源标识)
    b_user_key nvarchar(128) null,                      -- 操作用户 key
    b_source_type nvarchar(32) null,                    -- 来源类型(如 web/api)
    b_module_key nvarchar(128) null,                    -- 相关模块 key
    b_operation_key nvarchar(192) null,                 -- 相关操作 key(如 saveObject.submit)
    b_request_id nvarchar(128) null,                    -- 请求 ID
    b_trace_id nvarchar(128) null,                      -- 追踪 ID(串联链路)
    b_application_version nvarchar(128) null,           -- 应用版本
    b_server_node nvarchar(128) null,                   -- 服务节点标识
    b_duration_ms bigint null,                          -- 耗时(毫秒)
    b_result_code nvarchar(128) null,                   -- 结果码
    b_error_code nvarchar(128) null,                    -- 错误码
    b_error_message nvarchar(2000) null,                -- 错误信息
    b_exception_text nvarchar(max) null,                -- 异常堆栈(文本)
    b_context_text nvarchar(max) null,                  -- 上下文信息(文本)
    constraint pk_s_log_technical primary key (b_id)
);

create index ix_s_log_technical_trace_id
    on dbo.s_log_technical (b_trace_id, b_occurred_at desc);

create index ix_s_log_technical_org_time
    on dbo.s_log_technical (b_org_id, b_occurred_at desc);

create index ix_s_log_technical_level_time
    on dbo.s_log_technical (b_log_level, b_occurred_at desc);

5.2 登录日志

登录日志记录登录成功、失败、退出、刷新令牌和账号锁定等安全事件。它可以与技术日志使用相同的 b_request_id、b_trace_id 关联,但业务职责独立。

create table dbo.s_log_login (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_org_id nvarchar(128) null,                        -- 租户/组织 ID
    b_user_key nvarchar(128) null,                      -- 用户 key
    b_login_name nvarchar(256) null,                    -- 登录名
    b_login_type nvarchar(32) not null,                 -- 登录类型(如 password/token)
    b_login_status nvarchar(32) not null,               -- 登录状态(如 success/failed)
    b_auth_method nvarchar(32) null,                    -- 认证方式(如 ldap/oidc)
    b_failure_reason nvarchar(512) null,                -- 失败原因
    b_ip_address varchar(64) null,                      -- 登录 IP
    b_user_agent nvarchar(1000) null,                   -- 客户端 UA
    b_device_key nvarchar(256) null,                    -- 设备标识
    b_request_id nvarchar(128) null,                    -- 请求 ID
    b_trace_id nvarchar(128) null,                      -- 追踪 ID
    b_occurred_at datetime2(3) not null                 -- 发生时间(UTC)
        constraint df_s_log_login_occurred_at default sysutcdatetime(),
    b_created_at datetime2(3) not null                  -- 创建时间(UTC)
        constraint df_s_log_login_created_at default sysutcdatetime(),
    constraint pk_s_log_login primary key (b_id)
);

create index ix_s_log_login_user_time
    on dbo.s_log_login (b_user_key, b_occurred_at desc);

create index ix_s_log_login_name_time
    on dbo.s_log_login (b_login_name, b_occurred_at desc);

create index ix_s_log_login_status_time
    on dbo.s_log_login (b_login_status, b_occurred_at desc);

create index ix_s_log_login_trace_id
    on dbo.s_log_login (b_trace_id, b_occurred_at desc);

5.3 业务审计事件与字段变更

create table dbo.s_log_audit (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_event_key nvarchar(192) not null,                 -- 业务事件稳定标识
    b_module_key nvarchar(128) not null,                -- 被审计的数据模块 key
    b_entity_id nvarchar(128) not null,                 -- 被审计的业务数据 ID
    b_business_no nvarchar(192) null,                   -- 业务单号(如订舱号)
    b_operation_key nvarchar(192) null,                 -- 触发的操作 key(如 saveObject.submit)
    b_operator_key nvarchar(128) not null,              -- 操作人 key
    b_operator_name nvarchar(256) null,                 -- 操作人名称(快照)
    b_source_type nvarchar(32) not null,                -- 来源类型(如 user/ai/api)
    b_visibility nvarchar(32) not null,                 -- 可见性(内部/客户可见)
    b_request_id nvarchar(128) null,                    -- 请求 ID
    b_trace_id nvarchar(128) not null,                  -- 追踪 ID(关联技术日志)
    b_business_event_id bigint null,                    -- 关联的业务事件 ID
    b_payload_text nvarchar(max) null,                  -- 事件载荷(文本,如前后快照)
    b_occurred_at datetime2(3) not null                 -- 发生时间(UTC)
        constraint df_s_log_audit_occurred_at default sysutcdatetime(),
    constraint pk_s_log_audit primary key (b_id)
);

create table dbo.s_log_audit_field (
    b_id bigint identity(1, 1) not null,                -- 内部自增主键
    b_event_id bigint not null,                         -- 所属审计事件 ID
    b_module_key nvarchar(128) not null,                -- 数据模块 key
    b_entity_id nvarchar(128) not null,                 -- 业务数据 ID
    b_field_key nvarchar(128) not null,                 -- 变更的字段 key
    b_field_label_snapshot nvarchar(256) null,          -- 字段标签快照
    b_before_value_text nvarchar(max) null,             -- 变更前原始值
    b_after_value_text nvarchar(max) null,              -- 变更后原始值
    b_before_display_value nvarchar(1000) null,         -- 变更前显示值(如引用字段 label)
    b_after_display_value nvarchar(1000) null,          -- 变更后显示值
    b_visibility nvarchar(32) not null,                 -- 可见性(内部/客户可见)
    constraint pk_s_log_audit_field primary key (b_id)
);

create index ix_s_log_audit_module
    on dbo.s_log_audit (b_module_key, b_entity_id, b_occurred_at desc);

create index ix_s_log_audit_trace_id
    on dbo.s_log_audit (b_trace_id);

create index ix_s_log_audit_field_audit_event_id
    on dbo.s_log_audit_field (b_event_id);

6. 逻辑外键清单

以下关联不创建物理外键,由服务层、变更校验器和 Schema Compiler 负责检查:

表 字段 逻辑目标
s_module_dependency b_module_key s_module.b_module_key
s_module_dependency b_depends_on_module_key s_module.b_module_key
s_module_entity b_module_key s_module.b_module_key
s_module_field b_entity_key s_module_entity.b_entity_key
s_module_relation b_entity_key s_module_entity.b_entity_key
s_module_relation b_target_entity_key s_module_entity.b_entity_key
s_module_menu b_module_key s_module.b_module_key
s_module_menu b_parent_menu_key s_module_menu.b_menu_key
s_module_menu b_entity_key s_module_entity.b_entity_key
s_module_menu b_view_key s_module_view.b_view_key
s_module_menu b_form_key s_module_form.b_form_key
s_module_menu b_permission_key s_auth_permission.b_permission_key
s_module_view b_entity_key s_module_entity.b_entity_key
s_module_view_field b_view_key s_module_view.b_view_key
s_module_view_field b_field_key 实体范围内的 s_module_field.b_field_key
s_module_form b_entity_key s_module_entity.b_entity_key
s_module_form_field b_form_key s_module_form.b_form_key
s_module_form_field b_field_key 实体范围内的 s_module_field.b_field_key
s_module_form_relation b_form_key s_module_form.b_form_key
s_module_form_relation b_relation_key s_module_relation.b_relation_key
s_module_form_relation b_child_view_key s_module_view.b_view_key
s_module_form_relation b_child_form_key s_module_form.b_form_key
s_auth_user_role b_role_key s_auth_role.b_role_key
s_auth_role_permission b_permission_key s_auth_permission.b_permission_key
s_log_audit_field b_event_id s_log_audit.b_id
s_log_technical b_user_key 当前身份系统的用户 b_user_key
s_log_login b_user_key 当前身份系统的用户 b_user_key

逻辑外键写入时应执行以下校验:

稳定 key 是否存在
-> 目标资源是否启用
-> 跨模块引用是否合法(依赖图中可达)
-> 字段、实体类型和视图/表单配置是否匹配
-> 删除或停用前是否仍被其他资源引用

7. 实施建议

建议按以下顺序创建和启用这些表:

元数据基础表(模块/依赖/实体/字段/关系)
-> 视图与表单表
-> 页面菜单入口表
-> 多语言表
-> 权限表
-> 日志与审计表

正式执行前还应补充:

  • 根据实际 SQL Server 2022 环境确认过滤索引和 datetime2 支持情况。
  • 根据现有用户表确定 b_user_key、b_created_by 和 b_updated_by 的实际数据类型。
  • 根据最终稳定 key 长度评估唯一索引的键长度。
  • 为高数据量审计表制定归档及清理策略。
  • 用独立测试数据库执行完整建表脚本,并验证重复安装和 Schema 迁移流程。
  • 选择一条真实业务纵向验证(例如"基础资料 + 海运订舱 + 确认动作"),验证售后新增字段、Schema Compiler 加列、生成列表/表单和 DDL 失败回滚的完整链路。