9

複数のクライアントが使用するデータベースがあります。クライアント間で代理の増分キー値が出血することは本当に望んでいません。番号付けを 1 から開始し、クライアント固有にしたい。

の 2 つの部分からなる複合キーとtenant_id増分 ID を使用します。

テナントごとに増分キーを作成する最良の方法は何ですか?

SQL Server Azure を使用しています。テーブルのロック、重複キーなどについて心配しています。通常、主キーを IDENTITY に設定して先に進みます。

ありがとう

4

2 に答える 2

2

今後、SQL Azure フェデレーションを使用する予定はありますか? その場合、SQL Azure フェデレーションの現在のバージョンは、クラスター化インデックスの一部としての IDENTITY の使用をサポートしていません。詳細については、SQL Azure (フェデレーション) のテーブルでクラスター化されたインデックスとして guid を使用するための代替手段が存在することを参照してください。

フェデレーションをまだ見ていない場合は、データベースをシャーディングし、データベース内でテナントを分離するための興味深い方法を提供するので、チェックしてみてください。

最終的な目標によっては、フェデレーションを使用して、GUID をテーブルのプライマリ クラスター化インデックスとして使用したり、テーブルの増分 INT IDENTITY フィールドを使用したりできる場合があります。この INT IDENTITY フィールドは、エンドユーザーに表示される可能性があります。TenantID でフェデレートしている場合、各「テナント テーブル」は効果的にサイロになります (少なくとも私が理解しているように)。そのため、そのテーブル内のフィールドで IDENTITY を使用すると、特定のテナント内で増加する自動生成された値が効果的に増加します。 .

データが一緒にマージされた場合 (複数のテナントからのデータを組み合わせた場合)、この INT IDENTITY フィールドで衝突が発生します (したがって、フェデレーションで IDENTITY が主キーとしてサポートされない理由) が、これを使用しない限りシステム全体で一意の識別子としてフィールドを使用しても問題ありません。

于 2012-10-22T19:11:28.710 に答える
1

INSTEAD OF INSERT挿入時に一意の INT キーが自動的に割り当てられる利便性を再現したい場合は、既存の列の MAX +1 を使用して次の値を決定するトリガーを追加できます。

ID 値を持つ列がインデックスの最初のキーである場合、MAX クエリは単純なインデックス シークになり、非常に効率的になります。

トランザクションは一意の値が割り当てられることを保証しますが、このアプローチは標準の ID 列とは異なるロック セマンティクスを持ちます。IIRC、SQL Server は、並行して要求するトランザクションごとに異なる ID 値を割り当てることができ、トランザクションがロールバックされると、それに割り当てられた値は破棄されます。MAX アプローチでは、一度に 1 つのトランザクションのみがテーブルに行を挿入できます。

関連するアプローチとして、テーブル名、テナント ID、および現在の ID 値をキーとする専用のキー値テーブルを用意することもできます。そのキーテーブルを更新してクエリを実行するには、同じINSTEAD OF INSERTトリガーとより多くのボイラープレートが必要になります。ただし、並列操作は改善されません。ロックは別のテーブルのレコードにあるだけです。

ロックのボトルネックを修正する 1 つの可能性は、現在の SPID をキーの値に含めることです (ID キーは、シーケンシャル int と、単にシーケンシャルではなく、たまたまそれを割り当てた SPID の組み合わせです)、専用の ID 値テーブルを使用して挿入します。必要に応じて SPID ごとにそこに記録します。ID テーブル PK は (テーブル名、テナント、SPID) であり、現在の連続値を持つ非キー列があります。そうすれば、各 SPID に独自の動的に割り当てられた ID プールがあり、独自の SPID 固有のレコードのみがロックされます。

別の欠点は、特別な ID テーブルの列を変更するたびに更新する必要があるトリガーを維持することです。

于 2012-12-18T22:05:46.557 に答える