0

我有一个产品数据库,我想按任意类别进行过滤。举个例子,我经营一个车库。我有一部分产品是汽车。

每辆汽车都应该有一个属性集合,所有汽车都有相同数量和类型的属性;例如颜色:红色,门:2,品牌:福特;在所有汽车上将这些相同的属性设置为不同的值。

直觉告诉我,最好在产品表中添加“颜色”、“门”和“制造”列。

但是:并非表中的所有产品都是汽车。也许我想在汽车页面上列出轮胎。显然,“颜色”和“门”不适用于轮胎。即便如此,如果用户选择 colour=red 作为过滤器,我仍然希望显示轮胎,因为它们缺少颜色属性。

仔细考虑(我真的不是数据库专家,所以如果这种方法很糟糕,我深表歉意)我考虑有一个“属性”列,我可以用任意数量的任意命名的属性填充它,然后使用 SQL 字符串函数来做过滤。如果您仔细计划,我想您甚至可以在这里使用一个位字段。不过,这对我来说似乎很骇人听闻,我很想知道亚马逊等一些较大的网站是如何做到这一点的。

这些方法有什么问题,任何人都可以为我推荐任何替代方案或阐明这个主题吗?

提前致谢

4

2 回答 2

1

您应该阅读有关数据库规范化的信息。将串联字符串用作单个列中的值通常不是一个好主意。我做了一个很小的​​sqlfiddle让你开始玩。这并不能真正解决你所有的问题,但它可能会引导你走向正确的方向。

架构:

CREATE TABLE product (id int, name varchar(200), info varchar(200));
INSERT INTO product (id, name, info) VALUES (100, "Porsche", "cool");
...
INSERT INTO product (id, name, info) VALUES (103, "Tires", "you need them!");


CREATE TABLE attr (id int, product_id int, a_name varchar(200), a_value varchar(200));
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  100, "color", "black");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (2,  100, "doors", "2");
...

一个问题:

SELECT * FROM product INNER JOIN attr ON attr.product_id=product.id 
WHERE attr.a_name="doors" AND attr.a_value = "2"
于 2013-05-03T09:12:18.090 回答
1

任何人在未来阅读这篇文章,我都设法得到了我想要的结果,感谢 luksch 花时间帮助我!!!谢谢!!!

使用此布局:

CREATE TABLE product (id int, name varchar(200));
INSERT INTO product (id, name) VALUES (100, "Red Porsche");
INSERT INTO product (id, name) VALUES (101, "Red Ferrari V8");
INSERT INTO product (id, name) VALUES (102, "Red Ferrari V12");
INSERT INTO product (id, name) VALUES (103, "Blue Porsche");
INSERT INTO product (id, name) VALUES (104, "Blue Ferrari V8");
INSERT INTO product (id, name) VALUES (105, "Blue Ferrari V12");
INSERT INTO product (id, name) VALUES (106, "Snow Tires");
INSERT INTO product (id, name) VALUES (107, "Fluffy Dice");


CREATE TABLE attr (id int, product_id int, a_name varchar(200), a_value varchar(200));

INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  100, "colour", "red");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  101, "colour", "red");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  101, "cylinders", "8");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  102, "colour", "red");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  102, "cylinders", "12");

INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  103, "colour", "blue");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  104, "colour", "blue");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  104, "cylinders", "8");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  105, "colour", "blue");
INSERT INTO attr (id, product_id, a_name, a_value) VALUES (1,  105, "cylinders", "12");

我达到了我想要的结果;这是两件事:

首先,我希望能够按属性选择产品,比如按颜色和圆柱体,但还可以显示任何既没有颜色也没有圆柱体属性的产品,这是我通过以下查询实现的:

SELECT DISTINCT product.id, name, a_value
FROM product 
LEFT JOIN attr 
ON product_id=product.id 
WHERE
(
    (a_name="colour" AND a_value="blue")
    OR
    (a_name IS NULL)
)
AND product.id IN
(
  SELECT product.id
  FROM product 
  LEFT JOIN attr 
  ON product_id=product.id 
  WHERE
  (a_name="cylinders" AND a_value="12")
  OR
  (a_name IS NULL)
)

这列出了所有具有 12 个气缸的蓝色汽车,还列出了轮胎和毛茸茸的骰子,因为它们既没有颜色也没有气缸数。这可以很容易地适应过滤一个属性,或者您可以添加更多 AND / IN 子句以添加更多过滤器

而且我还希望能够列出所有相关属性(我WHERE 1在此示例中使用,但实际上这将WHERE idfolders=?列出与特定文件夹相关的所有属性)

SELECT DISTINCT a_value, a_name 
FROM product 
INNER JOIN attr
ON product_id=product.id
WHERE 1
于 2013-05-08T12:44:02.063 回答