有一个 table 和许多其他 table 的外键可以吗?

Is it fine to have one table with foreign keys to many other tables?

假设我的数据库中有 30 个 table,它们都与 Notations table:

具有一对多关系

另一种设置 Notations table 的方法(除了为其每个“父项”包含一个外键列外)对查询性能的影响较小? table 预计会变得非常大。

(因为每个 Notation 都包含一个 parent_table_id,其余 parent_tables 有 29 个空值 - 即每行要跟踪 29 个空值,看起来很多)

即。 SELECT text, table1_id, table2_id, ..., table30_id FROM Notations 会显示:

id         text         table1_id       table2_id      //     table30_id
0          "buzz"       74              null           //     null
1          "foo"        null            45             //     null
2          "bar"        22              null           //     null
3          "fizz"       22              null           //     null
4          "hello"      28              null           //     null
5          "world"      null            null           //     3
...etc

你不应该有符号 table

primary-foreign 键对的要点是外键的值与主键的值相同。符号 table 没有意义。规范化是数据库的一个极其重要的方面。我们希望减少冗余和重复的数据。 我们不想重复! 符号 table 会引入冗余数据。在这种情况下,冗余数据可以指我们可以用现有数据计算的数据。所有要归一化的table只能包含与自身相关的数据,不可计算。

我们可以计算每个 link,因为检查外键字段是否已填写并且键是否存在于相关 table 中。因此,这些 link 不适合放在单独的 table 中。正如您所提到的,这将是一个巨大的 table,这就是它只保存冗余数据的原因。不需要符号 table。相反,如果您需要查找 links,那么只需编写一个查询来检查主键和外键之间的匹配。这就是数据库使用外键的原因。

符号 table 仅适用于我们没有任何外键的情况。然后我们需要一个 table 来告诉我们每条记录如何与不同 table 中的另一条记录相关。但是因为你确实有外键,所以这个 table 导致重复和冗余数据。

你是正确的,存储 30 列而其中一列不是 NULL 是低效的——这些 NULL 值通常在每一行中占据 space。

假设所有id都是同一类型,可以简化结构使用:

table_name
table_id

只有两列。不幸的是,我不知道有任何数据库允许“有条件的”外键关系。尽管我提倡定义外键关系,但这可能是您选择不使用它们的情况。

这并不完全令人满意。虽然您可以使用触发器确保某些完整性,但这缺少外键的“级联”功能。您可以使用更多触发器来实现它。呸!

一个替代方案是为每个 table:

单独的符号 table
notations_table1
    text, id

notations_table2
    text, id

. . . 

然后您可以使用 union all 将它们组合在一起:

create view notations as (
    select text, id, 'table1' as table_name from notaions_table1 union all
    select text, id, 'table2' as table_name from notaions_table2 union all
    . . . 

底层 table 可以具有正确格式化的外键约束——甚至是级联约束。不幸的是,这缺少一个单独的列作为 id。 “真实”ID 是 table_nameid.

的组合

一些数据库有其他机制可能会有所帮助。例如,Postgres 支持一种在这种情况下可能有用的继承形式。