2009-10-29 60 views
1

目前的情况是,主题按3个主要类别排序。有可能增加的不仅仅是3个类别,而是更高层希望实现为一个主题添加不止1个类别的能力。我应该创建另一个表还是仅使用数组? (规范化或不规范化)

我的原始数据库设计在主题信息表中具有categoryID作为外键。从一开始,这可能是一个糟糕的主意,但我想他们只设置了3个类别,并且这样做会减少查询次数。

因此,从我所看到的我现在有两个选项: 1)输入categoryID作为一个逗号分隔的字符串,我解析的PHP结束。 2)重新构造数据库并将categoryID拉出到它自己的categoryID和topicID表中。

我想知道每个人都认为这是什么。我的第一本能是重组数据库。但是当我考虑这个问题时,第一个选择是实现最简单,并且最不可能通过改变数据库来打破现有的问题。这也可能导致不规范化,并且会导致数据不一致的可能性。

我已经阅读了解除归一化问题,只要您接受以不一致的数据换取性能的风险即可。在您看来,我会因此风险而获得很多业绩吗?对于我在这种情况下应该做的任何投入将不胜感激。

感谢您的帮助,
列维

回答

3

不要混淆非规范化(一个很好的例子,其中与问题保持在SO问题的表决票数一起,而不是从“票”表中的每个时间计算它)与可憎的是逗号分隔的ID列表。

建立适当的多对多关系;用逗号分隔的方法可能(并且会)出错的东西太多了。仅举几例:

  1. 没有参照完整性。
  2. 接下来无法在连接中使用。
  3. 不可能充分索引;非可扩展性。
+0

所有的优点,你的第三个关于是不可扩展的是我最初用我的数据库设计进入这个问题。 – Levi 2009-10-29 03:03:03

+0

+1此外,执行各种聚合查询更困难,例如对列表中的值进行计数,求和或平均。 – 2009-10-29 03:03:04

0

你最好的选择就是像你说的那样有一个类别ID-topicID对的数据库来查找这些主题属于哪个类别。

你可以通过以类别ID分解字符串的方式来做到这一点,但是当你搜索某个类别中的任何主题时,你必须遍历每个字段并在其上运行一个LIKE ...更多的资源密集型。

花时间重组数据库,最终得到更好的结果。

0

如果您需要在单个项目的DBMS中执行某些操作,请执行而不是以列表形式存储它们。这会让你的查询像狗一样运行,因为你的表变得更大。当然,如果你只是将这个列表当作一个单元来对待,那么以这种方式来存储它们也是可以的。

但是你最好确定你会一直把列表作为一个单元来处理,而不是作弊,说他们是一个单元,然后将它们分散到别处 - 最好让DBMS做到这一点您。

你应该总是先做3NF然后如果,并且只有当你有性能问题时,才会使速度变得非规范化。

你在这个问题上谈论的那些领域并不是你将作为一个单位来对待的那种领域。您需要对列表中的各个元素执行操作,因此应该将其分解到另一个表格中。

+0

好吧,我打算把它分解成另一张桌子,听起来像我在路上会有更少的错误。 只是好奇,是一个列表视为一个单元只有当它将被显示为是?所以如果我有'苹果,桔子,香蕉,猕猴桃',我用它输出'我喜欢苹果,橘子,香蕉,猕猴桃'。这很好吗? 1.4.3本, “我喜欢: -apples -kiwis -bananas -oranges ” 将是一个不错的主意,但因为我将不得不采取的字符串,并把它分解开的顺序来显示呢? 有没有一个真实世界的例子,你可以考虑使用列表作为一个单元? – Levi 2009-10-29 03:41:16

+0

是的,没关系。如果您只是按原样将其拉出,而不是操纵它,则可以像那样存储它。这是因为DBMS或您的程序没有额外的工作来处理它。在这种情况下,它实际上*更好*这样做,因为它比将单个列重新组合为字符串更快:-) – paxdiablo 2009-10-29 03:56:36

+0

真实世界的例子?如何在约会网站上列出你的兴趣(这可能是*任何*因此可能无法用作查找表)。你可能会进入“在海滩散步,Java开发和酷刑设备从16世纪”,这将被展示给未来的候选人(然后,他们会诚实地说,可能会像地狱一样)。 – paxdiablo 2009-10-29 04:11:12