2016-02-19 13 views
4

最好的例子是一個User實體,它需要被持久化。我有以下候選人爲用戶分配唯一標識符:何時以及如何爲DDD中的實體分配唯一的ID?

  1. 指定由後端(NDB,MySQL等)提供的密鑰。
  2. 通過某種服務(如系統時鐘)手工製作唯一標識符。
  3. 像emailId一樣的屬性。

以詳細視圖的一個簡單的例子,我們經常有這樣some/path/users/{user_id}的用戶的詳細顯示,如果我們保持EMAILID作爲唯一的ID,然後有機會,一個用戶可以更改其電子郵件ID一天,打破它。

哪一種更好的方法來識別相同的實體?

+1

[域驅動設計自動增量實體密鑰]的可能重複(http://stackoverflow.com/questions/34315605/domain-driven-design-auto-incremented-entity-key) – theDmi

+0

根據您的要求,所有三個所提出的選擇可以被認爲是「好策略」。 – Cerad

回答

3

命名爲UUID。

UUID,因爲它給人的標識一個很好的預測的結構,而不會引入任何語義含義(如電子郵件ID的例子)。認爲surrogate key

命名爲 UUID,因爲您希望生成的ID是確定性的。確定性意味着可重現:您可以將系統移動到測試環境,並重播命令以檢查結果。

它也給你一個額外的方法來檢測重複的工作 - 在你的系統應該發生什麼,如果一個用戶創建命令重複(例如:用戶發佈相同的Web表單兩次)。在中間層有多種方法可以防止這種情況發生,但是在持久層(也就是記錄系統)中覆蓋這種方法的一個非常簡單的方法是在id上加上唯一性約束。由於第二次運行該命令會生成一個具有相同ID的「新」用戶實體,持久層將反對複製,並且可以從那裏處理事情。

因此,你會得到冪等命令的處理,即使所有的中間層後衛的複製命令之間的時間間隔內重新啓動。

命名UUID爲您提供這些屬性;例如,您可以從實體類型和命令標識的標識符構建uuid(重新發送的命令在重新發送時將具有相同的標識)。

您可以使用用戶(如電子郵件地址)的瞬態特性作爲種子的一部分,你的名爲UUID,如果你有一個保證,財產永遠不會被分配給其他人。你確定[email protected]不會被分配給其他用戶嗎?那麼這不是一個好的種子使用。

後端鍵值不會檢測衝突如果一個命令是重複的 - 你需要依靠國家的一些其他位都能檢測到衝突。

系統時鐘是不是一個好的選擇,因爲它使重現同一個ID困難。如果您可以在測試環境中重現對本地時鐘的更新,則系統時鐘的本地副本可以工作。但是如果時間不是你的領域模型的一部分,那就是你不想要的額外努力。

0

我同意@VoiceOfUnreason但僅部分。我們都知道UUID拼寫和跟蹤很糟糕。所有使用增量且有意義的UUID的方法都只能解決這些問題的一部分。

使用創建方可用的某個ID創建聚合。雖然可以在不涉及任何外部組件的情況下生成UUID,但這不是唯一的解決方案。使用像Twitter Snowflake(退役)這樣的外部身份提供者也是一種選擇。

創建非常簡單和可靠的身份提供程序並不複雜,因爲它可以通過給定聚合類型名稱返回遞增長整型值。

當然,它增加了複雜性,只有在需要生成連續的唯一數值時才能證明是正確的。這項服務的彈性變得非常重要,需要認真解決。但它可以被看作是任何其他關鍵基礎設施組件,我們知道每個系統都有不少這樣的組件。

相關問題