规范化/表格中的第三范式?

Posted

技术标签:

【中文标题】规范化/表格中的第三范式?【英文标题】:Normalisation / 3rd Normal Form In Tables? 【发布时间】:2014-09-20 16:19:28 【问题描述】:

我正在创建一个小型新闻网站,有人建议我查看规范化,我这样做了,尽管我理解它,但我不太清楚它是否与数据库中的所有表相关。例如,我有这个“文章”表,其中包括:

ID                      -   10001
Featured                -   0 or 1
Category                -   Category Name
Title                   -   Title For The Article
Article                 -   This is the article.....
Photo Description       -   Photo to go with blog 10001
Photo Name              -   John Smith
Photo Link              -   www.johnsmith.com
Author                  -   myname@gmail.com
Keywords                -   keyword, keyword, keyword, ...
Added                   -   2014-07-27 10:41
Views                   -   600

保留此表有什么问题吗?还是需要将其转换为第三范式?

编辑:

如果我有:

**Authors**

ID
email
name
avatar
bio
website_link
facebook_link
twitter_link

**Articles**

ID                      -   10001
Featured                -   0 or 1
Title                   -   Title For The Article
Article                 -   This is the article.....
Photo                   -   10001.jpg
Photo Description       -   Acts as alt tag
Photo Name              -   Crediting photographer
Photo Link              -   Link to credited photographer
Author                  -   Author ID
Added                   -   2014-07-27 10:41
Views                   -   600

**categories**

ID
category

**article_categories**

ID
article_id
category_id

我仍然很难理解为什么拥有这么多表是一件好事,尽管现在有很多连接需要进行。为什么用php说起来不方便

select * from articles where category == $category

select * from articles where featured == 0

select * from articles where author == $author_id等等等等

【问题讨论】:

需要改进。 如果您需要匹配逗号分隔的值,它们几乎总是错误的。 好的@juergend,那么我该如何改进呢?我的意思是所有列都与文章相关 - 将数据拆分成更多表格不会使事情变得复杂吗? 不,拆分数据将使某些操作成为可能。例如。如果您想查找包含关键字 ab 的所有文章,那么(在您当前的架构中)无法创建索引来阻止对所有文章进行全表扫描。 一条新闻有多少个关键词? 【参考方案1】:

您如何选择规范化很大程度上取决于您的业务案例,不要仅仅为了它而规范化。这就是为什么您的设计方法至关重要的原因,从 ERD(自上而下的方法)开始有助于我决定如何最好地进行规范化。

【讨论】:

谢谢。就像上面建议的那样,为什么一个只有 12 列的表需要拆分为 8 个表,这有点令人困惑。我一直使用 php 来过滤信息,而不是试图将几个表链接在一起【参考方案2】:

为新闻、类别、照片、作者和关键字制作单独的表格

新闻

ID                      -   10001
Featured                -   0 or 1
category_id             -   //belongs to category table
Title                   -   Title For The Article
Article                 -   This is the article.....
Added                   -   2014-07-27 10:41
Views                   -   600

类别

ID
name

照片

ID
Photo Description       -   Photo to go with blog 10001
Photo Name              -   John Smith
Photo Link              -   www.johnsmith.com

作者

ID
Author                  -   myname@gmail.com

关键字

ID                      -   10001
Keywords                -   keyword

一条新闻可能有多张照片,所以制作一张桥表 news_photos

news_photos

id
news_id
photo_id

同样,一个新闻可能有多个作者,所以制作一张桥表 news_authors

news_authors

id
news_id
author_id

同样一条新闻可能有多个关键词,所以制作一张桥表 news_keywords

news_keywords

id
news_id
keyword_id

【讨论】:

也许featured 属性应该与site_id 一起在featured_news 表中? (这样您就可以在多个网站上刊登这篇文章..?) 不知道,但在大多数情况下,单个新闻的照片、作者和关键字是多个 .. 维护单独的表格是一种好习惯。例如:稍后您可能需要通过匹配标签来拉取相关新闻 桥接表中不需要id 字段。 @thebjorn :是的,但有时如果你使用框架,它就会成为强制性的。 @user3177012 不,一点也不。将相关信息分组到单独的表格中是标准的最佳实践。例如。如果您想在电子邮件之外显示作者的姓名(您会在每一行都重复一遍),您的方案会是什么样子?【参考方案3】:

我建议您至少将类别和关键字移动到单独的表格中。

当您必须按关键字或类别搜索文章时,这将帮助您编写更有效的 SQL 查询。

另一方面,您将不得不编写更多代码来执行此操作,参考数据插入表单等,但它会更好,更清晰,绝对更好。

您应该: 创建Categories 表(Id, Description) 创建Keywords 表(Article_Id, Keyword) 用Articles.Category_Id 替换您的Articles.Category 字段并删除您的Articles.Keywords 字段。

【讨论】:

谢谢,但是仅仅使用select * from articles where category == '$category'有什么问题? @user3177012 那么您需要在category 列上建立一个索引,如果您要创建一个索引,为什么不充分利用单独表的优势..? @user3177012 其中一个问题是,每篇文章中重复的类别描述会使您面临打字错误,而在不同的表格中仅重复一次的类别更“可检查” @kiks73,你的意思是category_name?即使该值是从下拉菜单中的值输入的?【参考方案4】:

您复制了许多描述类别名称的字符串。更容易存储整数值,而不是每次存储类别名称。

【讨论】:

谢谢,但类别将由作者自己设置,因此不仅仅是cat_1cat_2cat_3 的简单案例——更多的是@ 案例987654324@、author_1's cat_2author_2's cat_1

以上是关于规范化/表格中的第三范式?的主要内容,如果未能解决你的问题,请参考以下文章

第三范式

具有唯一值的第三范式

Oracle数据库设计第三范式

求数据库高手,解决有关范式的问题,谢谢!!

数据库规范化,数据库范式,和规范化实例

数据库规范化,数据库范式,和规范化实例