数据库规范化和单个字段突破

时间:2015-07-10 20:25:10

标签: database database-design database-schema normalization database-normalization

我的问题可能已被多次询问,但我找不到它(谷歌搜索也没有很好)。

我试图规范我们的数据库。这是一个例子:

假设我们目前有一个表:

Property
---------
id
name
type

类型可以是:

多系列 单亲家庭 卫生保健 商业

我可以把它分成一个单独的表,以便我们有:

Property       Prop_Type
--------       ----------
id             prop_id
name           type
type_id

根据2-n,我应该打破这个。但是我实际上在节省什么呢?我同意像这样分解表格会使我们更容易插入新类型的房地产,或修改当前的房地产。但假设这不是非常必要的,这是否会导致性能提升? Property.type字段最多包含一个32字节的字符串,而Property.type_id则类似(不是?)。另外,第二个选项需要一个额外的表,每次我们想要访问该数据时都需要加入。最后,我们的数据库不是那么大(可能是数万条记录),因此节省空间不是优先考虑的事情。

我应该继续正常化,还是应该推迟这些小小的休息?

谢谢!

2 个答案:

答案 0 :(得分:1)

我认为这不是规范化问题。

类型列本质上是一个离散类型,即具有一组有限的值 - 目前是多家庭,单家庭,医疗保健,商业。

您想要的是控制列中没有插入无效值。您的prop_type表和外键约束是一种解决方案。

更合适的解决方案是在列上使用CHECK CONSTRAINT:

CREATE TABLE Property
(
    id int PRIMARY KEY,
    name ...,
    type varchar(20) CONSTRAINT typeValues CHECK (type IN ('multi-family', 'single-family', 'healthcare', 'commercial'))
)

更进一步,不需要在每条记录中存储完整的类型字符串。您只需使用单个字符编码类型:

CREATE TABLE Property
(
    ...
    type char(1) CONSTRAINT typeValues CHECK (type IN ('M', 'S', 'H', 'C'))
)

当您提供类型时,例如在GUI中,您需要将它们转换为用户可读的文本。要输入值,您可以在GUI中使用下拉列表。

答案 1 :(得分:1)

  

我应该继续正常化,还是应该推迟这些小小的休息?

规范化到更高级的正常形式会使用相同的列替换其他表,这些列根据函数依赖关系和连接依赖关系连接回原始表。

  

根据2-n,我应该打破这个

据推测,你的意思是2NF。您没有提供任何信息来证明这一点。你所讨论的事情与规范化无关。

看起来你对正常化有所了解。获取参考资料,介绍并解释其问题,定义和程序。使用它们。引用它们。

  

但是我实际上在节省什么呢?

无论性能如何,都应该进行标准化。当你通过基于理想/原始的改变到另一个特定设计的证明的现值来证明你是合理的。

如果没有详细说明特定DBMS实现和预期用途,那么谈论设计性能是没有意义的。但粗略地说,引入id会占用较少的空间,但会导致更多的连接。

DBMSes 存在以使信息存储在由DBMS实现的代数和/或条件查询的表中。只需做出最直接的设计。在了解足以修改设计性能之前,您需要了解有关模式和查询的更多信息。

  

我同意像这样拆分表格会让我们更容易插入新类型的房地产,

不,这让它变得更难。您以前所要做的就是在Property行中输入您想要的类型值。使用ID,您必须添加Prop_Type行并在Property行中使用该type_id。

如果Property属性的可能值已修复,则在Property type:

上添加CHECK约束
CHECK(type IN ('multi-family','single-family','healthcare','commercial'))

(否则,不要。)

如果您希望在不更改架构的情况下更新和查询属性的可能值,并且不必为每种类型都提供属性,那么这是您的原始设计无法表达的内容。但你仍然不需要引入id;你可以有一个Prop_Type表,只有一个类型列和一个从属性类型到Prop_Type类型的外键。