如何更新关系表?

时间:2009-09-01 19:41:31

标签: php mysql database algorithm zend-framework

我有3张桌子。

用户(身份证,邮件,用户名等)

实践(id,name)

UsersPractices(userId,practiceId)

最后一个是关系表,它是n-n。

我想根据用户的意愿更新这个。

这意味着,他可能想要添加或删除他的一些做法。

我可以用什么算法来做这件事?

让这项工作(如果有办法)到数据库引擎更好吗? 或者我应该编写自己的算法来处理数据,然后向db发出请求吗?

修改

要明确:

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

也许,用户会尝试将他的练习从21改为15,但是希望保持练习18。

因此,从请求中,我将获得practice = array(15,18);

这意味着用户练习将如下所示:

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

那么实现这一目标的最佳途径是什么?

我应该选择&检查每个练习,然后在需要时删除?

全部删除,然后添加新闻。

4 个答案:

答案 0 :(得分:2)

假设您有InnoDB表,请将其作为事务处理。

这里的基本思想是擦除平板,然后创建/重新创建关联。这比确定每个更新的增量更容易(即,分别检查每一行并确定它是INSERT,UPDATE还是DELETE操作)。

这是您将使用的原始SQL

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;

答案 1 :(得分:1)

查看Doctrine(http://www.doctrine-project.org/)。它是PHP的对象关系映射器(ORM)框架。它可以轻松处理您想要完成的任务。

答案 2 :(得分:1)

如果您使用Zend_Db适配器直接执行SQL语句,则可以根据用户想要的选择构建UPDATE查询。例如:

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

仅在practiceId为21的行上将practiceId更改为15.在其他行上,practiceId列不会更改。

答案 3 :(得分:0)

嗯 - 我能想到处理这类事情的最简单方法是构建一个像这样的<select>元素:

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