用 PostgreSQL 实践 Palantir 本体论

作者简介:怀玉杰,瀚高股份研发工程师,负责 AI 方向研发,擅长算法分析与 AI 应用。

医院数据管理的挑战

介绍

当前医院的信息系统呈现出多系统并存的复杂局面。一家三甲医院通常运行着数十个不同的业务系统:HIS(医院信息系统)处理核心业务,EMR(电子病历系统)记录诊疗过程等。并且医院场景本身复杂多变,患者从入院到出院整个过程往往要经历多个阶段:入院登记、床位分配、科室调整、检查与治疗、最终出院。

以床位管理为例,护士寻找空床需要反复在系统查询和电话确认之间切换,效率低下且容易出错。当前主流医院系统设计是状态驱动的建模方式,只记录当前状态,如:在患者表中维护当前状态(在院/出院/转科中),无法追溯历史变化,随着数据增多、业务繁杂,各种问题也逐步暴露。

python 复制代码
CREATE TABLE beds (
	bed_id uuid DEFAULT gen_random_uuid() NOT NULL,
	bed_number varchar(100) NOT NULL,
	department_id uuid NULL,
	bed_type varchar(20) NULL CHECK (bed_type IN ('普通床', 'ICU床','隔离床', '抢救床','儿科床')),
	equipments jsonb NULL,
	current_status varchar(20) NULL CHECK (current_status IN ('占用','空闲','清理中')),
	physical_location jsonb NULL,
	support_isolation bool DEFAULT false NULL,
	specialty_attribute text NULL,
	created_at timestamptz DEFAULT now() NULL,
	updated_at timestamptz DEFAULT now() NULL
);

当前问题

首先是可追溯性问题。当系统只保留"当前状态"时,无法进行历史追溯、操作追溯,很难回答看似简单的问题:谁用过这张床?病人为什么转科?床位状态为什么是这样?

其次是逻辑分散、维护成本高的问题。技术实现中,每个业务操作需要编写专门的存储过程(procedure),且牵扯多种函数或表关系,当业务规则发生变化时,往往需要同时修改多处代码且新增业务类型时,需要考虑对现有流程的影响。随着业务流程的复杂,会导致系统越来越臃肿,最终复杂的存储过程与触发器会难以理解和调试,成本也会越来越高。

最后是系统语义模糊的问题。在状态驱动模型中,数据库中的一行记录,往往混合了三种含义:现实世界发生过什么;系统当前认为是什么状态;流程执行到了哪一步。这三者在数据层面被耦合在一起,使得系统越来越像一个"黑盒"。

综上所述,医院这种高度依赖时间、行为和约束,且场景多样复杂,行为动态变化的需求下,我们需要新的数据管理思维去建立新的系统。以床位系统为例,需要有以下优点:

  • 完整的历史追溯:能还原床位状态的完整演变过程。
  • 数据一致性:避免多系统间的数据矛盾。
  • 操作透明性:每个状态变化都有明确的上下文记录。
  • 扩展灵活性:新业务能快速上线,不影响现有功能。
  • 分析支持能力:基于历史数据提供决策支持。

因此,我们希望系统能够完整记录整个过程,状态只是从事实中推导出的结果。

Palantir 方法论

方法论简介

Palantir 提出了以 Ontology(本体论) 为核心的数据建模方法论,并在复杂业务系统中,将"行为(Action)"而非"状态(State)"放在系统的中心位置。

本体论是一种工程化的数据建模方法,其核心观点是:信息系统不应该关注"状态",而应该关注"发生了什么",然后从这些事实中推导出当前状态。

'行为记录'并不意味着把所有业务逻辑都放在数据库中。相反,本体论倡导清晰的职责分离:应用层负责业务流程的编排和规则执行,而数据库层则专注于忠实地记录这些流程产生的'行为'。这种分离使得系统既能享受行为驱动的追溯能力,又能保持架构的灵活性和可扩展性。

以床位系统为例:本体论不是记录"床位现在是空的",而是记录"病人 A 于 10:00 从床位 1 出院了",然后推导出"床位 1 现在是空的"。

在这种模型下,系统的职责不再是不断"修改状态",而是完整、准确地记录每一次行为的发生。一旦行为被记录下来:状态可以随时重新;计算历史可以完整回放;业务决策可以基于事实进行分析。

对比

我们以患者转科的例子来比较传统思维与 Ontology 的区别:

  1. 传统转科思维模式:
  • 更新患者表的状态:

UPDATE patient SET department_id = '心内科' WHERE patient_id = '001';

  • 更新床位表的状态

UPDATE bed SET current_status = '清理中' WHERE bed_id = 'B01';

UPDATE bed SET current_status = '占用' WHERE bed_id = 'B02';

  1. Palantir 思维模式:
  • 在行为表中记录一个不可变的事实
python 复制代码
INSERT INTO bed_events (
    patient_id,
    event_type,
    event_time,
    details
) VALUES (
    '001',
    '占用',
    '2024-01-15 14:30:00',
    '{
        "department": "心内科",
        "bed": "B01",
        "reason": "确诊冠心病需专科治疗",
        "doctor": "张明",
        "order_id": "ORDER_789"
    }'::JSONB
);
  • 自动更新床位的视图
python 复制代码
CREATE VIEW current_bed_status AS
WITH latest_bed_events AS (
    SELECT DISTINCT ON (bed_id) *
    FROM bed_events
    ORDER BY bed_id, event_time DESC
)

优势

通过上述对比,我们可以总结出以下优势:

  1. 业务优势:
  • 完整溯源:能够回答"病人为什么转科"、"床位谁用过"这类历史问题。

  • 数据一致性:所有系统基于相同的事实记录,避免状态不一致。

  • 业务灵活性:新增业务流程只需定义新的事实类型,无需修改现有结构。

  1. 技术优势:
  • 系统解耦:事实记录层与业务逻辑层分离。

  • 简化维护:无需复杂的存储过程链,核心逻辑是记录事实。

  • 便于分析:所有历史数据都在,方便进行趋势分析和决策支持。

医院业务的复杂性不仅在于流程多,更在于每个流程都需要完整的溯源能力。无论是医疗质量管理、费用追溯,还是医疗纠纷处理,都需要能够回答"当时发生了什么"。Palantir 的本体论解决了这一问题:不再试图维护一个"完美"的当前状态,而是忠实地记录所有重要事实,让状态成为事实的自然推导结果。

PostgreSQL :Palantir 思想的天然数据基石

PostgreSQL 的优势

这种思想转变带来了数据管理范式的革新,但要真正落地,我们需要一个能够有效支持这种数据模型的技术平台。在实践中,PostgreSQL 是本体论实现的天然数据基石。

以医院系统为例,有以下契合点:

  1. 记录事实:

本体论的核心在于事实优先,而相较于传统数据库,PostgreSQL 在事实型数据建模方面具备天然优势:

  • JSONB 类型:可存储任意结构的上下文数据,适合事实表的构建,当业务流程变化时,无需频繁修改表结构,只需在 JSONB 中扩展新的字段即可。
  • 时间类型丰富:PostgreSQL 提供了多种时间类型,并支持时区转换,适合精确描述行为发生的完整时间维度。
  • 表继承与分区:通过表继承能自然建立事实表的层级关系,而分区功能可以有效管理海量历史数据,提高查询性能和管理效率。
  1. 描述状态:

在本体论中,"状态"是由事实型数据推导的结果,而 PG 在这方面具备显著优势:

  • 视图与物化视图:PostgreSQL 支持复杂的视图和物化视图,可以从事实表中实时推导出当前状态。物化视图支持自动或手动刷新,在性能与实时性之间提供灵活平衡。
  • 窗口函数与聚合:PostgreSQL 拥有强大的窗口函数和聚合能力,能够基于历史事实序列计算出各种状态指标,如平均住院日、床位周转率等。
  • 递归查询支持:通过 CTE(公共表表达式)和递归查询,可以处理复杂的层次结构和时序分析,例如完整追溯患者的整个诊疗过程。
  1. 维护数据一致性:

PostgreSQL 提供了多种机制来维护事实数据的质量和一致性:

  • 事务保障:通过 ACID 事务保证事实记录的原子性和一致性,即使在高并发场景下也能确保数据完整。
  • 约束与触发器:丰富的约束类型(检查约束、唯一约束、外键约束)和触发器机制,能够在数据层自动维护数据质量,确保事实记录的准确性。
  • 并发控制:多版本并发控制(MVCC)机制确保在高并发环境下,事实记录的写入和状态查询可以高效并行执行。
  1. 特有扩展能力:

PostgreSQL 通过丰富的扩展生态系统,能够满足医疗场景中的特殊需求:

  • 空间数据分析:PostGIS 扩展支持地理空间数据存储与分析,可用于医院床位布局优化、患者动线分析等场景。
  • 外部数据集成:通过 FDW(Foreign Data Wrapper)可以透明地集成医院其他系统的数据,实现真正的数据融合,而无需复杂的 ETL 流程。
  • 时序数据优化:TimescaleDB 扩展专门优化时序数据处理,能够高效管理医院环境中产生的大量时间序列事实数据。
  • 图数据支持:Apache AGE 扩展为 PostgreSQL 增加图数据库能力,可以分析复杂的医患关系、疾病传播路径等。
  1. 生态成熟:

PostgreSQL 在生产环境中已经证明了其可靠性和稳定性:

  • 开源可控:开源许可确保医院能够完全掌握核心技术栈,避免厂商锁定风险,同时降低了软件许可成本。
  • 成熟工具链:拥有 pgAdmin、pgBackRest、pgBouncer 等成熟的运维管理工具,覆盖监控、备份、连接管理等关键运维场景。
  • 活跃社区:全球活跃的开源社区和多个商业支持厂商,确保技术问题能够快速响应和解决。
  • 云原生支持:所有主流云平台都提供托管的 PostgreSQL 服务,简化部署和运维。

PostgreSQL 的定位

综合来看,在本体论中,PostgreSQL 承担以下角色:

  • 现实世界行为的事实存储层。
  • 业务状态的推演与分析基础。
  • 多系统数据一致性的核心锚点。

这些特点使 PostgreSQL 作为数据层的坚实基础,成为本体论方法中落地的理想选择。

具体实现

在本文中,我们以医院床位管理为例,设计一个最小的 PostgreSQL Demo,用于验证本体论思路在实际业务场景中的可行性。

本体论视角下核心对象建模

在医院床位管理场景中,主要可以抽象出以下几类核心对象:

  • Patient
  • Bed
  • Department
  • Order(医嘱表):表示医生的医嘱,是意图而不是已发生的事实

这些对象本身相对稳定,业务变化不体现在对象结构上,而是体现在它们的关系变化上。

python 复制代码
create table beds(
bed_id uuid default gen_random_uuid() not null,
bed_code varchar(100) not null,
department_id uuid null,
bed_type varchar(20) null check (bed_type in ('普通床', 'icu床','隔离床', '抢救床','儿科床')),
last_changed_at timestamp
);

系统中的事实存储

在床位管理场景中,有事实存储表:bed_actions,只负责记录事实,不包含业务逻辑。需要强调的是:

  • Action 表不包含状态字段。
  • 不区分"执行中 / 已完成 / 已失败"。
  • 一条 Action 一旦写入,即被视为系统确认的事实。

这使得 Action 表天然具备以下特性:

  • 事实不可篡改。
  • 历史完整保留。
  • 行为语义清晰。
python 复制代码
create table bed_actions (
    action_id uuid primary key default gen_random_uuid(),
    action_type text not null check( action_type in ('被分配','被释放')),
    patient_id uuid not null references patients(patient_id),
    bed_id uuid references beds(bed_id),
    from_department_id uuid references departments(department_id),
    to_department_id uuid references departments(department_id),
    context jsonb,
    occurred_at timestamptz not null default now()
);

使用说明

在这个模型中表达一次转科流程,是两条 action:释放原床和分配新床。

python 复制代码
#释放原床
insert into bed_actions(
    action_type,
    patient_id,
    bed_id,
    from_department_id,
    context) values(
    '被释放',
    'Patient_01',
    'B01',
    'D01',
    jsonb_build_object(
        'reason','转科转出',
        'order_id':order_id
    )
);
#分配新床
insert into bed_actions(
    action_type,
    patient_id,
    bed_id,
    from_department_id,
    context) values(
    '被分配',
    'Patient_01',
    'B02',
    'D02',
    jsonb_build_object(
        'reason','转科转入',
        'order_id':order_id
    )
    );

若想查询"某科室有哪些空床",根据 bed_actions 表派生状态,使用 SQL 进行查询。

python 复制代码
#构建床位状态表
create view bed_current_status as
select
    b.bed_id,
    b.department_id,
    case
        when last_action.action_type = '被分配' then '占用'
        when last_action.action_type = '被释放' then '空闲'
        else '空闲'
    end as bed_status
from beds b
left join lateral (
    select *
    from bed_actions a
    where a.bed_id = b.bed_id
    order by occurred_at desc
    limit 1
) last_action on true;

#查询某科室空床
select *
from bed_current_status
where department_id = :dept_id
  and bed_status = '空闲';

总结

从状态驱动到行为驱动的转变,本质上是数据管理思维的根本革新。传统系统试图维护一个"完美的当前状态",而本体论方法选择忠实地记录"所有重要事实"。这种转变让系统具备了前所未有的追溯能力和灵活性。

PostgreSQL 凭借其强大的数据管理能力,成为这一方法落地的理想选择。它不仅提供了技术实现的可能,更重要的是其设计哲学与本体论思想高度一致:都强调数据的完整性、一致性和可追溯性。

在实际应用中,这种架构实现了职责的清晰分离:应用层专注于业务流程编排,PostgreSQL 作为数据基石。 选择 PostgreSQL,并以行为为核心建模时,许多看似复杂的问题------历史追溯、状态一致性、系统可解释性------都会在模型层面被自然化解。数据库不再只是数据的存储容器,而成为对现实世界的结构化表达。这正是本体论方法在复杂业务系统中真正的价值所在。


HOW 2026 议题招募中

2026 年 4 月 27-28 日,由 IvorySQL 社区联合 PGEU(欧洲 PG 社区)、PGAsia(亚洲 PG 社区)共同打造的 HOW 2026(IvorySQL & PostgreSQL 技术峰会) 将再度落地济南。届时,PostgreSQL 联合创始人 Bruce Momjian 等顶级大师将亲临现场。

自开启征集以来,HOW 2026 筹备组已感受到来自全球 PostgreSQL 爱好者的澎湃热情。为了确保大会议题的深度与广度,我们诚邀您在 2026 年 2 月 27 日截止日期前,提交您的技术见解。

投递链接:jsj.top/f/uebqBc

相关推荐
江湖有缘2 小时前
Docker一键部署docat:打造轻量级开源文档管理系统
docker·容器·开源
lkbhua莱克瓦242 小时前
进阶-存储对象1-视图
java·数据库·sql·mysql·视图
百***24372 小时前
GLM-4.7底层技术拆解与落地避坑:开源大模型编码实战指南
人工智能·gpt·开源
yangminlei2 小时前
Spring Boot 自动配置原理与自定义 Starter 开发实战
java·数据库·spring boot
萧曵 丶2 小时前
Redis 由浅到深面试题(分层次版)
数据库·redis·缓存
-XWB-2 小时前
【Oracle】Oracle诊断系列(1/6):健康体检指南——快速掌握数据库状态
数据库·oracle
杨了个杨89822 小时前
Redis常用命令
数据库·redis·缓存
-XWB-2 小时前
【MySQL】XtraBackup 全量备份还原操作指南(MySQL 5.7 / 8.0 通用)
数据库·mysql·adb
viperrrrrrrrrr72 小时前
开源模型如何盈利
人工智能·开源·deepseek-v4