2017-10-06 32 views
1

爲了簡單起見讓我們假設有一個帖子表和標籤表(未實際使用情況,但這將保持簡單)如何更新多對多鏈接表中的數據?

職位表

​​

標籤表

id | tag 
-------------------------------- 
1 | javascript 
2 | node 
3 | unrelated-thing 

posts_tags表

id| post_id | tag_id 
-------------------------------- 
1 | 1  | 1 
2 | 1  | 2 
3 | 1  | 3 
4 | 2  | 2 

一篇文章可以有許多標籤,一個標籤可以與許多帖子相關聯。

Web應用程序假設假裝添加/刪除標記不會在Web應用程序中針對鏈接表觸發單個非同步操作。 相反,用戶將編輯帖子(添加或刪除已創建的任何標籤),然後點擊保存。 Web應用程序將提交JSON,其中包含與Post相關的標籤ID數組到服務器,然後該服務器將處理代碼中的更新請求。

例如,post_id=1僅與tag_id=[1,2]一起提交,所以tag=3需要作爲鏈接表中的關聯被移除。

如果POST或標籤被刪除時,我有一個ON DELETE CASCADE上

  • posts_tags.post_id
  • posts_tags.tag_id

設置但是,什麼是最好的方法在更新與帖子相關聯的標籤的情況下更新鏈接表數據?

選項1:

  • 獲取所有的後期編輯後的標籤
SELECT * FROM posts_tags WHERE post_id = 1
  • 確定已添加標籤(並插入到連接表)
  • 確定哪些標籤已刪除(並從鏈接表刪除)

選項2:

  • 刪除所有標籤與鏈接表
  • 插入POST_ID所有提交的標籤到鏈接表

方案3:

  • 什麼我不想着:)

隨着表增長,選項2會對索引有更大的性能影響嗎?

編輯:

  • 爲了清楚起見,實際的郵政和標籤數據沒有更改或刪除。這純粹是關於更新後的相關標籤
  • 我正在使用的數據庫是PostgreSQL的9.6
+0

如果您將關鍵字設置爲「AFTER INSERT UPDATE DELETE」,您可以自動調用觸發器。在這種情況下,當您刪除一行時,具有相同ID的另一行將被級聯刪除。你做觸發一次然後他爲你做這項工作^^ – F0XS

+0

我不知道這將如何解決它? 在我的示例場景中,數據實際上並未在帖子或標籤表格中插入或更新。更新帖子時更新鏈接表(posts_tags)內的關聯標識,並將不同選擇的標籤與該帖子相關聯。 – nodenoob

+0

我給了你所有的可能性,但是如果你想做一個'AFTER UPDATE',你可以。在觸發器中最重要的是,您希望標識符在所有其他關聯的表上更新,這是很好的內容。 – F0XS

回答

1

選項2將是從性能上看罰款 - 比選擇1好得多,因爲你有一個單一的操作刪除舊的關聯,然後在插入語句上一堆。在選項1中,您有更多的查詢(您的第一個查詢檢索關聯,然後刪除,如果適用)。

只要你的表有一個post_id上的索引,那麼即使在一張巨大的桌子上,delete * from posts_tags where post_id = ?也會閃電般快。

有一種替代...

posts_tags表

id| post_id | tag_id | version_id 
-------------------------------- 
1 | 1  | 1  | 0 
2 | 1  | 2  | 0 
3 | 1  | 3  | 1 
4 | 2  | 2  | 0 
5 | 1  | 1  | 2 
6 | 1  | 3  | 2 

在這種情況下,您可以使用版本控制機制來確定的 「當前」 協會(MAX(VERSION_ID)),所以你永遠不必刪除任何東西 - 你只需插入新的行。

實際上,這可能不會更快,但它確實爲您節省了「刪除」查詢。

相關問題