规范化跨表共享的公共ID类型

时间:2008-10-21 12:23:47

标签: database database-design normalization

这是问题的简化版本。

我们有客户向我们发送大量数据然后进行查询。我们要求他们有几个“公共”ID,他们可以查询我们的数据。 (大多数人希望通过他们与数据一起发送的ID来查询我们的系统,但并不总是如此)。为简单起见,我们将其称为“pid”,“crid”和“musicbrainzid”。我们有一个“实体”表来存储这些信息。它看起来像这样(“权威”是谁发送数据):

entity 
-- 
entity_id   
authority  // who sent the data
type       // 'pid', 'crid', 'musicbrainz', etc.
value      // the actual id value

然后我们有单独的实体,如“剧集”,“系列”和“广播”(实际上,还有更多,但我在这里保持简单)。其中每个都有一个指向实体表的entity_id。

外部客户如何通过pid或crid搜索并获得适当的剧集或系列节目,以及正确识别它是什么?给定一个pid,我们可以获取实体ID,但是我们需要搜索该值的剧集,系列和广播表。此外,并非所有ID都必然与所有其他表相关,但任何实体(例如,“剧集”)可能都有几个ID(pid,crid等)

策略:

  1. 找到pid的实体ID,并在每隔一个表中搜索pid。
  2. 在实体上放置一个“entity_type”列,但是如果它是剧集表中的pid但是我们不小心将episode.type设置为系列呢?我们不想复制数据,我不想将数据库元数据放入列值。
  3. 选项编号1很慢并且看起来是错误的(此外,各种表格具有不同的结构使其成为问题)。

    选项2表示重复数据,此数据可能不同步。我们可以使用触发器强制这个,但这看起来真的很讨厌,无论如何,mysql触发器的实现中的错误已经多次击中我们。我们现在正在使用这种策略,但没有触发器。

    选项3是什么?

    旁注:我们知道我们需要将“权限”分解为单独的表,因为并非所有权限/类型组合都有效。

1 个答案:

答案 0 :(得分:3)

如果我已正确理解你的问题,我会选择选项1。

基于entity_id标识行的查询不应该那么慢,因为所有数据都应该在索引中。
如果索引配置正确,则甚至无法访问实际数据。 (至少在SQL Server中它不会。)

我做的一个小改动是创建一小组表来识别哪些id对哪些表有效。
然后,您可以使用它来缩小需要搜索的表格。

选项1或2的替代方法可能是完全更改数据库结构,使用entity_id作为主键在同一个表上存储不同的数据,以及包含数据的通用列。
这肯定会更激进,但我已经看到它适用于像你这样的系统,数据和它的结构非常动态。