Отказ от ответственности: я не знаком с PHP или CodeIgniter, но готов утверждать, что ни один из них не имеет какой-либо встроенной поддержки EAV. При этом я много знаю о EAV, поэтому отвечу в этом свете.
Когда вы пишете о поиске определенного значения, я предполагаю, что вы также имеете в виду конкретное поле. Итак, с учетом сказанного, поместите данные в XML CLOB вне таблицы форм (например, данные) и используйте функции MySQL MySQL для поиска по нему. Серьезно. Допустим, XML выглядит так:
<data>
<field id="[field_id]">value</field>
</data>
Ищите как таковой:
SELECT f.form_id
FROM
form f
WHERE
f.form_id = ?
AND ExtractValue(data, '//field[@id="[field_id]"]') = ?
Почему? Проблема заключается в том, что поиск нескольких критериев по модели EAV является сложной задачей. Рассмотрим этот пример:
SELECT f.form_id
FROM
form f
INNER JOIN form_fields f1 ON f1.form_id = f.form_id
INNER JOIN form_fields f2 ON f2.form_id = f.form_id
WHERE
f.form_id = ?
AND
(f1.field_id = ? AND f1.field_value = ?)
AND
(f2.field_id = ? AND f2.field_value = ?)
Все это выглядит хорошо и хорошо, теперь измените И на ИЛИ, и все вырвется на свободу.
SELECT f.form_id
FROM
form f
INNER JOIN form_fields f1 ON f1.form_id = f.form_id
INNER JOIN form_fields f2 ON f2.form_id = f.form_id
WHERE
f.form_id = ?
OR
(f1.field_id = ? AND f1.field_value = ?)
OR
(f2.field_id = ? AND f2.field_value = ?)
Вы видите проблему? INNER JOIN в предложении FROM означает, что записи будут возвращаться независимо от того, какие данные будут возвращены независимо от предложения WHERE. Таким образом, вместо JOIN в предложении FROM + WHERE, EAV требует EXISTS в предложении WHERE:
SELECT f.form_id
FROM
form f
WHERE
f.form_id = ?
AND (
EXISTS (
SELECT f1.form_id FROM form_fields f1
WHERE f1.field_id = ? AND f1.field_value = ? AND f1.form_id = f.form_id
)
-- note OR search
EXISTS (
SELECT f2.form_id FROM form_fields f2
WHERE f2.field_id = ? AND f2.field_value = ? AND f2.form_id = f.form_id
)
)
Как-то некрасиво да? Это и производительность подзапросов MySQL не очень хороши. Добавьте желание искать определенные типы данных, такие как даты и целые числа, и вы либо выполняете кастинг, либо работаете с несколькими столбцами в таблице form_field (например, field_date_value, field_int_value и т. д.).
Таким образом, XML CLOB означает только таблицу, которую следует учитывать при запросе, а также возможность использования многозначных атрибутов (на ум приходят множественные выборки или флажки).
person
orangepips
schedule
02.01.2011