SQL:引用一对一

时间:2013-04-22 21:29:19

标签: sql join reference

我有些人会称之为一个相当奇怪的问题/问题。

假设我有一个表,它可以引用许多不同的其他表中的一个(并且只有一个)。我将如何以最佳的方式做到这一点?我正在寻找一个适用于大多数数据库(MS SQL,MySQL,PostgreSQL等)的解决方案。我看待它的方式,有几种不同的解决方案(比其他解决方案更好吗?):

  1. 每个可能的参考都有一列。这些列中只有一列可能包含任何给定行的值,其他所有列都为null。允许使用严格的外键,但当“很多”(可能引用的表)数量变大时,它会变得乏味。
  2. 具有两列关系,即一列“描述”引用哪个表,另一列引用该实例(该表中的行)。虽然我不能以简单的方式执行单个查询查询(左连接所有可能的表,或者联合多个查询,每个查询连接到一个表),但是在“很多”(引用表)的数量增长时可以轻松扩展。
  3. ...
  4. 有意义吗?在这种情况下,最佳做法(如果有的话)是什么? 我特别希望能够从引用的实体中查询数据,而不是真正知道哪些表被引用。

    你会怎么做?

2 个答案:

答案 0 :(得分:2)

这两种方法都适用于任何关系数据库,因此您不必担心这种考虑。两者都导致相当麻烦的查询。对于第一种方法:

select . . .
from t left outer join
     ref1
     on t.ref1id = ref1.ref1id left outer join
     ref2
     on t.ref2id = ref2.ref2id . . .

对于第二种方法:

select . . .
from t left outer join
     ref1
     on t.anyid = ref1.ref1id and anytype = 'ref1' left outer join
     ref2
     on t.anyid = ref2.ref2id and anytype = 'ref2' . . .

因此,从简单查询的角度来看,我认为一方面与另一方面没有重大优势。第二个版本有一个小缺点 - 在编写查询时,您必须记住连接的名称。随着时间的推移,这可能会丢失(当然,您可以使用约束或触发器来确保只有一组固定的值进入列。)

从查询性能的角度来看,第一个版本具有很大的优势。您可以将该列标识为外键,数据库可以对其进行统计。例如,这可以帮助数据库选择正确的连接算法。第二种方法不容易提供这种可能性。

从数据大小的角度来看,第一个版本需要存储每个可能值的id。第二个更紧凑。从可维护性的角度来看,首先很难添加新的对象类型;第二个很容易。

如果您有一组彼此相似的东西,那么您可以考虑将它们存储在一个表中。不合适的属性可以为NULL。您甚至可以为不同风格的东西创建视图。一张表可能是也可能不是。

换句话说,这个问题没有正确的答案。与数据库设计的许多方面一样,它取决于数据的使用方式。如果没有其他信息,我可能会首先尝试将数据强制转换为单个表。如果那是不合理的话,如果可以一方面计算表的数量,我会选择第一个选项,如果有更多的表,我会选择第二个选项。

答案 1 :(得分:1)

1)

这对于少量静态表来说是合法的。如果您预计将来可能需要添加一些新表,请查看下面的 3) ...

2)

请不要那样做。您将丧失声明性FOREIGN KEY,这是维护数据完整性的最重要机制之一。

3)

使用继承。这篇文章中的更多信息:

您可能也有兴趣查看: