规范化帮助

时间:2010-01-14 20:28:30

标签: sql oracle schema normalization entity-relationship

我正在重构一个旧的Oracle 10g架构,试图引入一些规范化。在一个较大的表中,有一个文本字段最多有10-15个可能的值。在我看来,这个字段似乎是不必要的数据重复的一个例子,应该被提取到一个单独的表中。

在检查数据后,我找不到可能与该文本值相关联的一条相关信息。基本上,如果我将该值拉出并将其放入自己的表中,它将是该表中唯一的字段。它现在作为一个“旗帜”领域存在。我应该创建一个带有代理键的双列表,保持原样,还是做一些完全不同的事情?通过尽量减少这个领域的数据重复,我弊大于利吗?

4 个答案:

答案 0 :(得分:4)

您可以通过将列提取到单独的表来节省一些空间。这称为查找表。它可以为您提供其他一些好处:

  • 您可以向查找表声明一个外键约束,这样您就可以依赖主表中的列,除了您想要的10-15值之外,不会有任何值。

  • 通过查询查找表,可以轻松查询所有允许值的简明列表。这比在主表的列上使用SELECT DISTINCT要快。它还返回允许的值,但当前未在主表中使用。

  • 如果更改查找表中的值,它会自动应用于主表中引用它的所有行。

但是,使用一列创建查找表并不严格规范化。你只是将一个值替换为另一个值。主表中的属性或者已经支持普通表单。

使用代理键(与自然键相比)也与规范化无关。很多人犯了这个错误。

但是,如果将其他属性移动到查找表中,属性仅依赖于查找值,因此如果将它们保留在主表中,则会在主表中创建重复组(违反3NF),然后 会正常化。

答案 1 :(得分:1)

如果你想要标准化,请将其分解。

我认为DB中的这些类型的数据相当于C,C ++,C#中的enums。大多数情况下,你把它们作为文档放在表格中。

我经常为他们提供ID,名称,描述和审核列(例如修改日期,修改日期,创建日期,创建者,活动。)描述字段很少使用。

示例(有些人可能会说不仅仅是2个)

Gender
ID  Name   Audit Columns...
1   Male
2   Female

然后在您的联系人中,您将拥有一个与此相关联的GenderID列。

当然,你并不“需要”这张桌子。您可以在某处使用外部文档,其中1 =男性,2 =女性 - 但我认为这些表用于记录系统。

答案 2 :(得分:0)

如果它真的是一个自由输入的文本字段,并没有在数据库中的其他地方重复使用,并且只有一个字段没有重复的实例,我可能会继续保持原样。如果您决定将其分解,我将创建一个带有代理键和文本值的“验证”表,然后将代理键放在基表中。

分享并享受。

答案 3 :(得分:0)

这些10-15值是否真的有意义,或者它们真的只是标志?如果它们是有意义的文本片段并且复制它们似乎很浪费,那么确保创建一个查找表。但是如果它们只是任意标志值,那么你的新表只不过是从一个任意值到另一个值的映射,并且不是非常有用。

一个完全独立的问题是大表中的所有行或大多数行是否都有此列的值。如果没有,那么你确实有很好的规范化机会,并且可以创建一个单独的表来链接基表中的主键和标志值。

编辑:有一点。如果有可能在未来的某个时刻将这些“标志”值中的一个重新替换为另一个值,那么这将是创建表格的另一个好理由。

相关问题