2010-12-01 41 views
0

Je pense à cela depuis des jours et ne viens pas à saisir (depuis que je suis relativley nouveau à MVC et CI). Je ne suis même pas sûr que ce soit un problème avec MVC, MySQL ou les tableaux.CI: Interrogation de deux tables dans le modèle, exploser

Situation: 2 tables MySQL

  1. Tableau données: id, titre, liste
  2. Tableau valeurs: id, nom

Interrogation la données tableau résultats dans un tableau comme le suivant (extrait):

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

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

Le champ liste contient des valeurs séparées par des virgules qui correspondent à certains ID de la table des valeurs comme

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

Ce que j'essaie de faire pour chaque ligne est:

  • prendre la liste -values ​​& l'exploser en un tableau
  • contrôle avec le jeu de résultats à partir des valeurs -table (via in_array() méthode)
  • retour, les valeurs de nom de l'ID si
  • comprennent en quelque sorte dans le résultat principal défini (par exemple, un tableau à 2 dimensions):

    [5] => Array ( [id] => 4 [title] => Bar [list] => Array ( [0] => valeur6 [ 1] => value12 ... ) )

Mon approche naïve jusqu'à présent était de

  • exécuter une requête sur chacun des 2 tables
  • comparer les deux ensembles de résultats par in_array

Mon principal problème (tout en essayant de modèle strictement séparé, contrôleur et vue): Comment puis-je inclure le champ Nom de la valeur-table dans la « boucle principale "du data jeu de résultats de table?

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

Si j'utilise l'approche suivante (lourde) je reçois naturellement un nouvel élément à chaque fois:

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

Depuis c'est une base de données MySQL Je ne vois aucune façon de faire l'exploser et la comparaison SQL (avec LIKE ou autre chose).

Tout indice, même un simple lien vers un bit d'information, est très apprécié.

Merci un billion!

fabuleux

Répondre

1

Il y a un grand nombre à plusieurs entre les listes et les valeurs de la liste. La façon classique de modéliser cela dans une base de données relationnelle est de créer une table de jointure. Donc, je structurerais votre schéma comme ça.

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

list_values est la table de jointure. Il relie les listes avec des valeurs.

Pour construire une liste, vous pouvez avoir les fonctions suivantes dans votre modèle

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(); 
} 
+0

Absolument. Chaque fois que vous songez à stocker une liste d'identifiants séparés par des virgules dans une colonne d'une table, c'est un signal fort que vous faites probablement quelque chose de mal. –

+0

Vous avez absolument raison. plusieurs-à-plusieurs-relations toujours avec une table de jointure, bien sûr! Merci beaucoup. –