规范化/表格中的第三范式?
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,那么我该如何改进呢?我的意思是所有列都与文章相关 - 将数据拆分成更多表格不会使事情变得复杂吗? 不,拆分数据将使某些操作成为可能。例如。如果您想查找包含关键字a
和 b
的所有文章,那么(在您当前的架构中)无法创建索引来阻止对所有文章进行全表扫描。
一条新闻有多少个关键词?
【参考方案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_1
、cat_2
、cat_3
的简单案例——更多的是@ 案例987654324@、author_1's cat_2
、author_2's cat_1
等以上是关于规范化/表格中的第三范式?的主要内容,如果未能解决你的问题,请参考以下文章