【发布时间】:2015-06-20 23:56:28
【问题描述】:
下面的表格设计(完整架构见下文)有很多不足之处,也造成了很多困难,但我不知道如何最好地规范化它们。这些表格的用途是:
-
ICD9— 提供CICD9和CDESC组合的主查找。每个组合在ICD9表中都是唯一的&hellip 不能重复。 -
ICD9表中唯一键 (CICD9,CDESC) 的更改将级联到DX表。DX表永远不会有ICD9表中未表示的 (CICD9,CDESC) 组合。 - 表
DX-- 此表中的记录提供了有关此人在特定时间的特定信息。此表中的记录不能基于 Key(CICD9,CDESC,GROUPID,TPOSTED) 进行复制,其中GROUPID是个人唯一的,TPOSTED是创建记录的时间。 - 如下所示,
DX表包含与具有唯一键 (CICD9,CDESC,GROUPID,TPOSTED) 的记录相关的非键信息。
由于数据错误,有时会在 ICD9 和 DX 中创建重复记录。例如:
ICD9
|CICD9|CDESC |
|1234 |" TEST1"|
|1234 |"TEST1" |
DX
|CICD9|CDESC |GROUPID|TPOSTED |
|1234 |" TEST1|H |12301212|
|1234 |"TEST1" |H |12301212|
为了解决重复数据,更新ICD9表,修改CDESC,使" TEST1"变为"TEST1"。因为这是 Key(CICD9,CDESC) 的一部分,所以在 DX 中的外键上设置的级联将导致 DX 中的 CDESC 列也发生变化。此更改可能会导致DX 表中的记录与DX 表中的其他记录发生冲突,并违反DX 表中Key(CICD9,CDESC,GROUPID,TPOSTED) 上的不允许重复。
我可以删除ICD9 中的重复记录,我已经完成了这项工作。但我需要保留DX 中的其余数据(如RESOLVED 和TREATED),所以我不能只删除其中一行。我还需要保留唯一的密钥(CICD9,CDESC,GROUPID,TPOSTED)。有人建议这需要标准化,但我不知道该怎么做。
CREATE TABLE icd9
(
recid serial NOT NULL,
cicd9 character varying(8),
cdesc character varying(80) NOT NULL,
"timestamp" timestamp without time zone DEFAULT now(),
modified timestamp without time zone DEFAULT now(),
chronic boolean,
common boolean,
CONSTRAINT pk_icd9_recid PRIMARY KEY (recid),
CONSTRAINT constraint_cdesc UNIQUE (cicd9, cdesc),
CONSTRAINT desccheck CHECK (cdesc::text <> ''::text)
)
WITH (
OIDS=FALSE
);
CREATE TABLE dx
(
recid serial NOT NULL,
cpatient character varying(33) NOT NULL,
cicd9 character varying(8),
cdesc character varying(80) NOT NULL,
tposted timestamp without time zone NOT NULL,
"timestamp" timestamp without time zone DEFAULT now(),
modified timestamp without time zone DEFAULT now(),
resolved boolean DEFAULT false,
treated boolean DEFAULT false,
chronic boolean DEFAULT false,
groupid character varying(33) NOT NULL,
service integer DEFAULT 0,
explanation text,
pmh boolean DEFAULT false,
CONSTRAINT pk_dx_recid PRIMARY KEY (recid),
CONSTRAINT dx_cpatient_fkey FOREIGN KEY (cpatient)
REFERENCES patients (cpatient) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT dx_groupid_fkey FOREIGN KEY (groupid)
REFERENCES charts (groupid) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_icd9 FOREIGN KEY (cicd9, cdesc)
REFERENCES icd9 (cicd9, cdesc) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT noduplicate_dx UNIQUE (cicd9, cdesc, groupid, tposted),
CONSTRAINT desccheck CHECK (cdesc::text <> ''::text),
CONSTRAINT groupcheck CHECK (groupid::bpchar <> ''::bpchar),
CONSTRAINT patientcheck CHECK (cpatient::bpchar <> ''::bpchar)
)
WITH (
OIDS=FALSE
);
【问题讨论】:
-
@joDouglass 是的。当在 ICD9 表中创建重复记录时,icd9 中的约束确实会触发——我使用存储过程在失败前检测和删除。然而,“坏数据”通常只是拼写错误或描述不足——实际上并不是“错误”的意思,只是写得不好。所以删除 Dx 中的子记录不是一个可接受的解决方案,ICD9 表中的任何更改都需要将其 Dx 子记录移至“更好”的 ICD9 记录。本质上,我需要避免在 Dx 中丢失数据,纠正它,是的,丢失它,不。 :)
-
顺便说一句:所有这些时间戳在 icd9 表中的作用是什么?您是否打算允许码本的多个版本/修订共存?
-
@wildplasser 原始记录将具有“创建”时间戳,以及何时(或是否)发生任何更改的时间戳。这在将记录备份到另一台机器时使用。 tposted 时间戳是特定的,并且永远不会更改,因为它不是“容器”的一部分,而是“数据”的一部分。有没有更好的办法?谢谢。
标签: database postgresql database-design