病人基本信息该用什么字段类型存
医院系统里
patient_id必须是主键,推荐用
BIGINT UNSIGNED AUTO_INCREMENT,别用
INT——三甲医院十年积累的病人轻松超千万,
INT最大值 2147483647,撞上限后插入直接失败,错误信息是
ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'。
name用
VARCHAR(50)足够(含少数民族姓名、港澳台繁体),但必须加
COLLATE utf8mb4_unicode_ci,否则“喆”“煊”等字入库变问号;
id_card别用
INT或
BIGINT存身份证号——会丢前导零、自动转科学计数法,必须定义为
VARCHAR(18);
phone同理用
VARCHAR(15),预留国际区号和分机位。
如何存检验报告这类变长文本
检验单、病理描述、医生手写电子病历这些内容长度不可控,不能硬塞进
VARCHAR(1000)。超过 65535 字节就超出
TEXT上限,得用
MEDIUMTEXT(最大 16MB)。
实际建表时注意两点:
别把报告原文和结构化字段(如report_date、
lab_code)混在一张表里,应拆成
patient_reports独立表,用
patient_id外键关联
MEDIUMTEXT字段不参与索引,如果常按“报告中是否含‘肿瘤’二字”查询,得额外加
FULLTEXT索引,且查询必须用
MATCH ... AGAINST,不能用
LIKE '%肿瘤%'——后者会全表扫描,万级报告时响应超 5 秒
时间字段为什么必须用 DATETIME 而不是 TIMESTAMP
医院排班、手术记录、用药时间都要求精确到秒,且需跨时区保留原始录入时间(比如国际医疗队在非洲录入的记录,回国内不能自动转成北京时间)。
TIMESTAMP会被 MySQL 自动转成 UTC 存储、读取时再转回系统时区,导致历史数据时间漂移;
DATETIME是纯字面值存储,无时区转换。建表时统一用:
CREATE TABLE patient_visits ( id BIGINT PRIMARY KEY, patient_id BIGINT NOT NULL, visit_time DATETIME NOT NULL, -- 不加 DEFAULT CURRENT_TIMESTAMP created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
注意:别给业务时间字段(如
visit_time)设
DEFAULT CURRENT_TIMESTAMP,否则补录历史门诊记录时会误填成当前时间。
敏感字段加密不能只靠应用层
身份证号、手机号、诊断结论这些属于《个人信息保护法》明确定义的敏感个人信息,仅在 Java/Python 代码里 AES 加密再存进
VARCHAR是高危操作——DBA 直接查表、备份文件泄露、慢查询日志落盘都会暴露明文。
必须启用 MySQL 原生加密:
用AES_ENCRYPT()+
AES_DECRYPT()函数,在 SQL 层完成加解密,密钥由 KMS 托管,不硬编码在 SQL 里 字段类型改用
VARBINARY(255)存密文(AES-256 输出固定 32 字节,但 base64 编码后约 44 字节,留余量) 禁止对加密字段建索引——
AES_ENCRYPT('123', 'key') 和 AES_ENCRYPT('1234', 'key') 完全不同,无法范围查询
真正难的是密钥轮换:旧密钥加密的数据要批量重加密,期间系统得兼容双密钥解密逻辑,这个环节最容易出数据不一致。
