2011-10-26 29 views
1

當你想刪除一個類別 - 它會首先刪除所有相關的產品與相關的組和屬性。產品有很多關係。什麼是從許多表中刪除數據的正確方法?

這是如何處理刪除類別時:

if (isset($_POST['catid']) && $_POST['catid'] > 0) { 

    $category_id = mysql_real_escape_string($_POST['catid']); 

    $SQL = "SELECT * FROM products WHERE category_id = '$category_id'"; 
    $q_item = mysql_query($SQL); 

    while ($dItem = mysql_fetch_assoc($q_item)) { 
     $itemid = $dItem['id']; 

     $SQL = "SELECT * FROM option_groups WHERE item_id = " . $itemid; 
     $q = mysql_query($SQL); 

     while ($option_group = mysql_fetch_assoc($q)) { 
      $optionGroup = $option_group['id']; 

      $SQL = "SELECT * FROM options WHERE option_group_id = " . $optionGroup; 
      $q = mysql_query($SQL); 
      while ($row = mysql_fetch_assoc($q)) { 
       $option = $row['id']; 
       mysql_query("DELETE FROM options WHERE id = " . $option); 
       mysql_query("DELETE FROM e_groups_options WHERE option_id = " . $option); 
      } 

      mysql_query("DELETE FROM option_groups WHERE item_id = " . $itemid); 
      mysql_query("DELETE FROM products WHERE id = " . $itemid); 
     } 
    } 

    $SQL = "DELETE FROM categories WHERE id = '$category_id'"; 
    mysql_query($SQL); 

} 

你可以看到,我已經使用了包括許多DELETE查詢和代碼看起來有點亂,有另一種方式,更安全?

存儲引擎是MyISAM,我在表中有超過100,000行數據(字段被索引)。

回答

3

如果這些表與foreign key有關,則可以在外鍵中指定ON DELETE CASCADE,並且只刪除類別。你必須切換到InnoDB才能應用這個。引用外鍵的documentation

對於除InnoDB的其他存儲引擎,MySQL服務器解析的外鍵語法在CREATE TABLE語句,但不使用或存儲它

考慮到,級聯帳戶動作不會觸發觸發器。

您可以用ALTER TABLE table_name ENGINE = InnoDB將表格切換到InnoDB。 您可以添加一個外鍵與ALTER TABLE語句,比如:

ALTER TABLE products 
ADD FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE; 

有了這個外鍵,每當你categories發出DELETE聲明中,RDBMS還將刪除products這一類引用。

+0

我沒有在mysql中聲明「FOREIGN KEY」。 –

+0

@ user791022 - 好的,你有能力嗎? :) – halfer

+0

第一個問題是,你使用MyISAM作爲選擇,還是僅僅因爲它是默認的?如果你願意,你可以用'ALTER TABLE table_name ENGINE = InnoDB';將你的表切換到InnoDB。之後,您可以使用級聯創建外鍵。 –

1

我認爲在這裏工作的最佳方式是使用支持外鍵約束的存儲引擎(如InnoDB),並讓它通過ON DELETE CASCADE來處理這個問題,這樣DBMS將爲您完成這項工作。

MyISAM確實not support foreign keys到目前爲止。

1

如果你不想或者你的數據庫引擎無法改變InnoDB的,你可以做刪除多個表與加盟:

DELETE t1, t2, t3 
FROM tabel1 AS t1 
LEFT JOIN table2 AS t2 ON t1.id = t2.pid 
LEFT JOIN table3 AS t3 ON t2.id = t3.pid 
WHERE t1.id = $id 

如果有一種方法來連接所有的表從你想刪除行,你可以調整你的代碼來執行這樣的單個查詢。

2

由於您正在使用MyISAM並且無法進行級聯刪除,因此您可以簡單地執行聯合刪除。

DELETE table1, table2 FROM table1 LEFT JOIN table2 ON table1.id = table2.t1_id WHERE table1.id = $id 
0

的答案已經被接受,但利息:如果僅停留在那不級聯刪除的數據庫,你可以使用ORM如行走。我相信可以配置爲在本地不支持db的情況下手動進行級聯刪除。

相關問題