19

私は現在、テーブル名のリストと最後に使用された主キーを含むルックアップテーブルを介して主キーが生成される他の誰かのデータベースで作業しています。ストアド プロシージャは、この値をインクリメントし、呼び出し元の「挿入」SP に返す前に一意であることを確認します。

ID/自動番号を使用する代わりに、このような方法を使用する (または単に GUID を生成する) ことの利点は何ですか?

ISBN や製品コードのようなものを実際に「意味する」主キーについて話しているのではなく、一意の識別子について話しているだけです。

ありがとう。

4

16 に答える 16

27

自動生成された ID は、レプリケーションを使用している状況で問題を引き起こす可能性があります (あなたが見つけたテクニックができると確信しています!)。このような場合、通常は GUID を選択します。

レプリケーションを使用する可能性が低い場合は、自動インクリメント PK が問題なく機能する可能性が高くなります。

于 2008-11-04T17:13:15.893 に答える
20

オートナンバーの使用に本質的な問題はありませんが、使用しない理由がいくつかあります。それでも、dacracot が述べたように、独自のソリューションを展開することは最善のアイデアではありません。説明させてください。

各テーブルでオートナンバーを使用しない最初の理由は、複数のテーブルのレコードをマージする可能性があることです。Sales Order テーブルとその他の種類の注文テーブルがあり、いくつかの共通データを取り出して、複数のテーブル継承を使用することにしたとします。グローバルに一意な主キーがあると便利です。これは bobwienholt がデータベースのマージについて述べたことと似ていますが、データベース内で発生する可能性があります。

第二に、他のデータベースはこのパラダイムを使用しておらず、Oracle のシーケンスなどの他のパラダイムの方がはるかに優れています。幸いなことに、SQL Server を使用して Oracle シーケンスを模倣することができます。これを行う 1 つの方法は、データベース全体に対して、MainSequence などと呼ばれる単一の AutoNumber テーブルを作成することです。データベース内の他のテーブルは autonumber を使用しませんが、自動的に生成された主キーが必要な人は MainSequence を使用してそれを取得します。このようにして、dacracot が話していたビルトイン パフォーマンス、ロック、スレッド セーフなどを、自分でビルドすることなくすべて取得できます。

もう 1 つのオプションは、主キーに GUID を使用することですが、人間 (開発者でさえも) が決してそれらを読み取らないと確信していても、誰かがおそらく読み取り、それは難しいため、お勧めしません。さらに重要なことに、T-SQL では暗黙的に int にキャストするのは非常に簡単ですが、暗黙的に GUID にキャストする際に多くの問題が発生する可能性があります。基本的に不便です。

新しいシステムを構築する場合は、主キー生成専用のテーブルを使用することをお勧めします (Oracle シーケンスと同様)。既存のデータベースの場合、わざわざ変更するつもりはありません。

于 2008-11-04T17:57:58.830 に答える
10

CodingHorrorから:

GUID の長所

  • すべてのテーブル、すべてのデータベース、すべてのサーバーで一意
  • 異なるデータベースからのレコードを簡単にマージできます
  • 複数のサーバーにデータベースを簡単に分散できます
  • データベースへのラウンドトリップの代わりに、どこでも ID を生成できます。
  • とにかく、ほとんどのレプリケーション シナリオには GUID 列が必要です

GUID 短所

  • これは、従来の 4 バイトのインデックス値よりも 4 倍も大きくなります。注意しないと、これはパフォーマンスとストレージに深刻な影響を与える可能性があります
  • デバッグが面倒 (userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • 生成された GUID は、最高のパフォーマンス (SQL 2005 の newsequentialid() など) とクラスター化インデックスの使用を有効にするために、部分的に連続している必要があります。

この記事では、GUID と自動インクリメントのどちらを選択するかを決定するための優れた外部リンクが多数提供されています。可能であれば、GUID を使用します。

于 2008-11-04T18:15:42.587 に答える
6

インクリメントのプロシージャ メソッドは、スレッド セーフである必要があります。そうしないと、一意の番号を取得できない場合があります。また、高速である必要があり、そうでないとアプリケーションのボトルネックになります。組み込み関数は、これら 2 つの要因を既に考慮しています。

于 2008-11-04T17:15:27.480 に答える
6

挿入された ID でローカル オブジェクトを更新することなく、大量の ID を事前に割り当てて一括挿入を実行できることは、クライアントにとって便利です。次に、Galwegian が述べたように、レプリケーション全体の問題があります。

于 2008-11-04T17:15:57.807 に答える
4

キーとして整数を自動インクリメントするものは次のとおりです。

アクセスする前に、レコードを投稿する必要があります。つまり、レコードを投稿するまでは、たとえば、別のテーブルに保存される関連レコードを準備することはできません。また、新しいレコードの一意のテーブルにアクセスできると便利な他の多くの理由のいずれかを準備することもできません。 id、投稿する前に。

上記は、いずれかの方法を使用するかどうかの私の決定要因です。

于 2009-01-30T04:05:55.950 に答える
3

一意の識別子を使用すると、2 つの異なるデータベースからのデータをマージできます。

おそらく、複数のデータベースでデータを収集し、1 日のさまざまな時間にマスター データベースと「同期」するアプリケーションがあるとします。このシナリオでは、主キーの競合について心配する必要はありません。

または、実際にレコードを作成する前に、レコードの ID を知りたい場合もあります。

于 2008-11-04T17:17:40.627 に答える
2

利点の 1 つは、データベース/SQL をよりクロスプラットフォームにできることです。SQL は、SQL Server、Oracle などでまったく同じにすることができます...

于 2008-11-04T17:15:45.467 に答える
1

もう1つの考えられる理由は、意図的にランダムキーが必要なことです。これは、たとえば、データベースにあるすべてのアイテムをおせっかいなブラウザが通過することを望まない場合に望ましい場合がありますが、実際の認証セキュリティ対策を保証するほど重要ではありません。

于 2008-11-04T17:44:24.707 に答える
1

私が考えることができる唯一の理由は、コードsequencesが発明される前に書かれ、コードが追いつくのを忘れていたということです;)

于 2008-11-04T17:20:40.233 に答える
1

投稿の現在の方法が私にとって意味のあるほとんどのシナリオで GUID を使用することをお勧めします (レプリケーションは可能なものです)。レプリケーションが問題である場合、そのようなストアド プロシージャは、キーの一意性を確保するためにリンクする必要がある他のサーバーを認識する必要があります。
自動インクリメント ID ではない整数の主キーを使用する状況の 1 つは、データを消費するアプリケーションで対応する列挙型を持つ、外部キー制約を強制するめったに変更されないルックアップ テーブルの場合です。そのシナリオでは、特に複数の製品サーバーがある場合に、開発と展開の間で列挙型マッピングが正しいことを確認したいと考えています。

于 2008-11-04T17:24:01.927 に答える
0

自動インクリメントの代わりに GUID 主キーを使用することの便利な副次的な利点は、クライアント側で新しい行に PK 値を割り当てることができることです (実際、レプリケーション シナリオではこれを行う必要があります)。サーバーに追加したばかりの行の PK を取得する手間がかかります。

GUID PK の欠点の 1 つは、GUID フィールドへの結合が遅くなることです (これが最近変更されていない限り)。GUID を使用することのもう 1 つの利点は、GUID の衝突が起こりそうにない理由を技術者ではない管理者に説明してみるのが楽しいことです。

于 2008-11-04T18:17:14.220 に答える
0

Galwegian の答えは必ずしも真ではありません。

MySQL では、データベース インスタンスごとにキー オフセットを設定できます。これを十分に大きな増分と組み合わせると、うまくいきます。他のベンダーも同様の設定をしていると思います。

レプリケートしたいデータベースが 2 つあるとします。次の方法で設定できます。

increment = 2
db1 - offset = 1
db2 - offset = 2

この意味は

db1 にはキー 1、3、5、7.... があります。

db2 にはキー 2、4、6、8.... があります。

したがって、挿入時にキーが衝突することはありません。

于 2009-01-30T04:04:13.740 に答える
0

自動インクリメント キーに関する私の主な問題は、キーに意味がないことです。

特定のフィールドが一意性を提供するテーブルの場合(単独で、または別のフィールドと組み合わせて)、代わりにそれを使用することを選択します。

于 2008-11-05T14:42:59.613 に答える
-1

これを行う唯一の本当の理由は、データベースに依存しないことです (異なるデータベース バージョンが異なる自動番号付け手法を使用する場合)。

ここで言及されているもう 1 つの問題は、複数の場所 (本社や移動中のユーザーのラップトップなど) でレコードを作成できることです。ただしその場合、各 ID の前に付けられた各インストールに固有の「サイトコード」のようなものが必要になるでしょう。

于 2008-11-04T17:26:52.467 に答える