web-dev-qa-db-ja.com

文字列キーの使用が一般的に悪い考えと考えられているのはなぜですか?

これはしばらくの間私を悩ませてきました。ほとんどの場合、ハッシュテーブル、プログラマー、本、記事などの構造にデータを格納することになると、文字列値によって前記構造の要素にインデックスを付けることは悪い習慣だと考えられています。しかし、これまでのところ、それが悪い習慣であると考えられる理由を説明するためのそのような情報源は1つもありません。それはプログラミング言語に依存しますか?基礎となるフレームワークについて?実装については?

役立つ場合は、2つの簡単な例を見てみましょう。

文字列の主キーによって行がインデックス付けされるSQLのようなテーブル。

キーが文字列である.NET辞書。

25
user52800

基本的には、次の2つのことすべてに関係しています。

1)ルックアップの速度(たとえば、整数ははるかに優れています)

2)インデックスのサイズ(文字列インデックスが爆発する場所)

これはすべて、ニーズとデータセットのサイズに依存します。テーブルまたはコレクションに10〜20個の要素が含まれている場合、キーのタイプは関係ありません。文字列キーでも非常に高速になります。

追伸質問とは関係ないかもしれませんが、Guidはデータベースキーにも不適切と見なされます(16バイトのGuidと4バイトの整数)。データ量が多い場合、Guidは検索を遅くします。

18
bunny

キーとして文字列を使用すること、またはより正確に、文字列リテラルをキーとして使用することには、純粋なパフォーマンス/効率の理由を別にして、もう1つの問題があります。タイプミス。文字列リテラルをディクショナリのキーとして使用する場合、"ReceiverId""RecieverId"になると、厄介な驚きに陥ります。キー値を格納する定数を設定し、辞書にアクセスするたびにそれらを再利用します。

些細で明白なことですが、Web上の驚くべき数の.NETコードの例では、文字列リテラルを使用しており、この疑わしい習慣を広めています。すべてのセッション、ViewStates、およびQueryParamsがコードベース全体に散らばったASP.NETは、ここで特に有罪です。

10
scrwtp

ここには多くのトレードオフがあります。実際には文字列キーを頻繁に使用しますが、結合には代理のセカンダリキーを含めることがよくあります(MySQLを使用している場合は明らかに逆になります)。ただし、そうでない場合もあります。

まず私は、dbがこれを適切に処理できるプライマリキーとしてナチュラルキーを宣言するファンです(たとえばPostgreSQL)。これは正規化に役立ち、より明確なデータベース設計を可能にします。代理キーにより、参加が簡単になります。

通常、代理キーを追加する理由は2つあります。

  1. 自然な鍵が何であるかが常に明確であるとは限りません。時にはこれらを変更する必要があります。結合および参照整合性に使用するときに自然な複合キーを変更することは複雑で、エラーが発生しやすくなります。

  2. 複合キーの結合パフォーマンスには問題があり、自然なキールートをたどると、そこに行き詰まります。

ただし、自然キーが定義的で、単一の列とテキストの場合、通常は文字列キーで結合します。これを行う理由は、これによりルックアップでの結合が回避されることが多いためです。最も一般的な使用法は、列挙型のユースケースを中心に適切なdb設計を提供することです。ほとんどの場合、これらはnotを実行して、ルーチンクエリの追加の結合を必要とします。したがって、これが当てはまる場合、文字列キー(結合キーとしては完全に意味があります。

たとえば、LedgerSMBでは、アカウントの分類を保存します。これらは文字列参照によって識別されます。他のいくつかのデータは文字列参照と共に保存され、アカウントに影響を与える可能性のある分類の組み合わせに関するルールを適用するために使用されます。ロジックが必要になるのは、一連の分類を保存するときだけなので、文字列キーで結合します。

なぜデフォルトが整数キーになるのかについては、インデックスサイズの問題だけではないと思います。大きな問題はキーの管理です。キーは任意であり、何百万ものレコードを処理している可能性があるため、一意の文字列を生成する方法が必要です。人々がこれにUUIDを使用する場合がありますが、UUIDの衝突の可能性はゼロではなく、何十億ものレコードが格納されている場合、この可能性は、インクリメントされた整数型との衝突の可能性がゼロである間に実際に見られるほど高くなります。定義により。

4
Chris Travers

文字列をキーとして使用することには、特にSQLのようなテーブルに関しては、いくつかの潜在的な問題があります。 @bunnyで述べたように、テーブルのインデックスは大きくなりますが、もっと重要なことは、テーブルへの外部キーの関係には、軽量(整数)の識別子ではなく、両方のテーブルに文字列が含まれることになると思います。最初のものへの参照を持つさらに多くのテーブルがあることがわかった場合、文字列キーはデータベース全体に増殖します。

1
Matthew Flynn

それ自体は悪い考えではありません。通常、20/20の事後判断では、設計の妥協が不十分です。ストリングの柔軟性と範囲と追加のコストおよび複雑さ。

整数が適切な範囲で機能し、高価な処理の大部分が整数が何を表すかを知る必要がない場合は、整数を使用します。

1
Tony Hopkinson

どういうわけか、Hashtableから間違ったデータを取得しました。

「DaytimeTelephone」または「EveningTelephone」ですか?

または

1234567か1234576ですか?

数字は間違いなくmachineの方が効率的ですが、物事がうまくいかない場合は(実際にそうなります)、何が起こったのかを理解するためにyou and Iのようになります。その時点で、数バイトのストレージと数マイクロ(ナノ?)秒の処理の節約は、毎回明快さを失うことになります。

0
Phill W.