# FMS 新系统核心表结构设计 ## 1. 说明 本文档给出 FMS 新系统核心平台表的 SQL Server 建表语句,范围包括元数据、动态表单、配置版本、Schema 迁移、权限、技术日志、登录日志与业务审计。 约定如下: - 所有表名以 `s_` 开头,字段名以 `b_` 开头。 - 表名、字段名、索引名和约束名统一使用 `snake_case`。 - 不创建物理外键,关联字段只作为逻辑外键使用。 - 逻辑外键必须创建必要的普通索引或唯一索引。 - 一个租户使用一个独立业务数据库,普通业务表不重复保存 `b_tenant_id` 或 `b_org_id`;集中技术日志和登录日志允许使用 `b_org_id` 标识日志来源。 - 内部主键统一使用 `bigint identity(1, 1)`,跨环境标识使用稳定的 `b_*_key`。 - 同库内的逻辑关联 ID(例如 `b_form_id`、`b_release_id`)统一使用 `bigint`,不使用 `uniqueidentifier`。 - 业务编号(例如 `b_change_set_no`、`b_release_no`)使用 `bigint`,由应用或数据库序列生成,不声明为 `identity`。 - 时间点统一使用 `datetime2(3)`,应用层按 UTC 写入。 - 稳定业务标识统一使用 `b_*_key`,跨环境导入导出不得依赖内部 `b_id`。 - 扩展内容统一使用 `nvarchar(max)` 普通文本保存,由应用层按业务约定解析和校验,不使用 JSON 字段类型。 - 原布尔语义字段统一使用 `tinyint`,取值约定为 `0`(否)或 `1`(是)。 - 下面的 `b_*_id`、`b_*_key` 关联均为逻辑外键,由应用服务负责校验一致性。 本文档只定义平台核心表。海运订舱、集装箱、发票等业务实体表由 Schema Compiler 根据 `s_meta_entity`、`s_meta_field` 和 `s_meta_relation` 生成。 ## 2. 元数据中心 ### 2.1 模块 ```sql create table dbo.s_meta_module ( b_id bigint identity(1, 1) not null, b_module_key nvarchar(128) not null, b_revision_no int not null, b_name_key nvarchar(256) not null, b_description nvarchar(1000) null, b_origin nvarchar(32) not null constraint df_s_meta_module_origin default N'platform', b_enabled tinyint not null constraint df_s_meta_module_enabled default 1, b_protected tinyint not null constraint df_s_meta_module_protected default 0, b_dependency_text nvarchar(max) null, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_module_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_module primary key (b_id), constraint ux_s_meta_module_key_revision unique (b_module_key, b_revision_no) ); create index ix_s_meta_module_key on dbo.s_meta_module (b_module_key, b_enabled); ``` ### 2.2 实体 ```sql create table dbo.s_meta_entity ( b_id bigint identity(1, 1) not null, b_entity_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_name_key nvarchar(256) not null, b_description nvarchar(1000) null, b_physical_table_name sysname not null, b_primary_key_field nvarchar(128) not null constraint df_s_meta_entity_primary_key_field default N'b_id', b_delete_policy nvarchar(64) not null, b_origin nvarchar(32) not null constraint df_s_meta_entity_origin default N'platform', b_enabled tinyint not null constraint df_s_meta_entity_enabled default 1, b_protected tinyint not null constraint df_s_meta_entity_protected default 0, b_required_by_code tinyint not null constraint df_s_meta_entity_required_by_code default 0, b_deprecated_since nvarchar(64) null, b_removable_after_version nvarchar(64) null, b_validator_key nvarchar(192) null, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_entity_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_entity primary key (b_id), constraint ux_s_meta_entity_key_revision unique (b_entity_key, b_revision_no) ); create index ix_s_meta_entity_module_key on dbo.s_meta_entity (b_module_key, b_enabled); create index ix_s_meta_entity_physical_table_name on dbo.s_meta_entity (b_physical_table_name); ``` ### 2.3 字段 ```sql create table dbo.s_meta_field ( b_id bigint identity(1, 1) not null, b_entity_key nvarchar(192) not null, b_field_key nvarchar(128) not null, b_revision_no int not null, b_name_key nvarchar(256) not null, b_label nvarchar(256) not null, b_description nvarchar(1000) null, b_physical_column_name sysname not null, b_data_type nvarchar(64) not null, b_semantic_type nvarchar(128) null, b_write_mode nvarchar(32) not null constraint df_s_meta_field_write_mode default N'direct', b_required tinyint not null constraint df_s_meta_field_required default 0, b_enabled tinyint not null constraint df_s_meta_field_enabled default 1, b_searchable tinyint not null constraint df_s_meta_field_searchable default 0, b_sortable tinyint not null constraint df_s_meta_field_sortable default 0, b_auditable tinyint not null constraint df_s_meta_field_auditable default 0, b_audit_visibility nvarchar(32) null, b_sensitive tinyint not null constraint df_s_meta_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, b_unit_key nvarchar(128) null, b_default_value_text nvarchar(max) null, b_aliases_text nvarchar(max) null, b_validation_text nvarchar(max) null, b_ai_hints_text nvarchar(max) null, b_origin nvarchar(32) not null constraint df_s_meta_field_origin default N'platform', b_protected tinyint not null constraint df_s_meta_field_protected default 0, b_required_by_code tinyint not null constraint df_s_meta_field_required_by_code default 0, b_deprecated_since nvarchar(64) null, b_removable_after_version nvarchar(64) null, b_created_at datetime2(3) not null constraint df_s_meta_field_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_field primary key (b_id), constraint ux_s_meta_field_key_revision unique ( b_entity_key, b_field_key, b_revision_no ) ); create index ix_s_meta_field_entity_key on dbo.s_meta_field (b_entity_key, b_enabled, b_field_key); create index ix_s_meta_field_physical_column_name on dbo.s_meta_field (b_entity_key, b_physical_column_name); ``` ### 2.4 实体关系 ```sql create table dbo.s_meta_relation ( b_id bigint identity(1, 1) not null, b_relation_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_source_entity_key nvarchar(192) not null, b_source_field_key nvarchar(128) null, b_target_entity_key nvarchar(192) not null, b_target_field_key nvarchar(128) not null constraint df_s_meta_relation_target_field_key default N'b_id', b_relation_type nvarchar(32) not null, b_ownership_type nvarchar(32) not null, b_required tinyint not null constraint df_s_meta_relation_required default 0, b_delete_policy nvarchar(32) not null, b_save_policy nvarchar(32) not null, b_sort_field_key nvarchar(128) null, b_unique_rule_text nvarchar(max) null, b_enabled tinyint not null constraint df_s_meta_relation_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_relation_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_relation primary key (b_id), constraint ux_s_meta_relation_key_revision unique ( b_relation_key, b_revision_no ) ); create index ix_s_meta_relation_source_entity_key on dbo.s_meta_relation (b_source_entity_key, b_enabled); create index ix_s_meta_relation_target_entity_key on dbo.s_meta_relation (b_target_entity_key, b_enabled); ``` ### 2.5 字典与字典项 ```sql create table dbo.s_meta_dictionary ( b_id bigint identity(1, 1) not null, b_dictionary_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_name_key nvarchar(256) not null, b_description nvarchar(1000) null, b_enabled tinyint not null constraint df_s_meta_dictionary_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_dictionary_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_dictionary primary key (b_id), constraint ux_s_meta_dictionary_key_revision unique ( b_dictionary_key, b_revision_no ) ); create table dbo.s_meta_dictionary_item ( b_id bigint identity(1, 1) not null, b_dictionary_id bigint not null, b_item_key nvarchar(128) not null, b_item_value nvarchar(512) not null, b_name_key nvarchar(256) not null, b_sort_no int not null constraint df_s_meta_dictionary_item_sort_no default 0, b_enabled tinyint not null constraint df_s_meta_dictionary_item_enabled default 1, b_config_text nvarchar(max) null, constraint pk_s_meta_dictionary_item primary key (b_id), constraint ux_s_meta_dictionary_item_key unique ( b_dictionary_id, b_item_key ) ); create index ix_s_meta_dictionary_item_dictionary_id on dbo.s_meta_dictionary_item (b_dictionary_id, b_enabled, b_sort_no); ``` ### 2.6 注册查询资源 ```sql create table dbo.s_meta_query_source ( b_id bigint identity(1, 1) not null, b_query_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_name_key nvarchar(256) not null, b_source_type nvarchar(32) not null, b_entity_key nvarchar(192) null, b_statement_text nvarchar(max) null, b_parameter_schema_text nvarchar(max) null, b_output_schema_text nvarchar(max) null, b_permission_key nvarchar(192) null, b_timeout_seconds int not null constraint df_s_meta_query_source_timeout_seconds default 30, b_max_rows int not null constraint df_s_meta_query_source_max_rows default 1000, b_enabled tinyint not null constraint df_s_meta_query_source_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_query_source_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_query_source primary key (b_id), constraint ux_s_meta_query_source_key_revision unique ( b_query_key, b_revision_no ) ); create index ix_s_meta_query_source_module_key on dbo.s_meta_query_source (b_module_key, b_enabled); ``` ### 2.7 页面与菜单 页面是可访问的业务入口,负责把运行时视图、表单或特殊 Vue 组件绑定到稳定路由和页面权限。菜单是页面和模块的导航表现,可以配置目录、页面和外链,但不能替代页面访问权限判断。 ```sql create table dbo.s_meta_page ( b_id bigint identity(1, 1) not null, b_page_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_name_key nvarchar(256) not null, b_page_type nvarchar(32) not null, b_route nvarchar(256) not null, b_component_key nvarchar(192) null, b_view_key nvarchar(192) null, b_form_key nvarchar(192) null, b_permission_key nvarchar(192) not null, b_visible tinyint not null constraint df_s_meta_page_visible default 1, b_enabled tinyint not null constraint df_s_meta_page_enabled default 1, b_protected tinyint not null constraint df_s_meta_page_protected default 0, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_page_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_page primary key (b_id), constraint ux_s_meta_page_key_revision unique (b_page_key, b_revision_no) ); create index ix_s_meta_page_module_key on dbo.s_meta_page (b_module_key, b_enabled); create index ix_s_meta_page_route on dbo.s_meta_page (b_route, b_enabled); create table dbo.s_meta_menu ( b_id bigint identity(1, 1) not null, b_menu_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_parent_menu_key nvarchar(192) null, b_name_key nvarchar(256) not null, b_menu_type nvarchar(32) not null, b_page_key nvarchar(192) null, b_route nvarchar(256) null, b_permission_key nvarchar(192) null, b_icon_key nvarchar(128) null, b_sort_no int not null constraint df_s_meta_menu_sort_no default 0, b_visible tinyint not null constraint df_s_meta_menu_visible default 1, b_enabled tinyint not null constraint df_s_meta_menu_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_menu_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_menu primary key (b_id), constraint ux_s_meta_menu_key_revision unique (b_menu_key, b_revision_no) ); create index ix_s_meta_menu_parent_key on dbo.s_meta_menu (b_parent_menu_key, b_sort_no, b_enabled); create index ix_s_meta_menu_page_key on dbo.s_meta_menu (b_page_key, b_enabled); ``` 约束由元数据校验器执行:`directory` 菜单不能绑定页面或路由,`page` 菜单必须绑定 `b_page_key`,`external` 菜单必须填写 `b_route` 和 `b_permission_key`;内部页面菜单的路由必须从页面资源解析,不能单独维护第二份内部路由,权限默认继承所绑定页面的 `b_permission_key`。目录仅在至少存在一个可访问子页面时显示。 ### 2.8 列表与详情视图 ```sql create table dbo.s_meta_view ( b_id bigint identity(1, 1) not null, b_view_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_entity_key nvarchar(192) not null, b_name_key nvarchar(256) not null, b_view_type nvarchar(32) not null, b_query_source_key nvarchar(192) null, b_page_size int not null constraint df_s_meta_view_page_size default 50, b_enabled tinyint not null constraint df_s_meta_view_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_view_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_view primary key (b_id), constraint ux_s_meta_view_key_revision unique (b_view_key, b_revision_no) ); create table dbo.s_meta_view_field ( b_id bigint identity(1, 1) not null, b_view_id bigint not null, b_field_key nvarchar(128) not null, b_sort_no int not null constraint df_s_meta_view_field_sort_no default 0, b_visible tinyint not null constraint df_s_meta_view_field_visible default 1, b_width int null, b_min_width int null, b_fixed_position nvarchar(16) null, b_sortable tinyint not null constraint df_s_meta_view_field_sortable default 0, b_filterable tinyint not null constraint df_s_meta_view_field_filterable default 0, b_formatter_key nvarchar(128) null, b_align_type nvarchar(16) null, b_config_text nvarchar(max) null, constraint pk_s_meta_view_field primary key (b_id), constraint ux_s_meta_view_field_key unique (b_view_id, b_field_key) ); create index ix_s_meta_view_entity_key on dbo.s_meta_view (b_entity_key, b_view_type, b_enabled); create index ix_s_meta_view_field_view_id on dbo.s_meta_view_field (b_view_id, b_sort_no); ``` ### 2.9 动态表单与主子表区域 ```sql create table dbo.s_meta_form ( b_id bigint identity(1, 1) not null, b_form_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_entity_key nvarchar(192) not null, b_name_key nvarchar(256) not null, b_form_type nvarchar(32) not null constraint df_s_meta_form_form_type default N'edit', b_column_count tinyint not null constraint df_s_meta_form_column_count default 2, b_enabled tinyint not null constraint df_s_meta_form_enabled default 1, b_layout_text nvarchar(max) null, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_form_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_form primary key (b_id), constraint ux_s_meta_form_key_revision unique (b_form_key, b_revision_no) ); create table dbo.s_meta_form_field ( b_id bigint identity(1, 1) not null, b_form_id bigint not null, b_field_key nvarchar(128) not null, b_group_key nvarchar(128) null, b_row_no int not null, b_column_no tinyint not null, b_column_span tinyint not null constraint df_s_meta_form_field_column_span default 1, b_sort_no int not null constraint df_s_meta_form_field_sort_no default 0, b_component_type nvarchar(64) not null, b_visible tinyint not null constraint df_s_meta_form_field_visible default 1, b_readonly tinyint not null constraint df_s_meta_form_field_readonly default 0, b_required_override tinyint null, b_label_position nvarchar(16) null, b_component_props_text nvarchar(max) null, b_validation_text nvarchar(max) null, b_config_text nvarchar(max) null, constraint pk_s_meta_form_field primary key (b_id), constraint ux_s_meta_form_field_key unique (b_form_id, b_field_key) ); create table dbo.s_meta_form_relation ( b_id bigint identity(1, 1) not null, b_form_id bigint not null, b_relation_key nvarchar(192) not null, b_group_key nvarchar(128) null, b_child_view_key nvarchar(192) not null, b_child_form_key nvarchar(192) null, b_display_mode nvarchar(32) not null constraint df_s_meta_form_relation_display_mode default N'table', b_row_no int not null, b_column_no tinyint not null constraint df_s_meta_form_relation_column_no default 1, b_column_span tinyint not null constraint df_s_meta_form_relation_column_span default 2, b_sort_no int not null constraint df_s_meta_form_relation_sort_no default 0, b_editable tinyint not null constraint df_s_meta_form_relation_editable default 1, b_allow_add tinyint not null constraint df_s_meta_form_relation_allow_add default 1, b_allow_delete tinyint not null constraint df_s_meta_form_relation_allow_delete default 1, b_allow_sort tinyint not null constraint df_s_meta_form_relation_allow_sort default 0, b_min_rows int null, b_max_rows int null, b_config_text nvarchar(max) null, constraint pk_s_meta_form_relation primary key (b_id), constraint ux_s_meta_form_relation_key unique (b_form_id, b_relation_key) ); create index ix_s_meta_form_entity_key on dbo.s_meta_form (b_entity_key, b_form_type, b_enabled); create index ix_s_meta_form_field_form_id on dbo.s_meta_form_field (b_form_id, b_row_no, b_column_no, b_sort_no); create index ix_s_meta_form_relation_form_id on dbo.s_meta_form_relation (b_form_id, b_row_no, b_column_no, b_sort_no); ``` ### 2.10 业务动作 ```sql create table dbo.s_meta_action ( b_id bigint identity(1, 1) not null, b_action_key nvarchar(192) not null, b_revision_no int not null, b_module_key nvarchar(128) not null, b_entity_key nvarchar(192) null, b_name_key nvarchar(256) not null, b_action_type nvarchar(32) not null, b_handler_key nvarchar(192) null, b_permission_key nvarchar(192) not null, b_input_schema_text nvarchar(max) null, b_output_schema_text nvarchar(max) null, b_precondition_text nvarchar(max) null, b_audit_event_key nvarchar(192) null, b_confirmation_mode nvarchar(32) null, b_idempotency_required tinyint not null constraint df_s_meta_action_idempotency_required default 1, b_enabled tinyint not null constraint df_s_meta_action_enabled default 1, b_config_text nvarchar(max) null, b_created_at datetime2(3) not null constraint df_s_meta_action_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_action primary key (b_id), constraint ux_s_meta_action_key_revision unique (b_action_key, b_revision_no) ); create index ix_s_meta_action_entity_key on dbo.s_meta_action (b_entity_key, b_enabled); create index ix_s_meta_action_permission_key on dbo.s_meta_action (b_permission_key); ``` ### 2.11 多语言 ```sql create table dbo.s_meta_i18n ( b_id bigint identity(1, 1) not null, b_resource_key nvarchar(256) not null, b_locale nvarchar(32) not null, b_revision_no int not null, b_resource_value nvarchar(max) not null, b_source_type nvarchar(32) not null constraint df_s_meta_i18n_source_type default N'manual', b_resource_status nvarchar(32) not null constraint df_s_meta_i18n_resource_status default N'confirmed', b_model_key nvarchar(128) null, b_created_at datetime2(3) not null constraint df_s_meta_i18n_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_i18n primary key (b_id), constraint ux_s_meta_i18n_key_locale_revision unique ( b_resource_key, b_locale, b_revision_no ) ); create index ix_s_meta_i18n_resource_key on dbo.s_meta_i18n (b_resource_key, b_locale); ``` ## 3. 配置版本与 Schema Compiler ### 3.1 配置变更集 ```sql create table dbo.s_meta_change_set ( b_id bigint identity(1, 1) not null, b_change_set_no bigint not null, b_base_release_id bigint null, b_operation_type nvarchar(32) not null, b_reason nvarchar(1000) null, b_change_text nvarchar(max) not null, b_ddl_plan_text nvarchar(max) null, b_validation_text nvarchar(max) null, b_impact_text nvarchar(max) null, b_checksum varchar(128) not null, b_execution_status nvarchar(32) not null, b_created_at datetime2(3) not null constraint df_s_meta_change_set_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, b_completed_at datetime2(3) null, b_error_code nvarchar(128) null, b_error_message nvarchar(2000) null, constraint pk_s_meta_change_set primary key (b_id), constraint ux_s_meta_change_set_no unique (b_change_set_no) ); create index ix_s_meta_change_set_base_release_id on dbo.s_meta_change_set (b_base_release_id); create index ix_s_meta_change_set_execution_status on dbo.s_meta_change_set (b_execution_status, b_created_at); ``` ### 3.2 不可变配置版本 ```sql create table dbo.s_meta_release ( b_id bigint identity(1, 1) not null, b_release_no bigint not null, b_change_set_id bigint not null, b_checksum varchar(128) not null, b_validation_status nvarchar(32) not null, b_description nvarchar(1000) null, b_created_at datetime2(3) not null constraint df_s_meta_release_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_meta_release primary key (b_id), constraint ux_s_meta_release_no unique (b_release_no), constraint ux_s_meta_release_checksum unique (b_checksum) ); create table dbo.s_meta_release_resource ( b_id bigint identity(1, 1) not null, b_release_id bigint not null, b_resource_type nvarchar(64) not null, b_resource_key nvarchar(256) not null, b_resource_id bigint not null, b_resource_revision_no int not null, b_checksum varchar(128) not null, constraint pk_s_meta_release_resource primary key (b_id), constraint ux_s_meta_release_resource_key unique ( b_release_id, b_resource_type, b_resource_key ) ); create index ix_s_meta_release_resource_release_id on dbo.s_meta_release_resource (b_release_id, b_resource_type); create index ix_s_meta_release_resource_resource_id on dbo.s_meta_release_resource (b_resource_id); ``` ### 3.3 当前运行版本与激活历史 ```sql create table dbo.s_meta_runtime_state ( b_id bigint identity(1, 1) not null, b_state_key nvarchar(64) not null constraint df_s_meta_runtime_state_state_key default N'default', b_current_release_id bigint not null, b_updated_at datetime2(3) not null constraint df_s_meta_runtime_state_updated_at default sysutcdatetime(), b_updated_by nvarchar(128) not null, b_row_version rowversion not null, constraint pk_s_meta_runtime_state primary key (b_id), constraint ux_s_meta_runtime_state_key unique (b_state_key) ); create table dbo.s_meta_release_activation ( b_id bigint identity(1, 1) not null, b_release_id bigint not null, b_previous_release_id bigint null, b_activation_type nvarchar(32) not null, b_reason nvarchar(1000) null, b_request_id nvarchar(128) null, b_trace_id nvarchar(128) null, b_activated_at datetime2(3) not null constraint df_s_meta_release_activation_activated_at default sysutcdatetime(), b_activated_by nvarchar(128) not null, constraint pk_s_meta_release_activation primary key (b_id) ); create index ix_s_meta_release_activation_release_id on dbo.s_meta_release_activation (b_release_id, b_activated_at desc); ``` ### 3.4 Schema 迁移任务与步骤 ```sql create table dbo.s_schema_migration ( b_id bigint identity(1, 1) not null, b_change_set_id bigint not null, b_target_release_id bigint null, b_migration_status nvarchar(32) not null, b_lock_owner nvarchar(128) null, b_lock_expires_at datetime2(3) null, b_plan_checksum varchar(128) not null, b_current_step_no int null, b_started_at datetime2(3) null, b_completed_at datetime2(3) null, b_created_at datetime2(3) not null constraint df_s_schema_migration_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, b_error_code nvarchar(128) null, b_error_message nvarchar(2000) null, constraint pk_s_schema_migration primary key (b_id), constraint ux_s_schema_migration_change_set_id unique (b_change_set_id) ); create table dbo.s_schema_migration_step ( b_id bigint identity(1, 1) not null, b_migration_id bigint not null, b_step_no int not null, b_step_type nvarchar(32) not null, b_object_key nvarchar(256) null, b_statement_text nvarchar(max) null, b_rollback_statement_text nvarchar(max) null, b_checksum varchar(128) not null, b_step_status nvarchar(32) not null, b_started_at datetime2(3) null, b_completed_at datetime2(3) null, b_result_text nvarchar(max) null, b_error_message nvarchar(2000) null, constraint pk_s_schema_migration_step primary key (b_id), constraint ux_s_schema_migration_step_no unique (b_migration_id, b_step_no) ); create index ix_s_schema_migration_status on dbo.s_schema_migration (b_migration_status, b_created_at); create index ix_s_schema_migration_step_migration_id on dbo.s_schema_migration_step (b_migration_id, b_step_status, b_step_no); ``` ## 4. 统一权限中心 ### 4.1 角色与用户角色关系 ```sql 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 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 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, b_row_version rowversion not 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, b_role_key nvarchar(128) not null, 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 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 功能权限 ```sql 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, b_resource_type nvarchar(32) not null, b_resource_key nvarchar(256) not null, b_action_type nvarchar(64) null, b_name_key nvarchar(256) not null, b_description nvarchar(1000) null, b_enabled tinyint not null constraint df_s_auth_permission_enabled default 1, b_protected tinyint not null constraint df_s_auth_permission_protected default 0, b_created_at datetime2(3) not null 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, b_permission_key nvarchar(192) not null, b_permission_effect nvarchar(16) not null constraint df_s_auth_role_permission_effect default N'allow', b_created_at datetime2(3) not null 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); ``` ### 4.3 数据范围权限 ```sql create table dbo.s_auth_data_policy ( b_id bigint identity(1, 1) not null, b_policy_key nvarchar(192) not null, b_module_key nvarchar(128) null, b_entity_key nvarchar(192) not null, b_policy_name nvarchar(256) not null, b_action_text nvarchar(max) not null, b_scope_text nvarchar(max) not null, b_enabled tinyint not null constraint df_s_auth_data_policy_enabled default 1, b_priority_no int not null constraint df_s_auth_data_policy_priority_no default 0, b_created_at datetime2(3) not null constraint df_s_auth_data_policy_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, b_updated_at datetime2(3) null, b_updated_by nvarchar(128) null, b_row_version rowversion not null, constraint pk_s_auth_data_policy primary key (b_id), constraint ux_s_auth_data_policy_key unique (b_policy_key) ); create table dbo.s_auth_role_data_policy ( b_id bigint identity(1, 1) not null, b_role_key nvarchar(128) not null, b_policy_key nvarchar(192) not null, b_policy_effect nvarchar(16) not null constraint df_s_auth_role_data_policy_effect default N'allow', b_created_at datetime2(3) not null constraint df_s_auth_role_data_policy_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, constraint pk_s_auth_role_data_policy primary key (b_id), constraint ux_s_auth_role_data_policy_key unique ( b_role_key, b_policy_key ) ); create index ix_s_auth_data_policy_entity_key on dbo.s_auth_data_policy (b_entity_key, b_enabled, b_priority_no); create index ix_s_auth_role_data_policy_policy_key on dbo.s_auth_role_data_policy (b_policy_key, b_policy_effect); ``` ### 4.4 字段查看、导出和脱敏权限 ```sql create table dbo.s_auth_field_policy ( b_id bigint identity(1, 1) not null, b_policy_key nvarchar(256) not null, b_entity_key nvarchar(192) not null, b_field_key nvarchar(128) not null, b_subject_type nvarchar(32) not null, b_subject_key nvarchar(128) not null, b_view_effect nvarchar(16) not null constraint df_s_auth_field_policy_view_effect default N'allow', b_export_effect nvarchar(16) not null constraint df_s_auth_field_policy_export_effect default N'allow', b_mask_mode nvarchar(32) not null constraint df_s_auth_field_policy_mask_mode default N'none', b_mask_config_text nvarchar(max) null, b_priority_no int not null constraint df_s_auth_field_policy_priority_no default 0, b_enabled tinyint not null constraint df_s_auth_field_policy_enabled default 1, b_created_at datetime2(3) not null constraint df_s_auth_field_policy_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, b_updated_at datetime2(3) null, b_updated_by nvarchar(128) null, b_row_version rowversion not null, constraint pk_s_auth_field_policy primary key (b_id), constraint ux_s_auth_field_policy_key unique (b_policy_key), constraint ux_s_auth_field_policy_subject unique ( b_entity_key, b_field_key, b_subject_type, b_subject_key ) ); create index ix_s_auth_field_policy_lookup on dbo.s_auth_field_policy ( b_subject_type, b_subject_key, b_entity_key, b_enabled, b_priority_no ); create index ix_s_auth_field_policy_field_key on dbo.s_auth_field_policy (b_entity_key, b_field_key, b_enabled); ``` ### 4.5 权限快照 ```sql create table dbo.s_auth_permission_snapshot ( b_id bigint identity(1, 1) not null, b_user_key nvarchar(128) not null, b_snapshot_version bigint not null, b_release_id bigint not null, b_permission_text nvarchar(max) not null, b_checksum varchar(128) not null, b_created_at datetime2(3) not null constraint df_s_auth_permission_snapshot_created_at default sysutcdatetime(), b_expires_at datetime2(3) null, b_invalidated_at datetime2(3) null, constraint pk_s_auth_permission_snapshot primary key (b_id), constraint ux_s_auth_permission_snapshot_version unique ( b_user_key, b_snapshot_version ) ); create index ix_s_auth_permission_snapshot_user_key on dbo.s_auth_permission_snapshot (b_user_key, b_invalidated_at, b_expires_at); ``` ## 5. 日志与审计 ### 5.1 技术日志 技术日志主要用于请求链路、SQL、异常、性能和外部接口排查,推荐写入 Loki、OpenSearch、Elasticsearch 等日志平台。下面的表适合集中日志库或短期数据库兜底,不建议把所有高频技术日志长期写入租户业务库。 ```sql create table dbo.s_log_technical ( b_id bigint identity(1, 1) not null, b_occurred_at datetime2(3) not null constraint df_s_log_technical_occurred_at default sysutcdatetime(), b_log_level nvarchar(16) not null, b_log_category nvarchar(64) not null, b_operation nvarchar(192) not null, b_org_id nvarchar(128) null, b_user_key nvarchar(128) null, b_source_type nvarchar(32) null, b_module_key nvarchar(128) null, b_entity_key nvarchar(192) null, b_action_key nvarchar(192) null, b_request_id nvarchar(128) null, b_trace_id nvarchar(128) null, 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` 关联,但业务职责独立。 ```sql create table dbo.s_log_login ( b_id bigint identity(1, 1) not null, b_org_id nvarchar(128) null, b_user_key nvarchar(128) null, b_login_name nvarchar(256) null, b_login_type nvarchar(32) not null, b_login_status nvarchar(32) not null, b_auth_method nvarchar(32) null, b_failure_reason nvarchar(512) null, b_ip_address varchar(64) null, b_user_agent nvarchar(1000) null, b_device_key nvarchar(256) null, b_request_id nvarchar(128) null, b_trace_id nvarchar(128) null, b_occurred_at datetime2(3) not null constraint df_s_log_login_occurred_at default sysutcdatetime(), b_created_at datetime2(3) not null 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 业务审计事件与字段变更 ```sql 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) null, b_entity_key nvarchar(192) not null, b_entity_id nvarchar(128) not null, b_business_no nvarchar(192) null, b_action_key nvarchar(192) null, b_operator_key nvarchar(128) not null, b_operator_name nvarchar(256) null, b_source_type nvarchar(32) not null, b_visibility nvarchar(32) not null, b_request_id nvarchar(128) null, b_trace_id nvarchar(128) not null, b_release_id bigint null, b_business_event_id bigint null, b_payload_text nvarchar(max) null, b_occurred_at datetime2(3) not null 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, b_entity_key nvarchar(192) not null, b_entity_id nvarchar(128) not null, b_field_key nvarchar(128) not null, 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, 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_entity on dbo.s_log_audit (b_entity_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_meta_entity` | `b_module_key` | `s_meta_module.b_module_key` | | `s_meta_field` | `b_entity_key` | `s_meta_entity.b_entity_key` | | `s_meta_relation` | `b_source_entity_key` | `s_meta_entity.b_entity_key` | | `s_meta_relation` | `b_target_entity_key` | `s_meta_entity.b_entity_key` | | `s_meta_dictionary_item` | `b_dictionary_id` | `s_meta_dictionary.b_id` | | `s_meta_page` | `b_module_key` | `s_meta_module.b_module_key` | | `s_meta_page` | `b_view_key` | `s_meta_view.b_view_key` | | `s_meta_page` | `b_form_key` | `s_meta_form.b_form_key` | | `s_meta_page` | `b_permission_key` | `s_auth_permission.b_permission_key` | | `s_meta_menu` | `b_module_key` | `s_meta_module.b_module_key` | | `s_meta_menu` | `b_parent_menu_key` | `s_meta_menu.b_menu_key` | | `s_meta_menu` | `b_page_key` | `s_meta_page.b_page_key` | | `s_meta_menu` | `b_permission_key` | `s_auth_permission.b_permission_key` | | `s_meta_view` | `b_entity_key` | `s_meta_entity.b_entity_key` | | `s_meta_view_field` | `b_view_id` | `s_meta_view.b_id` | | `s_meta_form` | `b_entity_key` | `s_meta_entity.b_entity_key` | | `s_meta_form_field` | `b_form_id` | `s_meta_form.b_id` | | `s_meta_form_relation` | `b_form_id` | `s_meta_form.b_id` | | `s_meta_form_relation` | `b_relation_key` | `s_meta_relation.b_relation_key` | | `s_meta_form_relation` | `b_child_view_key` | `s_meta_view.b_view_key` | | `s_meta_form_relation` | `b_child_form_key` | `s_meta_form.b_form_key` | | `s_meta_release` | `b_change_set_id` | `s_meta_change_set.b_id` | | `s_meta_release_resource` | `b_release_id` | `s_meta_release.b_id` | | `s_meta_runtime_state` | `b_current_release_id` | `s_meta_release.b_id` | | `s_schema_migration` | `b_change_set_id` | `s_meta_change_set.b_id` | | `s_schema_migration_step` | `b_migration_id` | `s_schema_migration.b_id` | | `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_auth_role_data_policy` | `b_policy_key` | `s_auth_data_policy.b_policy_key` | | `s_auth_field_policy` | `b_entity_key` | `s_meta_entity.b_entity_key` | | `s_auth_field_policy` | `b_field_key` | `s_meta_field.b_field_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` | 逻辑外键写入时应执行以下校验: ```text 稳定 key 是否存在 -> 目标资源是否属于当前 release -> 目标资源是否启用 -> 模块依赖是否合法 -> 字段、关系和页面类型是否匹配 -> 删除或停用前是否仍被其他资源引用 ``` ## 7. 实施建议 建议按以下顺序创建和启用这些表: ```text 元数据基础表 -> 页面和菜单表 -> 视图和动态表单表 -> 配置 release 表 -> Schema 迁移表 -> 权限表 -> 日志与审计表 ``` 正式执行前还应补充: - 根据实际 SQL Server 2022 环境确认过滤索引和 `datetime2` 支持情况。 - 根据现有用户表确定 `b_user_key`、`b_created_by` 和 `b_updated_by` 的实际数据类型。 - 根据最终稳定 key 长度评估唯一索引的键长度。 - 为高数据量审计表制定归档及清理策略。 - 用独立测试数据库执行完整建表脚本,并验证重复安装、初始化 release 和回滚流程。