web-dev-qa-db-ja.com

一意のIDを明示的に生成するID列またはUDF?

Identity Columns からPRIMARY KEYを作成する方が良いかどうかについて、私は議論の最中です。 、一意のIDを明示的に生成するUDFの外。

  • ID列について議論しています。
  • 私のパートナーは、手動で値を生成することを主張しています、と彼は主張します
    • uDFを置くことができる別のテーブルにUDFを置くことによって
      • リソースをロックする
      • ID_Value by 1と呼ばれる1つのフィールドでIDテーブルをインクリメントします
      • これをグローバル一意識別子として使用します
    • または、挿入時にテーブルにid+1を実行させる
    • 識別制約のないサーバーや環境間でデータを移動する方が簡単です。データがあるDBから、ステージングデータやダミーデータなどの別の同様のDBに移動する。非本番環境でのテストの場合、すべてのレコードを昨日からテスト用のステージングまで引き下げることができます。

どの実装がより意味がありますか?

11
kacalapy

あなたの同僚はばかです。

ソリューションはスケーラブルではなく、UDFは同時ではありません( これと同じ理由 )。そして、どのように複数行の挿入を処理しますか?これには、行ごとにUDF呼び出しが必要になります

そして、他のRDBMSへの移行は実際には頻繁に行われません... SQL Serverを今は使用せず、Oracleでシーケンスを使用して、移行しないことを望んでもよいでしょう。

編集:

更新では、データの移動は非本番データベースを更新するためのものであると述べています。

その場合、更新時にID列を無視します。非製品のロードを容易にするために、実装に妥協する必要はありません。または、一時テーブルを使用してID値の変更を追跡します。

または、プロセスを使用します。問題を完全に回避するため、本番環境から毎晩テストシステムを更新します。 (そして、私たちの製品バックアップも復元できることを保証します)

21
gbn

ID値を使用します。独自のシーケンステーブルとシーケンス値を生成すると、多くのオーバーヘッドがかかり、数値を生成しようとする際に多くのロックとブロックが発生します。

アイデンティティは理由のために存在します、それを使用してください。

SQL Denaliが登場すると、アイデンティティよりも効率的なシーケンスをサポートしますが、自分でより効率的なものを作成することはできません。

ある環境から別の環境へのレコードの移動については、挿入を行うときにIDENTITY_INSERTをONにするか、SSISのボックスをオンにします。

11
mrdenny

ID列は正常に聞こえます。サーバー間でデータを移動するのが難しい理由についてのロジックに従っているのかわかりません。

各行にグローバルに一意のIDを持たせたい場合は、UUIDを使用できますが、グローバルな一意性が必要であることが確かでない限り、通常は使用しません。 UUIDをIDとして使用すると、パフォーマンスが低下し、必要なディスク容量が増え、デバッグが困難になります。長さがUUIDを思い出したり、電話で誰かに伝えたり、エラーなしで紙に書き留めたりすることが難しいためです。

5
Mark Byers

単純な数値IDの場合は、IDを使用して、手動でIDを生成する際のすべての問題を忘れてください。

IDをPKとして使用し、タイプ列とその他の情報を持つ「スーパーテーブル」をいつでも作成できます。新しいIDが必要な場合(異なるテーブル間で一意のIDSを意味すると仮定)、このテーブルに挿入してSCOPE_IDENTITY()を取得し、必要な実際のテーブルに挿入します。

基本的にテーブルを作成します:MasterIDsアイデンティティPKを使用して、Table1に行を挿入する必要がある場合は、INSERT INTO MasterIDsを使用し、SCOPE_IDENTITY()を使用してその行によって生成されたアイデンティティを取得します。そして、その値をPKとして使用してTable1に挿入します。

Table1には、非IDのint PKがあります。同じプロセスを実行してTable2などに挿入します。SQLServerにMasterIDsテーブルのID値を管理させ、他のテーブルで使用できるようにします。 MasterIDsには、タイプなどの他のテーブルを含めることができます(そのため、Table1またはTable2など、どのテーブルがそのID値を使用するかを知ることができます。

4
RacerX

外部キー制約を適切に使用している限り(カスケード、更新など)、IDフィールドを使用しても問題ありません。この場合、他のソリューションの利点は本当にわかりません。

3
Joe Phillips

アイデンティティはあなたのシナリオに合うように作られました。サーバー/環境のデータ交換のレプリケーションなど、すべてをまとめて維持するツールがあります。

2
Silx

SQL Serverのidentity列を通常のintフィールドに置き換え、IDの割り当てを自分で制御する作業を終えたところです。

私はかなり印象的なパフォーマンスの向上を見てきました。 OPとは異なり、IDを生成するためのUDFがありません。しかし、原則はほとんど同じです。IDのプールを維持するソフトウェアの一部があります。彼らが尽きると、データベースに次のLow値を問い合わせることで別のバッチを取得し、これを次のHighにインクリメントします。

これにより、バッチをデータベースに送信する前に、IDを生成してORM内のトランザクションの外部にあるすべてのエンティティを関連付け、さらに追加のラウンドトリップなしで大きなバッチを送信して、挿入されたばかりのIDを取得できます(ID列で必要)。

Idテーブルには複数の行があり、必要に応じて特定の範囲を使用できます。つまり、削除されたブロックと負のIDを再利用します。

1
Mark

私は何年もIDを使用しており、ID番号をUNIQUEIDENTIFIERに置き換えることを真剣に検討しています。誰かがそれをコンパクトデータベースとして設計した場合はデータ型を変更する必要があり、列にIDを追加する必要がある場合は悪夢です。また、ID列を更新することもできません。あなたがintを入れて、データベースが20億レコードを超えて大きくなると想像してみてください。再び変更するのは悪夢です(FKを考慮してください)。アイデンティティで何かを変更することは悪夢であり、bigintを使用しない限り、スケールフレンドリーではありません。 UNIQUEIDENTIFIER vs Identity =利便性と堅牢性vsおそらく目立ったパフォーマンスの改善(ベンチマークを行わなかった)。

更新:私が見た後 this 私は間違いなくUNIQUEIDENTIFIERに傾いています。これは、bigintアイデンティティの本当のメリットと、UNIQUEIDENTIFIERの多くのメリットを示していません。 SQL Serverのバージョンが異なると、結果も異なる可能性があります。すべてのデータベースとシステムにまたがる一意のIDを持つこと(美しさ)には美しさがあります。データを自由に移動、コピー、変換してください! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

0
Hrvoje Batrnek