数据库设计-何时拆分表格?

6
有时候创建一个单独的表会产生更多的工作量,我应该分割它吗?
例如,在我的项目中,我有一个客户表,每个客户都有自己的特殊产品价格(只有5种产品,未来也不打算增加),每个客户还有独特的一周配送时间。当需要更改客户的配送时间/价格或显示所有客户的配送时间和价格等操作时,如果将配送时间和产品价格作为列添加到客户表中而不是单独的表中,会更容易实现。在这种情况下,仅创建一个大的客户表是否可行?有哪些缺点?
更新:他们刚刚告诉我,一年后或更长时间后,他们可能会增加更多的产品,他们说他们的业务不会超过20-30个产品。 我仍然无法理解为什么在这种情况下(每个客户都有自己的特殊价格)向产品表添加行比向客户表添加列更好? 我唯一能想到的好处是,只有5种产品的客户不必“携带”20个可空产品(节省服务器空间)?由于经验不足,我可能忽略了显而易见的事情。

3
未来没有计划推出更多产品。永远不要说“永远不”。 - N West
2
许多操作[...]如果日期和产品价格是客户表中的列而不是单独的表,将会更容易。真的吗?编写几个INNER JOIN语句有多难?如果添加/删除新产品时要添加更多列,您想怎么做? - LittleBobbyTables - Au Revoir
1
你需要区分表格的标准化格式和非标准化数据版本之间的差异,前者对于保持数据最新非常有用,而后者则对于报告至关重要。听起来你想要一个单独的报告表格集合,可能每天更新而不是实时更新。 - Gordon Linoff
@LittleBobbyTables - 我不是说它很难,但是这还需要更多的工作,特别是应用程序有很多操作。为什么我不应该这样做并节省自己的工作量呢?特别是新产品没有计划,如果他们想要升级,他们会付给我更多的费用。还有这些天呢?每周7天还是非常稳定的吧? - BornToCode
3
即使他需要单独的报告表,该架构部分的格式仍然很可能是“规范化”的。如果你想进行后期维护,这并不会增加更多工作量。研究表明,约80%的开发工作时间花费在维护上,而不是在初始生产上。正确地规范化你的初始数据库,只有在性能要求时才生成一个(额外的)非规范化的架构。要对客户专业一点,不要采取“简单”的方法。此外,一个完全非规范化的结构可能难以轻松使用。 - Clockwork-Muse
2个回答

5
显然,仅仅说应该总是进行规范化并不切实际。没有什么建议是永远正确的。
如果你能确定只需要5个“项目”很长一段时间,那么将它们存储为列如果可以节省工作量,我认为完全没问题。
如果你的预测失败并且需要存储第6个项目,则可以添加新列。 只要列数不会高得离谱,这应该不是问题。
但要小心使用这种策略,因为许多程序员预测未来的能力非常有限。 最终只有一件事情很重要:以最低成本提供所需的解决方案。代码的纯洁性不是目标。

1
当项目数量是恒定且较小的时候(例如星期几或鸡蛋大小),我通常会使用列解决方案。简单又快速。 - usr
如果我在一个表中最终会有30-40列,这对性能不会产生不良影响吗?唯一的缺点是如果客户有一天修改了需求怎么办?为什么在另一个帖子中人们支持这样做,而在这里大家都在责备我? - BornToCode
1
将一行存储的成本视为存储一列的10到100倍。每添加一列,您就可以在您的情况下节省一行。如果您的CPU受限,这是一种很好的性能权衡,而许多OLTP服务器都是如此。人们批评您是因为程序员接受过识别模式和反模式的培训。总的来说,但不适用于这种特殊情况,这是一种反模式。不要太担心其他人认为什么对您是正确的。 - usr
1
@BornToCode,我倾向于说不。他们会添加更多的产品和产品变体(比如颜色)。我认为你需要从列式策略中获得非常高的收益才能在这一点上证明它的合理性。需求已经变得不稳定,列数也很高。 - usr
我本来就担心你会这么说 :) 但我接受了。我真的很感谢你,因为这对我来说是一个至关重要的决定。如果您能帮我个忙,并解释一下为什么在这种情况下(产品价格没有关系,每个客户的价格完全不同),添加行比添加列更好吗? (在产品表中,每行将包含客户ID、产品名称和产品价格)。我唯一想到的好处是,只有5个产品的客户不必“携带”20个可空产品(节省服务器空间)? 我没有太多经验,所以也许我错过了显而易见的东西? - BornToCode
显示剩余2条评论

2

规范化是关于数据完整性(一致性)的,没有其他任何属性,比如难、易、快、慢、高效等。当前的设计几乎肯定会导致数据异常。如果现在不是,那么当您尝试跟踪价格变化、发票、订单等时,就会陷入死胡同。


如果我有另一个特殊的表——“销售历史记录”,保存了销售执行时的所有信息,那该怎么办?一切似乎都可以追踪?您能否举个例子说明一下您所说的数据异常情况(我可以理解为什么规范化对于修改可能更好(例如,如果会不断添加新产品),但在我的具体示例中,我无法理解预期出现什么样的数据异常情况?) - BornToCode
@BornToCode;很简单,看看你能否更新(更改)任何一个特定顾客/产品的字段(行-列交叉点),以便获取不同的数据(应该是相同的)。 - Damir Sudarevic
@BornToCode;无论如何,维基百科都涵盖了它http://en.wikipedia.org/wiki/Database_normalization#Normal_forms,包括示例。 - Damir Sudarevic
“(which is supposed to be the same)” - 对不起,我还是没明白,在我的情况下,每个客户对于每种产品都有自己的特殊价格?我试着在维基百科上查找,但不幸的是我的中文水平不足以理解他们在说什么 :) - BornToCode
假设有一个产品,所有客户的价格应该相同($5)。我能否只为一个客户更新价格为$3(打破规则)?我认为每个产品都有一个基础价格,每个客户都有自己的加价(折扣);价格属于产品,加价属于客户。请阅读维基百科上的相关文章。 - Damir Sudarevic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接