是否需要创建一个尽可能少的表的数据库


52

我们是否应该创建具有最少表数的数据库结构?

应该以一种将所有内容都放在一个地方的方式进行设计,还是可以有更多的桌子?

反正会影响什么吗?

我问这个问题是因为我的一个朋友修改了mediaWiki中的某些数据库结构。最后,他只用了8张桌子而不是20张桌子,花了8个月的时间才完成(这是他的大学任务)。

编辑

我得出的结论是:在特殊情况下,表的大小并不重要;在这种情况下,非规范化可能会有所帮助。

感谢大家的答案。


15
最小数量的表很容易,只需将整个序列序列化为master_table(table_name,col_name,col_type,row_id,value)。
印加

什么?我不明白
Shaheer 2011年

12
由于数据库中的每个字段都是由表名,列名,主键和值的组合定义的,因此您始终可以通过将规范化为仅存储该表的单个表来减少表的数量。不是很有用,但完全有可能。
印加

好吧,我是为了知道而问的,如果某件事没有现有的有用,为什么还要去改变它呢?我的意思是,它将在任何方面带来任何改善吗?性能例如?
沙赫尔2011年

1
@Hamza:它可能会提高性能。这确实取决于具体情况。这里几乎没有足够的信息可为我们提供具体答案。
FrustratedWithFormsDesigner

Answers:


155

忽略表数。更担心正确的设计。如果您最关心的是表的数量,则可能不应该设计数据库系统。

如果您的朋友只需要8张桌子,并且系统可以正常工作,那么8张是正确的数字,剩下的12张对于他所做的任何事情可能都是不必要的。

可能的例外情况可能是对表号有严格限制的特殊环境,但我想不出这种系统的具体示例。


107
+1:If your major concern is quantity of tables, you should probably not be designing database systems.
Joel Etherton

9
结论:数据库表不会占用太多的额外空间。数据占用空间。规范化=更多表=更少重复=更少使用空间。通过尝试最小化表的数量,您不仅在设计上受到损害,而且实际上浪费了空间。除非某些桌子在字面上是多余的,否则这种“桌上高尔夫”在所有方面都是不好的。
亚伦诺特2011年

1
+1,尽管我认为我们还不足以说在他的情况下正确的数字是8,因为我们无法比较这些模式(对于当前的应用程序而言,原始模式可能比当前应用程序具有更高的交易量,因为示例)
亚当·罗宾逊

2
@Hamza:好的,因此他可能具有良好的PHP技能良好的数据库技能,并且该项目可能需要两者-但不要假设拥有一个自动意味着另一个。许多开发人员可能具有一项技能,但没有另一项技能。
FrustratedWithFormsDesigner

4
@Tom Anderson-那么您仍然不应该设计数据库系统。
乔尔·埃瑟顿


17

数据库表应该像类一样遵守单一职责原则。每个表开始时都应处理不多于一组的相关数据。除了性能之外,这使整个野兽更易于管理,因为表本身会更小。由于较小的表可以更快地搜索和连接,因此也可以提高性能。

不用担心表的数量,也不必担心表的数量- 不用担心。专注于编写良好,干净,可读的代码,而不是占用多少空间。一旦有了可以使用的更好的产品,就可以进行积极的重构-我的意思也就是数据库!您将看到应该在其他表中或不需要的列,等等。分析以查看哪些查询花费的时间最长以及原因为何,并在确实存在问题的情况下解决这些问题。


4
在规范化数据模型中,这是最好的方法,但是,如果该数据库用于报告或主要是读取访问,则非规范化的“扁平化”表将在大数据集上表现更好。在这种情况下,较少数量的表将导致更少的联接和更好的性能。
maple_shaft

2
@maple绝对同意。但是,您必须进行概要分析以确定哪些数据集需要分组,因此您需要开始IMO。YMMV,专家们可能会全力以赴:) 杰夫(Jeff)发表一篇关于反规范化的文章,您可能也会觉得很有趣。
Michael K

1
文章简明扼要,我之前读过这篇文章!有时您可以利用两全其美的优势。如果报告不需要是100%实时的,则维护两个方案,一个主要方案是供应用程序使用的事务标准化方案,另一个则是定期流化并针对报告数据访问量身定制的非标准化方案。
maple_shaft

1
:与星型模式的解释主题的更多信息publib.boulder.ibm.com/infocenter/rbhelp/v6r3/...
maple_shaft

1
@maple_shaft,我同意报表数据库通常会降低性能,但我不希望它们允许学生或初级程序员使用。我知道我当然不会让没有专业知识的人来处理我的数据仓库。
HLGEM 2011年

7

业务应用程序的生产数据库可能包含数百个甚至数千个表。您需要业务需求所需的表数。仅出于减少表数量的目的而尝试减少表的数量通常会导致数据库更难查询,存在数据完整性问题并且比规范化数据库更难维护。

有时需要进行非规范化。此操作仅应由确切知道她/他在做什么以及为什么的人来完成。进行非标化很容易,因此只能由具有多年数据库经验的数据库专家或高级应用程序开发人员来完成。没有经验的人应该努力在他/她设计的任何数据库中至少努力达到第三范式(除非您正在进行数据仓库,这是我不考虑雇用没有经验的人的领域)。

当人们说由于联接昂贵而减少表时,它们通常是无知的,或者设计得不好,数据库缺少关键索引或使用大型多列自然键。关系数据库被设计为使用联接,并且如果FK正确索引并且它们使用较小的字段进行联接(则整数效率最高),则联接会非常高效。您会注意到,拥有terrabyte大小的数据库的大型企业以某种方式设法获得了出色的性能并使用了联接。

没有认真的数据库设计者曾经试图减少表的数量,只是因为他们想要更少的表。由于不再需要数据,或者由于性能问题而无法解决其他问题,因此减少了表的数量(在尝试对表进行非规范化的数据承担大量风险之前,有很多方法可以尝试) 。


Google设计了BigTable并故意排除了联接,因为它不可并行化。
Lie Ryan

2
@Lie Ryan,BigTable是一种特殊情况,不适用于大多数业务应用程序,因为数据完整性不是一个大问题。Google不需要太多复杂的业务规则来进行搜索。我敢打赌他们的公司财务应用程序不使用BigTable。但是,实际上,如果设计人员是知识渊博的人,大多数具有大型数据库的业务应用程序都可以使用联接并表现良好。企业数据库有许多提高性能(包括分区)的方法,因此不必丢失关系数据库的数据完整性功能。
HLGEM 2011年

为您+ 1,@ HLGEM,同时提供答案和评论;对于许多跳入文档数据库潮流的开发人员,因为他们认为“ joins = slow”而只是去尝试解决20年前由关系数据库解决的关系问题,真是太可惜了。
亚当·罗宾逊

5

由于数据库中的每个字段都是由表名,列名,主键和值的组合定义的,因此您始终可以通过将规范化为仅存储该表的单个表来减少表的数量。不是很有用,但完全有可能。

表是一个抽象层,有助于解决数据处理问题。这就是为什么创建它们的原因。我开了个玩笑,但是了解到可以将每组数据减少到一个主表后,立即指出了为什么不这样做:因为表为您带来了一些好处。从概念上讲,它们给您带来的结构比序列化数据更容易为人类所理解。在两者之间,它们带来了标准化的概念:避免保存冗余数据并为更改指定一个要点,而不是在多个位置进行更改。在技​​术层面上,数据库带来了您想对数据进行的大部分处理,大量工具,并实现了它们,并比您自己可能会进行的测试还要多。考虑数据类型,默认值,用户权限,索引,外键约束等。它已经过测试,使用过许多优化和调试。(不是完美,但仍然如此。)

由于数据库是一种工具,所以主要的事情就是确定如何使用该工具。表的数量并不重要。最小化总是可能的,但是却以牺牲收益为代价。(如果您了解有关规范化的更多信息,那么您会遇到几种非规范化的情况-但即使如此,它也只是关于正确的决策,而不仅仅是盲目地减少表的数量。)


谢谢,现在已经很清楚了!而且,我已经读过有关规范化btw的信息,即使在cakePHP数据库中也是如此,这鼓励了另一种略有不同的方法。
Shaheer 2011年

3

您应该使用正确数量的表。从理论上讲,您可以通过对整个数据库进行非规范化来处理单个表表,但是该数据库将无法使用。您的朋友听起来好像他手上有太多时间。


2

拥有最少的桌子数量使我成为一个非常特殊的目标。

当然,将模式从20个表减少到8个表可能是一件好事(如果做得好,可能会减少连接并提高性能,删除未使用的列等),但同样可能使理解和增强过程变得更加困难。

用另一种方式思考,您认为规范化是一件好事吗?规范化通常会导致表数量增加,但也会导致解决方案的维护性更高,减少数据重复并简化数据管理。

当然,这也会导致性能降低(假设非规范化数据库设计合理)。

最终,您需要考虑这些方面的要求,但是作为默认的初始位置,我想说的是进行合理程度的标准化,然后查看这是否会导致特定的问题,而较少的表可能是解决方案。


0

数字并不重要。设计是。查看那里的一些系统。Magento,PHPBB等。它们在系统中有数十个表,工作正常。


0

除了对规范化和性能的关注之外,您还可以使用“将需要另一个表”作为管理应用程序范围的一种方式。该功能将需要一张新表,并且需要所有时间,精力和精力来设计,构建,测试,管理升级以及所有其他涉及的编码。向现有表中添加5个字段(如果适用)比5列表容易得多。


0

如果您在设计数据库时尝试最小化表的创建,那么您很快就会发现突如其来的困难并以自己的方式犯错。

创建数据库设计时,表计数不应该放在您的首位。将事情放在逻辑和关系所需的地方。


0

我认为表的数量很重要,如果您选择将出于所有业务目的和目的应保持在一起的数据拆分为多个表(即,您将拥有一个规范化的数据库),则表的数量将对性能产生重大影响。通常,当您执行此操作时,将被迫进行JOIN操作(或非SQL等效操作)以获取所需的所有数据,并且对于如此结构的足够大的表,性能会很快下降。

我不愿赘述,但我认为表的数量会影响性能这一非常现实的事实是未发明Cassandra,Mongo和Google BigTable之类的SQL数据库的原因之一,这就是为什么它们鼓励对数据进行非规范化(并因此避免使用大量表/集合等)的原因。

对于诸如Apache的Solr之类的搜索服务器,也可以说同样的话,它实际上并不能鼓励或轻松地将您的文档拆分为多个“表”或“条目类型”,从而鼓励您使用具有共同字段的“一个包含所有内容”的模式到要索引的所有文档类型(因此避免进行类似于JOIN的操作)。

我并不是说,在架构中拥有x个表的简单事实必然会使它始终比具有x / 2个表的架构慢,但是在某些情况下,由于结果的原因,它可能导致速度变慢汇总所有这些表中的数据所需的额外操作。继续这样做,我也不认为可以说“任何数量的表和数据的极端规范化都不会对性能产生任何影响”。


0

鲍伯叔叔会争辩说,“更简单”。

参见http://c2.com/cgi/wiki?FearOfAddingTables

“通常通过添加表来简化好的设计”

我相信几乎所有实体都是多对多的,这需要更多的表。

制作一个包含大陆代码的国家/地区表。哦,不能,因为实际上有8个跨洲国家/地区。与货币相同。巴拿马使用两个。


-2

那么答案是肯定的。

但是要取决于“最小”表数的真正含义是什么。

例如(反示例)。

如果我还有下一个物件

  1. 使用者
  2. 顾客

并且它们都共享相同的状态(字段),并且没有安全限制,那么它更适合做一个表

  1. table_persons

而是两个不同的表

  1. table_users
  2. table_customers

缺点是,我们将需要在table_persons中添加一个新字段(type_of_person)。

另一个错误(如果不是真正需要做的话,会犯错误)是将表“拆分”为:将单个表分成两部分。

  1. table_persons

在两个表中

  1. table_info_persons
  2. table_extra_info_persons

因为您要强制某些查询将两个表联接起来,所以这样做很不好。


嘿,您的回答很有描述性,对您有所帮助,谢谢
Shaheer 2011年

2
这使我回想起了我的第一个企业应用程序及其背后的数据库,以及DBA在这种情况下成为表格纳粹所造成的噩梦。我绝对不会将完全不同的业务实体与客户和用户联系在一起。

-1:用户和客户具有不同的领域;如果不是现在,他们将在将来的某个时候使用。因此,它们应该有单独的表。
Sjoerd

1
@ Sjoerd,@ Chris:虽然通常是这种情况,但不一定如此。诸如此类的事情取决于应用程序。话虽如此,我确实同意这一观点。数据库开发人员经常会看到“公用字段名称”,这意味着它们是相同的数据。当您首先从ORM(换句话说,向后)查看数据库时,这样做特别容易。虽然可以在数据库中对OO概念进行建模,但是数据库是行和关系,而不是对象
亚当·罗宾逊

1
+1表示“数据库是行和关系,而不是对象”,我将其添加到我的收藏夹引号中!
Shaheer 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.