打破规范化3NF的表

时间:2014-07-30 16:50:12

标签: mysql sql normalization database-normalization

我刚刚开始研究规范化,它正在努力弄清楚应该创建多少个表来保存我一直存储在一个表中的数据。所以这就是我到目前为止打破一张桌子的方式:

Paper ID | Paper Name  | Category | Owner

01       | Weekly News | CAT_01  | USER_1
02       | Daily News  | CAT_01  | USER_2
03       | The Times   | CAT_02  | USER_1

现在这是正确的标准化,还是应该分解为3个表格,如:

Paper ID | Paper Name

01       | Weekly News
02       | Daily News
03       | The Times

Paper ID | Category

01       | CAT_1
02       | CAT_1
03       | CAT_2

Paper ID | Owner

01       | USER_1
02       | USER_2
03       | USER_1

另外,在规范化表格中有空白单元格是错误的吗?我有一个看起来像:

Author ID | Last Name | First Name | Facebook | Twitter | Website

01        | Griffin   | Brian      | (url)    | (url)   | (url)
02        | Griffin   | Peter      |          | (url)   | 
03        | Griffin   | Meg        | (url)    |         | (url)
04        | Griffin   | Stewie     | (url)    | (url)   | (url)

5 个答案:

答案 0 :(得分:1)

在实体关系建模方面:

每个"实体"在模型中应该表示为表中的一行。一个"实体"是一个人,地点,事物,概念或事件,可以唯一识别,对业务很重要,我们可以存储有关的信息。

"实体的属性"在表格中显示为列。在"重复"的情况下属性,可以多次出现的属性,我们可以创建一个辅助子表。

"正常化"并不要求将每个属性分解为单独的表。

代表"缺失"完全有效。或"未知"具有特殊值的属性值;我们经常使用特殊的NULL值来表示缺少值,尽管使用您选择的任何其他值,零长度字符串或诸如'N/A'之类的字符串完全有效,取决于要求/用例。


完全"标准化"模型,每个属性都依赖于" 键,整个键,只有键"。

答案 1 :(得分:1)

  1. 不,将它分成三个表只会很傻。

  2. 不是"错误"在某些情况下具有空值,但我担心您基本上将一对多信息实现为多列。如果要添加其他URL类型,则需要更改表模式以及读取它的所有代码,这样做并不好。你应该做更多的事情:

  3. Author ID | Last Name | First Name
    
    01        | Griffin   | Brian      
    02        | Griffin   | Peter      
    03        | Griffin   | Meg        
    04        | Griffin   | Stewie     
    
    ID        | Author ID | URL Type  | URL
    
    01        | 01        | Facebook  | (url)      
    02        | 01        | Twitter   | (url)      
    03        | 01        | Website   | (url)        
    04        | 02        | Twitter   | (url)
    

    如果您想阻止作者拥有两个Twitter网址,请在作者ID +网址类型上添加唯一索引。

答案 2 :(得分:1)

这应该是

论文表

Paper ID | Paper Name  | Category_Id | Owner_id

01       | Weekly News | CAT_01      | USER_1
02       | Daily News  | CAT_01      | USER_2
03       | The Times   | CAT_02      | USER_1

分类表

Category ID | Category name     
1           |  Category_a

所有者表

Owner ID | Owner Name | 
1        | Owner X

您的基本目标应该是将每个实体移动到自己的表中。每个实体都有自己的属性,应该在特定的实体表中添加。

现在例如一篇论文属于特定类别。您需要做的就是参考纸张表中类别表中的类别ID。纸质表不需要具有类别名称列。可以使用类别ID

的引用来收集其余类别数据

在表格中有空白单元格并没有错。我建议不要过于复杂化。虽然规范化确实听起来很深奥,但数据库设计更具常识。考虑一下,您可以选择允许用户使用Facebook登录。你知道有些人会选择这个选项,所以你必须将他们的Facebook ID存储在某个地方。另一方面,会有一些人不想通过Facebook登录,所以他们的facebook_id列将是空的。

还有更多要阅读: Intro to Normalization

答案 3 :(得分:1)

1

假设所有者有三个值firstname,lastname和address。

在这种情况下,您的设计可能看起来像

Paper ID | Paper Name  | Category | FirstName | LastName | Address

这是糟糕的设计,因为所有者可以拥有多本书。在这种情况下,将重复所有者的详细信息。为避免这种情况,您应该有两个关系,即Paper和Owner

纸张:

Paper ID | Paper Name  | Category | OwnerID

拥有者:

OwnerID | FirstName | LastName | Address

只要遵循NormalForms,就可以将关系(表)划分为多个关系。你不需要像你提到的那样划分关系。

阅读普通表格。

2

在列中具有空值以表示空有效。但是如果列数很少就没问题。如果数字列很大,则说10但是作者几乎没有2到3个网址的最大值,在这种情况下遵循以下结构。

关系1:社交网站

 sid <primary key> | Name     | URL
 ------------------------------------
 1                 |Facebook  | <url>
 2                 |Twitter   | <url>

关系2:作者

 AuthorID<PK> | Last Name | First Name
 -----------------------------------
 01           | Griffin   | Brian

关系3:authorsitemapping

 AuthorID | Sid
 --------------
 01       | 1
 02       | 2

这里{AuthorID,Sid}是主键。 AuthorID引用作者和Sid引用社交网站。

答案 4 :(得分:1)

您和其他答案描述的重新排列不是必需的。它们与normalizaiton无关。

特别是您不需要引入ID,也不需要将列移动到单独的基表中。

规范化不适用于具有NULL的表。但是你使用NULL是一种典型的SQL习惯用法,它对应于带有表而不是每个可空列的规范化设计。因此,改变您的设计不会出于规范化的原因。

您是否应重新排列表格取决于您未提供的信息,即您的FD和JD。

规范化与实体或列数无关。规范化要求您确定&#34;功能依赖性&#34; (FD)(即当列是其他列的函数时)和&#34;加入依赖关系&#34; (JDs)(即表格可以表示为投影的连接)。然后你确定候选键&#34; (CKs)(即列集,其中所有其他列都是函数但不包含任何较小的此类集)。当一个表的所有JD都被&#34;表示为&#34;时,表被归一化(到5NF)。其候选键(即,如果它是投影的连接,则每个投影的列集是一些关键列集加上零个或多个列,这些列是那些关键列集的函数但没有更小的子集)。如果你不学习必要的概念和技术,你就无法正常化。