Как создать несколько записей по индексу на основе полей одной строки?
-
16-10-2019 - |
Вопрос
Я никогда не находил хорошего способа индексировать несколько полей одной строки в качестве записей индекса или имитировать эту функцию на MySQL.
Проблема возникает, когда у вас есть поля, работающие в качестве тегов или аналогичной концепции. Пример: поля имена как TAG1, TAG2, TAG3. Для поиска строк с определенным тегом быстро требуется, чтобы у вас было 3 индекса и выполнить 3 отдельных запроса по самым основным и очевидным способам.
Есть ли способ индексировать эти 3 поля в качестве записей одного индекса, позволяя только один поиск.
ID tag1 tag2 tag3
-- ---- ---- ----
01 abc xyz bla
02 foo bar ble
03 xyz bla bar
index
abc -> 01
bar -> 02 03
bla -> 01 03
ble -> 02
foo -> 02
xyz -> 01 03
Или есть другой способ сделать это эффективно?
Решение
Если я правильно понимаю, этот запрос должен работать:
SELECT id FROM testTag WHERE LOCATE('bar', CONCAT(tag1,'.',tag2,'.',tag3)) > 0;
Учитывая эту структуру таблицы:
CREATE TABLE `testTag` (
`id` int(11) NOT NULL,
`tag1` varchar(10) DEFAULT NULL,
`tag2` varchar(10) DEFAULT NULL,
`tag3` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tags` (`tag1`,`tag2`,`tag3`)
) ENGINE=InnoDB
mysql> EXPLAIN SELECT id FROM testTag WHERE LOCATE('bar', CONCAT(tag1,'.',tag2,'.',tag3)) > 0;
+----+-------------+---------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------+---------+------+------+--------------------------+
| 1 | SIMPLE | testTag | index | NULL | tags | 39 | NULL | 15 | Using where; Using index |
+----+-------------+---------+-------+---------------+------+---------+------+------+--------------------------+
Другие советы
Каждый раз, когда у вас есть число с нумерованным полем, вы не нормализовали свои таблицы. Скорее всего, у меня есть таблица «тега», которую я мог бы тогда присоединиться к тому, что я помечаю:
ID tag
-- ---
01 abc
01 xyz
01 bla
02 foo
02 bar
02 ble
03 xyz
03 bla
03 bar
(С первичным ключом является многоколонный, и существует дополнительный индекс на любом месте, которое является вторым полем в многоцелевом индексе)
Вы всегда можете добавить столбец «порядка», если необходимо, чтобы теги были в определенном порядке.