2009-09-01 144 views
0

我有3張桌子。如何更新關係表?

用戶(ID,郵箱,用戶名等)

實踐(ID,姓名)

UsersPractices(用戶ID,practiceId)

最後一個是關係表是NN 。

我想根據用戶的意願更新這一個。

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

我可以用什麼算法來做到這一點?

將數據庫引擎的這項工作(如果有的話)應該更好嗎? 或者我應該寫我自己的算法來處理數據,然後執行我對數據庫的請求?

編輯:

要明確:

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

也許,用戶將嘗試從21他的做法改爲15,但要保持練習18

所以,從請求中,我會得到practice = array(15,18);

,這意味着用戶的做法將是這樣的:

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

那麼,什麼是實現這一目標的最佳方式是什麼?

我應該選擇&檢查每個練習,然後刪除,如果需要?

將它們全部刪除,然後添加新聞。

+0

我不太確定你到底在問什麼? – Amber 2009-09-01 19:44:37

回答

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; 
+0

這就是我想的,除了交易,這確實可以在這裏引起興趣。 – 2009-09-01 20:00:57

+0

交易對於這種模式起作用非常重要。它把這個多步驟的過程變成了一個原子單位 - 如果一個部分失敗了,整個事務就會失敗,從而阻止你不可避免地抹去某人的忠誠。但是你不能用MyISAM表格來完成。 – 2009-09-01 20:07:34

1

檢出原則(http://www.doctrine-project.org/)。這是一個用於PHP的對象關係映射器(ORM)框架。它可以輕鬆處理你想要完成的任務。

+0

我沒有使用Doctrine,而是Zend Framework,它有不同的實現。 – 2009-09-01 19:52:34

+1

您不必使用'Zend_Db_Table'組件。您甚至可以在Zend Framework應用程序中使用Doctrine。 – 2009-09-01 19:57:21

+0

學說*應該*與ZF一起玩,如果您嘗試將其添加到您的項目中。據我所知,ZF缺乏ORM。所以你可以推出你自己的解決方案,或者使用預製的解決方案。這裏有一篇關於如何結合兩者的文章:http://ruben.savanne.be/articles/integrating-zend-framework-and-doctrine – 2009-09-01 19:58:43

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 
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 15只排在那裏practiceId是21.其他行,它將使不改變practiceId列。

+0

這很有趣,但它看起來很難處理,因爲我需要做一個選擇,檢索現有的做法,然後,使用您的請求,更新和檢查。 無論如何,它可能會在不久的將來有用。 – 2009-09-02 09:33:34

+0

無論您使用哪種解決方案,您都需要進行選擇以獲取當前數據。 – 2009-09-02 14:49:33