文字対整数の主キー


30

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

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

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

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

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

回答:


22

エンジンに依存します。一般的な常識は、読み取りは安価で、ここでは数バイトであり、中小規模のデータベースのパフォーマンスに大きな影響を与えないということです。

さらに重要なことは、主キーを使用する用途によって異なります。整数シリアルには、使用と実装が簡単であるという利点があります。また、シリアル化方法の特定の実装に応じて、ほとんどのデータベースはシリアル番号をオンザフライで取得するのではなく、固定された場所に保存するだけなので、迅速に導出できるという利点がSelect max(ID)+1 from fooあります。

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

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

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

レシピが10,000個ある場合、5文字のキーと20文字のキーの差は増えませんか?

スペースは安い。たぶん、OLAP操作を行っている10,000,000のレシピを話しているとき。10kのレシピを使用すると、150kのスペースが表示されます。

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

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


@ BrianBallsun-Stantonこれらのルックアップテーブルに関連するかさばるシーケンシャルデータがある場合、RAMに完全にキャッシュできないRDBのディスク読み取り速度がボトルネックであるため、ストレージスペースは(クエリ速度の点で)安くありません。時系列DBビジネスのベストと競合できるRDBスキーマを開発しようとしているときにこれを発見しました。完全な開示、Skysparkとは関係がありませんが、彼らは非常に効率的なDBの使用に対して雇用主に多くを請求します。
ホブ

8

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


3

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

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

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

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

Djangoのような一般的で効率的なORM がPKの整数を自動的にインクリメントするようにデフォルト設定されている理由と、他のSOの質問が同じ結論に達した理由があります。

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