SQL Serverでは、主キーを使用することの欠点と欠点は何ですか。
2文字のテーブル識別子+ YEAR + MONTH + DAY + HOUR + MINUTE + MILLISECOND + 0〜100のランダムな整数?
なぜこれはInteger Auto_Incrementedフィールドを使用するよりも好まれますか? (そうでなければ、私もそれを知りたいです。)
これが本当に悪い設計慣行である理由が好きです。その整数値を取り戻すためにすべてをキャストすることも、お尻の苦痛です。
私は基本的に、ひどく必要なアプリケーションのデータベースを改善するために私の小さな開発者チームにアクセスする機会を一度与えます-左詰めゼロの主キーVarchar(50)フィールドのような状況を回避するため、または単に非-正規化されたデータベース、または1つのフィールド内のコンマ区切りリスト。
もちろんできますが、なぜそうするのでしょうか。いくつかのCAST式を保存するには?それは少し弱いようです。
自動インクリメントサロゲートint PKを使用する理由は多数あります。
私の最後の考え:複合キーは、多くの変更の影響を受けない(管理オーバーヘッドが低い)メンバーの数が少ない(つまり、複合キーが短いため、必要なスペースが少ない)ルックアップテーブルのFINEです。たとえば、米国の2文字の州コードです。それらは、潜在的に結合が1つ少なく、多くのストアドプロシージャを超えることを意味します。これにより、小さいながらも測定可能なパフォーマンスが向上する可能性があります。
あなたのアイデアはそれほどクレイジーではありません。主キーの順序付けは断片化を減らしますが、これはIDENTITY列で実現できます。ただし、順序付けされたキーにも欠点があります。つまり、ここに記載されているもの http://kejser.org/clustered-indexes-vs-heaps です。
これで、キーが生成されたときに、そのために少し追加の情報をパックする必要があることを知ることがどのように役立つかがわかります。これは正規化規則に違反していますが、それらは学者向けであり、実際のシステム設計者向けではありません。
テーブル名をキーの前に付けると、どこから来たのかを知っていると思います(間違っている場合は修正してください)。これにより、ユーザーが間違ったキーに参加して不正なデータを取得することがなくなります。
戦略を維持し、優れた物理設計の利点を維持したい場合は、次のようにします。
上記の戦略を使用すると、毎日2Bキーを生成できます。これで十分です。そうでない場合は、年を2桁に削減することを検討してください(そうですね、そうですね...)
この上記の戦略は、これが持つ利点と欠点を備えた、順次配置されたインデックスを作成します。キーロジックを変更してよりスケーラブルなレイアウトを使用する場合は、ここで説明するトリックを使用して下位32ビットのビットシーケンスを反転できます。 http://dangerousdba.blogspot.co.uk/2011/ 10/day-sequences-saved-world.html 。
これは、自動インクリメント整数フィールドよりも間違いなく推奨されません。
手始めに:
余談として;いったいなぜ、この新しいフィールドのすべてのインスタンスに2文字のテーブル識別子を挿入したいのですか?行が形成された表は、検査されている表からすぐにわかります。
多数のサイトにわたるデータの衝突率が非常に高く、このようなスキームを正当化できると本当に思う場合は、少なくとも、このNIH設計の代わりに、すでに実装されているテクノロジであるGUIDを使用してください。
更新
自動インクリメントキーの単調な性質は、一部の 合計を実行するための非常に効率的な集計テーブルアルゴリズム(少なくとも) で使用され、実行合計の計算の適切な順序付けを強制します。このスキームは、それらのアルゴリズムの使用を無効にします。
私の好みは、主キーにID列を使用し、必要に応じて一意性を適用する必要がある場合は、他のフィールドに一意インデックスを追加することです。
私の意見では、主なキーの仕事は、単一のデータ行を一意に識別することです。整数は、あいまいさのリスクなしにこれをより効率的に行います。
Varcharsをpkeyとして、または結合で使用することは、スペース、大文字/小文字、パディング、先行ゼロ、または暗黙的な変換の影響を受ける可能性があるため、嫌いです。
明確な値を持つ単一のフィールドに単純なpkeyがあると、全員の作業が容易になります。
うーん、私はあなたに同意します、そしてあなたの行を識別するために任意の整数を使用することを提案する人々にはほとんど同意しません。
あなたの主キーは
tid char(2), asof datetime, sequence smallint
ここでシーケンスを制御します。 行を識別するであるため、これは完全に優れた主キーです。 「よりきめ細かい」識別子が必要になる状況を説明するのは、代理群衆の負担です。
これにより、16バイトのキーが得られます。それは正しく、ほとんど巨大ではなく、サロゲートキーよりもmore効率的ではありません。どうして?
日付を表すには、文字データの代わりにdatetime
を使用します。自動日付検証が行われ、日付計算が大幅に簡略化されます。
また、シーケンス番号は本当に必要ですか?そうでない場合は、ドロップできます。もしそうなら、それはanother自動インクリメント値を避ける理由です:すべての挿入は同じ場所から自動インクリメント値を取得する必要があるため、これらはリソース競合のポイントです。
シーケンス番号が必要な場合は、次のようにします。
insert into T as t
select /* values ... */ , 1 + coalesce(max(sequence), 0) as seq
from T
where tid = t.tid and asof = t.asof
insert ... select
の原子性は、各プロセスが異なる値を取得することを保証するためです。