web-dev-qa-db-ja.com

文字と整数の主キー

メインエンティティの可能な属性を含む複数のルックアップテーブルを持つデータベースを設計しています。自動インクリメントする整数ではなく、4または5文字のキーを使用してこれらのルックアップ値を識別することを考えているので、これらの属性IDをメインテーブルに格納すると、単なる乱数ではなく意味のある値が表示されます。

文字フィールドを整数ではなく主キーとして使用すると、パフォーマンスにどのような影響がありますか?

それが重要な場合は、MySQLを使用しています。

[編集]
これらのルックアップテーブルには、まれに追加される新しいレコードがあります。それらは手動で維持され、文字ベースのキーも手動で作成されます。次に例を示します。

      CUISINES
 ID      Description
-----  --------------
CHNSE  Chinese
ITALN  Italian
MXICN  Mexican
31
BenV

エンジンによって異なります。よく知られているのは、読み込みが安価で、ここでは数バイトであり、中小規模のデータベースのパフォーマンスに大きな影響を与えないということです。

さらに重要なことは、主キーを使用する用途によって異なります。整数シリアルには、使用と実装が簡単であるという利点があります。ほとんどのデータベースはシリアル番号を派生ではなく固定された場所に格納するだけなので、シリアル化メソッドの特定の実装に応じて、迅速に派生可能であるという利点もあります。オンザフライでSelect max(ID)+1 from fooを使用します。

問題は次のとおりです。5文字のキーは、あなたとアプリケーションに「意味のある価値」をどのように提示するのでしょうか。この値はどのように作成され、増分するシリアル番号を見つけるよりも多少時間がかかりますか。一部の整数ではわずかなスペースが節約されますが、システムの大部分はこのスペースの節約を無視します。

パフォーマンスへの影響はありません。「キー」が存在しないため、文字スキームでは自動エンジンが決してないことが必要です。特定のドメインについては、人工的なキーを気にせず、キー名として中国語、日本語、タイ語を使用してください。可能なアプリケーションの一意性を保証することはできませんが、スコープでは、ひどい、強制的な5文字の略語の代わりにそれらを使用する方がはるかに合理的です。数百万のタプルに到達するまで、パフォーマンスに大きな影響はありません。

または、特定の郷土料理(広東料理、四川料理、シチリア料理、ウンブリア料理、カラブリア料理、ユカテカン料理、オアハカ料理など)ではなく、原産国だけで追跡する場合は、常に ISO 3166を使用できます。コード

レシピが10,000ある場合、5文字のキーと20文字のキーの違いが増え始めませんか?

スペースはcheapです。 OLAP操作を実行している10,000,000のレシピを話しているとしたら、多分。

しかし、再び、それは依存します。何百万ものレコードがあり、それらに対して結合を実行している場合は、この簡単なもの(マテリアライズドビューへ)のルックアップを非正規化することは理にかなっています。すべての実用的な目的で、5文字のキーと可変長キーの間の最近のマシンでの相対的な結合効率は非常に似ているため、まったく同じです。幸いにも、私たちは豊富なCPUと豊富なディスクの世界に住んでいます。厄介なのは、文字ごとの比較ではなく、多すぎる結合とクエリの非効率性です。そうは言っても、常にテスト

このレベルのP&Tはデータベースに依存しているため、一般化は非常に困難です。データベースの2つのサンプルモデルを作成し、それらに推定レコード数を入力して、どちらが高速かを確認します。私の経験では、文字の長さは、適切なインデックス、適切なメモリ構成、およびその他の重要なパフォーマンス調整要素と比較して大きな違いはありません。

22

めったに変更されないテーブルのパフォーマンスには問題はないと思います。多分あなたは将来デザインに問題を抱えることになるでしょう。ビジネスの変化のため、ビジネスデータを主キーとして使用しないことをお勧めします。追加の主キーを使用して、モデル内のテーブルを「リンク」します。ビジネス上の変更は、この1つのテーブルに関連するものには影響しません。

8
garik

本当の問題は、DBクエリのパフォーマンスがアプリケーション(データサイズ)に対してまったく重要かどうかです。クエリに数マイクロ秒かかる場合、Intキーを使用してそれらの数マイクロ秒を節約することは、読みやすさ/保守性のペナルティに値しません。ただし、クエリに数分かかる場合は、それらの数分の一部を保存することは、Intキーの痛みに値するかもしれません。

以下は、整数によってクエリ時間を節約できる(全体的なクエリ時間のパーセンテージとして)と思う理由ですが、SkySparkの創設者は私よりも それを説明することができます 。完全な開示として、私の雇用主はSkySparkにDBを使用するために多額のお金を払っています。私はより良い/より速いものを構築しようとしています。

ルックアップテーブルのいずれかにリンク(関係)を持つ多くのシーケンシャルデータ(ログファイル、時系列、分析、テキストまたは音声コーパス)がある場合、@にもかかわらず、ストレージスペースがクエリの速度にとって重要であることがわかりますBallsun-Stantonによるcheapスペースの$内の正しい分析。ほとんどのクエリ時間(シーケンシャルデータの場合)はディスクの読み取りに費やされるため、時間(全体のクエリ時間の割合として)の観点から、スペースはcheapではありません)。したがって、RDBがすべての外部キー(関連レコードへのキー)を自動的かつ効率的に圧縮/解凍しない限り、すべてのキーをIntにする必要があります。これは、ディスク領域(および読み取り)の観点で最も効率的です。速度)情報コンテンツの単位あたり(エントロピー)。 MySqlのFYI MyISAMは、圧縮データ行で実行できること(読み取り専用)に制限 を設定します。つまり、ほとんどのDB整数フィールドの最小サイズ制限が低いため、自動インクリメントされた整数は、理論的に可能な限り 既に圧縮されています 。そして、その圧縮には、

  1. クエリ時の圧縮/解凍のペナルティ
  2. クエリ時のディスク読み取りペナルティ
  3. 圧縮データレコードまたはキーに対する読み取り専用またはその他のDBの制限

Djangoのような人気のある効率的なORMがデフォルトでPKの整数を自動インクリメントする 理由と、他の SO質問 が来た理由があります同じ結論。

3
hobs