2011-05-07 23 views
2

我正在設計一個應用程序,其中我的Order對象需要具有順序且用戶友好的Id字段。我避開了HiLo算法,因爲它產生的間隙相當大(見here)。自然,Guid的價值觀會讓我的企業用戶去香蕉。我還避免因爲它的主要缺點甲骨文序列:如何在NHibernate中實現無縫,用戶友好的ID?

(來源:NHibernate POID Generators revealed

後插入發電機,正如其名字 建議,分配的ID後 實體存儲在數據庫中。 A select語句是針對 數據庫執行的。他們有許多缺點, ,在我看來,他們只能在棕地項目上使用 。 那些 發電機是我們不建議 作爲NH團隊。

>有些缺點是繼 :

  • 工作單元與使用 這些戰略打破。使用FlushMode.Commit的 並不重要,每個 將結果保存在針對數據庫的插入語句 中。作爲最佳做法,我們 應該延遲插入提交, ,但使用後插入生成器 使它保存(這是什麼 UoW不這樣做)。
  • 抵消配料這些戰略,你不能拿 利用發送多個查詢 一次(因爲它必須在 保存的時間去數據庫)的。

實現用戶友好型ID的任何想法/經驗沒有大的差距?

編輯:

  • 用戶友好Id領域是那些我的企業用戶能記住,甚至討論和/或有電話交談通過它的代碼,例如在談論一個特定Order 「我打電話要知道爲什麼1625號訂單被拒絕。」
  • Id不需要嚴格無縫,但我擔心我的用戶會看到像100,201,305之類的空白時會感到困惑。對於我的舊項目,我目前使用Oracle序列實現NHibernate在拋出異常時偶爾會丟失一些序列,但是對它們保持相當整潔的順序。他們的缺點是他們如何破壞工作單元,這會導致每個Save命令的額外命中數據庫有或沒有Session.Flush
+0

你如何定義「用戶友好的ID」?就像連續的整數一樣? – R0MANARMY 2011-05-08 01:54:12

+0

你能否進一步擴展oracle序列的這些「主要缺點」?正確使用時,我從來沒有遇到任何問題(適合您環境的緩存設置)。爲什麼你需要它無間隙,每當有人問這個問題時,我傾向於覺得他們通常走錯了路。 – 2011-05-08 02:35:58

+0

@Matthew和@ R0MANARMY - 請參閱我的帖子更新。 :) – rebelliard 2011-05-08 02:52:45

回答

1

一種選擇是保留一個只存儲遞增值的鍵表。這可能會引入一些問題,即可能的鎖定問題以及數據庫的附加命中。

另一種選擇可能是通過「用戶友好標識」來改進您的意思。這可能包括日期/時間和客戶特定序列(或包括客戶ID)的組合。此外,您的訂單ID不一定必須是表格上的實際密鑰。沒有什麼可說的,你不能使用代理鍵和代表訂單ID的單獨「計算」列。

底線是,它聽起來像你想使用代理鍵,但有一個自然鍵的好處。實現這一目標可能非常困難,並且很大程度上取決於您如何實際計劃使用數據,用戶如何解讀數據以及個人偏好。

+0

我其實很喜歡你的「複雜」日期+客戶的想法,不必介意額外的命中數據庫(如果需要)。對於「05/07/2011 11:30:10 pm」的創建日期和「614」的customerId,您會如何選擇代理鍵? **我真的喜歡這個主意。 – rebelliard 2011-05-08 03:58:04

+0

@binaryhowl有幾個選項,即「201105071130-614」,或其中的一些組合(我將格式化日期/時間,因爲如果你願意,以後可以對它進行排序)。這將是一個自然的關鍵。代理鍵將獨立於數據。所以,例如,你可以有一個類型爲identity的「id」列和一個varchar類型的「orderid」列。一個自然的關鍵,或者一個自然的+代理 - 都解決了這個問題,這是當它涉及到使用,解釋和偏好時。 – 2011-05-08 04:02:12

+0

方式......太棒了。這個解決方案可以幫助我保持我的HiLo以及我的客戶可以輕鬆理解的代理鍵*和*,這也保護了我的其他條目(例如,沒有更多的「哦,讓我們看看是什麼?Id = 200給我!」) 。謝謝! :「d – rebelliard 2011-05-08 04:09:47