需要数据库结构建议

时间:2009-10-25 23:53:53

标签: php mysql database database-design

我目前正在开发一个包含产品目录的网站。我对数据库设计有点新意,所以我正在寻找有关如何最好地做到这一点的建议。我熟悉关系数据库设计,所以我理解“多对多”或“一对多”等(在大学里学习了很好的数据库课程)。以下是项目可归类为以下内容的示例:

Propeller -> aircraft -> wood -> brand -> product.

不要试图编写我目前所拥有的内容,只需快速浏览一下我从phpmyadmin设计器功能创建的图像。

alt text http://www.usfultimate.com/temp/db_design.jpg

现在,这一切看起来都很精致,直到我意识到“木头”类别也将在螺旋桨下使用 - > airboat - > (木)。这意味着,每次我想在不同的父母下使用它时,都必须重新创建“木头”。这不是世界末日,但我想知道是否有更好的方法来解决这个问题。

此外,我试图让这件事尽可能保持活力,以便客户可以根据需要改变他的目录。

*编辑。正在考虑创建一个“标签”表。所以我可以将标签“wood”或“metal”或“50inch”分配给1到多个项目。我仍然会为主要类别保留一个育儿类型的东西,但这样的类别不会那么深,并且不会有重复。

8 个答案:

答案 0 :(得分:27)

答案 1 :(得分:10)

在数据库中创建层次结构类别模型之前,请先查看this article,它解释了问题和解决方案(使用嵌套集)。

总而言之,使用简单的parent_category_id不能很好地扩展,并且您将很难编写高性能的SQL查询。答案是使用嵌套集,使您可以将多对多类别模型可视化为嵌套在其他集合中的集合。

答案 2 :(得分:4)

如果您希望类别具有多个父类别,那么它只是“多对多”关系而不是“一对多”关系。你需要在类别和它自己之间放置一个桥接表。

然而,我怀疑这是你想要的。如果我正在寻找类别 Aircraft> Wood 然后我不想看到来自 Boating>的项目木。有两个 Wood 类别,因为它们包含不同的项目。

答案 3 :(得分:4)

我的建议

  • 在Item和Category之间建立多对多关系,以便产品可以在许多层次结构节点中显示(在ebay,sourceforge中使用......)
  • 保持类别层次结构

类别层次结构上的效果

如果您的类别层次结构是深度,那么您可以生成“祖先”表。该表将由批处理工作生成,并包含:

  • ChildId(类别的ID)
  • AncestorId(其父母,祖父母的身份......所有祖先类别)

这意味着如果您有3个类别:1-Propeller> 2架飞机> 3号木杆

然后Ancestor表将包含:

ChildId  AncestorId
1        2
1        3
2        3

这意味着要拥有category1的所有子项,您只需要1个查询,而您没有执行嵌套查询。顺便说一下,无论你的类别层次结构的深度是多少,这都无关紧要。

感谢此表,您只需要1个联接来查询某个类别(包含其子级)。

如果您需要有关如何创建Ancestor表的帮助,请告诉我。

答案 4 :(得分:3)

  

在创建分层结构之前   在您的数据库中的类别模型,采取   看一下this article解释   问题和解决方案(使用   嵌套集。)

     

总结一下,使用简单   parent_category_id不能非常扩展   好吧,你会很难过   编写高性能的SQL查询。该   答案是使用嵌套集合   让你想象你的多对多   类别模型作为集合   嵌套在其他集合中。

值得指出的是,“多个类别”的想法基本上是“标记”的工作原理。除了“标记”之外,我们允许任何产品都有许多类别。通过允许任何产品分为多个类别,您允许客户完整能力 通过开始 过滤他们的搜索相信他们需要开始。它可以点击“飞机”,然后点击“木头”,然后点击“涡轮喷气发动机”(或其他)。或者他们可以用Wood开始他们的搜索,并获得相同的结果。

这将为您提供最大的灵活性,客户将享受更好的UX ,但仍允许您维护层次结构。因此,虽然引用的答案建议让类别为M:N到类别,但我的建议是允许产品改为M:N类别。

总而言之,结果大致相同,类别将具有自然层次结构将借出更大的灵活性

我还应该注意,这并不妨碍严格的层次结构。您可以在必要时轻松地在代码中强制执行层次结构(例如,仅在您的初始页面上显示“汽车”,“飞机”和“船只”类别)。它只是将“严格性”转移到您的业务逻辑上,从长远来看,这可能会使其变得更好。

编辑:我刚刚意识到你在答案中已经提到了这一点。我实际上并没有注意到它,但我认为这是你想做的事情。否则,您将两个层次结构系统混合到您的程序中而没有太大的好处。

答案 5 :(得分:2)

我以前做过这个。我建议从标记开始(多对多关系表到产品)。您可以在标签(树或嵌套集,或其他)上构建层次结构关系,这比您的产品容易得多。因为标记是相对自由形式的,所以这也使您能够自然地对人进行分类,然后对某些预期行为进行编码。

例如,我们有像2009-Nov-Special这样的特殊标签。任何此类产品都有资格在该月的首页上显示为特价。所以我们没有必要构建一个特殊的系统来处理我们刚刚使用现有标签系统的首页上的旋转特价。稍后可以增强这些标签以隐藏消费者等等。

同样,您可以使用标记前缀,例如:style:wood mfg:Nike,允许您进行相对复杂的分类和下钻,而不会出现复杂数据库重新洗牌或EAV噩梦的困难,所有这些都在标记系统中为您提供更多灵活地满足用户期望。请记住,用户可能希望以与数据库和业务所有者可能期望的不同的方式导航产品。使用标记系统可以帮助您启用购物界面,而不会影响您的库存或销售跟踪或其他任何内容。

答案 6 :(得分:2)

  

现在,这一切看起来都很精致,直到我意识到“木头”类别也将在螺旋桨下使用 - > airboat - > (木)。这意味着,每次我想在不同的父母下使用它时,都必须重新创建“木头”。这不是世界末日,但我想知道是否有更好的方法来解决这个问题。

如果您的飞机是木结构的,但螺旋桨可能是碳纤维,玻璃纤维,金属,石墨会怎么样?

我定义了一个材质表,并在items表中使用外键引用。如果你想支持多种材料(IE:说有金属重新加强,或螺丝......),那么你需要一个corrollary / lookup / xref表。

MATERIALS_TYPE_CODE

  • MATERIALS_TYPE_CODE pk
  • MATERIALS_TYPE_CODE_DESC

PRODUCTS

  • PRODUCT_ID,pk
  • MATERIALS_TYPE_CODE fk IF 只有一种资料可以关联

PRODUCT_MATERIALS_XREF

  • PRODUCT_ID,pk
  • MATERIALS_TYPE_CODE pk

我还会使用corrollary / lookup / xref表将产品相互关联。产品可能与多种配套产品有关:

KITTED_PRODUCTS

  • PARENT_PRODUCT_ID,fk
  • CHILD_PRODUCT_ID,fk

...它支持层次关系,因为孩子可能是其他人的父母。

答案 7 :(得分:1)

您可以在http://cakeapp.com

轻松测试数据库设计