2013-04-29 80 views
1

我有一個Web項目,它使用數據庫來存儲數據,這些數據用於生成將爲遠程計算機處理的任務,以更改該記錄並存儲新數據。我的問題在於,我必須在每張桌子上存儲所有更改,但我不需要所有這些信息。例如,表A可能有5個字段,但爲了歷史目的,我只需要2個字段。另一個表B可能有3個,我將不得不添加另一個(例如日期)。另外,在日常任務生成過程中,我不需要更改,只需要最近一次。管理數據庫中的歷史記錄

哪一個是維護變更歷史的最佳方式?有人告訴我,一個好主意是有兩個表,A(B)表和另一個表A_history(B_history)以及所需的字段。這實際上是我正在做的,使用觸發器插入到歷史記錄表中,但我對這種方法感到不舒服。我的項目使用Spring(Spring數據,Hibernate和JPA),如果我更改數據庫(當前MySQL),我不得不遷移觸發器。有沒有一種管理歷史記錄的好方法?表可以使用Hibernate/JPA註釋生成。

如果我維護兩個表的方法,我可以將一個方法添加到存儲庫以同時從當前表和歷史表中獲取行?

回答

1

爲此傾斜有一個特殊的Hibernate Envers項目。請參閱官方文檔here。只需配置它,使用@Audited註釋標註必要的屬性即可。不需要數據庫觸發器。

一個缺陷:如果你想爲每個刪除操作有一個記錄,那麼你需要使用Session.delete(entity)的方式,而不是HQL「刪除...」。

編輯。也看看spring數據jpa的native auditing support

+0

Hibernate Envers正是我所需要的(至少我認爲是這樣)。只是一個問題。與Spring Data(JPA)兼容。我使用存儲庫連接我的數據庫,我不想重寫太多來添加Envers。 – 2013-04-30 21:40:20

+0

我沒有這樣的實驗:Spring Data JPA + Hibernate Envers。布我相信它必須正常工作。正如我前面提到的,如果你想在相應的審計表中捕獲它們的更改,不要使用更新/刪除HQL查詢(在JpaRepository中不要使用像'deleteInBatch(Iterable entities)'和'deleteAllInBatch()'這樣的方法) – 2013-05-02 10:01:11

1

我不是數據庫專家。我所看到的他們可以歸結爲幾種方法。

1)它們向事務表添加觸發器,該觸發器將插入和更新複製到歷史記錄表但不刪除。這意味着任何需要包含歷史記錄的查詢都可以從歷史記錄表中完成,因爲所有當前信息都存在。

  • a)他們可以記錄歷史表中的每個條目的時間和日期,並且 記錄所有原始記錄的狀態。
  • b)他們只能記錄 記錄原始記錄的當前狀態,然後當原始記錄被刪除時它就會穩定下來。

2)他們有一個週期性的任務,並且將標記爲可刪除的數據複製到歷史表中。然後它從事務表中刪除數據。事務表中的任何查詢都必須確保忽略可刪除的行。任何需要歷史記錄的查詢都必須搜索兩個表併合並結果。 3)如果數據量不是太大,他們只是將所有內容都放在一張表中,並將一些條目標記爲歷史。查詢必須忽略歷史行。包含歷史的查詢很容易。這可能會隨着表的增長而減慢數據庫訪問速度,以包含許多未使用的行,但有時可以通過巧妙使用索引來改善。