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


11

私は、一意のIDを明示的に生成するUDFからPRIMARY KEYIdentity Columnsを使用する方が良いかどうかについて議論しています。

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

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

回答:


21

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

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

また、他のRDBMSへの移行は現実には頻繁に行われません。SQLServerを使用せず、Oracleでシーケンスを使用して、移行しないことを望んでもかまいません。

編集:

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

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

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


11

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

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

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

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


「本番」から「テスト」に移行し、IDフィールドがある場合、データを上書きまたは衝突するリスクがあります。私が言っているのはそれだけです。ええ、それその方向の問題ではないはずですが、私はそれが起こる可能性があると言っているだけです。
jcolebrand

確かに、dev、test、qa、uat、およびproductionの異なる行の値には同じ番号が入ります。だから何?これらの値が重要な場合(ルックアップテーブルなど)、手動でハードコーディングします。これらのテーブルに値を頻繁に入力することはないので、問題にはなりません。衝突を回避するために環境間のID値を制御する必要がある場合は、実稼働環境から復元するときに、環境間のID値をリセットしてください。
mrdenny、2011年

5

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

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


4

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

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

基本的にテーブルを作成します。テーブル1に行を挿入する必要がある場合、ID PKを持つMasterIDsINSERT INTO MasterIDs使用してSCOPE_IDENTITY()、その行によって生成されたIDを取得し、その値をPKとして使用してTable1に挿入します。

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


3

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


2

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


1

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

私はかなり印象的なパフォーマンスの向上を見てきました。OPとは異なり、IDを生成するためのUDFがありません。しかし、原則はほとんど同じです。IDのプールを維持するソフトウェアの一部があります。彼らが実行すると、それは次のデータベースを照会することによって、別のバッチを取得し、低値と次に刻み、この高いです

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

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


0

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

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


64ビットINTは...長い長い時間が続く
Vérace
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.