【问题标题】:SQLALCHEMY: How to define a foreign key column that can reference multiple tablesSQLALCHEMY:如何定义可以引用多个表的外键列
【发布时间】:2020-06-11 12:54:43
【问题描述】:

假设我有 2 个表,学生和教师,每个表都有 id 作为主键。

然后我有一个活动表来记录一个人所做的活动。

活动表有 id、activity_name、person_id、person_type 列

因此 person_id 应该引用学生表或教师表中的 id(基于 person_type)。

如何在 sqlalchemy 中表示?

【问题讨论】:

  • 提及您使用的数据库可能是个好主意。我认为没有很多或任何支持像这样引用多个表的外键。

标签: database sqlalchemy


【解决方案1】:

对于这个问题,人们通常会使用:

  1. joined-table-inheritance:创建一个带有 id 和 type 的基本 person 表,student 和 teacher 表都共享 id,允许 activity 表只使用 people(id) 作为其外键
  2. single-table-inheritance:创建一个统一的人员表,其中包含教师和学生所需的所有列,并根据类型将它们包括在内,再​​次活动仅使用人员(id)作为外键

我不确定您的确切要求,但另一种选择可能是将 person_id 拆分为employee_id 和teacher_id 并在活动中删除类型列,或者将其留给您的应用程序分支,以便在设置类型时使用 use 来防止 NULL使用唯一约束。如果您在更多表中这样做,这可能会进一步扩大问题,并且可能会使查询复杂化。

【讨论】:

    【解决方案2】:

    没有直接的方法可以做到这一点。外键始终只存在于两个特定表之间。

    您正在处理数据库中的一个常见模式:如何为子类型/超类型建模。在这里,您将教师和学生作为人的子类型。

    您有三个基本选项。

    (1) 一张桌子。您可以有一个包含教师和学生的所有属性的 Person 表,以及一个类型列。您将需要应用程序或数据库级别的逻辑来强制执行哪些列应该是必需的、可选的或按类型禁止的。在这里,您可以使用从 Activity 到 Person 表的单个外键。

    (2) N+1 个表。有一个 Person 表,其中只有所有子类型共享的属性;加上具有独特属性的教师和学生表。教师和学生将是 Person 的 FK 子级。您将需要应用程序或数据库逻辑来确保每个人员记录都由一个且只有一个教师或学生记录指向。在这里,您可以使用从 Activity 到 Person 表的单个外键。

    (3) N 个表。像现在一样拥有单独的教师和学生表。如有必要,在它们之间重复属性。在这里,您可以创建一个从 Activity 到 Teacher 的外键,以及另一个从 Activity 到 Student 的外键。您需要应用或数据库逻辑来确保每个活动记录都指向教师记录或学生记录,而另一个为空。

    每种方法都有明显的权衡。

    https://docs.sqlalchemy.org/en/13/orm/inheritance.html

    【讨论】:

    • 我已经考虑了所有这些方法。是否有关于何时应该使用哪个的一般准则?
    • 并非如此。选择可能归结为您最能接受的权衡,例如哪个应用程序或数据库逻辑场景最容易实现,或者对您的应用程序风险最低。
    猜你喜欢
    • 2015-02-04
    • 2021-07-02
    • 2021-05-02
    • 2019-11-24
    • 2011-01-13
    • 2020-12-23
    • 1970-01-01
    • 2019-07-02
    • 2020-05-29
    相关资源
    最近更新 更多