2012-05-15 28 views
2

我經常遇到更新問題有很多關係。 例如,我們採取以下三個表:更新標籤列表 - 或更新has_many關係

  • 帖子
  • 標籤
  • posts_tags

當用戶創建一個新的職位,他可以添加標籤的帖子。帖子已保存,所選標籤通過_posts_tags_附加到它。

當用戶編輯帖子(也可能或不可以編輯標籤列表),並提交表格時,我必須更新帖子的標籤列表。

解決方案可能如下:更新帖子時,我從_posts_tags_刪除該帖子的所有標籤,並插入提交的帖子。

另一種解決方案是從數據庫中獲取帖子的所有標籤,將列表與提交的列表進行比較,並決定我們必須刪除的內容以及我們要插入的內容。

這兩種解決方案都很耗時。
什麼是更聰明的解決方案?

+1

我有點疲倦,昏昏欲睡,所以忍受着我(可能讀過這個錯誤),但不是說,級聯是爲了? – Bono

+1

@Bono:不。問題不在於如何在外部表中的相關記錄中級聯更新,而是如何檢測應用程序中哪些記錄已被修改,以便在數據庫中反映這些修改。 – eggyal

+0

在你發佈的兩個解決方案中,第一個通常會更可取。使用索引進行刪除將比第二個要求的比較類型更快。至於找到一個更「聰明」的解決方案,你應該考慮在這裏應用[KISS原則](http://en.wikipedia.org/wiki/KISS_principle)嗎? –

回答

0

當一篇文章被編輯並且標籤沒有被編輯(可選)時,那麼只需保存文章並且什麼也不做。爲什麼?原因是,在posts,tags和posts_tags表中,您有一個自動增量列,它是您的主鍵。這個數字列然後在相應的表中的外鍵,即該表將如下所示:

帖子:id_post(PK),POST_TITLE,POST_CONTENT

標籤:id_tag(PK),TAG_NAME

posts_tags:id_post_tag(PK),id_post(FK),id_tag(FK)

PK:主鍵 FK:外鍵

一旦保存在此格式的數據,你會發現沒有必要更新任何依賴t因爲文本數據不再用於維護數據庫模式和關係。由於Bono暗示的任何級聯作業中的數據庫並不繁忙,這也加快了事務處理時間。

然後爲帖子中的所有標籤運行一個簡單循環,以檢查它們是否存在於post_tags表中的id_post中,如果找不到,則插入它。雖然這樣做循環建立一個字符串,您將在下面使用:

接下來,運行以下查詢:

delete from post_tags where id_post = {$id_post} and id_tag not in {$list_id_tags} 

該操作通過減少它們由行造成IO操作最大限度地減少數據庫服務器超載被添加和刪除。您刪除所有post_tags並再次插入所有標籤的情況會產生較大的IO,而此方法會最小化該IO。