我有一堆产品和一堆类别页面。一种产品可以分为多个类别。所以在我的数据库中,我有一个带有“类别”列的产品表。在此列中,我存储了当前产品存储的所有类别的ID,它是一个用分号分隔的字符串。
示例:1;5;23;35;49;
。
当我浏览到类别页面ID 5时,我想查看其category-column中包含5;
的所有产品。我目前通过
SELECT * FROM products WHERE categories LIKE "%".category.";%"
问题是这不仅仅匹配5.它匹配15;
或25;
。
所以问题:
答案 0 :(得分:1)
其他人提到过联结表是设计数据库的正确方法。 SQL有一个非常好的数据结构用于存储列表。它不被称为“字符串”,它被称为“表”。
但是,有时人们会坚持使用这种格式的数据,并且需要使用它。在这种情况下,关键是将分隔符放在两边以防止出现问题:
SELECT *
FROM products
WHERE concat(';', categories) LIKE "%;".category.";%"
您的列表已经以分号结尾,因此没有必要。
另一个更典型的MySQL解决方案是find_in_set()
:
SELECT *
FROM products
WHERE find_in_set(category, replace(categories, ';', ',') > 0;
它专为逗号分隔的列表而设计。奇怪的是MySQL在以这种方式存储列表时支持这样的功能通常是一个坏主意,但确实如此。不过,出于性能原因(以及其他原因),联结表更好。
答案 1 :(得分:0)
回答/评论你的两个问题:
我能想到的唯一可以在不修改模式的情况下执行此操作(参见#2)的方法是使用MySQL正则表达式,但这不是一个好主意。有关文档,请参阅http://dev.mysql.com/doc/refman/5.1/en/regexp.html
你是对的 - 这不是存储类别的好方法。你想要的是一个连接,也称为连接表(见http://en.wikipedia.org/wiki/Junction_table)。一种方法是拥有三个表:product
,category
和product_categories
表。产品和类别将具有您已有的唯一ID,product_categories表将包含两列:product_id和category_id。如果产品1属于类别10和11,那么product_categories表中将有两行:1,10和1,11。
如果您需要更多帮助,我可以详细说明,但这应该让您开始正确地重新构建数据库(更多)。
答案 2 :(得分:-2)
您可以尝试将喜欢的条件更改为“%;”。category。“;%”