简体   繁体   English

类别和子类别表结构-MySQL

[英]Categories and Subcategories Table Structure - mysql

An admin can create multi category and subcategory. 管理员可以创建多个类别和子类别。

for example what admin can : 例如什么管理员可以:

cat1                            cat2
   ->sub1                         ->sub1
   ->sub2                            ->sub1_1
   ->sub3
      ->sub3_1
      ->sub3_2
         ->sub3_2_1
         ->sub3_2_2
   ->sub4
      sub4_1
   -sub5

I don't know what is the best choice? 我不知道什么是最好的选择? I should a table or two tables ? 我应该一张桌子还是两张桌子?

It's what I know: 这就是我所知道的:

id    title   parent_cat_id

1      cat1        0
2      sub1        1
3      sub2        1
3      sub3        1
4      sub3_1      3
5      sub3_2      3
6      sub3_2_1 5
7      sub3_2_2 5
...  

Categories and sub-categories are both just logical 'categories' so there's no need to implement more than one physical table unless your design has a specific requirement to do so (although I can't think of one right now...). 类别和子类别都只是逻辑上的“类别”,因此除非您的设计有特定要求,否则无需实现多个物理表(尽管我现在不能想到一个...)。

Additionally, there's no need to have a structure specifically for each level in your hierarchy; 另外,不需要为层次结构中的每个级别都专门设计一个结构。 a single table with a self referential join back to the parent at each 'category' (or 'sub-category') level is all you need. 您只需要一个表,就可以在每个“类别”(或“子类别”)级别将具有自引用联接的表返回到父级。

I'm assuming in this example that your categories (or sub-categories) may contain elements so: 在此示例中,我假设您的类别(或子类别)可能包含以下元素:

// categories table 
category_id
category_name
element 
parent_category_id

This solution is elegant and allows for expansion of your hierarchy without changing the table. 该解决方案很优雅,可以在不更改表的情况下扩展层次结构。

DML for top level categories are made with the predicate "parent_category_id IS NULL". 顶级类别的DML使用谓词“ parent_category_id IS NULL”进行。

DML for lower level categories (or sub-categories) are made with the predicate "parent_category_id = 'whatever the parent category ID is'". 使用谓词“ parent_category_id ='无论父类别ID是什么”来制作用于较低级别类别(或子类别)的DML。

Cheers Scott 干杯斯科特

PS I don't have enough rep to respond directory to Sherif's answer, and I might be (read probably am) missing something, but a modified preorder transversal (or nested set) can also be implemented with a single table; PS我没有足够的代表来响应目录对Sherif的回答,我可能(可能读到了)缺少一些东西,但是也可以用单个表实现修改后的预遍历(或嵌套集)。 method and comparison with Adjancey list are described well in this document 方法和与邻接表的比较在本文档中有很好的描述

I do agree with the pros and cons of each method as described by Sherif. 我确实同意Sherif描述的每种方法的利弊。

Best is a relative term, but we can certainly explore the trade-offs of the available solutions to storing hierarchical data structures in a relational DBMS. 最好是一个相对术语,但是我们当然可以探索在关系DBMS中存储分层数据结构的可用解决方案的取舍。 Relational databases tend to be flat structures, because they're typically normalized as 2-dimensional tables, made up of columns interesting with rows. 关系数据库往往是平面结构,因为它们通常被归一化为二维表,由有趣的列组成。 This makes the very idea of a nested structure rather difficult to store in such a database. 这使得嵌套结构的想法很难存储在这样的数据库中。

There are two common ways to store this type of data in your relational database. 有两种常见的方法将这种类型的数据存储在关系数据库中。 Specifically, as an adjacency list , or using modified preorder traversal . 具体来说,作为邻接表 ,或使用修改的预遍历

  • Adjancey list approach 邻接表方式

    • Pros 优点

      • Easy to implement and understand 易于实施和理解
      • You can easily migrate a large sub category into another parent 您可以轻松地将较大的子类别迁移到另一个父类别
      • No huge cost of writes to the database no matter how large the structure grows 无论结构增长多大,都不会对数据库进行大量写入
    • Cons 缺点

      • A lot more expensive to read ( requires a lot of iteration/recursion to rebuild the structure ) 读取成本高得多( 需要大量的迭代/递归才能重建结构
      • Easy to break your data in SQL (SQL doesn't do recursion) 易于在SQL中破坏数据(SQL不执行递归)
  • Using preorder traversal 使用预遍历

    • Pros 优点

      • Easier to find all parents in SQL 在SQL中更容易找到所有父母
      • Easier to not break the data in SQL 更容易不破坏SQL中的数据
      • Cheaper to build the entire tree 便宜地建造整棵树
    • Cons 缺点

      • Slightly harder to implement 实施起来有点困难
      • Cost of insertion/update grows as the structure deepens 插入/更新的成本随着结构的加深而增加

Now, in your case specifically, it doesn't matter if you have the title column in the table that stores your id and parent_id , because you depend entirely on the primary key of the parent_id . 现在,你的情况而言,这并不重要,如果你有title中存储你的表列idparent_id ,因为你的主键完全取决于parent_id

The adjacency list approach is similar to the one you're stating in your question. 邻接表方法与您在问题中说明的方法类似。 You don't need two tables to do that, because you use the id and parent_id fields as an adjacency list to compose and decompose the structure. 您不需要两个表来执行此操作,因为您使用idparent_id字段作为邻接表来构成和分解结构。

The preorder traversal does require using two tables (one to store the categery name or title in your case, and one to store the relationship of a parent to its children). 预先遍历确实需要使用两个表(一个用于存储案例名称或title ,另一个用于存储父级与其子级之间的关系)。 Instead of storing the id , and parent_id in each row, you need to store the left and right child nodes of every parent node. 而不是存储的id ,并parent_id每一行中,你需要存储的leftright的每个父节点的子节点。

categories table
----------------
id    title
1     cat1
2     subcat1_1
3     subcat1_2
4     subcat1_2_1



Relationship table
------------------
parent_id      left      right
------------------------------
1              2         3
3              4         NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM