我将用一个例子来解释这个问题: 我正在设计表中参照完整性的特定情况。该模型中有两个表,企业表和文档。我们注册公司,然后有人插入与之相关的文件。企业名称是可变的。在恢复文档时,我需要企业名称与注册时的名称相同,而不是企业目前的名称。我认为解决方案是使用相同的代码在每次更改中重新注册公司,以这种方式更新的名称将获得预期的结果,但是我不确定这是否是最佳解决方案。有人可以提出建议吗?
答案 0 :(得分:0)
为您的企业添加日期范围:valid_from,valid_to。初始化为-infinity,+ infinity。当您更改企业名称时,改为:将现有行(将valid_to = + infinity更改为now()),并使用valid_from = now(),valid_to = + infinity插入新名称。
将日期字段添加到文档中,例如create_date。然后,当加入企业时,您将在e.valid_from和e.valid_to之间加入ID和d.create_date。
这是一种简单的方法,它破坏了ID和代码的唯一性。为了解决这个问题,您可以将名称记录在带有id,from,to,name的单独表中。保留原始表的唯一ID和代码以保持唯一性。
答案 1 :(得分:0)
有几种可能的解决方案,很难确定哪种解决方案最简单。
附带评论:您的问题仅限于有效管理名称,但我想评论一个事实,即您的数据库对文件的移动,重命名或删除很敏感。如果操作系统级别发生任何事情,数据库将无法使记录保持最新。您也应该考虑对此做些事情。
在我考虑过的几种解决方案中,最标准化的一种是以下模式:
CREATE TABLE Enterprise
(
IdEnterprise SERIAL PRIMARY KEY
, Code VARCHAR(4) UNIQUE
, IdName INTEGER DEFAULT -1 /* This will be used to get a single active name */
);
CREATE TABLE EnterpriseName (
IDName SERIAL PRIMARY KEY
, IdEnterprise INTEGER NOT NULL REFERENCES Enterprise(IdEnterprise) ON UPDATE NO ACTION ON DELETE CASCADE
, Name TEXT NOT NULL
);
ALTER TABLE Enterprise ADD FOREIGN KEY (IdName) REFERENCES EnterpriseName(IdName) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;
CREATE TABLE Document
(
IdDocument SERIAL PRIMARY KEY
, IdName INTEGER NOT NULL REFERENCES EnterpriseName(IDName) ON UPDATE NO ACTION ON DELETE NO ACTION
, FilePath TEXT NOT NULL
, Description TEXT
);
使用标志和/或时间戳记或将企业名称移动到document
表是有吸引力的解决方案,但这只是乍一看。
特别是,您必须确保公司始终拥有1,而只有1个“活动”名称的部分并非易事。