数据库体系结构,用于从父类别中检索存储在子类别中的项目

时间:2011-12-09 06:08:57

标签: php mysql data-structures hierarchy

未能找到this问题的解决方案我想知道是否有更好的方法来存储此问题的数据。

该db结构允许项目存储在多个类别中,但不允许轻松访问父类别层次结构。

我想要的是一个类别关系,例如:

Books 
  > Novels
    > Paperbacks
    > Hardbacks

并且有一个项目存储在Paperbacks中,例如也会出现在小说和书籍中。因此,“类别”实际上更像过滤器而不是实际类别。

1 个答案:

答案 0 :(得分:2)

首先,您需要使用Nested Set架构设计类别表。使用嵌套集您可以轻松选择整个分类分类,然后您就可以选择这些类别的产品。

所以第一个表将是:

CREATE TABLE categories (
  id int unsigned NOT NULL auto_increment,
  name varchar(255) NOT NULL,
  left int unsigned NOT NULL,
  right int unsigned NOT NULL,
  PRIMARY KEY (id)
);

第二个表格是:

CREATE TABLE products (
  id int unsigned NOT NULL auto_increment,
  name varchar(255) NOT NULL,
  PRIMARY KEY (id)
);

第三个表格将是:

CREATE TABLE product_categories (
  category_id int unsigned NOT NULL,
  product_id int unsigned NOT NULL,
  PRIMARY KEY (category_id, product_id)
);

现在要为整个分类分类选择所有产品,您需要使用如下查询:

SELECT p.*
  FROM categories AS c1
  LEFT JOIN categories AS c2 ON c1.left <= c2.left AND c2.right <= c1.right
  LEFT JOIN product_categories AS pc ON pc.category_id = c2.id
  LEFT JOIN products AS p ON pc.product_id = p.id
 WHERE c1.id = @id

嵌套集合操作

添加新节点

第一步:更新已存在的类别

UPDATE categories 
   SET right = right + 2, left = IF(left > @right, left + 2, left) 
 WHERE right >= @right

第二步:插入新类别

INSERT INTO categories SET left = @right, right = @right + 1, name = @name

删除现有节点

第1步:删除节点

DELETE FROM categories WHERE left >= @left AND right <= @right

第二步:更新其他节点

UPDATE categories 
   SET left = IF(left > @left, left – (@right - @left + 1), left), 
       right = right – (@right - @left + 1) 
 WHERE right > @right