Модель значения атрибута объекта с использованием codeigniter / php - PullRequest
0 голосов
/ 21 декабря 2010

ТАК Я пытаюсь создать способ структурировать свою базу данных, чтобы иметь возможность настраивать формы.

Я изучил шаблон EAV и вот моя структура БД:

Форма стола - form_id - form_name - form_added_on - form_modified_at

Таблица: поля формы - field_id - form_id - field_type (TEXT, RADIO и т. д.) - field_default_value - field_required

Таблица: form_data - data_id - field_id - form_id - field_value

так что теперь я могу сохранить любую произвольную форму в базе данных, и если я хочу получить значения для отдельной формы, я могу просто присоединиться к ней с помощью "form_id" ..

проблема:

Я хочу иметь возможность искать во всех формах определенное значение поля.

Как я могу сделать это с моделью EAV?

Кроме того, я подумал о том, чтобы просто хранить пользовательские данные в виде сериализованного (JSON) объекта, но потом я не уверен, как можно запросить эти данные.

Обратите внимание, что я использую Codeigniter с MYSQL. Так что, если разговор может использовать библиотеки Codeigniter, если это необходимо.

Ответы [ 3 ]

3 голосов
/ 02 января 2011

Отказ от ответственности : я не знаю PHP или CodeIgniter, но я бы хотел заявить, что ни у одного из них нет встроенной поддержки EAV.Тем не менее, я знаю много о EAV, поэтому я отвечу в этом свете.

Когда вы пишете о поиске определенного значения, я предполагаю, что вы имеете в виду и в конкретном поле.Итак, с учетом сказанного поместите данные в XML CLOB вне таблицы форм (например, в данные) и используйте функции MySQL XML для поиска по ним.Шутки в сторону.Допустим, 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 = ?)

Все это выглядит хорошо и хорошо, теперь измените AND на ИЛИ и весь ад вырвется на свободу.

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 означает только таблицу, которую следует учитывать при запросах, а также возможность многозначных атрибутов (на выбор приходят множественные выборки или флажки).

1 голос
/ 29 декабря 2010

По вашему вопросу похоже, что вы должны получить идентификатор формы, когда у вас есть тип поля формы и значение поля -

Для достижения этой цели вы можете попробовать следующий запрос -

Сначала запустите этот запрос, чтобы получить все идентификаторы формы с определенным типом поля =

    $sql = "SELECT ff.form_id from form_fields ff where ff.field_type = 'The field type you are searching for'";

    $result = $this->db->query($sql);

    $form_ids = $result->result_array();

Теперь вы можете использовать этот массив во втором запросе, чтобы получить окончательный результат, как показано ниже -

    $this->db->select('fd.form_id');
    $this->db->from('form_data fd');
    $this->db->where('fd.field_value','your field value');
    $this->db->where_in('fd.form_id',$form_ids);
    $required_form_id = $this->db->get();

поэтому в переменной $required_form_id у вас будет требуемый идентификатор формы.

Я предлагаю использовать перечисление для столбца field_type в таблице form_fields.

Надеюсь, это поможет вам.

0 голосов
/ 28 декабря 2010

Прежде всего, поле form_id в вашей таблице form_data представляется избыточным.Каждая запись form_data ссылается на запись form_fields (через field_id), а каждая запись form_fields ссылается на запись формы (через form_id).Поэтому вам не нужно помещать form_id в таблицу form_data.

Похоже, у вас возникли следующие вопросы: как получить значение form_id на основе определенного значения field_value?

Вот простой SQLзапрос, который должен сделать трюк:

SELECT f.form_id FROM form_data d 
JOIN form_fields f USING(field_id) 
WHERE d.field_value = '??????'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...