У меня вопрос, связанный с SQL, относительно общей структуры базы данных, которая кажется довольно распространенной.Однажды я придумал это, пытаясь решить проблему, и (позже) я видел, как другие люди делают то же самое (или что-то удивительно похожее), поэтому я думаю, что сама структура имеет смысл.У меня просто возникают проблемы при попытке сформировать определенные запросы к нему.
Идея состоит в том, что у вас есть таблица с "элементами" в ней, и вы хотите сохранить набор полей и их значений для каждого элемента.Обычно это можно сделать, просто добавив столбцы в таблицу элементов, проблема в том, что сами поля (а не только значения) меняются от элемента к элементу.Например, у меня может быть два элемента:
Статья 1
product_id = aproductid
hidden_key = ahiddenkeyvalue
Статья 2
product_id = anotherproductid
address = anaddress
Вы можете видеть, что оба элемента имеют поле product_id (с разными значениями), но данные, хранящиеся для каждого элемента, различны.
Структура в базе данных заканчивается примерно так:
ItemsTable
id
itemdata_1
itemdata_2
...
FieldsTable
id
field_name
...
Итаблица, которая связывает их и заставляет работать
FieldsItemRelationsTable
field_id
item_id
value
Хорошо, когда я пытаюсь сделать что-то, чтовключает в себя только одно значение "динамического поля", нет проблем.Я обычно делаю что-то похожее на:
SELECT i.* FROM ItemsTable i
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id
INNER JOIN FieldsTable f ON f.id = v.field_id
WHERE v.value = 50 AND f.name = 'product_id';
, который выбирает все элементы, где product_id = 50
Проблема возникает, когда мне нужно сделать что-то с несколькими значениями «динамического поля».Скажем, я хочу выбрать все элементы, где product_id = 50 AND hidden_key = 30. Возможно ли это с помощью одного оператора SQL?Я пытался:
SELECT i.* FROM ItemsTable i
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id
INNER JOIN FieldsTable f ON f.id = v.field_id
WHERE (v.value = 50 AND f.name = 'product_id')
AND (v.value = 30 AND f.name = 'hidden_key');
Но он просто возвращает ноль строк.