CI: запрос двух таблиц в модели, разнесение

Я думаю об этом уже несколько дней и не понимаю (поскольку я относительно новичок в MVC и CI). Я даже не уверен, что это проблема с MVC, MySQL или массивами.

Ситуация: 2 таблицы MySQL

  1. Таблица данные: идентификатор, заголовок, список
  2. Табличные значения: идентификатор, имя

Запрос к таблице data приводит к массиву, подобному следующему (отрывок):

[4] => Array
        (
            [id] => 3
            [title] => Foo                
            [list] => 1,2,3,4,6,14
        )

[5] => Array
        (
            [id] => 4
            [title] => Bar                
            [list] => 2,6,9,12
        )

Поле list содержит значения, разделенные запятыми, которые соответствуют некоторым идентификаторам таблицы values, например

[3] => Array
            (
                [id] => 12
                [name] => 'value12'                
            )

Что я пытаюсь сделать для каждой строки:

  • взять список-values ​​и взорвать его в массив
  • проверить набор результатов из таблицы values (через метод in_array())
  • вернуть значения имен идентификаторов, если
  • включите его каким-либо образом в основной набор результатов (например, в виде двумерного массива):

    [5] => Массив ( [id] => 4 [title] => Bar [list] => Array ( [0] => value6 [1] => value12 ... ) )

Мой наивный подход до сих пор состоял в том, чтобы

  • выполнить запрос для каждой из двух таблиц
  • сравните 2 набора результатов через in_array

Моя основная проблема (при попытке строго разделить модель, контроллер и представление): как я могу включить поле имени из таблицы значений в «основной цикл» набора результатов таблицы data?

if($q->num_rows() > 0)
{
    $data[] = $q->result_array();
    foreach ($q->result() as $row)
    {
        $data[] = $row;
    }
    return $data;
}

Если я использую следующий (громоздкий) подход, я, естественно, каждый раз получаю новый элемент:

foreach ($q->result_array() as $row) 
{
    $data[]['id'] = $row['id'];
    $data[]['title'] = $row['title'];
    $data[]['list'] = $row['year'];
}

Поскольку это база данных MySQL, я не вижу возможности выполнить анализ и сравнение в SQL (с помощью LIKE или чего-то еще).

Любая подсказка, даже простая ссылка на информационный бит, высоко ценится.

Триллион спасибо!

потрясающий


person Fab Ian Fuerste    schedule 01.12.2010    source источник


Ответы (1)


Между списками и значениями списка существует отношение «многие ко многим». Обычный способ смоделировать это в реляционной базе данных — создать соединительную таблицу. Поэтому я бы структурировал вашу схему следующим образом.

lists : list_id, title
values : value_id, name
list_values : list_id, value_id

list_values — это соединительная таблица. Он связывает списки со значениями.

Чтобы создать список, в вашей модели могут быть следующие функции.

function build_list($list_id)
{
    $list = $this->get_list($list_id);
    $list->values = $this->get_list_values($list_id);
    return $list;
}

function get_list($list_id)
{
    $sql = 'select * from lists where list_id=?';
    return $this->db->query($sql, array($list_id))->row();
}

function get_list_values($list_id)
{
    $sql = 'select v.value_id, v.name
        from list_values lv
        join values v on v.value_id=lv.value_id
        where lv.list_id=?';
    return $this->db->query($sql, array($list_id))->result();
}
person Stephen Curran    schedule 01.12.2010
comment
Абсолютно. Всякий раз, когда вы думаете о сохранении списка идентификаторов, разделенных запятыми, в столбце таблицы, это явный признак того, что вы, вероятно, делаете что-то не так. - person Matt Gibson; 01.12.2010
comment
Вы, ребята, абсолютно правы. конечно, отношения многие-ко-многим всегда с таблицей соединений! большое спасибо. - person Fab Ian Fuerste; 01.12.2010