我的表格如下;
我有4个MySQL表;
table1
========================
id1 | brand | tags
========================
111 | mercedes | xx
-----+-----------+------
222 | mercedes | yy
-----+-----------+------
333 | ford | xx,yy
-----+-----------+------
444 | audi | yy,zz
-----+-----------+------
555 | jaguar | xx,yy,zz
========================
table2
========================
id2 | model | id1
========================
aaa | s class | 111
-----+-----------+------
bbb | figo | 333
-----+-----------+------
ccc | a6 | 444
-----+-----------+------
ddd | xf | 555
-----+-----------+------
eee | a4 | 444
========================
table3
============
id1 | id3
============
111 | xx
-----+------
222 | yy
-----+------
333 | xx
-----+------
333 | yy
-----+------
444 | yy
-----+------
444 | zz
-----+------
555 | xx
-----+------
555 | yy
-----+------
555 | zz
============
table4
==================
id3 | tagdetails
==================
xx | description
-----+------------
yy | description
-----+------------
zz | description
==================
我的意图是组合搜索。我使用php mysql。我正在用标签作为输入来获取记录。例如,当我给出xx
时,我将获得mercedes
,ford
和jaguar
。当我给出xx,yy,zz
时,我单独得到jaguar
。当有大量记录时,这是一个非常低效的解决方案。是否可以免费使用现有类似解决方案?
谢谢。
您可以将SET
列用于此类型的应用程序。创建列时,您指定了该列可以包含的最多64个可能值的列表,但是在数据库中,这些列表被存储为二进制位集,因此第一个项目为1,第二项为2,第三为4、8、8、16,32等
您可以通过名称或数字访问它们,并使用LIKE
对文本值或使用所有位操作员进行搜索。稍微设置的美之处在于,标签的所有可能组合都将具有唯一的数字。如果xxx = 1
和yyy = 2
,则具有两个遗嘱标签的汽车将= 3
。
假设您在此处发布的表结构是准确的,那么以下内容将添加必要的列并计算所有内容的值:
SELECT @tags:= GROUP_CONCAT(id3 SEPARATOR '", "') FROM table4;
SET @s = CONCAT('ALTER TABLE table1 ADD tagset SET("', @tags, '")');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
ALTER TABLE table4 ADD tags int NULL;
SET @tags:= NULL;
UPDATE table4 SET tags = (SELECT (@tags:= IF(@tags IS NULL, '1', @tags * 2)));
UPDATE table1 SET tagset = tags;
这将每个标签的数字值和一个SET
列添加到Table4中,并使用正确的标签设置为Table1。然后,您构建您的查询以根据标签名称计算正确的值。
SELECT * FROM table1 WHERE tagset = (SELECT SUM(tags) FROM table4 WHERE id3 IN ('xx', 'yy'));
// Using '=' will only return matches with tag xx and yy exactly
SELECT * FROM table1 WHERE tagset & (SELECT SUM(tags) FROM table4 WHERE id3 IN ('xx'));
// Using '&' will return all matches with xx
所有其他位比较操作员都可以使用。更多信息在这里和这里
这里有一个演示sqlfiddle