灵越智报 2.0 - 数据库设计文档(定稿)
版本: v1.0-final
定稿时间: 2026-02-12
设计原则: 简化单层项目结构,前端只关心"项目"概念
数据库: PostgreSQL 15+
初始化脚本: init_mock_new.sql
一、整体架构
1.1 设计思想
采用关系型数据库实现图数据库的思路:
- 节点(Node): 所有业务实体均为节点,通过
node_type 区分
- 关系(Edge): 节点间的关联通过边表示,通过
edge_type 区分
- 属性(Property): 节点和边的属性通过 KV 表存储,支持动态扩展
- 视图(View): 通过数据库视图将图结构映射为业务友好的查询接口
1.2 表分类
| 分类 |
表名前缀 |
数量 |
说明 |
| 前端业务支撑表 |
sys_* |
13张 |
用户、角色、权限、字典、日志等 |
| 核心图结构表 |
nodes, edges, *_properties |
7张 |
节点、关系、属性、类型定义 |
| 业务视图 |
v_* |
7个 |
项目、要素、值、附件、实体、规则等 |
1.3 数据模型概览
PROJECT (项目)
├── HAS_ELEMENT ──→ ELEMENT (要素定义)
├── HAS_VALUE ────→ VALUE (要素值) ──FOR_ELEMENT──→ ELEMENT
├── HAS_ATTACHMENT → ATTACHMENT (附件)
│ └── HAS_ENTITY ──→ ENTITY (实体)
├── HAS_RULE ────→ RULE (规则)
│ ├── FOR_ELEMENT ──→ ELEMENT
│ └── INPUT_FROM ──→ ENTITY / ATTACHMENT / VALUE
└── COPIED_FROM ──→ PROJECT (复制来源)
二、前端业务支撑表(sys_* 系列)
2.1 sys_users - 用户表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| node_id |
BIGINT |
|
关联 nodes 表(可选) |
| username |
VARCHAR(100) |
NOT NULL, UNIQUE |
用户名 |
| password_hash |
VARCHAR(255) |
NOT NULL |
密码哈希(BCrypt) |
| salt |
VARCHAR(50) |
|
盐值 |
| email |
VARCHAR(200) |
|
邮箱 |
| phone |
VARCHAR(20) |
|
手机号 |
| avatar |
VARCHAR(500) |
|
头像URL |
| real_name |
VARCHAR(100) |
|
真实姓名 |
| department |
VARCHAR(200) |
|
部门 |
| position |
VARCHAR(100) |
|
职位 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态:active/disabled |
| last_login_at |
TIMESTAMP |
|
最后登录时间 |
| last_login_ip |
VARCHAR(50) |
|
最后登录IP |
| login_count |
INT |
DEFAULT 0 |
登录次数 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_sys_users_username ON (username)
idx_sys_users_node ON (node_id)
2.2 sys_sessions - 会话表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| user_id |
BIGINT |
NOT NULL, FK→sys_users |
用户ID |
| session_token |
VARCHAR(255) |
NOT NULL, UNIQUE |
会话Token |
| refresh_token |
VARCHAR(255) |
|
刷新Token |
| device_type |
VARCHAR(50) |
|
设备类型:web/mobile/desktop |
| device_info |
TEXT |
|
设备信息 |
| ip_address |
VARCHAR(50) |
|
IP地址 |
| user_agent |
TEXT |
|
User-Agent |
| expires_at |
TIMESTAMP |
NOT NULL |
过期时间 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_sys_sessions_user ON (user_id)
idx_sys_sessions_token ON (session_token)
2.3 sys_login_logs - 登录日志表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| user_id |
BIGINT |
FK→sys_users (SET NULL) |
用户ID |
| username |
VARCHAR(100) |
|
用户名(冗余) |
| login_type |
VARCHAR(20) |
|
登录类型:password/token/sso |
| ip_address |
VARCHAR(50) |
|
IP地址 |
| user_agent |
TEXT |
|
User-Agent |
| device_type |
VARCHAR(50) |
|
设备类型 |
| location |
VARCHAR(200) |
|
登录地点 |
| status |
VARCHAR(20) |
NOT NULL |
状态:success/failed |
| message |
TEXT |
|
消息(失败原因等) |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
索引:
idx_sys_login_logs_user ON (user_id)
idx_sys_login_logs_created ON (created_at DESC)
2.4 sys_roles - 角色表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| role_code |
VARCHAR(50) |
NOT NULL, UNIQUE |
角色编码 |
| role_name |
VARCHAR(100) |
NOT NULL |
角色名称 |
| description |
TEXT |
|
描述 |
| sort_order |
INT |
DEFAULT 0 |
排序 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态 |
| created_by |
BIGINT |
|
创建人 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_sys_roles_code ON (role_code)
2.5 sys_permissions - 权限表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| perm_code |
VARCHAR(100) |
NOT NULL, UNIQUE |
权限编码 |
| perm_name |
VARCHAR(200) |
NOT NULL |
权限名称 |
| perm_type |
VARCHAR(20) |
NOT NULL |
类型:menu/button/api |
| parent_id |
INT |
FK→sys_permissions |
父级ID |
| path |
VARCHAR(500) |
|
路由路径 |
| icon |
VARCHAR(100) |
|
图标 |
| component |
VARCHAR(200) |
|
前端组件路径 |
| sort_order |
INT |
DEFAULT 0 |
排序 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
索引:
idx_sys_permissions_parent ON (parent_id)
idx_sys_permissions_type ON (perm_type)
2.6 sys_user_roles - 用户角色关联表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| user_id |
BIGINT |
NOT NULL, FK→sys_users |
用户ID |
| role_id |
INT |
NOT NULL, FK→sys_roles |
角色ID |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
约束: UNIQUE(user_id, role_id)
2.7 sys_role_permissions - 角色权限关联表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| role_id |
INT |
NOT NULL, FK→sys_roles |
角色ID |
| permission_id |
INT |
NOT NULL, FK→sys_permissions |
权限ID |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
约束: UNIQUE(role_id, permission_id)
2.8 sys_configs - 系统配置表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| config_key |
VARCHAR(100) |
NOT NULL, UNIQUE |
配置键 |
| config_value |
TEXT |
|
配置值(文本) |
| config_json |
JSONB |
|
配置值(JSON) |
| config_type |
VARCHAR(50) |
|
值类型:string/number/boolean/json |
| description |
TEXT |
|
描述 |
| is_public |
BOOLEAN |
DEFAULT false |
是否公开(前端可读) |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
2.9 sys_dict_types - 数据字典类型表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| dict_code |
VARCHAR(100) |
NOT NULL, UNIQUE |
字典编码 |
| dict_name |
VARCHAR(200) |
NOT NULL |
字典名称 |
| description |
TEXT |
|
描述 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
2.10 sys_dict_items - 数据字典项表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| dict_type_id |
INT |
NOT NULL, FK→sys_dict_types |
字典类型ID |
| item_code |
VARCHAR(100) |
NOT NULL |
项编码 |
| item_name |
VARCHAR(200) |
NOT NULL |
项名称 |
| item_value |
TEXT |
|
项值 |
| sort_order |
INT |
DEFAULT 0 |
排序 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态 |
| extra |
JSONB |
|
扩展信息 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
约束: UNIQUE(dict_type_id, item_code)
2.11 sys_operation_logs - 操作日志表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| user_id |
BIGINT |
|
用户ID |
| username |
VARCHAR(100) |
|
用户名 |
| module |
VARCHAR(100) |
|
模块名 |
| action |
VARCHAR(100) |
|
操作名 |
| method |
VARCHAR(10) |
|
HTTP方法 |
| url |
VARCHAR(500) |
|
请求URL |
| params |
TEXT |
|
请求参数 |
| result |
TEXT |
|
返回结果 |
| ip_address |
VARCHAR(50) |
|
IP地址 |
| user_agent |
TEXT |
|
User-Agent |
| duration_ms |
INT |
|
耗时(毫秒) |
| status |
VARCHAR(20) |
|
状态:success/error |
| error_msg |
TEXT |
|
错误信息 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
索引:
idx_sys_operation_logs_user ON (user_id)
idx_sys_operation_logs_created ON (created_at DESC)
2.12 sys_files - 文件存储表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| file_key |
VARCHAR(100) |
NOT NULL, UNIQUE |
文件唯一标识 |
| original_name |
VARCHAR(500) |
NOT NULL |
原始文件名 |
| storage_name |
VARCHAR(200) |
NOT NULL |
存储文件名 |
| storage_path |
VARCHAR(500) |
NOT NULL |
存储路径 |
| file_type |
VARCHAR(100) |
|
MIME类型 |
| file_size |
BIGINT |
|
文件大小(字节) |
| md5_hash |
VARCHAR(32) |
|
MD5哈希 |
| storage_type |
VARCHAR(20) |
DEFAULT 'local' |
存储类型:local/oss/minio |
| bucket |
VARCHAR(100) |
|
存储桶 |
| url |
VARCHAR(1000) |
|
访问URL |
| thumbnail_url |
VARCHAR(1000) |
|
缩略图URL |
| uploaded_by |
BIGINT |
|
上传人 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
2.13 sys_tasks - 异步任务队列表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| task_type |
VARCHAR(50) |
NOT NULL |
任务类型:parse/ner/export |
| task_key |
VARCHAR(100) |
|
任务标识 |
| payload |
JSONB |
|
任务参数 |
| status |
VARCHAR(20) |
DEFAULT 'pending' |
状态:pending/running/success/failed |
| priority |
INT |
DEFAULT 0 |
优先级 |
| retry_count |
INT |
DEFAULT 0 |
已重试次数 |
| max_retries |
INT |
DEFAULT 3 |
最大重试次数 |
| result |
JSONB |
|
执行结果 |
| error_msg |
TEXT |
|
错误信息 |
| started_at |
TIMESTAMP |
|
开始时间 |
| finished_at |
TIMESTAMP |
|
完成时间 |
| created_by |
BIGINT |
|
创建人 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_sys_tasks_type ON (task_type)
idx_sys_tasks_status ON (status)
idx_sys_tasks_created ON (created_at DESC)
三、核心图结构表
3.1 node_types - 节点类型定义表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| type_code |
VARCHAR(50) |
NOT NULL, UNIQUE |
类型编码 |
| type_name |
VARCHAR(100) |
NOT NULL |
类型名称 |
| description |
TEXT |
|
描述 |
| icon |
VARCHAR(100) |
|
图标名 |
| color |
VARCHAR(20) |
|
颜色值 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
预置数据:
| type_code |
type_name |
说明 |
| PROJECT |
项目 |
智报项目(包含要素定义和内容) |
| ELEMENT |
要素 |
项目要素定义 |
| VALUE |
要素值 |
要素的具体值 |
| ATTACHMENT |
附件 |
项目附件 |
| ENTITY |
实体 |
NER识别的实体 |
| RULE |
规则 |
数据提取规则 |
3.2 edge_types - 关系类型定义表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| type_code |
VARCHAR(50) |
NOT NULL, UNIQUE |
类型编码 |
| type_name |
VARCHAR(100) |
NOT NULL |
类型名称 |
| from_node_type |
VARCHAR(50) |
|
起始节点类型 |
| to_node_type |
VARCHAR(50) |
|
目标节点类型 |
| description |
TEXT |
|
描述 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
预置数据:
| type_code |
from → to |
说明 |
| HAS_ELEMENT |
PROJECT → ELEMENT |
项目包含要素定义 |
| HAS_VALUE |
PROJECT → VALUE |
项目有要素值 |
| FOR_ELEMENT |
VALUE → ELEMENT |
值对应的要素 |
| HAS_ATTACHMENT |
PROJECT → ATTACHMENT |
项目有附件 |
| HAS_ENTITY |
ATTACHMENT → ENTITY |
附件有实体 |
| HAS_RULE |
PROJECT → RULE |
项目有规则 |
| FOR_ELEMENT |
RULE → ELEMENT |
规则对应的要素 |
| INPUT_FROM |
RULE → ENTITY |
规则输入来源(实体) |
| INPUT_FROM |
RULE → ATTACHMENT |
规则输入来源(附件) |
| INPUT_FROM |
RULE → VALUE |
规则输入来源(其他值) |
| COPIED_FROM |
PROJECT → PROJECT |
项目复制来源 |
3.3 nodes - 节点表(核心)
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| node_type |
VARCHAR(50) |
NOT NULL |
节点类型(对应 node_types.type_code) |
| node_key |
VARCHAR(200) |
|
业务键(同类型内唯一) |
| name |
VARCHAR(500) |
NOT NULL |
节点名称 |
| status |
VARCHAR(50) |
DEFAULT 'active' |
状态 |
| created_by |
BIGINT |
|
创建人(sys_users.id) |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_nodes_type ON (node_type)
idx_nodes_type_status ON (node_type, status)
idx_nodes_key ON (node_key)
idx_nodes_type_key UNIQUE ON (node_type, node_key) WHERE node_key IS NOT NULL
idx_nodes_created_by ON (created_by)
idx_nodes_created_at ON (created_at DESC)
各节点类型的 node_key 约定:
| node_type |
node_key 格式 |
示例 |
| PROJECT |
PRJ-{年份}-{序号} |
PRJ-2024-001 |
| ELEMENT |
{namespace}.{fieldName} |
basicInfo.projectCode |
| VALUE |
{projectKey}:{elementKey} |
PRJ-2024-001:basicInfo.projectCode |
| ATTACHMENT |
ATT-{年份}-{序号} |
ATT-2024-001 |
| ENTITY |
{entityType}:{entityText} |
ORG:成都院 |
| RULE |
{projectKey}:{elementKey} |
PRJ-2024-001:basicInfo.projectCode |
3.4 edges - 关系表(核心)
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| edge_type |
VARCHAR(50) |
NOT NULL |
关系类型(对应 edge_types.type_code) |
| from_node_id |
BIGINT |
NOT NULL, FK→nodes |
起始节点ID |
| to_node_id |
BIGINT |
NOT NULL, FK→nodes |
目标节点ID |
| sort_order |
INT |
DEFAULT 0 |
排序序号 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
索引:
idx_edges_type ON (edge_type)
idx_edges_from ON (from_node_id)
idx_edges_to ON (to_node_id)
idx_edges_type_from ON (edge_type, from_node_id)
idx_edges_type_to ON (edge_type, to_node_id)
idx_edges_unique UNIQUE ON (edge_type, from_node_id, to_node_id)
3.5 node_properties - 节点属性表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| node_id |
BIGINT |
NOT NULL, FK→nodes |
节点ID |
| prop_key |
VARCHAR(100) |
NOT NULL |
属性键 |
| prop_value |
TEXT |
|
文本值 |
| prop_json |
JSONB |
|
JSON值 |
| prop_number |
DECIMAL(20,4) |
|
数值 |
| prop_date |
TIMESTAMP |
|
日期值 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
索引:
idx_node_props_node ON (node_id)
idx_node_props_unique UNIQUE ON (node_id, prop_key)
idx_node_props_key ON (prop_key)
各节点类型的属性定义:
PROJECT 节点属性
| prop_key |
数据类型 |
说明 |
| title |
prop_value |
项目标题 |
| description |
prop_value |
项目描述 |
| status |
prop_value |
状态:draft/in_progress/completed/archived |
| template_type |
prop_value |
模板类型(如"电力安全生产标准化复审报告") |
| content_html |
prop_value |
报告内容(HTML格式) |
| content_markdown |
prop_value |
报告内容(Markdown格式) |
ELEMENT 节点属性
| prop_key |
数据类型 |
说明 |
| element_type |
prop_value |
要素类型:text/paragraph/table |
| namespace |
prop_value |
命名空间(如 basicInfo, schedule, result) |
| field_name |
prop_value |
字段名(如 projectCode, startDate) |
| required |
prop_value |
是否必填:true/false |
| default_value |
prop_value |
默认值 |
| description |
prop_value |
要素描述 |
| table_columns |
prop_json |
表格列定义(仅 table 类型) |
VALUE 节点属性
| prop_key |
数据类型 |
说明 |
| value_text |
prop_value |
文本值 |
| value_json |
prop_json |
JSON值(表格数据等) |
| is_filled |
prop_value |
是否已填充:true/false |
| fill_source |
prop_value |
填充来源:default/manual/rule/ai |
ATTACHMENT 节点属性
| prop_key |
数据类型 |
说明 |
| file_name |
prop_value |
文件名 |
| file_path |
prop_value |
文件路径 |
| file_type |
prop_value |
文件类型:pdf/docx/xlsx |
| file_size |
prop_number |
文件大小(字节) |
| parse_status |
prop_value |
解析状态:pending/parsing/completed/failed |
| parsed_text |
prop_value |
解析后的文本 |
| parsed_at |
prop_date |
解析完成时间 |
ENTITY 节点属性
| prop_key |
数据类型 |
说明 |
| entity_type |
prop_value |
实体类型:ORG/PERSON/DATE/NUMBER/CODE/LOCATION |
| business_label |
prop_value |
业务标签(如"评审对象"、"项目编号") |
| confidence |
prop_number |
置信度(0-1) |
| occurrence_count |
prop_number |
出现次数 |
RULE 节点属性
| prop_key |
数据类型 |
说明 |
| rule_type |
prop_value |
规则类型:direct_entity/extraction/llm/aggregate/dsl |
| action_type |
prop_value |
动作类型:use_entity_value/regex_extract/llm_generate |
| description |
prop_value |
规则描述 |
| action_config |
prop_json |
动作配置 |
| dsl_content |
prop_value |
DSL代码(规则引擎对接,预留) |
| last_output_text |
prop_value |
最后输出文本 |
| last_output_json |
prop_json |
最后输出JSON |
| last_run_status |
prop_value |
最后运行状态:success/failed/pending |
| last_run_time |
prop_date |
最后运行时间 |
| last_run_error |
prop_value |
最后运行错误信息 |
3.6 edge_properties - 关系属性表
| 字段 |
类型 |
约束 |
说明 |
| id |
BIGSERIAL |
PK |
主键 |
| edge_id |
BIGINT |
NOT NULL, FK→edges |
关系ID |
| prop_key |
VARCHAR(100) |
NOT NULL |
属性键 |
| prop_value |
TEXT |
|
文本值 |
| prop_json |
JSONB |
|
JSON值 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
索引:
idx_edge_props_edge ON (edge_id)
idx_edge_props_unique UNIQUE ON (edge_id, prop_key)
INPUT_FROM 边属性:
| prop_key |
说明 |
| input_key |
输入参数名(如 'entity') |
| input_type |
输入类型:entity_ref/attachment_ref/value_ref |
| input_name |
输入名称(显示用) |
| fixed_value |
固定值(可选) |
3.7 property_definitions - 属性定义表
| 字段 |
类型 |
约束 |
说明 |
| id |
SERIAL |
PK |
主键 |
| owner_type |
VARCHAR(20) |
NOT NULL |
所有者类型:node/edge |
| target_type |
VARCHAR(50) |
NOT NULL |
目标类型(如 PROJECT, RULE) |
| prop_key |
VARCHAR(100) |
NOT NULL |
属性键 |
| prop_name |
VARCHAR(200) |
NOT NULL |
属性名称 |
| data_type |
VARCHAR(50) |
NOT NULL |
数据类型:string/number/boolean/json/date |
| required |
BOOLEAN |
DEFAULT false |
是否必填 |
| default_value |
TEXT |
|
默认值 |
| description |
TEXT |
|
描述 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
四、视图定义
4.1 v_projects - 项目视图
CREATE OR REPLACE VIEW v_projects AS
SELECT
n.id,
n.name AS title,
n.node_key AS project_code,
n.status,
n.created_at,
n.updated_at,
-- 属性
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'description') AS description,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'template_type') AS template_type,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'content_html') AS content_html,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'content_markdown') AS content_markdown,
-- 统计
(SELECT COUNT(*) FROM edges e WHERE e.from_node_id = n.id AND e.edge_type = 'HAS_ELEMENT') AS element_count,
(SELECT COUNT(*) FROM edges e WHERE e.from_node_id = n.id AND e.edge_type = 'HAS_ATTACHMENT') AS attachment_count,
(SELECT COUNT(*) FROM edges e WHERE e.from_node_id = n.id AND e.edge_type = 'HAS_RULE') AS rule_count,
(SELECT COUNT(*) FROM edges e
JOIN nodes v ON v.id = e.to_node_id
WHERE e.from_node_id = n.id AND e.edge_type = 'HAS_VALUE'
AND EXISTS (SELECT 1 FROM node_properties WHERE node_id = v.id AND prop_key = 'is_filled' AND prop_value = 'true')
) AS filled_count,
-- 关联
(SELECT n2.id FROM edges e JOIN nodes n2 ON n2.id = e.to_node_id
WHERE e.from_node_id = n.id AND e.edge_type = 'COPIED_FROM' LIMIT 1) AS source_project_id,
n.created_by,
(SELECT username FROM sys_users WHERE node_id = n.created_by) AS created_by_name
FROM nodes n
WHERE n.node_type = 'PROJECT';
用途: 项目列表查询、项目详情查询
4.2 v_project_elements - 项目要素视图
CREATE OR REPLACE VIEW v_project_elements AS
SELECT
n.id,
n.name AS element_name,
n.node_key AS element_key,
n.created_at,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'element_type') AS element_type,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'namespace') AS namespace,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'field_name') AS field_name,
(SELECT prop_json FROM node_properties WHERE node_id = n.id AND prop_key = 'table_columns') AS table_columns,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'required')::boolean AS required,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'default_value') AS default_value,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'description') AS description,
(SELECT e.from_node_id FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_ELEMENT' LIMIT 1) AS project_id,
(SELECT e.sort_order FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_ELEMENT' LIMIT 1) AS sort_order
FROM nodes n
WHERE n.node_type = 'ELEMENT';
用途: 查询项目的要素定义列表
4.3 v_project_values - 项目要素值视图
CREATE OR REPLACE VIEW v_project_values AS
SELECT
n.id AS value_id,
n.node_key AS element_key,
n.created_at,
n.updated_at,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'value_text') AS value_text,
(SELECT prop_json FROM node_properties WHERE node_id = n.id AND prop_key = 'value_json') AS value_json,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'is_filled')::boolean AS is_filled,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'fill_source') AS fill_source,
(SELECT e.from_node_id FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_VALUE' LIMIT 1) AS project_id
FROM nodes n
WHERE n.node_type = 'VALUE';
用途: 查询项目的要素值列表
4.4 v_attachments - 附件视图
CREATE OR REPLACE VIEW v_attachments AS
SELECT
n.id,
n.name AS display_name,
n.node_key AS file_key,
n.created_at,
n.updated_at,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'file_name') AS file_name,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'file_path') AS file_path,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'file_type') AS file_type,
(SELECT prop_number FROM node_properties WHERE node_id = n.id AND prop_key = 'file_size')::bigint AS file_size,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'parse_status') AS parse_status,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'parsed_text') AS parsed_text,
(SELECT prop_date FROM node_properties WHERE node_id = n.id AND prop_key = 'parsed_at') AS parsed_at,
(SELECT COUNT(*) FROM edges e WHERE e.from_node_id = n.id AND e.edge_type = 'HAS_ENTITY') AS entity_count,
(SELECT e.from_node_id FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_ATTACHMENT' LIMIT 1) AS project_id,
(SELECT e.sort_order FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_ATTACHMENT' LIMIT 1) AS sort_order
FROM nodes n
WHERE n.node_type = 'ATTACHMENT';
4.5 v_entities - 实体视图
CREATE OR REPLACE VIEW v_entities AS
SELECT
n.id,
n.name AS entity_text,
n.node_key AS entity_key,
n.created_at,
n.updated_at,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'entity_type') AS entity_type,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'business_label') AS business_label,
(SELECT prop_number FROM node_properties WHERE node_id = n.id AND prop_key = 'confidence') AS confidence,
(SELECT prop_number FROM node_properties WHERE node_id = n.id AND prop_key = 'occurrence_count')::int AS occurrence_count,
(SELECT e.from_node_id FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_ENTITY' LIMIT 1) AS attachment_id
FROM nodes n
WHERE n.node_type = 'ENTITY';
4.6 v_rules - 规则视图
CREATE OR REPLACE VIEW v_rules AS
SELECT
n.id,
n.name AS rule_name,
n.node_key AS element_key,
n.status,
n.created_at,
n.updated_at,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'description') AS description,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'rule_type') AS rule_type,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'action_type') AS action_type,
(SELECT prop_json FROM node_properties WHERE node_id = n.id AND prop_key = 'action_config') AS action_config,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'dsl_content') AS dsl_content,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'last_output_text') AS last_output_text,
(SELECT prop_json FROM node_properties WHERE node_id = n.id AND prop_key = 'last_output_json') AS last_output_json,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'last_run_status') AS last_run_status,
(SELECT prop_date FROM node_properties WHERE node_id = n.id AND prop_key = 'last_run_time') AS last_run_time,
(SELECT prop_value FROM node_properties WHERE node_id = n.id AND prop_key = 'last_run_error') AS last_run_error,
(SELECT e.from_node_id FROM edges e WHERE e.to_node_id = n.id AND e.edge_type = 'HAS_RULE' LIMIT 1) AS project_id
FROM nodes n
WHERE n.node_type = 'RULE';
4.7 v_rule_inputs - 规则输入视图
CREATE OR REPLACE VIEW v_rule_inputs AS
SELECT
e.id AS input_id,
e.from_node_id AS rule_id,
e.to_node_id AS source_node_id,
e.sort_order,
(SELECT prop_value FROM edge_properties WHERE edge_id = e.id AND prop_key = 'input_key') AS input_key,
(SELECT prop_value FROM edge_properties WHERE edge_id = e.id AND prop_key = 'input_name') AS input_name,
(SELECT prop_value FROM edge_properties WHERE edge_id = e.id AND prop_key = 'input_type') AS input_type,
(SELECT prop_value FROM edge_properties WHERE edge_id = e.id AND prop_key = 'fixed_value') AS fixed_value,
n.node_type AS source_type,
n.name AS source_name
FROM edges e
JOIN nodes n ON n.id = e.to_node_id
WHERE e.edge_type = 'INPUT_FROM';
五、常用查询示例
5.1 获取项目列表(分页)
SELECT * FROM v_projects
WHERE status != 'archived'
ORDER BY updated_at DESC
LIMIT 20 OFFSET 0;
5.2 获取项目详情(含要素和值)
-- 项目基本信息
SELECT * FROM v_projects WHERE id = 10;
-- 要素定义列表
SELECT * FROM v_project_elements WHERE project_id = 10 ORDER BY sort_order;
-- 要素值列表
SELECT * FROM v_project_values WHERE project_id = 10;
-- 附件列表
SELECT * FROM v_attachments WHERE project_id = 10 ORDER BY sort_order;
-- 规则列表
SELECT * FROM v_rules WHERE project_id = 10;
5.3 获取项目所有实体
SELECT e.* FROM v_entities e
JOIN v_attachments a ON a.id = e.attachment_id
WHERE a.project_id = 10
ORDER BY e.entity_type, e.confidence DESC;
5.4 获取规则的输入来源
SELECT * FROM v_rule_inputs WHERE rule_id = 600;
5.5 创建项目完整流程
-- 1. 创建项目节点
INSERT INTO nodes (node_type, node_key, name, status, created_by)
VALUES ('PROJECT', 'PRJ-2024-002', '新项目', 'draft', 1)
RETURNING id; -- 假设返回 id = 20
-- 2. 设置项目属性
INSERT INTO node_properties (node_id, prop_key, prop_value) VALUES
(20, 'title', '新项目'),
(20, 'description', '项目描述'),
(20, 'status', 'draft'),
(20, 'template_type', '电力安全生产标准化复审报告');
-- 3. 创建要素定义(从模板复制或手动创建)
INSERT INTO nodes (node_type, node_key, name, created_by)
VALUES ('ELEMENT', 'basicInfo.projectCode', '项目编号', 1)
RETURNING id; -- 假设返回 id = 210
-- 4. 建立关系
INSERT INTO edges (edge_type, from_node_id, to_node_id, sort_order)
VALUES ('HAS_ELEMENT', 20, 210, 1);
-- 5. 创建空值节点
INSERT INTO nodes (node_type, node_key, name, created_by)
VALUES ('VALUE', 'PRJ-2024-002:basicInfo.projectCode', '项目编号值', 1)
RETURNING id; -- 假设返回 id = 310
-- 6. 建立值关系
INSERT INTO edges (edge_type, from_node_id, to_node_id)
VALUES ('HAS_VALUE', 20, 310);
INSERT INTO edges (edge_type, from_node_id, to_node_id)
VALUES ('FOR_ELEMENT', 310, 210);
-- 7. 初始化值属性
INSERT INTO node_properties (node_id, prop_key, prop_value) VALUES
(310, 'is_filled', 'false');
六、规则引擎对接(预留)
6.1 当前状态
规则引擎由独立团队开发,将提供接口供本系统调用。当前设计中:
- RULE 节点的
dsl_content 属性预留存储 DSL 代码
- RULE 节点的
rule_type 支持 dsl 类型
- INPUT_FROM 边记录规则的输入参数
6.2 对接时需要提供的数据
根据规则引擎 DSL 示例,对接时需要传递的核心参数为节点ID:
# 规则引擎需要的参数就是各种节点ID
one_two_ch_id = 12578 # 某个节点的ID
standard_item1_score_id = 234808 # 某个节点的ID
当前设计中,所有业务实体都是 nodes 表中的记录,每条记录都有唯一的 id,可以直接作为规则引擎的输入参数。
6.3 待确认事项
七、数据统计
7.1 表统计
| 分类 |
数量 |
| sys_* 业务支撑表 |
13张 |
| 核心图结构表 |
7张 |
| 业务视图 |
7个 |
| 合计 |
20张表 + 7个视图 |
7.2 节点类型统计
7.3 索引统计
| 表 |
索引数 |
| nodes |
6个 |
| edges |
6个 |
| node_properties |
3个 |
| edge_properties |
2个 |
| sys_* 表 |
约20个 |
| 合计 |
约37个 |