これらの特定のテーブルには代理キーが必要ですか?


13

バックグラウンド

このテーブルがあります

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_code string (PK) |  |country_code string (PK)|
|address string           |  |name string             |
|name  string             |  +------------------------+
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_code string (PK)|
|name string              |
+-------------------------+

airport_codeは、IATA(国際航空運送協会)の 空港コードです。飛行機で旅行する場合は、荷物タグで確認できます。

ここに画像の説明を入力してください

country_codeISO 3166-1 A3標準の国コードです。オリンピックで見ることができます。

ここに画像の説明を入力してください

currency_codeは、IS0 417標準の3文字の通貨コードです。国際通貨交換の表示板で確認できます。

ここに画像の説明を入力してください

ご質問

これらの自然なPKは十分ですか?

業界全体で受け入れられているPKにとって十分な世界的に尊敬されている標準を使用していますか?

この表には、何があっても代理変数が必要ですか?

回答:


15

いいえ、そうではありません。これらのキーは間違いなく十分です!

これらは一意であり、 めったに変更されることなく意味のあるものであり、サロゲートキーよりも上位です。それが、かなり良いPKの定義です。

不変で数値整数であるPKに関する制限は、リレーショナルモデル(コッド)またはSQL標準(ANSIまたはその他)の一部ではありません。


3
主キーも不変でなければなりません。IATA空港コードは絶対にそうではありません。IATAの気まぐれで変更できます。
ジェームズスネル

3
@JamesSnell-IATA空港コードは、国コードとほぼ同じ不変です。もしそうなら、あなたはたぶん10年に一度の変化について話している。問題の議論についてはこちらをご覧ください。変更するには手間がかかりすぎるため、まだ残っている古いコードがたくさんあります。さらに、それがCASCADE更新の目的です。 可変プライマリキーは、素晴らしいプラクティスではありませんが、正当です。
ボブソン

2
@EricKingこれらのサードパーティは、多くの業界のすべての主要なパーティの代表者で構成されており、その後数年にわたって規格が議論され、合理的な合意に達するまで投票されます。また、変更または新規追加が行われるメカニズムについても同意します。それに加えて、コードリスト標準は気まぐれではなく作成されますが、世界中で相互運用し、世界中で適切に通信できるようにするために、制御され、尊敬され、合意された何かのコードのリストを作成する必要があるためです。
Tulainsコルドバ

2
@ user61852-これらの標準は主キーとさていると言えます。
ボブソン

3
@Bobson:「変更するのが面倒だからまだ残っている古いコードがたくさんある」->おそらくそれらが主キーだから?
マチェイ

2

私は考える必要性が非常に強い言葉であり、厳密な意味では、テーブルはおそらくありません必要な代理キーを

ただし、データベースの場合は、とにかくサロゲートキーを追加します。標準がどれほど安定しているかに関係なく、データベース設計を多数のサードパーティ(IATA、ISO)に依存させる必要は必ずしもありません。または、特定の標準にまったく依存したくない場合があります(他の通貨コード標準はありますか?知りません)。私はおそらく、次のような代理キーを使用してテーブルをモデリングします。

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+

言い換えると、これらの業界標準コードがアプリケーションにとって本質的に重要でない限り、それらをテーブルのPKとして使用することはありません。それらは単なるラベルです。私の他のテーブルのほとんどはおそらくとにかく代理キーを持っているでしょう、そしてこのセットアップは私のデータモデルに一貫性を追加します。代理キーを「追加」するコストは最小限です。

いくつかのコメントに基づいて更新します。

サンプルテーブルのコンテキストを知らないと、データベースを使用するアプリケーションにとってIATA空港コードなどの重要性を知ることは不可能です。明らかに、アプリケーション全体でIATAコードが中心的に重要であり、広く使用されている場合、適切な分析の後、コードをテーブルのPKとして使用することが正しい決定になる可能性があります。

ただし、テーブルがアプリのいくつかのコーナーで使用される単なるルックアップテーブルである場合、IATAコードの相対的な重要性は、データベースインフラストラクチャ内のそのような顕著なスポットを正当化できない場合があります。確かに、あちこちのいくつかのクエリで追加の結合を作成する必要があるかもしれませんが、その努力は、IATAコードを作成することの意味を完全に理解するために研究を行うのにかかる労力と比べると些細なことかもしれません主キーフィールド。場合によっては、気にしないだけでなく、IATAコードを気にする必要はありません。以下の@James Snellのコメントは、テーブルのPKに影響することを心配する必要はないかもしれないものの完璧な例です。

また、設計の一貫性が重要です。すべてが一貫してサロゲートキーを設計した多数のテーブルを含むデータベースがあり、その後、サードパーティコードをPKとして使用しているルックアップテーブルがいくつかあると、矛盾が生じます。それは完全に悪いことではありませんが、ドキュメントには特別な注意が必要であり、保証されないかもしれません。これらは参照テーブルであり、一貫性のために代理キーを使用するだけで十分です。

さらなる調査に基づく更新:

OK

判明したように、IATAコードは、質問がそれらを明らかにするほど普遍的で信頼できるものではありません。このページによると:

ほとんどの国では、公式の航空刊行物でIATAコードではなく、4文字のICAOコードを使用しています。

さらに、IATAコードとICAOコードは、飛行場を識別するもう1つの方法であるFAA識別子コードとは異なります。

これらを提起する私のポイントは、どのコードがより優れているか、より普遍的であるか、より権威あるか、より包括的なかについて議論を始めることではありませんが、任意のサードパーティ識別子を中心にデータベース構造を設計することが私が選択するものではない理由を正確に示すことです、そうする特定のビジネス上の理由がない限り

この場合、私は感じて、私のデータベースはプライマリキー候補としてIATAコード(またはいずれかのサードパーティ、潜在的に変更可能なコード)の前述および代理キーを使用することによって、より良い、より安定した構造化し、より柔軟なことでしょう。そうすることで、主キーの選択が原因で生じる可能性のある潜在的な落とし穴を避けることができます。


1
IATA規格は航空会社にとっては十分ですが、あなたにとっては十分ではありませんか?
Tulainsコルドバ

1
もちろん、ロンドンヒースロー空港から荷物を探したい場合は、空港のテーブルまでずっと参加する必要があります。できないのでselect * from baggage where airport_code = 'LHR'、データベースはアプリケーションを投げるだけです。特に、ビジネスオーナーがデータベースの代金を支払い、それを所有している場合にアプローチします。また、PKコリジョンを回避するために、あるデータベースから別のデータベースにデータをインポートするなどの日常的なことを行うコードを記述する必要があります。
Tulainsコルドバ

1
IATAコードは不変ではないため、PKの候補と見なすことはできません。例:コードIDLは、JFKに名前が変更されるまでニューヨークにありました。IDLコードは現在ミシシッピ州にあります。
ジェームズスネル

2
@EricKing IATAとISOは、コードが十分に安定しており、独自性があり、普遍的に受け入れられていることを重視しています。これは、テーブルを設計する人の興味とよく一致します。
Tulainsコルドバ

2
@ user61852-これらが標準コードであるからといって、航空会社のシステムがそれらをPKとして使用することを意味するわけではありません(ここでより多くの洞察を得られるでしょうか?)。このような大規模なカスケード更新を行うことは、非常に悪い考えのようです。
ジェフ

1

フィールドに代理キーを置くことは問題ありませんが、インデックスページのサイズ自体を考慮することは問題ありません。

これはリレーショナルデータベースであるため、多くの結合を行い、数値型の代理キーを使用すると、データベースでの処理が容易になる場合があります。つまり、インデックスページサイズが小さくなり、トラフの検索が高速になります。これが小さなプロジェクトである場合、それは問題ではなく、問題なく通過できますが、アプリケーションが大きくなればなるほど、ボトルネックを減らすことができます。

BIGINT、INT、SMALLINT、TINYINT、または整数のようなデータ型を使用すると、今後のトラブルを軽減できます。

ちょうど私の2セント

更新:

小さなプロジェクト-数人、おそらく数十人が使用します。小規模、デモプロジェクト、個人用プロジェクト、経験のないスキルを提示するときにポートフォリオに追加するものなど。

大規模プロジェクト-毎日数千、数万、数百万のユーザーが使用しています。巨大なユーザーベースを持つ国内/国際企業のために構築するもの。

通常起こることは、レコードの選択された少数が頻繁に選択され、サーバーが高速アクセスのために結果をキャッシュすることですが、時々、使用頻度の低いレコードにアクセスする必要があります。ページ。(上記の空港名の例では、多くの場合、国内の航空会社を飛行します。チチャゴ->ロサンゼルスと言いますが、ボストン->ジンバブエからどれくらいの頻度で飛行しますか)

VARCHARが使用されている場合、データが常に同じ長さでない限り、間隔が均一ではないことを意味します(その時点でCHAR値がより効果的です)。これにより、インデックスの検索が遅くなり、サーバーがすでに毎秒数千および数千のクエリを処理しているため、不均一なインデックスで時間を無駄にし、結合で同じことをもう一度行う必要があります最適化されていないテーブルでの通常の選択。データ検索を高速化するために可能な限り少ない結合がある場合の例としてDWを取り上げます。また、データベースエンジンを混乱させる可能性のあるUTFを使用している場合もあります(いくつかのケースを見てきました)。

個人的には、適切に編成されたインデックスにより、結合の速度が〜70%増加し、整数列で結合を実行すると、結合の速度が〜25%程度になります(データに応じて) 。メインテーブルが大きくなり始め、これらのテーブルがそれらで使用されるようになると、より多くのスペースを占有するVARCHAR / CHARフィールドではなく、整数データ型が数バイトの列を占有します。これは、ディスク容量の節約、パフォーマンスの向上、およびリレーショナルデータベースの全体的な構造に帰着します。

また、ジェームス・スネルが述べたように:

主キーも不変でなければなりません。IATA空港コードは絶対にそうではありません。IATAの気まぐれで変更できます。

したがって、これを考慮すると、番号にバインドされている1つのレコードを更新する必要がありますか?その1つのレコードと、結合先のテーブル内のすべてのレコードを更新する必要があります。


これは妥当な考えですが、これらのテーブルのポイントは、各テーブルには有限量のレコードしかないということです。実際にsmall projectbiggerでコードサイズを意味する場合は、それが重要になる理由を明確にするために更新してください。
ボブソン

1
不変で数値整数であるPKに関する制限は、リレーショナルモデル(コッド)またはSQL標準(ANSIまたはその他)の一部ではありません。
Tulainsコルドバ

4
固定長の短い文字列(ISOコードなど)に基づくインデックスは、整数と同じくらい高速です。可変長に基づくインデックス、長い文字列はそうではありません。
Tulainsコルドバ

それは私が述べたものです(上記のVARCHARとCHARの部分を参照)固定長の短い文字列と数値整数をテストする機会はありませんでしたが、可変長と整数でテストする機会がありました
Toni Kostelac

2
参加パフォーマンスはストローマンです。多くの場合、自然キーを使用すると、そもそも結合する必要はありません。
マイクシェリル 'キャットリコール'

1

「常に代理キーを使用する」アプローチをとると、この種の懸念を回避できます。データを考えることが重要なので、これは良いことではないかもしれませんが、確かに多くの時間、エネルギー、労力を節約できます。誰もがこの規則への同意を採用する場合、変更を行うにはほぼ「議会の行為」を要するため、リストされた例は確かに適格です。

これらの自然キーを持つデータベースのアドホッククエリは確かに役立ちます。ルックアップテーブルを含めることで同じことを行うビューの作成も同様に機能します。最近のデータベースは、この種のデータを使って、おそらく問題にならない程度まで、はるかに良い仕事をします。

基準が大幅に変更された米国固有のケースがいくつかあります。郵便番号は5〜9桁に拡張され、州の略語は一貫した2文字になり、ピリオドがなくなります(イリノイが病気だったときを覚えていますか?)世界はY2Kに対処しなければなりませんでした。世界中に数十億のレコードを含むデータを含むリアルタイムアプリがある場合、カスケード更新は最良のアイデアではありませんが、このような課題に直面しているすべての場所で作業すべきではありませんか?このデータセットを使用して、自分でテストし、より重要な答えを見つけることができます。


+1すばらしい回答。ほとんどの場合、人々はこの問題について非常に独断的です。多くのデータベース設計者は巨大な自我を持ち、自分自身をデータベースとデータの所有者と考えています。他の人は、データの所有者が特定のアプリケーションを介してしかデータを使用できないことを理解しています。また、データのインポートやクエリの作成など、日常的に行われていることを生き生きとさせながら、将来発生する可能性のあるもの、または発生しない可能性のあるものを準備することを好みます。また、彼らの見解を支持するあらゆる種類の正典目録の作成に失敗した。
Tulainsコルドバ

ちなみに、「私は常に代理キーを使用します」というルールは、リレーショナルモデル(Codd)にもSQL標準にもありません。Oracleデータ・ディクショナリ・スキームでは、可能な場合は自然キーを使用し、他のインスタンスでは人工キーを使用します。PPDM(ppdm.org)も混合アプローチを推奨しており、モデルで使用しています。ANSI SQL Standardは、全代理について何も述べていません。すべての代理人とすべての自然は腐食性だと思います。一部の自然および一部の代理は、リレーショナルモデルが教えるものです。
Tulainsコルドバ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.