1

我有这个七表数据库存储具有历史价值的区域(例如旧墓地或石器时代的房屋遗址),可以划分为子区域。对这些地区进行了检查和挖掘。区域、子区域、检查和挖掘这四个表都可以有一个或多个“位置”或“发现”。

位置表和查找表目前与链接表相关,链接表包含目标表的名称和该表中的目标 ID,例如target_table="subarea", target_id=5.

问题是在数据库中存储表名是我的理解不是好的做法。那么,将位置和查找与四个表中的任何一个的 N-1 关系联系起来的最佳解决方案是什么?

4

1 回答 1

1

有很多不同的方法可以做到这一点。我的解决方案使用了 PostgreSQL 的一些有争议的特性,因此请参阅下面的注意事项。

CREATE TABLE link_categories (
    id int not null unique,
    label text primary key
);

INSERT INTO link_categories(id, label)
VALUES (1, 'Area'), 
       (2, 'Sub-area'),
       (3, 'Inspection'),
       (4, 'Excavation');

CREATE TABLE location_base (
   -- add your base fields here
   link_category int not null,
   refkey bigint not null -- assume all id's on the other tables are bigints?
);

CREATE TABLE finding_base (
  -- add your base fields here
   link_category int not null,
  refkey bigint not null -- see above
);

然后我会使用表继承来创建子表,以管理您的多态关联。

CREATE TABLE location_area (
   CHECK (link_category = 1),
   FOREIGN KEY (refkey) REFERENCES area(id),
   PRIMARY KEY (...) -- needs to be repeated for each child table
) INHERITS (location_base);

CREATE TABLE location_subarea (
   CHECK (link_category = 2),
   FOREIGN KEY (refkey) REFERENCES subarea(id),
   PRIMARY KEY (...) -- needs to be repeated for each child table
) INHERITS (location_base);

等对结果表重复

请注意,表继承在 PostgreSQL 上是一个颇有争议的特性。您需要考虑利用表继承的一些底层怪癖来发挥您的优势,并像表分区系统一样实现它。请注意,在这种情况下,link_category 基本上成为主键的一部分。

但是,在使用此解决方案之前,请阅读 PostgreSQL 文档:

请注意,这是一个有点危险的特性,但多态关联通常会带来危险。我在这里特别推荐这个,因为我认为它可以简化你的失败案例,即使它是以牺牲其他一些东西为代价的。

于 2012-10-02T07:50:01.800 回答