Hierarchical Data in MySQL

后端 未结 8 1476
南笙
南笙 2020-12-04 22:57

I\'ve got a sort of tree like thing going on in my MySQL database.

I have a database that has categories, and each category has a subcat. I\'m keeping all the catego

相关标签:
8条回答
  • 2020-12-04 23:34

    This thread may help: http://forums.mysql.com/read.php?10,32818,32818#msg-32818

    What you really want is START WITH and CONNECT BY syntax, but this is only supported in Oracle, not MySQL.

    0 讨论(0)
  • 2020-12-04 23:35

    I'm assuming you know how to get the ID number and that's not the point of the question. Also, parent_id should also be a FK referencing id, and I would use NULL for the topmost layer, not 0.

    If your top-most categories have at most one level of sub-category, you can use this query to get all Toys:

    SELECT *
    FROM items
    WHERE items.category_id IN (SELECT id FROM categories
                                WHERE categories.parent_id = 1
                                OR categories.id = 1);
    

    If your categories can have nested sub-categories, you'll have to use a stored procedure and call it recursively. Pseudocode:

    Procedure getItemsInCategory
    Input: @category_id integer
    Output: items rows
    {
        For each item in (SELECT *
                          FROM items
                          WHERE items.category_id = @category_id):
            return the row;
    
        For each id in (SELECT id 
                        FROM categories
                        WHERE categories.parent_id = @category_id):
            return the rows in getItemsInCategory(id);
    }
    
    0 讨论(0)
  • 2020-12-04 23:39
    1. Use the IN operator.
    2. Use a stored procedure.
    3. Optimise your tables to better reflect how they tend to get used.
    0 讨论(0)
  • 2020-12-04 23:47

    But if I had like 10 categories under Toys, then I'd have to do this join and query 10 times. Is there a better way to handle this?

    Yes, there's a way of storing data called "nested sets". It's a bit harder to insert the data, but simple to select an entire, multi-level branch using a single select statement.

    Also, Celko has written a book about this subject, with a chapter about nested sets and other chapters about other methods.

    0 讨论(0)
  • 2020-12-04 23:48

    I am not familiar with MySQL, but here is the way I would do it in TSQL (SQL SERVER), maybe try to find an equivalent way of doing it in MySQL?

    1) Loop through all categories to get the children for the specific item, in this case categorie id = 1

    2) Filter the items to that relating to the children in the Hierarchy CTE(Common Table Expression).

    With Hierarchy As
    (
    
    SELECT    id, name, parent_id
    from         categories
    where        id = 1
    UNION ALL
    SELECT      child.id, child.name, child.parent_id
    from           categories child
    inner join  Hierarchy parent on child.parent_id = parent.id
    )
    SELECT * FROM items
    WHERE category_id IN 
    (
       Select id
       from Hierarchy 
     )
    
    0 讨论(0)
  • 2020-12-04 23:54

    Assuming you know the id of the Toys category, and nothing is in the top-level Toys category:

    SELECT * FROM items WHERE category_id IN (SELECT id FROM categories WHERE parent_id = 1)
    
    0 讨论(0)
提交回复
热议问题