2009-09-01 11 views
0

J'ai 3 tables.Comment mettre à jour une table relationnelle?

utilisateurs (id, courrier, nom d'utilisateur, etc ..)

pratiques (id, nom)

UsersPractices (userId, practiceId)

Le dernier est la table relationnelle qui est nn .

Je voudrais mettre à jour celui-ci, en fonction de la volonté de l'utilisateur.

Cela veut dire qu'il pourrait vouloir ajouter ou supprimer certaines de ses pratiques.

Quel algorithme pourrais-je utiliser pour faire ceci?

Devrait-il être préférable de laisser ce travail (s'il y a un moyen) au moteur de base de données? Ou devrais-je écrire mon propre algorithme pour gérer les données, puis faire mes demandes à la base de données?

EDIT:

Pour être clair:

___________________________ 
| UserId | PracticeId | 
|-----------|-------------| 
| 12  |  21  | 
|-----------|-------------| 
| 12  |  18  | 
|-----------|-------------| 

Peut-être, l'utilisateur essaiera de changer sa pratique 21-15, mais veut garder la pratique 18.

Donc, , à partir de la requête, j'obtiendrai practices = array (15,18);

cela signifie que la pratique des utilisateurs ressemblera:

___________________________ 
| UserId | PracticeId | 
|-----------|-------------| 
| 12  |  15  | 
|-----------|-------------| 
| 12  |  18  | 
|-----------|-------------| 

SO quelle est la meilleure façon d'y parvenir?

Devrais-je sélectionner & vérifier chaque exercice, puis supprimer si nécessaire?

Supprimez-les tous et ajoutez les nouvelles.

+0

Je ne sais pas exactement ce que vous demandez ici? – Amber

Répondre

2

En supposant que vous avez des tables InnoDB, faites-le comme une transaction.

L'idée de base ici est d'effacer l'ardoise puis de créer/recréer les associations. Cela est plus facile que de déterminer le delta de chaque mise à jour (c'est-à-dire inspecter chaque rangée individuellement et déterminer s'il s'agit d'une action INSERT, UPDATE ou DELETE).

Voici le SQL cru que vous utilisez

BEGIN; 

DELETE FROM UsersPractices 
WHERE userId = [User ID]; 

INSERT INTO UsersPractices (
     userId 
    , practiceId) 
VALUES ([User ID], [Practice ID 1]) 
    , ([User ID], [Practice ID 2]) 
    ... 
    , ([User ID], [Practice ID N]); 

COMMIT; 
+0

C'est ce que j'ai supposé, à l'exception de la transaction, qui peut effectivement être intéressante ici. –

+0

La transaction est importante pour que ce modèle fonctionne. Il transforme ce processus en plusieurs étapes en une unité atomique - si une partie échoue, toute la transaction échoue, vous empêchant ainsi d'effacer de façon irréversible l'adat de quelqu'un. Mais vous ne pouvez pas le faire avec les tables MyISAM. –

1

Consultez Doctrine (http://www.doctrine-project.org/). C'est un framework Object Relational Mapper (ORM) pour PHP. Il peut facilement gérer ce que vous voulez accomplir.

+0

Je n'utilise pas Doctrine, mais Zend Framework, qui a une implentation différente. –

+1

Vous n'avez pas besoin d'utiliser le composant 'Zend_Db_Table'. Vous pouvez utiliser Doctrine à la place même dans une application Zend Framework. –

+0

Doctrine * devrait * jouer avec ZF, si vous essayez de l'ajouter à votre projet. D'après ce que je sais, ZF manque d'ORM. Donc, vous pouvez soit rouler votre propre solution, ou aller avec un pré-fait. Voici un article sur la façon de combiner les deux: http://ruben.savanne.be/articles/integrating-zend-framework-and-doctrine –

0

bien - la meilleure façon que je pouvais penser à gérer ce genre de chose serait de construire un quelque chose comme élément <select> ceci:

function getUserPractices($userId) { 
    $data = array(); 
    $result = mysql_query("SELECT Practices.* FROM UsersPractices LEFT JOIN Practices on UsersPractices.practiceId = Practices.id WHERE userId = '".mysql_real_escape($userId)."'"); 
    while ($row = mysql_fetch_array($result)) { 
    $data[$row['id']] = $row['name']; 
    } 
    return $data; 
} 

// assuming $user is your user row... 
$user_practices = getUserPractices($user['id']); 
$result = mysql_query("SELECT * FROM Practices ORDER BY name"); 
echo "<select multiple='multiple' name='practices[]'>"; 
while ($row = mysql_fetch_assoc($result)) { 
    echo "<option value='".$row['id']."'"; 
    if (isset($user_practices[$row["id"]])) echo " selected='selected'"; 
    echo ">".htmlentities($row['name'])."</option>"; 
} 
echo "</select>"; 

// This should result in an array $_POST['practices'] that contains practiceId's 
// will come back to write more about actually inserting the change into the db 
// but simplest way is to delete all of them based on userId then insert the new ones 
1

Si vous exécutez des instructions SQL directement à l'aide de l'adaptateur Zend_Db, vous pouvez générer une requête UPDATE en fonction des choix que l'utilisateur souhaite effectuer.Par exemple:

$db->query('UPDATE UsersPractices 
    SET practiceId = 
     CASE practiceId 
     WHEN 21 THEN 15 
     ELSE practiceId 
     END 
    WHERE userId = ?', 
    array($userId)); 

Cela changerait practiceId-15 uniquement sur la ligne où est practiceId 21. Sur les autres lignes, il n'y aurait aucun changement à la colonne practiceId.

+0

C'est intéressant, mais il semble que ce sera difficile à gérer, parce que je vais devoir faire un select, pour récupérer les pratiques existantes, puis, en utilisant votre requête, mettre à jour et vérifier. Merci quand même, cela pourrait être utile dans un futur proche. –

+0

Vous devrez effectuer une sélection pour obtenir les données actuelles, quelle que soit la solution utilisée. –

Questions connexes