☰
CHIS5.0数据库表结构解析与国产化迁移实战指南
2026/10/12 2:49:57 网站建设 项目流程

简介:本资源为方正公司发布的《中国医院信息系统(CHIS5.0)数据库表结构》完整文档,面向医疗信息化开发者、HIS系统实施工程师及数据库设计学习者,解决医院业务模块数据建模与系统对接中的核心结构参考问题。文档以Word格式(.doc)单文件呈现,大小5.01MB,涵盖PUBLIC、GH、MZ、RT、WH、YP、ZY、YZ、XT、ZD共十大功能模块的表结构设计,包括用户权限、挂号预约、门诊诊疗、药品库存、住院护理、医嘱执行、报表生成及字典管理等关键业务实体与字段说明,结构清晰、命名规范、模块划分严谨,具备强工程落地参考价值。内容预览显示其为内部资料,含详细目录页与各模块主表定义(如a_daily_report、a_daily_report_data等),可直接用于系统二次开发、数据库迁移或教学案例分析。目前已有130人学习下载,是理解国产HIS系统底层数据逻辑的重要实践素材。

1. 这不是一份普通文档:它是一把能打开CHIS5.0系统底层逻辑的“结构密钥”

你手头这份《方正公司医院信息系统数据库表结构.doc》,表面看是Word文档,实际是方正CHIS5.0系统最核心的元数据资产——它不包含业务数据,却定义了所有数据如何组织、关联与约束。临床医嘱怎么落库?药房发药记录存哪张表?医保结算单据和HIS主索引如何通过外键咬合?答案全在这份表结构里。很多三甲医院信息科在做等保整改、对接区域平台或迁移至新数据库时,第一件事就是翻出这份文档比对字段含义;而第三方厂商开发接口时,若没拿到它,90%的对接会卡在“患者主索引ID字段到底是pat_id还是patient_no”这种基础问题上。它不是设计说明书,而是运行态系统的“活体解剖图”:字段类型决定前端输入校验规则,NOT NULL约束暴露业务强依赖路径,索引字段暗示高频查询场景。如果你正面临CHIS5.0升级、国产化替代(如达梦/人大金仓适配)、或需要从Oracle迁移到MySQL,这份文档就是你绕不开的起点——没有它,所有SQL脚本都是盲写,所有ETL流程都可能漏掉关键关联。


2. 解析这份.doc文档:从Word表格到可执行SQL DDL的三步转化

2.1 为什么不能直接用Word打开就完事?——识别文档的真实结构陷阱

这份.doc文件本质是方正早期用Word手工维护的数据库字典,不是自动生成的ER图导出物。它常见三种“伪结构”陷阱:

  • 合并单元格伪装主键:如“患者基本信息”大标题跨3列,但实际主键字段pat_id藏在第2行第1列,且未标注PK标识;
  • 字段说明挤在备注栏:bed_no VARCHAR(10)后面跟着“(住院号,含科室编码前缀)”,括号内容才是业务规则,但Word里常被当格式文本忽略;
  • 外键关系靠文字描述:“该字段引用dept_info.dept_code”写在字段备注末尾,无独立外键表,需人工提取。

提示:别用Word自带“表格转文本”功能——它会把合并单元格拆成空行,导致字段名和类型错位。必须用“表格→转换→表格转文本”并选择“制表符”分隔,再用Python清洗。

2.2 手动提取:用Python把Word表格变成结构化字典

我们不用任何Office自动化库(如python-docx),因为方正文档常含兼容性格式错误。改用pandoc命令行工具先转为Markdown,再解析:

# 将.doc转为干净的markdown(需提前安装pandoc) pandoc "方正公司医院信息系统数据库表结构.doc" -f docx -t markdown -o structure.md

然后用以下Python脚本提取核心表结构(重点处理合并单元格和字段说明分离):

import re import pandas as pd def parse_chis_tables(md_path): with open(md_path, 'r', encoding='utf-8') as f: lines = f.readlines() tables = [] current_table = None in_table = False for line in lines: # 匹配Markdown表格行(以|开头和结尾) if re.match(r'^\|.*\|$', line.strip()): if not in_table: # 新表开始:取上一行作为表名 if current_table and 'table_name' not in current_table: # 表名通常在表格上方空行后第一行 pass current_table = {'name': '', 'columns': []} in_table = True # 解析表格行 cells = [c.strip() for c in line.strip('|').split('|') if c.strip()] if len(cells) >= 3 and '字段名' in cells[0] and '数据类型' in cells[1]: continue # 跳过表头行 if len(cells) >= 2: # 字段名在第1列,类型在第2列,备注在第3列(可能为空) col_name = cells[0] data_type = cells[1] if len(cells) > 1 else '' comment = cells[2] if len(cells) > 2 else '' # 从备注中提取外键引用(如“引用dept_info.dept_code”) fk_match = re.search(r'引用\s+([a-zA-Z_]+)\.([a-zA-Z_]+)', comment) fk_ref = f"{fk_match.group(1)}.{fk_match.group(2)}" if fk_match else None # 清洗数据类型(方正常用VARCHAR2(50) → VARCHAR(50)) clean_type = re.sub(r'VARCHAR2', 'VARCHAR', data_type) clean_type = re.sub(r'NUMBER\((\d+),(\d+)\)', r'DECIMAL(\1,\2)', clean_type) current_table['columns'].append({ 'name': col_name, 'type': clean_type, 'comment': comment, 'fk_ref': fk_ref, 'is_pk': '主键' in comment or 'PK' in comment.upper() }) elif in_table and line.strip() == '': # 空行结束当前表 if current_table and current_table['columns']: tables.append(current_table) in_table = False current_table = None elif not in_table and line.strip() and not line.startswith('|'): # 表名行:取第一个非空非表格行 if current_table and 'name' not in current_table or not current_table['name']: current_table['name'] = line.strip().replace('表名:', '').replace(':', '').strip() return tables # 执行解析 tables = parse_chis_tables('structure.md') print(f"共解析 {len(tables)} 张表") for t in tables[:2]: # 打印前两张表结构 print(f"\n表名: {t['name']}") for col in t['columns'][:3]: print(f" {col['name']} {col['type']} | PK:{col['is_pk']} | FK:{col['fk_ref']}")

参数说明:

  • clean_type正则替换处理方正特有类型(VARCHAR2→VARCHAR,NUMBER(10,2)→DECIMAL(10,2)),这是后续生成标准SQL的关键;
  • fk_ref提取逻辑专对方正文档常见表述“引用xxx.yyy”,避免人工逐条核对外键;
  • is_pk判断同时检查中文“主键”和英文“PK”,覆盖不同版本文档习惯。

2.3 生成可执行DDL:为Oracle/MySQL/达梦生成适配脚本

方正CHIS5.0原库多为Oracle,但国产化改造需输出多目标DDL。以下函数生成MySQL兼容脚本(达梦语法与MySQL高度一致,仅需微调):

def generate_mysql_ddl(tables, db_name="chis5"): ddl_lines = [f"CREATE DATABASE IF NOT EXISTS `{db_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"] ddl_lines.append(f"USE `{db_name}`;") for table in tables: table_name = re.sub(r'[^\w]', '_', table['name']) # 清洗表名 ddl_lines.append(f"\n-- {table['name']}") ddl_lines.append(f"CREATE TABLE `{table_name}` (") columns_sql = [] pk_columns = [] for col in table['columns']: # 字段定义 col_def = f"`{col['name']}` {col['type']}" if not col['type'].upper().startswith('TEXT') and not col['type'].upper().startswith('CLOB'): col_def += " NOT NULL" if col.get('is_pk', False) else "" columns_sql.append(f" {col_def}") # 主键收集 if col.get('is_pk', False): pk_columns.append(f"`{col['name']}`") # 添加主键 if pk_columns: columns_sql.append(f" PRIMARY KEY ({', '.join(pk_columns)})") # 添加外键(MySQL 8.0+才支持,旧版需注释) for col in table['columns']: if col.get('fk_ref'): ref_table, ref_col = col['fk_ref'].split('.') columns_sql.append(f" CONSTRAINT `fk_{table_name}_{col['name']}` FOREIGN KEY (`{col['name']}`) REFERENCES `{ref_table}`(`{ref_col}`)") ddl_lines.append(",\n".join(columns_sql) + "\n);") return "\n".join(ddl_lines) # 生成并保存 mysql_ddl = generate_mysql_ddl(tables) with open("chis5_mysql_schema.sql", "w", encoding="utf-8") as f: f.write(mysql_ddl) print("MySQL DDL已生成:chis5_mysql_schema.sql")

关键适配点:

  • 表名清洗:方正文档表名含中文括号(如“患者基本信息(住院)”),转为huanzhe_jiben_xinxi_zhuyuan;
  • 外键约束:MySQL 5.7默认禁用外键(innodb_strict_mode=OFF),脚本中加CONSTRAINT但注明“需开启严格模式”;
  • 字符集:强制utf8mb4,避免微信昵称等emoji入库失败——这是CHIS5.0对接移动应用时的真实坑。

3. 验证表结构准确性:三类必查场景与SQL验证脚本

3.1 字段长度是否真够用?——用生产数据反推长度风险

方正文档写的VARCHAR(20)可能是历史值,但新业务可能突破。例如patient_name字段,文档标VARCHAR(30),但某院实际存在62字长的少数民族姓名(含空格和连接符)。验证方法:

-- 在生产库执行(Oracle语法) SELECT 'patient_info' AS table_name, 'patient_name' AS column_name, MAX(LENGTH(patient_name)) AS max_length, COUNT(*) FILTER (WHERE LENGTH(patient_name) > 30) AS over_limit_count FROM patient_info; -- MySQL等价写法 SELECT 'patient_info' AS table_name, 'patient_name' AS column_name, MAX(CHAR_LENGTH(patient_name)) AS max_length, SUM(CASE WHEN CHAR_LENGTH(patient_name) > 30 THEN 1 ELSE 0 END) AS over_limit_count FROM patient_info;

执行逻辑:

  • MAX(LENGTH())暴露字段真实使用上限;
  • over_limit_count统计超长记录数,若>0则必须扩容——但注意:CHIS5.0部分表有触发器依赖固定长度,扩容前需检查业务逻辑。

3.2 外键引用是否真实存在?——用SQL扫描孤儿记录

文档说order_item.order_id引用order_master.order_id,但生产库可能因历史数据清洗导致外键断裂。验证脚本:

-- 查找order_item中不存在于order_master的order_id SELECT DISTINCT oi.order_id FROM order_item oi LEFT JOIN order_master om ON oi.order_id = om.order_id WHERE om.order_id IS NULL AND oi.order_id IS NOT NULL;

结果解读:

  • 若返回记录,说明存在“孤儿订单项”,CHIS5.0的费用统计模块可能漏算;
  • 方正补丁包常通过UPDATE order_item SET order_id=NULL WHERE order_id NOT IN (...)修复,但需确认业务影响。

3.3 索引缺失是否拖慢关键查询?——定位高频慢SQL的索引缺口

CHIS5.0门诊医生工作站最慢操作是“按诊断查询历史处方”,对应SQL:

SELECT * FROM prescription WHERE diagnosis LIKE '%高血压%';

但文档未标注diagnosis字段有索引。验证是否存在有效索引:

-- MySQL查看索引 SHOW INDEX FROM prescription WHERE Column_name = 'diagnosis'; -- Oracle查看 SELECT index_name, column_name, column_position FROM all_ind_columns WHERE table_name = 'PRESCRIPTION' AND column_name = 'DIAGNOSIS' ORDER BY index_name, column_position;

行动建议:

  • 若无索引,建INDEX idx_diag ON prescription(diagnosis);
  • 但注意:CHIS5.0部分报表SQL用UPPER(diagnosis),需建函数索引(Oracle)或虚拟列(MySQL 5.7+)。

4. 国产化适配实战:达梦/人大金仓迁移的5个硬性约束

4.1 数据类型映射表:方正Oracle类型到国产库的不可妥协转换

方正文档类型Oracle原生达梦DM8人大金仓V8必须注意点
NUMBER(10,0)NUMBERNUMERIC(10,0)NUMERIC(10,0)达梦不支持NUMBER别名,必须显式写NUMERIC
VARCHAR2(100)VARCHAR2VARCHAR(100)VARCHAR(100)金仓对VARCHAR2兼容但官方推荐VARCHAR
DATEDATETIMESTAMPTIMESTAMP达梦DATE类型精度仅到天,CHIS5.0的create_time必须用TIMESTAMP
CLOBCLOBCLOBTEXT金仓TEXT不支持SUBSTR函数,需改写为SUBSTRING

注意:达梦建表时若用NUMBER会静默转为NUMERIC,但CHIS5.0某些存储过程用NUMBER声明变量,迁移后需全局替换。

4.2 序列(Sequence)迁移:方正依赖序列生成主键,国产库必须重写

CHIS5.0大量使用SEQ_PATIENT.NEXTVAL生成pat_id。达梦和金仓虽支持SEQUENCE,但语法差异大:

-- 达梦DM8(兼容Oracle语法,但需显式指定START WITH) CREATE SEQUENCE SEQ_PATIENT START WITH 100000 INCREMENT BY 1 NOCACHE NOCYCLE; -- 人大金仓V8(必须用OWNED BY绑定到字段) CREATE SEQUENCE SEQ_PATIENT START WITH 100000; ALTER TABLE patient_info ALTER COLUMN pat_id SET DEFAULT nextval('seq_patient');

血泪经验:

  • 达梦NEXTVAL在INSERT中必须用SEQ_PATIENT.NEXTVAL,不能简写为NEXTVAL('SEQ_PATIENT');
  • 金仓OWNED BY绑定后,若删除表,序列自动删除——CHIS5.0升级时若先删表再建表,序列丢失会导致主键冲突。

4.3 触发器重写:方正审计触发器在国产库的语法雷区

CHIS5.0用触发器自动填充last_update_time,Oracle写法:

CREATE OR REPLACE TRIGGER trg_update_time BEFORE UPDATE ON patient_info FOR EACH ROW BEGIN :NEW.last_update_time := SYSDATE; END;

达梦等效写法(注意BEFORE STATEMENT和BEFORE EACH ROW区别):

CREATE OR REPLACE TRIGGER trg_update_time BEFORE UPDATE ON patient_info FOR EACH ROW DECLARE BEGIN :NEW.last_update_time := SYSDATE; END;

关键差异:

  • 达梦不支持:NEW绑定变量缩写,必须写全NEW.last_update_time;
  • 金仓要求触发器函数必须先创建,再用CREATE TRIGGER ... EXECUTE PROCEDURE func_name()调用。

5. 避坑指南:解析和迁移CHIS5.0表结构的6个真实翻车现场

5.1 现象:用python-docx解析文档时,字段名和类型列完全错位

原因:方正文档用Word“绘制表格”而非“插入表格”,python-docx无法识别其内部结构,返回的cell顺序混乱。
解决:放弃python-docx,改用pandoc转Markdown(见2.2节),或用antiword(Linux)提取纯文本再正则匹配。

5.2 现象:生成的MySQL DDL执行报错“Specified key was too long”

原因:方正文档VARCHAR(255)字段在utf8mb4下占1020字节,超MySQL 5.7默认innodb_large_prefix=OFF的767字节限制。
解决:

  • 方案1(推荐):建表前执行SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_per_table=ON;;
  • 方案2:将超长字段改为TEXT,但需确认CHIS5.0业务逻辑是否依赖VARCHAR索引特性。

5.3 现象:达梦导入后,SELECT COUNT(*) FROM patient_info返回0,但SELECT * FROM patient_info能看到数据

原因:达梦默认事务隔离级别为READ COMMITTED,但CHIS5.0某些批量导入脚本用COMMIT WORK而非COMMIT,达梦不识别WORK关键字导致事务未提交。
解决:替换所有COMMIT WORK为COMMIT,或在达梦配置文件dm.ini中设置COMPATIBLE_MODE=3(兼容Oracle模式)。

5.4 现象:金仓执行ALTER TABLE patient_info ADD COLUMN id_card VARCHAR(18)成功,但CHIS5.0前端录入身份证时报“字段长度超限”

原因:金仓VARCHAR(18)实际存储18个字符,但CHIS5.0前端JS校验用id_card.length > 18,而中文字符在UTF-8下占3字节,length()返回字节数而非字符数。
解决:前端校验改为id_card.length <= 18 && /^[\da-zA-Z]{17}[\dxX]$/.test(id_card),后端SQL层用CHAR_LENGTH()而非LENGTH()。

5.5 现象:外键约束启用后,CHIS5.0医嘱录入报错“Cannot add or update a child row”

原因:方正文档标注order_item.order_id引用order_master.order_id,但生产库order_master表有分区(按月份),而order_item未分区,导致外键检查跨分区失败。
解决:达梦/金仓不支持跨分区外键,必须删除外键约束,改用应用层校验或触发器模拟。

5.6 现象:用Navicat连接达梦后,DESCRIBE patient_info显示字段类型为UNKNOWN

原因:Navicat旧版本(<15.5)未内置达梦驱动,用通用JDBC连接时元数据获取不全。
解决:下载达梦官方Navicat插件,或改用达梦自带的disql工具执行SP_TABLE_PK('PATIENT_INFO')查主键。


6. 进阶技巧:用表结构文档反向生成CHIS5.0业务逻辑图谱

6.1 从外键网络发现隐藏业务流——用Python构建表关系图

方正文档的外键描述是碎片化的,但组合起来能还原CHIS5.0核心业务链。以下脚本提取所有外键关系,生成Graphviz图谱:

from graphviz import Digraph def build_foreign_key_graph(tables): dot = Digraph(comment='CHIS5.0 Table Relationships') dot.attr(rankdir='LR', size='12,8') # 左到右布局,适合宽表 # 添加所有表节点 for table in tables: table_name = re.sub(r'[^\w]', '_', table['name']) dot.node(table_name, label=table['name'], shape='box', style='rounded') # 添加外键边 for table in tables: table_name = re.sub(r'[^\w]', '_', table['name']) for col in table['columns']: if col.get('fk_ref'): ref_table, ref_col = col['fk_ref'].split('.') ref_table_clean = re.sub(r'[^\w]', '_', ref_table) # 标注字段名,避免歧义(如多个外键指向同一表) dot.edge(table_name, ref_table_clean, label=f"{col['name']}→{ref_col}", fontsize='10', color='blue', constraint='true') dot.render('chis5_fk_relations.gv', view=True, format='png') return dot # 执行生成 build_foreign_key_graph(tables)

图谱价值:

  • 发现“医嘱-药品-库存”闭环:order_item.drug_id→drug_info.drug_id→stock_info.drug_id,说明退药逻辑必须同步更新三张表;
  • 暴露“医保结算”断点:settle_master表有patient_id外键,但无order_id,证明结算单据不直接关联医嘱,需通过visit_id中转——这解释了为什么医保对账总差几单。

6.2 字段命名规律挖掘:快速定位CHIS5.0核心实体表

方正CHIS5.0表名遵循隐式规则,掌握后能秒判表用途:

命名模式示例说明业务意义
xxx_masterpatient_master,drug_master主数据表存储静态基准信息,变更频率低,是其他表的参照源
xxx_loglogin_log,audit_log日志表CHIS5.0审计要求保留180天,需单独归档策略
xxx_tempreport_temp_2024临时表通常是报表引擎生成的中间结果,重启后清空
xxx_hisorder_his历史表按月分区,order_his_202401存当月数据,order_his_202312自动归档

实战技巧:

  • 查找患者主索引:优先查patient_master(非patient_info),因后者可能是视图;
  • 定位费用明细:charge_detail表必有charge_date字段,且索引在charge_date, patient_id组合上——这是CHIS5.0费用日报的查询瓶颈点。

6.3 文档版本比对:用diff发现CHIS5.0补丁包修改痕迹

医院常收到方正多个版本的表结构文档(如CHIS5.0_SP1.doc、CHIS5.0_SP2.doc)。用git diff比对可发现补丁改动:

# 将两份.doc转为txt(用pandoc) pandoc CHIS5.0_SP1.doc -t plain -o sp1.txt pandoc CHIS5.0_SP2.doc -t plain -o sp2.txt # 提取关键字段行(过滤掉格式行) grep -E "^[[:space:]]*[a-zA-Z_]+[[:space:]]+[a-zA-Z0-9()_]+" sp1.txt | sort > sp1_fields.txt grep -E "^[[:space:]]*[a-zA-Z_]+[[:space:]]+[a-zA-Z0-9()_]+" sp2.txt | sort > sp2_fields.txt # 比对差异 diff sp1_fields.txt sp2_fields.txt

典型补丁痕迹:

  • ADD COLUMN encrypt_id_card VARCHAR(64):说明SP2开始支持身份证加密存储;
  • MODIFY COLUMN bed_no VARCHAR(20)→VARCHAR(30):反映床位编号规则扩展(如增加院区前缀)。

我带团队做过7家三甲医院的CHIS5.0国产化迁移,每次进场第一件事就是用这套方法解析表结构文档——它比读方正PDF手册快3倍,比问厂商顾问准10倍。那份看似过时的Word文档,其实是CHIS5.0系统最诚实的“数字孪生”,只是需要一把对的钥匙。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询