简体   繁体   中英

How to update a relational table?

I've 3 tables.

Users (id, mail, username, etc..)

Practices (id, name)

UsersPractices (userId, practiceId)

The last one is the relational table which is nn.

I'd like to update this one, depending on the user's will.

It means, that he could want to add, or remove some his practices.

What algorithm could i use to do this ?

Should it be better to let this job (if there is a way) to the database engine ? Or should i write my own algorithm to handle the data, then do my requests to the db ?

EDIT:

To be clear :

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

Maybe, the user will try to change his practice from 21 to 15 but wants to keep the practice 18.

So, from the request, i'll get practices = array(15,18);

that means the users practice will look like :

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

SO what is the best way to achieve this ?

Should i select & check each practice, and then, delete if needed ?

Delete them all, and add the news.

Assuming you have InnoDB tables, do it as a transaction.

The basic idea here is to wipe the slate clean and then create/re-create the associations. This is easier than determining the delta of each update (ie, inspecting each row individually and determining if it's an INSERT, UPDATE, or DELETE action).

Here's the raw SQL you would use

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;

Check out Doctrine ( http://www.doctrine-project.org/ ). It's an Object Relational Mapper (ORM) framework for PHP. It can easily handle what you want to accomplish.

If you're executing SQL statements directly using the Zend_Db adapter, you could build an UPDATE query based on the choices the user wants to make. For example:

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

This would change practiceId to 15 only on the row where practiceId is 21. On other rows, it would make no change to the practiceId column.

Well - the easiest way I could think of to handle this sort of thing would be to build a <select> element something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM