2008-11-14 63 views
1

下面是我的(簡化的)模式(在MySQL版本5.0.51b中)和我的更新策略。有一個更好的方法。插入新項目需要4次到數據庫,編輯/更新項目最多需要!更新MySQL中的關聯表格

:的itemId,ITEMNAME
類別:CATID,catName
地圖:的azazaz *,的itemId,CATID
*的azazaz(VARCHAR)是的itemId的CONCAT + | + catId

1)如果插入:插入項目。通過MySQL API獲取itemId。
其他更新:只需更新項目表。我們已經有itemId。

2)有條件批量插入categories

INSERT IGNORE INTO categories (catName) 
VALUES ('each'), ('category'), ('name'); 

3)從categories中選擇ID。

SELECT catId FROM categories 
WHERE catName = 'each' OR catName = 'category' OR catName = 'name'; 

4)有條件批量插入map

INSERT IGNORE INTO map (mapId, itemId, catId) 
VALUES ('1|1', 1, 1), ('1|2', 1, 2), ('1|3', 1, 3); 

如果插入:我們完成了。否則更新:繼續。

5)有可能我們不再將類別與更新前我們所做的這個項目相關聯。刪除此itemId的舊類別。

DELETE FROM MAP WHERE itemId = 2 
AND catID <> 2 AND catID <> 3 AND catID <> 5; 

6)如果我們從一個類別取消關聯自己,它可能是我們離開它而成爲孤兒。我們不希望沒有物品的類別。因此,如果affected rows > 0,殺死孤兒類別。我還沒有找到一種在MySQL中結合這些的方法,所以這是#6 &#7。在步驟找到

SELECT categories.catId 
FROM categories 
LEFT JOIN map USING (catId) 
GROUP BY categories.catId 
HAVING COUNT(map.catId) < 1; 

7)刪除標識6.

DELETE FROM categories 
WHERE catId = 9 
    AND catId = 10; 

請告訴我有說我沒有看到一個更好的辦法。

回答

1

步驟6 & 7可以組合很輕鬆地:

DELETE categories.* 
FROM categories 
LEFT JOIN map USING (catId) 
WHERE map.catID IS NULL; 

步驟3 & 4也可以合併:

INSERT IGNORE INTO map (mapId, itemId, catId) 
    SELECT CONCAT('1|', c.catId), 1, c.catID 
    FROM categories AS c 
    WHERE c.catName IN('each','category','name'); 

否則,你的解決方案是非常標準的,除非你想使用觸發器來維護映射表。

2

有許多事情可以做,以使更容易一點:

  • 閱讀有關[INSERT...ON DUPLICATE KEY UPDATE] [1]

  • 刪除舊類別插入新的類別之前。這可能會從索引中受益更好。

    DELETE FROM map WHERE itemId=2;你可能不需要map.mapID。相反,通過(itemID, catID)聲明一個複合主鍵。

  • 正如彼得在他回答說,使用MySQL的多表中刪除:

    DELETE categories.* FROM categories LEFT JOIN map USING (catId) 
    WHERE map.catID IS NULL 
    

    http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

2

此外,如果你擔心前往分貝,讓步入一個存儲過程。然後你有一次旅行。

+0

Doh!你可以告訴別人被困在MySQL v3的土地上太久了。存儲proc.s甚至沒有發生在我身上。好決定。 – Dinah 2008-11-14 16:04:29