以下是专为CRM场景设计的完整数据库架构,分为元数据层、业务数据层、工作流层、权限层、CRM业务层五大模块。
一、元数据层(Metadata Layer)
1.1 实体元数据表(Core Entity)
CREATE TABLE lc_entities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_code VARCHAR(100) NOT NULL, -- 编码:customer/contact/opportunity
entity_name VARCHAR(100) NOT NULL, -- 名称:客户/联系人/销售机会
table_name VARCHAR(100) NOT NULL, -- 物理表名:ent_customer
storage_type VARCHAR(20) DEFAULT 'jsonb', -- 存储策略:jsonb/ddl/hybrid
tenant_id UUID NOT NULL, -- 多租户隔离
is_system BOOLEAN DEFAULT false, -- 是否为系统预置(不可删除)
is_enabled BOOLEAN DEFAULT true,
description TEXT,
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 租户内实体编码唯一
UNIQUE(tenant_id, entity_code)
);
COMMENT ON TABLE lc_entities IS '实体元数据表,定义CRM所有业务对象';
CREATE INDEX idx_lc_entities_tenant ON lc_entities(tenant_id);1.2 字段元数据表(Field Definition)
CREATE TABLE lc_fields (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id) ON DELETE CASCADE,
field_code VARCHAR(100) NOT NULL, -- 字段编码:name/phone/amount
field_name VARCHAR(100) NOT NULL, -- 显示名称:客户名称
field_type VARCHAR(30) NOT NULL, -- 基础类型:text/number/date/select/boolean
component_type VARCHAR(50), -- 组件类型:Input/Select/ImageUpload
-- 布局与分组
field_group VARCHAR(50), -- 分组:基础信息/扩展信息/系统信息
sort_order INT DEFAULT 0, -- 排序
width VARCHAR(20) DEFAULT '1', -- 布局宽度:1/2/1/3/1/4
-- 校验规则
is_required BOOLEAN DEFAULT false,
is_unique BOOLEAN DEFAULT false,
validation_rules JSONB, -- {"minLength":2,"maxLength":50,"regex":"^1[3-9]\\d{9}$"}
-- 类型扩展属性
attributes JSONB, -- 单选:{"options":[{"label":"男","value":"M","color":"blue"}]} 数字:{"precision":2,"isAmount":true}
-- 关联关系(外键)
ref_entity_id UUID REFERENCES lc_entities(id), -- 关联实体ID(如联系人关联客户)
ref_type VARCHAR(20), -- 关联类型:oneToOne/oneToMany/manyToMany
-- 统计配置
is_summary BOOLEAN DEFAULT false, -- 是否参与汇总
-- 状态
is_system BOOLEAN DEFAULT false, -- 系统字段(不可删除)
is_enabled BOOLEAN DEFAULT true,
-- 审计
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 实体内字段编码唯一
UNIQUE(entity_id, field_code)
);
COMMENT ON TABLE lc_fields IS '字段元数据表,定义每个实体的动态字段';
CREATE INDEX idx_lc_fields_entity ON lc_fields(entity_id);
CREATE INDEX idx_lc_fields_type ON lc_fields(field_type);1.3 表单元数据(Layout & UI)
CREATE TABLE lc_forms (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id) ON DELETE CASCADE,
form_code VARCHAR(100) NOT NULL, -- 表单编码:create_form/update_form
form_name VARCHAR(100) NOT NULL, -- 表单名称:新建客户
layout_config JSONB, -- 布局:{"columns":2,"titlePosition":"top"}
field_ids UUID[] NOT NULL, -- 字段ID列表(按顺序)
is_default BOOLEAN DEFAULT false, -- 是否为默认表单
is_enabled BOOLEAN DEFAULT true,
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(entity_id, form_code)
);
COMMENT ON TABLE lc_forms IS '表单元数据,定义表单布局';
CREATE INDEX idx_lc_forms_entity ON lc_forms(entity_id);低代码CRM工作流数据库架构设计
CRM低代码平台数据库设计(PostgreSQL)
以下是专为CRM场景设计的完整数据库架构,分为元数据层、业务数据层、工作流层、权限层、CRM业务层五大模块。
一、元数据层(Metadata Layer)
1.1 实体元数据表(Core Entity)
sql
复制
CREATE TABLE lc_entities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_code VARCHAR(100) NOT NULL, -- 编码:customer/contact/opportunity
entity_name VARCHAR(100) NOT NULL, -- 名称:客户/联系人/销售机会
table_name VARCHAR(100) NOT NULL, -- 物理表名:ent_customer
storage_type VARCHAR(20) DEFAULT 'jsonb', -- 存储策略:jsonb/ddl/hybrid
tenant_id UUID NOT NULL, -- 多租户隔离
is_system BOOLEAN DEFAULT false, -- 是否为系统预置(不可删除)
is_enabled BOOLEAN DEFAULT true,
description TEXT,
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 租户内实体编码唯一
UNIQUE(tenant_id, entity_code)
);
COMMENT ON TABLE lc_entities IS '实体元数据表,定义CRM所有业务对象';
CREATE INDEX idx_lc_entities_tenant ON lc_entities(tenant_id);1.2 字段元数据表(Field Definition)
sql
复制
CREATE TABLE lc_fields (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id) ON DELETE CASCADE,
field_code VARCHAR(100) NOT NULL, -- 字段编码:name/phone/amount
field_name VARCHAR(100) NOT NULL, -- 显示名称:客户名称
field_type VARCHAR(30) NOT NULL, -- 基础类型:text/number/date/select/boolean
component_type VARCHAR(50), -- 组件类型:Input/Select/ImageUpload
-- 布局与分组
field_group VARCHAR(50), -- 分组:基础信息/扩展信息/系统信息
sort_order INT DEFAULT 0, -- 排序
width VARCHAR(20) DEFAULT '1', -- 布局宽度:1/2/1/3/1/4
-- 校验规则
is_required BOOLEAN DEFAULT false,
is_unique BOOLEAN DEFAULT false,
validation_rules JSONB, -- {"minLength":2,"maxLength":50,"regex":"^1[3-9]\\d{9}$"}
-- 类型扩展属性
attributes JSONB, -- 单选:{"options":[{"label":"男","value":"M","color":"blue"}]} 数字:{"precision":2,"isAmount":true}
-- 关联关系(外键)
ref_entity_id UUID REFERENCES lc_entities(id), -- 关联实体ID(如联系人关联客户)
ref_type VARCHAR(20), -- 关联类型:oneToOne/oneToMany/manyToMany
-- 统计配置
is_summary BOOLEAN DEFAULT false, -- 是否参与汇总
-- 状态
is_system BOOLEAN DEFAULT false, -- 系统字段(不可删除)
is_enabled BOOLEAN DEFAULT true,
-- 审计
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- 实体内字段编码唯一
UNIQUE(entity_id, field_code)
);
COMMENT ON TABLE lc_fields IS '字段元数据表,定义每个实体的动态字段';
CREATE INDEX idx_lc_fields_entity ON lc_fields(entity_id);
CREATE INDEX idx_lc_fields_type ON lc_fields(field_type);1.3 表单元数据(Layout & UI)
sql
复制
CREATE TABLE lc_forms (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id) ON DELETE CASCADE,
form_code VARCHAR(100) NOT NULL, -- 表单编码:create_form/update_form
form_name VARCHAR(100) NOT NULL, -- 表单名称:新建客户
layout_config JSONB, -- 布局:{"columns":2,"titlePosition":"top"}
field_ids UUID[] NOT NULL, -- 字段ID列表(按顺序)
is_default BOOLEAN DEFAULT false, -- 是否为默认表单
is_enabled BOOLEAN DEFAULT true,
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(entity_id, form_code)
);
COMMENT ON TABLE lc_forms IS '表单元数据,定义表单布局';
CREATE INDEX idx_lc_forms_entity ON lc_forms(entity_id);1.4 字段依赖关系表(Field Dependencies)
sql
复制
CREATE TABLE lc_field_deps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id) ON DELETE CASCADE,
parent_field_id UUID NOT NULL REFERENCES lc_fields(id),
child_field_id UUID NOT NULL REFERENCES lc_fields(id),
data_source_url TEXT, -- 级联数据源:/api/options/city?province={value}
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(entity_id, parent_field_id, child_field_id)
);
COMMENT ON TABLE lc_field_deps IS '字段依赖关系(级联选择)';二、业务数据层(Business Data Layer)
2.1 统一动态数据表(JSONB 存储)
CREATE TABLE lc_data (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id),
tenant_id UUID NOT NULL,
record_id UUID NOT NULL, -- 业务记录ID(用于关联)
-- 动态数据(核心)
field_values JSONB NOT NULL DEFAULT '{}', -- {"name":"客户A","phone":"13800000000","amount":10000}
-- 系统字段
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_by VARCHAR(50),
updated_at TIMESTAMP DEFAULT NOW(),
owner_id UUID, -- 负责人
dept_id UUID, -- 所属部门
-- 辅助字段(提升查询性能)
is_starred BOOLEAN DEFAULT false, -- 是否重点客户
last_follow_time TIMESTAMP, -- 最后跟进时间
-- 索引
INDEX idx_lc_data_entity_tenant (entity_id, tenant_id),
INDEX idx_lc_data_record (record_id),
INDEX idx_lc_data_created (created_at DESC),
INDEX idx_lc_data_owner (owner_id),
-- GIN 索引(JSONB 全文检索)
INDEX idx_lc_data_values_gin ON lc_data USING GIN (field_values)
);
COMMENT ON TABLE lc_data IS '统一业务数据表,所有实体的动态数据存入 JSONB';2.2 数据关系表(ManyToMany)
CREATE TABLE lc_relations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id),
from_record_id UUID NOT NULL, -- 源记录ID
to_record_id UUID NOT NULL, -- 目标记录ID
relation_type VARCHAR(50), -- 关联类型:contact/opportunity/order
created_at TIMESTAMP DEFAULT NOW(),
-- 联合索引(双向查询)
INDEX idx_relations_from (entity_id, from_record_id),
INDEX idx_relations_to (entity_id, to_record_id)
);
COMMENT ON TABLE lc_relations IS '实体关系表(客户-联系人、客户-机会)';2.3 数据快照表(历史版本)
CREATE TABLE lc_data_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data_id UUID NOT NULL REFERENCES lc_data(id) ON DELETE CASCADE,
version INT NOT NULL, -- 版本号
field_values JSONB NOT NULL, -- 历史数据快照
operation_type VARCHAR(20), -- create/update/delete
operator VARCHAR(50),
operated_at TIMESTAMP DEFAULT NOW(),
INDEX idx_history_data (data_id, version DESC)
);
COMMENT ON TABLE lc_data_history IS '数据历史版本表(操作日志)';
三、工作流层(Workflow Layer)
3.1 工作流定义表
CREATE TABLE wf_definitions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wf_code VARCHAR(100) NOT NULL, -- 编码:contract_approval
wf_name VARCHAR(100) NOT NULL, -- 名称:合同审批流
entity_id UUID REFERENCES lc_entities(id), -- 关联实体(可选)
tenant_id UUID NOT NULL,
-- BPMN 流程定义
bpmn_xml TEXT, -- BPMN 2.0 XML
process_definition_id VARCHAR(100), -- Flowable/Camunda 流程定义ID
is_enabled BOOLEAN DEFAULT true,
version INT DEFAULT 1,
created_by VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(tenant_id, wf_code, version)
);
COMMENT ON TABLE wf_definitions IS '工作流定义表';
CREATE INDEX idx_wf_def_tenant ON wf_definitions(tenant_id);3.2 流程实例表
CREATE TABLE wf_instances (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wf_definition_id UUID NOT NULL REFERENCES wf_definitions(id),
business_key VARCHAR(100), -- 业务主键(如合同ID)
record_id UUID, -- 关联业务记录
-- 流程状态
status VARCHAR(20) DEFAULT 'running', -- running/completed/suspended
current_node VARCHAR(100), -- 当前节点
-- 发起人
starter_id UUID,
start_time TIMESTAMP DEFAULT NOW(),
end_time TIMESTAMP,
INDEX idx_wf_instances_business (business_key),
INDEX idx_wf_instances_record (record_id)
);
COMMENT ON TABLE wf_instances IS '流程实例表';3.3 任务表(待办事项)
CREATE TABLE wf_tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
instance_id UUID NOT NULL REFERENCES wf_instances(id) ON DELETE CASCADE,
node_id VARCHAR(100) NOT NULL,
node_name VARCHAR(100), -- 节点名称:部门经理审批
-- 任务分配
assignee_id UUID, -- 负责人
assignee_dept_id UUID, -- 负责部门(支持部门负责人审批)
-- 任务状态
status VARCHAR(20) DEFAULT 'pending', -- pending/completed/delegated
priority INT DEFAULT 5, -- 优先级 1-10
-- 时间
create_time TIMESTAMP DEFAULT NOW(),
due_time TIMESTAMP, -- 截止时间
complete_time TIMESTAMP,
-- 扩展
variables JSONB, -- 流程变量
INDEX idx_wf_tasks_assignee (assignee_id, status),
INDEX idx_wf_tasks_due (due_time)
);
COMMENT ON TABLE wf_tasks IS '工作流任务表(用户待办)';3.4 任务操作日志
CREATE TABLE wf_task_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
task_id UUID NOT NULL REFERENCES wf_tasks(id),
operation VARCHAR(20), -- approve/reject/delegate
operator_id UUID,
comment TEXT,
operate_time TIMESTAMP DEFAULT NOW(),
INDEX idx_logs_task (task_id)
);
COMMENT ON TABLE wf_task_logs IS '任务操作日志';四、权限层(Permission Layer)
4.1 角色表
sql
复制
CREATE TABLE perm_roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
role_code VARCHAR(100) NOT NULL, -- admin/manager/sales
role_name VARCHAR(100),
is_system BOOLEAN DEFAULT false,
parent_id UUID REFERENCES perm_roles(id), -- 角色层级
UNIQUE(tenant_id, role_code)
);
COMMENT ON TABLE perm_roles IS '角色表';
CREATE INDEX idx_perm_roles_tenant ON perm_roles(tenant_id);4.2 用户角色关系
sql
复制
CREATE TABLE perm_user_roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
role_id UUID NOT NULL REFERENCES perm_roles(id),
tenant_id UUID NOT NULL,
UNIQUE(user_id, role_id, tenant_id)
);
COMMENT ON TABLE perm_user_roles IS '用户角色关系';4.3 数据权限规则(核心)
sql
复制
CREATE TABLE perm_data_rules (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL REFERENCES lc_entities(id),
role_id UUID REFERENCES perm_roles(id),
user_id UUID, -- 特定用户规则(优先级高于角色)
-- 规则类型
rule_type VARCHAR(20), -- owner/dept/created/custom
-- 自定义规则(SQL WHERE 片段)
custom_filter TEXT, -- owner_id = ${currentUserId}
is_enabled BOOLEAN DEFAULT true,
priority INT DEFAULT 0, -- 规则优先级
INDEX idx_perm_rules_entity (entity_id)
);
COMMENT ON TABLE perm_data_rules IS '数据权限规则(谁能看什么数据)';4.4 字段权限表
sql
复制
CREATE TABLE perm_field_rules (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
field_id UUID NOT NULL REFERENCES lc_fields(id),
role_id UUID REFERENCES perm_roles(id),
user_id UUID,
-- 权限
can_visible BOOLEAN DEFAULT true,
can_edit BOOLEAN DEFAULT false,
-- 高级规则(排除特定用户)
exclude_user_ids UUID[],
is_enabled BOOLEAN DEFAULT true,
UNIQUE(field_id, role_id, user_id)
);
COMMENT ON TABLE perm_field_rules IS '字段级权限(谁能看/编辑某个字段)';五、CRM 业务层(CRM-Specific)
5.1 租户配置表
sql
复制
CREATE TABLE crm_tenant_config (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL UNIQUE,
-- 客户查重规则
dedup_enabled BOOLEAN DEFAULT true,
dedup_fields TEXT[] DEFAULT '{name,phone}', -- 默认查重字段
-- 公海池规则
pool_enabled BOOLEAN DEFAULT true,
pool_expire_days INT DEFAULT 30, -- 多久未跟进进入公海
-- 客户编号规则
serial_number_rule TEXT DEFAULT 'KH{yyyy}{MM}{dddd}', -- 流水号规则
created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE crm_tenant_config IS '租户级CRM配置';5.2 公海池记录
sql
复制
CREATE TABLE crm_customer_pool (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
customer_id UUID NOT NULL, -- 客户ID(关联 lc_data)
tenant_id UUID NOT NULL,
-- 进入公海原因
enter_reason VARCHAR(50), -- expire/manual
enter_time TIMESTAMP DEFAULT NOW(),
-- 领取限制
last_pickup_user_id UUID, -- 上次负责人(防止重复领取)
INDEX idx_pool_tenant (tenant_id, enter_time)
);
COMMENT ON TABLE crm_customer_pool IS '公海池客户';5.3 跟进计划
sql
复制
CREATE TABLE crm_visit_plans (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
record_id UUID NOT NULL, -- 关联业务记录(客户ID)
entity_id UUID NOT NULL,
tenant_id UUID NOT NULL,
-- 计划内容
plan_time TIMESTAMP NOT NULL, -- 计划时间
plan_content TEXT,
plan_type VARCHAR(20), -- phone/visit/demo
-- 执行结果
execute_time TIMESTAMP,
execute_result TEXT,
status VARCHAR(20) DEFAULT 'pending', -- pending/completed/overdue
-- 负责人
owner_id UUID,
INDEX idx_plans_record (record_id, plan_time),
INDEX idx_plans_owner (owner_id, plan_time)
);
COMMENT ON TABLE crm_visit_plans IS '访客计划';六、扩展功能表(Extension)
6.1 查重日志
sql
复制
CREATE TABLE dup_check_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_id UUID NOT NULL,
tenant_id UUID NOT NULL,
checked_data JSONB, -- {name: "客户A", phone: "138000"}
matched_records UUID[], -- 匹配到的记录ID
match_score FLOAT, -- 匹配度
created_at TIMESTAMP DEFAULT NOW(),
INDEX idx_dup_log_tenant (tenant_id, created_at)
);
COMMENT ON TABLE dup_check_logs IS '查重检测日志';6.2 操作审计表
sql
复制
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
user_id UUID NOT NULL,
entity_id UUID,
record_id UUID,
operation VARCHAR(20), -- create/read/update/delete
old_values JSONB, -- 旧值
new_values JSONB, -- 新值
ip_address INET,
user_agent TEXT,
operated_at TIMESTAMP DEFAULT NOW(),
INDEX idx_audit_user (user_id, operated_at),
INDEX idx_audit_record (entity_id, record_id)
);
COMMENT ON TABLE audit_logs IS '全量操作审计';七、PostgreSQL 高级特性应用
7.1 行级安全(RLS)- 实现多租户隔离
sql
复制
-- 启用RLS
ALTER TABLE lc_data ENABLE ROW LEVEL SECURITY;
-- 创建策略(每个租户只能看到自己的数据)
CREATE POLICY tenant_isolation ON lc_data
FOR ALL
USING (tenant_id = current_setting('app.current_tenant')::UUID);
-- 应用连接时设置租户上下文
SET app.current_tenant = 'your-tenant-id';7.2 分区表(应对大数据量)
sql
复制
-- 按创建时间分区(每月一个分区)
CREATE TABLE lc_data_2025_01 PARTITION OF lc_data
FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
CREATE TABLE lc_data_2025_02 PARTITION OF lc_data
FOR VALUES FROM ('2025-02-01') TO ('2025-03-01');
-- 自动分区函数(每月执行)
CREATE OR REPLACE FUNCTION create_monthly_partition()
RETURNS void AS $$
DECLARE
partition_name TEXT;
start_date DATE;
end_date DATE;
BEGIN
start_date := date_trunc('month', CURRENT_DATE + interval '1 month');
end_date := start_date + interval '1 month';
partition_name := 'lc_data_' || to_char(start_date, 'YYYY_MM');
EXECUTE format(
'CREATE TABLE IF NOT EXISTS %I PARTITION OF lc_data FOR VALUES FROM (%L) TO (%L)',
partition_name, start_date, end_date
);
END;
$$ LANGUAGE plpgsql;7.3 JSONB 查询性能优化
sql
复制
-- 表达式索引(高频字段)
CREATE INDEX idx_customer_name ON lc_data ((field_values->>'name'))
WHERE entity_id = 'customer-entity-id';
-- 复合GIN索引
CREATE INDEX idx_lc_data_multi_gin ON lc_data
USING GIN (field_values jsonb_path_ops);
-- 覆盖索引
CREATE INDEX idx_lc_data_covering
ON lc_data (tenant_id, entity_id, created_at DESC)
INCLUDE (field_values);八、初始化 SQL 脚本
sql
复制
-- 执行顺序:先元数据 → 再业务 → 最后工作流
-- 1. 创建扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- 模糊匹配
-- 2. 创建元数据表
\i 01_metadata_tables.sql
-- 3. 创建业务数据表
\i 02_business_tables.sql
-- 4. 创建工作流表
\i 03_workflow_tables.sql
-- 5. 创建权限表
\i 04_permission_tables.sql
-- 6. 创建CRM业务表
\i 05_crm_tables.sql
-- 7. 创建索引
\i 06_create_indexes.sql
-- 8. 创建RLS策略(可选)
\i 07_rls_policies.sql九、核心使用示例
9.1 创建客户实体
sql
复制
-- 1. 插入实体元数据
INSERT INTO lc_entities (entity_code, entity_name, table_name, tenant_id)
VALUES ('customer', '客户管理', 'ent_customer', 'tenant-001');
-- 2. 插入字段元数据
INSERT INTO lc_fields (entity_id, field_code, field_name, field_type, component_type, sort_order, is_required)
VALUES
(currval('lc_entities_id_seq'), 'name', '客户名称', 'text', 'Input', 10, true),
(currval('lc_entities_id_seq'), 'phone', '手机号', 'text', 'Input', 20, true),
(currval('lc_entities_id_seq'), 'amount', '合同金额', 'number', 'NumberPicker', 30, false);9.2 查询客户数据
sql
复制
-- 根据元数据动态查询
SELECT
field_values->>'name' AS name,
field_values->>'phone' AS phone,
(field_values->>'amount')::DECIMAL AS amount
FROM lc_data
WHERE entity_id = 'customer-entity-id'
AND tenant_id = 'tenant-001'
AND field_values->>'name' ILIKE '%阿里巴巴%'
ORDER BY created_at DESC
LIMIT 20;9.3 创建工作流
sql
复制
INSERT INTO wf_definitions (wf_code, wf_name, entity_id, tenant_id, bpmn_xml)
VALUES (
'contract_approval',
'合同审批流',
'contract-entity-id',
'tenant-001',
'<bpmn:process>...</bpmn:process>' -- BPMN XML
);十、性能与安全建议
性能优化清单
大表分区:
lc_data按tenant_id+created_at分区索引策略:每个租户高频查询字段建表达式索引
查询限流:复杂查询强制走
EXPLAIN ANALYZE,超时自动熔断读写分离:只读查询走从库,写入走主库
安全加固清单
强制 RLS:所有业务表启用行级安全
SQL 注入防护:使用参数化查询,禁止拼接 SQL
字段权限:后端每次查询后,根据
perm_field_rules过滤字段审计日志:所有写操作记录到
audit_logs表
总结
元数据层是大脑:存储"如何展示、如何校验、谁能看"的配置
业务数据层是血液:存储实际业务数据,通过
entity_id与元数据关联工作流层是神经:驱动业务流程,通过
record_id关联业务数据权限层是免疫系统:所有访问必须经过权限校验
核心查询逻辑:所有查询都从 lc_entities 开始 → 加载 lc_fields → 生成动态 SQL → 查询 lc_data,权限过滤贯穿始终。