GUIDを主キーとして使用する
私は通常、データベースの主キーとして自動インクリメントのIDを使用しています。 GUIDを使用することの利点を学びたいと考えています。 私はこの記事を読みました: https://betterexplained.com/articles/the-quick-guide-to-guids/
このGUIDは、アプリケーション・レベルでオブジェクトを識別するために使用されると理解しています。 また、データベースレベルでも主キーとして保存されるのでしょうか。 例えば、次のようなクラスがあったとします。
public class Person
{
public GUID ID;
public string Name;
..
//Person Methods follow
}
メモリ上に新しいPersonを作成し、そのPersonをデータベースに挿入したいとします。 こうすればいいのか。
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);
GUIDを主キーとする数百万行のデータベースがあるとします。 これは常に一意になるのでしょうか?私はGUIDを正しく理解しているのでしょうか?
以前、この記事(http://enterprisecraftsmanship.com/2014/11/15/cqs-with-database-generated-ids/)を読みました。 GUIDと整数の中間を主キーとして推奨しているように見え、少し混乱しています。
11/06/18を編集しました。
私の要件には、intsよりもGuidsの方が適していると思うようになりました。 最近はCQRSを使うことが多くなり、GUIDの方がしっくりくるようになりました。
開発者によっては、GUIDをドメインモデルで文字列としてモデル化していることに気づきました。例えば、https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs - この場合。この場合、IdentityGuidは文字列としてモデル化されたGUIDである。 この場合、IdentityGuidは文字列としてモデル化される。このようにする理由は、ここに記載されている以外にあるのだろうか: https://softwareengineering.stackexchange.com/questions/239220/use-a-custom-value-object-or-a-guid-as-an-entity-identifier-in-a-distributed-sys。 GUID を文字列としてモデル化するのは普通ですか。それとも、モデルおよびデータベースで GUID としてモデル化する必要がありますか。
GUIDは定義上、"Globally Unique IDentifiers"(世界的にユニークな識別子)です。 JavaにはUUID(Universally Unique IDentifiers)と呼ばれる、似ているが少し異なるコンセプトがあります。 この2つの名称は、実用上、互換性があります。
GUIDは、マイクロソフトが想定していたデータベースクラスタリングの仕組みの中心であり、時々つながっているソースからデータを取り込む必要がある場合、データの衝突を防ぐのに非常に役立ちます。
プロGUIDの事実もあります。
GUIDの不都合な点
GUIDを使用するとインデックスが大きくなるため、カラムのインデックス作成にかかるディスクスペースのコストが高くなります。 ランダムなGUIDはインデックスを断片化する。
異なるネットワークからデータを同期させるつもりがないことが分かっている場合、GUIDはその価値以上にオーバーヘッドをもたらす可能性があります。
時々接続しているクライアントからデータを取り込む必要がある場合、これらのクライアントのシーケンス範囲を設定することに頼るよりも、キーの衝突を防ぐためにはるかに堅牢になる可能性があります。
それはビットの有限なシーケンスです。
GUIDを主キーとする数百万行のデータベースがあったとします。
何百万も何千万もあれば、おそらく安全でしょう。 何百万もあれば、衝突の可能性は大きくなります。 しかし、良い知らせがあります。そのような事態になる前に、あなたはすでにディスクスペースを使い果たしているのです。
しかし、それは完全に良いアイデアではありません。 ドメインモデルは通常、乱数を生成すべきではありません; これらはモデルへの入力であるべきです。
さらに、信頼性の低いネットワークを扱っていて、重複したメッセージを受け取る可能性がある場合、_決定論的に生成されたUUIDは重複した実体を持つことからあなたを守ることができます。 しかし、それぞれに新しい乱数を割り当てるのであれば、重複を特定するための作業が増えることになります。
RFC 4122]2の名前ベースのuuidの説明を参照してください。
あまり関係ないと思います。 ドメインモデルの大部分では、それは_identifier_です;あなたがそれに対して求める唯一のクエリは、それが他の識別子と同じであるかどうかです。 ドメインモデルは通常、識別子のインメモリ表現を見ることはありません。
もしGUIDがドメインにとらわれない設定で"プリミティブ型"として利用できるのであれば、私はそれを使用します。
しかし、識別子の表現は、メモリ上とストレージ上の両方で、実装の中で決定していることであり、したがって、その決定と結びついたコードのフットプリントが小さくなるように手段を講じるべきであることを認識する必要があります。
GUIDやUUIDは、その生成方法からユニークである可能性が非常に高く、中央当局と通信しなくてもユニークさを保証できる安全な方法となります。
GUIDを主キーにするメリット。
ご提示いただいた例では
挿入時前にGUIDを指定することで、連続した子レコードを挿入する際にデータベースとの往復を省き、同一トランザクション内でコミットすることができます。
GUIDを主キーにすることの弊害
シャーディングやクラスタリングを必要としないアプリケーションでは、intやbigintのような小さくてシンプルなデータ型にこだわるのがベストでしょう。
多くのデータベースは、GUIDによって引き起こされるストレージの問題を軽減しようとする独自の内部実装を持っており、SQL ServerはUUIDの順序付けを支援する関数newsequentialidを持ち、インデックスをより良く使用できるようにしています。
さらに、アプリケーションに携わるテスター、ユーザー、開発者の立場からすると、GUIDよりもIDを使用する方が、コミュニケーションを大幅に改善することができます。GUIDを電話越しに読むことを想像してみてください。
結局のところ、大規模なクラスタリングやURLの難読化が要件でない限り、自動インクリメントのIDにこだわる方がより現実的です。