联众电子病历表结构文档:EMR数据字典与二次开发实战指南

发布时间:2026/10/9 15:45:56
联众电子病历表结构文档:EMR数据字典与二次开发实战指南
简介《联众电子病历表结构文档》面向ZJHIS、EMR3、EMR及EMRJK等系统的开发、运维与数据管理人员系统梳理电子病历核心数据表的字段定义与设计逻辑帮助读者理解并高效管理临床与运营数据。文档由占贵顺、葛向东多次修订完善内容覆盖用户信息、系统配置、医院标识、公用代码、病人类别与性质、科室与病区代码、系统参数、职工与用户信息、医生分组、医疗收费及套餐、费用接口、项目审批、住院病人信息、婴儿登记等模块并延伸至病案系统相关表结构目录层级清晰便于按业务域检索。资源包共1个doc文件约6.07MB以表格与字段说明为主适合作为数据字典查阅或二次开发参考。目前已有349人学习下载可帮助读者快速定位关键表、理清表间关联为接口对接、报表统计与系统维护提供扎实依据。1. 联众电子病历表结构文档一份被低估的 EMR 数据字典接手一个已经上线两三年的电子病历系统最怕的不是代码写得烂而是没人说得清数据库里那两百多张表到底谁是谁。我最近就碰到这么个事某公司的一套 EMR 系统要接第三方体检数据接口文档写得含糊字段对不上翻遍代码也找不到映射关系。最后解决问题的是一份躺在共享盘角落里、文件名就叫「联众电子病历表结构文档.doc」的东西。它不是什么教程也不是源码包而是一份实打实的数据字典——把联众电子病历系统里主要数据表的字段名、类型、含义、关联关系一条条列了出来。对于要做 EMR 二次开发、数据迁移、接口对接或者报表取数的人来说这份文档的价值在于它让你不用靠猜和试错去理解一个陌生系统的数据模型。适合谁做医疗信息化的后端、数据工程师、实施顾问以及需要从 EMR 里抽数据做分析的人。如果你正对着联众的库发愁这份文档能省你至少一周的逆向时间。2. 联众 EMR 表结构怎么读从患者主索引到临床文档2.1 先搞清楚联众 EMR 的数据分层逻辑拿到一份表结构文档最忌讳从头到尾一页页翻。联众这套 EMR 的表设计遵循一个比较典型的分层思路你先把层次理清楚后面查字段就是按图索骥。第一层是患者主索引层核心表通常围绕PATIENT或PAT_MASTER_INDEX展开存的是患者基本信息、病案号、身份证号、联系方式这些全局唯一的身份数据。这一层的关键是主键设计——联众一般用PATIENT_ID作为内部唯一标识病案号和住院号是业务标识两者不要混。第二层是就诊/住院层围绕VISIT或INPATIENT表记录每一次就诊或住院的上下文。一个患者可以有多次就诊所以这里是一对多关系。就诊层往下挂的是医嘱、病程记录、检验检查申请等。第三层是临床文档层这是 EMR 的核心包括病程记录、入院记录、手术记录、护理记录等。联众的设计里这类文档通常不是一张大表存所有内容而是按文档类型分表或者用主表加明细表的方式。比如EMR_DOCUMENT存文档元数据文档类型、创建时间、作者、状态EMR_DOCUMENT_CONTENT存实际内容。第四层是字典/编码层比如诊断字典、药品字典、科室字典。这一层看起来不起眼但做数据映射的时候全靠它。读文档的时候建议先找到这四层的入口表把 ER 关系在纸上画一遍再去看具体字段。不然你会在几百个字段名里迷路。2.2 用文档反查字段以「取患者最近一次住院的入院记录」为例光说逻辑不够直接看一个实际场景。假设你要写一条 SQL取某个患者最近一次住院的入院记录内容。没有文档的时候你得猜表名、猜字段、猜关联条件。有了这份表结构文档步骤是这样的第一步在文档里搜「患者主索引」找到PATIENT表确认PATIENT_ID是主键ID_CARD或CARD_NO是身份证号字段。第二步搜「住院」或「就诊」找到VISIT表确认它通过PATIENT_ID关联患者并且有VISIT_TYPE字段区分门诊/住院有ADMISSION_TIME记录入院时间。第三步搜「入院记录」找到对应的文档表比如EMR_ADMISSION_NOTE确认它通过VISIT_ID关联就诊表。第四步根据文档里标注的字段含义拼出查询语句。-- 取指定患者最近一次住院的入院记录 SELECT p.PATIENT_NAME, -- 患者姓名 v.ADMISSION_TIME, -- 入院时间 v.DEPT_NAME, -- 入院科室 a.CHIEF_COMPLAINT, -- 主诉 a.PRESENT_ILLNESS, -- 现病史 a.PAST_HISTORY -- 既往史 FROM PATIENT p JOIN VISIT v ON p.PATIENT_ID v.PATIENT_ID JOIN EMR_ADMISSION_NOTE a ON v.VISIT_ID a.VISIT_ID WHERE p.ID_CARD 某身份证号 AND v.VISIT_TYPE 住院 ORDER BY v.ADMISSION_TIME DESC FETCH FIRST 1 ROW ONLY;这段 SQL 里每个字段名都是从文档里查出来的不是猜的。VISIT_TYPE的取值文档里一般会列出来比如门诊、住院、急诊写条件的时候要按文档里的实际值来。FETCH FIRST 1 ROW ONLY是标准 SQL 写法不同数据库可能用LIMIT 1或TOP 1根据你的环境调整。参数说明ID_CARD是身份证号如果文档里标注的是CARD_NO或SOCIAL_ID就换成对应字段。ADMISSION_TIME是入院时间排序用它才能取到最近一次。如果文档里入院记录表不是EMR_ADMISSION_NOTE而是别的名字以文档为准。2.3 文档里没写全的关联关系怎么补这份表结构文档虽然覆盖了主要表但不可能把每个外键关系都标出来。实际用的时候经常遇到文档里两张表看起来有关联但没写关联字段的情况。我的做法是先看字段命名规律。联众的表里外键字段通常跟主表主键同名或加后缀。比如PATIENT_ID在几乎所有业务表里都是关联患者的外键VISIT_ID关联就诊ORDER_ID关联医嘱。命名规律能解决大部分关联问题。再看文档里的字段注释。有些字段注释会写「关联 XX 表 XX 字段」这种直接抄。没有注释的看字段类型和长度是否匹配。比如VISIT_ID在主表里是VARCHAR2(20)在子表里也是VARCHAR2(20)大概率就是关联字段。最后如果文档和实际库有出入以实际库为准。文档是参考不是圣旨。我一般会先跑一条SELECT * FROM 表名 WHERE ROWNUM 1看看实际数据长什么样再结合文档理解字段含义。提示读表结构文档的时候建议同时开着数据库客户端边看文档边验证字段。文档里写的字段类型和实际库不一致的情况并不少见尤其是系统升级过几个版本之后。3. 把表结构文档变成可查询的数据字典导入与检索3.1 为什么要把 .doc 转成结构化数据.doc 格式的文档有个天然缺陷没法快速检索没法做字段级对比没法生成 ER 图。你每次查一个字段得打开文档、翻页、肉眼找。如果团队里几个人同时用还得传来传去。更麻烦的是做数据映射的时候你需要把源系统和目标系统的字段并排对比在 Word 里做这件事效率极低。我的做法是把文档里的表结构信息抽出来存成结构化格式比如 CSV 或者直接建一张元数据表。这样你可以用 SQL 查字段、用脚本做对比、用工具生成 ER 图。一次投入后面省事。3.2 从文档到 CSV手工整理与脚本辅助如果文档里的表不多手工整理是最快的方式。打开文档把每张表的表名、字段名、字段类型、是否主键、字段含义、备注这几列抄到 Excel 里存成 CSV。注意几个点表名和字段名保持原样不要改大小写。联众的表名和字段名在文档里可能是大写实际库里也可能是大写改了反而对不上。字段含义这一列文档里怎么写的就怎么抄不要自己概括。比如文档写「患者姓名加密存储」你就把「加密存储」也带上这个信息后面做数据脱敏的时候有用。如果表特别多手工抄不现实可以用脚本从 .doc 里抽文本。Python 的python-docx库可以读 .docx但 .doc 格式需要先转成 .docx。转换可以用 LibreOffice 的命令行工具# 把 .doc 转成 .docx方便后续用 python-docx 读取 libreoffice --headless --convert-to docx 联众电子病历表结构文档.doc --outdir ./converted转换完之后用 Python 读取文档里的表格from docx import Document import csv doc Document(./converted/联众电子病历表结构文档.docx) rows [] # 遍历文档里所有表格假设每个表格对应一张表的结构 for table in doc.tables: for row in table.rows: cells [cell.text.strip() for cell in row.cells] rows.append(cells) # 写入 CSV后续可以用 Excel 或数据库工具导入 with open(emr_table_structure.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerows(rows)逻辑说明Document加载 .docx 文件doc.tables拿到所有表格对象。每个表格里按行遍历row.cells拿到单元格文本。最后写 CSV 的时候用utf-8-sig编码这样 Excel 打开不会乱码。参数说明如果你的文档里表格结构不统一比如有些表有合并单元格row.cells拿到的文本可能会重复。这种情况需要根据实际表格结构调整解析逻辑比如用cell._tc判断合并状态。另外libreoffice命令的路径根据你的系统环境可能不同Windows 下通常是soffice.exe。3.3 建一张元数据表用 SQL 查字段CSV 整理好之后导入数据库建一张元数据表后面查字段就方便了。以 PostgreSQL 为例-- 建元数据表存表结构文档里的信息 CREATE TABLE emr_meta_columns ( table_name VARCHAR(100), -- 表名 column_name VARCHAR(100), -- 字段名 data_type VARCHAR(50), -- 字段类型 is_primary_key BOOLEAN, -- 是否主键 description TEXT, -- 字段含义 remark TEXT -- 备注 ); -- 导入 CSV 数据用 \copy 命令路径按实际调整 \copy emr_meta_columns FROM emr_table_structure.csv WITH CSV HEADER;导入之后查字段就变成一条 SQL 的事-- 查所有跟「诊断」相关的字段 SELECT table_name, column_name, data_type, description FROM emr_meta_columns WHERE description LIKE %诊断% OR column_name LIKE %DIAG% ORDER BY table_name, column_name;这种方式比翻 Word 文档快得多而且可以跟团队共享。如果多人同时查直接连同一个库就行。注意导入 CSV 的时候字段类型和实际库可能不完全一致。比如文档里写VARCHAR2PostgreSQL 里对应VARCHAR。元数据表里的data_type只是参考实际建表的时候要以目标数据库的语法为准。4. 避坑联众 EMR 表结构文档使用中的五个常见问题4.1 文档版本和实际库对不上现象按文档里的字段名写 SQL执行报「字段不存在」。原因系统升级过实际库加了字段或改了字段名但文档没更新。解决先用DESCRIBE 表名或查INFORMATION_SCHEMA.COLUMNS看实际字段以实际库为准。文档只用来理解字段含义和关联关系字段名和类型以库为准。4.2 把业务主键和物理主键搞混现象用病案号去关联两张表结果查出来数据重复或对不上。原因联众的表里PATIENT_ID是物理主键病案号MRN是业务主键两者在不同表里的使用不一致。有些表用PATIENT_ID关联有些用MRN。解决在文档里确认每张表的关联字段到底是哪个不要想当然。如果文档没写清楚看字段类型和长度PATIENT_ID通常是定长字符串MRN可能是数字或另一种格式。4.3 忽略字段的加密和脱敏标记现象直接查患者姓名和身份证号发现是乱码或者脱敏后的值。原因联众 EMR 对敏感字段做了加密存储文档里可能标注了「加密」但没写加密算法。解决不要试图在 SQL 里解密加密逻辑通常在应用层。如果做数据迁移需要走应用层的接口或者找 DBA 要解密方案。做报表取数的时候直接用脱敏后的值就行别想着还原。4.4 文档里的表名和实际库大小写不一致现象SQL 里写SELECT * FROM patient报「表不存在」但文档里写的就是patient。原因数据库在 Linux 下默认区分大小写实际表名可能是PATIENT或Patient。解决在文档里确认表名的实际大小写或者直接查INFORMATION_SCHEMA.TABLES看实际表名。写 SQL 的时候保持一致。4.5 用文档里的字段注释当唯一依据现象按文档注释理解字段含义结果业务逻辑理解错了。原因文档注释可能写得简略或者有歧义。比如一个字段注释写「状态」但实际取值有十几种文档里没列全。解决文档注释作为参考实际取值要查数据或者问业务方。对于关键字段跑一条SELECT DISTINCT 字段名 FROM 表名看看实际有哪些值比看注释靠谱。5. 进阶用表结构文档做数据映射和 ER 图生成5.1 做源系统到目标系统的字段映射数据迁移或者接口对接的时候最花时间的就是字段映射。有了结构化的元数据表这件事可以半自动化。假设你要把联众 EMR 的患者信息映射到另一个系统的患者表步骤是先把目标系统的字段也整理成一张元数据表结构跟emr_meta_columns一样。然后用 SQL 做模糊匹配找出两边可能对应的字段-- 模糊匹配源系统和目标系统的字段辅助人工确认映射关系 SELECT s.table_name AS src_table, s.column_name AS src_column, s.description AS src_desc, t.table_name AS tgt_table, t.column_name AS tgt_column, t.description AS tgt_desc FROM emr_meta_columns s JOIN target_meta_columns t ON s.description LIKE % || t.description || % OR t.description LIKE % || s.description || % WHERE s.table_name PATIENT ORDER BY s.column_name;逻辑说明用LIKE做双向模糊匹配把描述相似的字段对列出来。这只是辅助最终映射关系要人工确认。参数说明||是字符串拼接不同数据库可能用CONCAT。target_meta_columns是目标系统的元数据表需要你先整理好。匹配结果出来之后人工过一遍把确认的映射关系存到一张映射表里后面写 ETL 脚本直接读这张表。5.2 从元数据生成 ER 图ER 图对理解表关系很有帮助但手工画太费时间。如果元数据表里存了关联关系比如在remark字段里写了「关联 VISIT.VISIT_ID」可以用脚本生成 Graphviz 的 DOT 文件再渲染成图。import csv # 读元数据 CSV提取表名和关联关系 edges set() with open(emr_table_structure.csv, encodingutf-8-sig) as f: reader csv.DictReader(f) for row in reader: remark row.get(remark, ) # 假设 remark 里用「关联 表名.字段名」的格式标注关联 if 关联 in remark: target remark.split(关联)[-1].strip() if . in target: tgt_table target.split(.)[0] edges.add((row[table_name], tgt_table)) # 生成 Graphviz DOT 文件 with open(emr_er.dot, w, encodingutf-8) as f: f.write(digraph EMR {\n) f.write( rankdirLR;\n) f.write( node [shapebox];\n) for src, tgt in edges: f.write(f {src} - {tgt};\n) f.write(}\n)逻辑说明从 CSV 的remark列里提取关联关系生成 DOT 格式的边。然后用 Graphviz 的dot命令渲染dot -Tpng emr_er.dot -o emr_er.png参数说明rankdirLR让图从左到右布局表多的时候比从上到下好看。node [shapebox]让表名显示成方框。如果你的remark字段格式不一样调整split的逻辑就行。5.3 一个我踩过的坑刚开始用这份文档的时候我觉得字段注释写得挺清楚就直接按注释理解业务含义没去实际库里验证。结果做患者去重的时候用PATIENT_NAME加ID_CARD做匹配发现有一批患者明明是同一个人但ID_CARD字段一个是空的一个是脱敏后的值。后来查了实际数据才知道联众对身份证号做了部分脱敏有些历史数据没补全。从那以后我每次用表结构文档都强制走一遍「文档查字段 → 实际库验证 → 跑 DISTINCT 看取值」的流程再也不敢只看文档就下结论。希望这份文档到你手里的时候你能比我少走点弯路。本文还有配套的精品资源点击获取