Программное обеспечение, над которым я работаю, позволяет администраторам создавать настраиваемые поля для хранения произвольной информации о пользователе. Поля хранятся в таблице под названием meta
, а их значения для каждого пользователя хранятся в таблице meta_value
, которая ссылается на таблицы user
и meta
через внешние ключи.
Упрощенное определение таблиц:
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_username` (`username`)
);
CREATE TABLE `meta` (
`id` INT NOT NULL AUTO_INCREMENT,
`key` VARCHAR(120) NOT NULL UNIQUE,
PRIMARY KEY (`id`),
INDEX `idx_key` (`key`)
);
CREATE TABLE `meta_value` (
`id` INT NOT NULL AUTO_INCREMENT,
`value` VARCHAR(120) NOT NULL,
`meta_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`meta_id`) REFERENCES `meta` (`id`),
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
INDEX `idx_value` (`value`)
);
Я реализую функцию поиска, при которой пользователь может искать других пользователей по значениям настраиваемых полей. Поисковый запрос (упрощенный) выглядит так: ?firstName[eq]=Andrew&lastName[eq]=Johnson&cityName[like]=Minneapol
.
Эта строка запроса должна выбирать всех пользователей с полями firstName = 'Andrew'
И lastName = 'Johnson'
И city LIKE 'Minneapol%'
.
Я попробовал очевидное решение:
SELECT `user`.*
FROM `user`
INNER JOIN `meta_value` ON `meta_value`.`user_id` = `user`.`id`
INNER JOIN `meta` ON `meta`.`id` = `meta_value`.`meta_id`
WHERE (
CASE `meta`.`key`
WHEN 'firstName' THEN `meta_value`.`value` = 'Andrew'
WHEN 'lastName' THEN `meta_value`.`value` = 'Johnson'
WHEN 'cityName' THEN `meta_value`.`value` LIKE 'Minneapol%'
END
);
Этот запрос возвращает результаты, где firstName = 'Andrew'
OR lastName = 'Johnson'
OR cityName LIKE 'Minneapol%'
, что не является желаемым результатом.
Я ценю все предложения о том, как чтобы решить эту проблему, или правильный способ сделать это, если я делаю это неправильно.
Обратите внимание, что структура таблицы не высечена в камне и может быть изменена, поэтому, если вы знаете более подходящий способ предложите, пожалуйста, структурировать данные для этой цели.