在實際的系統上,一個模組所使用的資料,常會依賴於所多其他的模組,這些關聯可能會透過新增資料時來建立, 以照片管理應用程式來說,至少會有相片模組及使用者模組,以相片模組來說,新增完一張照片後,通常,相關聯的資料會是

  1. 或者照片本身的細節資訊(分別存放在多個tables)
  2. 這張照片是屬於那個人的(使用者模組的使用者資料)
  3. 這個照片被誰引用(別的使用者將這張相片放入自已的相本)

以上面的例子來說,第一個是一對多 + 多對一的Master-Details關係,第二個是透過在相片主table放一個user_id的Forgin Key的多對一,第三個是一張相片可能被多人引用,也可能一個人引用多張相片的多對多的關係。 在大多數的應用上,通常, 第一點的照片本身及細節的table,因為跟相片本身有比較大的相關性,所以,通常會放在相片模組裡面,刪除時,通常會一併處理, 第二點因為相片是透過存forgin key,如果只是刪除相片本身,通常沒什麼問題,但如果刪除使用者時是否需一併刪除相關的相片,這就是本文要討論的重點。 第三點,設計時,是否會放在相片的module,與是否一併刪除,就看設計者的考量。

正常的設計上,刪除使用者,一併刪除所有相關的資料,這樣不會造成幽靈資料(Orphan data),但如果與使用者相關的模組的變多,變複雜,那刪除一個使用者,要一併刪除底下一大串的相關資料,這樣容易會造成刪除的動作失敗。

目前想得到,最佳的solution是只刪除最直接相關的資料,其他間接相關的資料不進行刪除,這樣最大的好處是簡化設計,但可能需提供一個清除這樣幽靈資料的功能或sql script。目前關於這個做法相關的議題如下:

幽靈資料(Orphan data)會造成資料庫的負擔

基本上,這個問題不需要太被關注,如果要解決,已經是資料庫效能調校的議題。或者,可透過清除幽靈資料(Orphan data)的動作進行處理。

幽靈資料(Orphan data)是否會造成統計異常,資料不一致

如果統計時,都有依據關聯的key做統計,那不存在的FK的資料就不會被計入,就不會照成這個問題

如果採原始的刪除方式(刪除所有相關資料),如果有一筆資料無法刪除,就會發生刪除無法成功(所有刪除動作在同一個transcation)或者資料不一致(刪除的動作不在同一個transcation)