9

设置

因此,一旦您决定使用 STI(单表继承),我发现这是一个相当普遍的场景。

您有一些具有各种子类型的基本类型。

  • 人 <(教师、学生、员工等)
  • 用户 <(会员、管理员)
  • 会员<(买方,卖方)
  • 车辆 <(汽车、船、飞机)
  • 等等

在数据库中建模有两种主要方法:

  • 单表继承
    • 一个带有类型字段和一堆可为空字段的大表
  • 类表继承
    • 每种类型一张桌子,共享 PK(从子代到父代的 FK)

虽然 STI 存在一些问题,但我确实喜欢它如何设法减少您必须进行的连接数量,以及 Rails 等框架中的一些支持,但我遇到了一个关于如何关联的问题子类特定的表。

例如:

  • 认证只能参考教师-人员
  • 配置文件应仅引用成员用户
  • WingInformation 不应与汽车或船相关(除非你可能是蝙蝠侠)
  • 广告归卖方会员而非买方会员所有

使用 CTI,这些关系是微不足道的 - 只需在相关表上打一个外键,你就完成了:

ALTER TABLE advertisements
 ADD FOREIGN KEY (seller_id) REFERENCES sellers (id)

但是对于 STI,类似的事情不会捕获子类型限制。

ALTER TABLE advertisements
  ADD FOREIGN KEY (seller_id) REFERENCES members (id)

我想看到的是这样的:

* Does not work in most (all?) databases *
ALTER TABLE advertisements
  ADD FOREIGN KEY (seller_id, 'seller') REFERENCES members (id, type)

我所能找到的只是一个肮脏的黑客,需要向相关表添加一个计算列:

ALTER TABLE advertisements
  ADD seller_type VARCHAR(20) NOT NULL DEFAULT 'seller'
ALTER TABLE advertisements
  FOREIGN KEY (seller_id, seller-type) REFERENCES members (id, type)

这让我觉得很奇怪(更不用说不雅了)。

真正的问题

那里有一个 RDBMS 可以让我这样做吗?

有没有理由为什么这甚至不可能?

这只是除了在最微不足道的情况下不使用 STI 的另一个原因吗?

4

1 回答 1

5

没有在外键声明中声明常量的标准方法。您必须命名列。

但是您可以使用以下方法之一强制该列具有固定值:

  • 计算列

  • CHECK 约束

  • 在 INSERT/UPDATE 之前触发以使用默认值覆盖任何用户提供的值。

于 2012-11-25T18:36:04.813 回答