У меня есть таблицы, как показано ниже;
У меня есть 4 таблицы MySQL, как это;
Таблица 1
========================
id1 | brand | tags
========================
111 | mercedes | xx
-----+-----------+------
222 | mercedes | yy
-----+-----------+------
333 | ford | xx,yy
-----+-----------+------
444 | audi | yy,zz
-----+-----------+------
555 | jaguar | xx,yy,zz
========================
Таблица 2
========================
id2 | model | id1
========================
aaa | s class | 111
-----+-----------+------
bbb | figo | 333
-----+-----------+------
ccc | a6 | 444
-----+-----------+------
ddd | xf | 555
-----+-----------+------
eee | a4 | 444
========================
Таблица3
============
id1 | id3
============
111 | xx
-----+------
222 | yy
-----+------
333 | xx
-----+------
333 | yy
-----+------
444 | yy
-----+------
444 | zz
-----+------
555 | xx
-----+------
555 | yy
-----+------
555 | zz
============
Таблица 4
==================
id3 | tagdetails
==================
xx | description
-----+------------
yy | description
-----+------------
zz | description
==================
Мое намерение — это комбинированный поиск. Я использую PHP + MySQL. Я получаю записи с тегами, которые я даю в качестве входных данных. Например, когда я даю xx
, Я получу mercedes
, ford
а также jaguar
, Когда я даю xx,yy,zz
, я получил jaguar
в одиночестве. Это очень неэффективное решение, когда существует огромное количество записей. Есть ли бесплатное использование существующего аналогичного решения?
Спасибо.
Вы можете использовать SET
столбец для этого типа приложения. При создании столбца указывается список до 64 возможных значений, которые может содержать столбец, однако в базе данных они хранятся в виде двоичного набора битов, поэтому первый элемент равен 1, второй — 2, третий — 4, 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;
Это добавляет столбец в table4 с числовыми значениями для каждого тега и SET
столбец в 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 Вот
Других решений пока нет …