web-dev-qa-db-ja.com

データベース:郵便番号を住所の主キーとして選択することには意味がありますか?

SQLデータベースの通常の形式のチュートリアルに従っていたところ、この例に混乱してしまいました: https://www.tutorialspoint.com/sql/third-normal-form.htm

から

CREATE TABLE CUSTOMERS(
   CUST_ID       INT              NOT NULL,
   CUST_NAME     VARCHAR (20)      NOT NULL,
   DOB           DATE,
   STREET        VARCHAR(200),
   CITY          VARCHAR(100),
   STATE         VARCHAR(100),
   Zip           VARCHAR(12),
   EMAIL_ID      VARCHAR(256),
   PRIMARY KEY (CUST_ID)
);

「郵便番号と住所の間に推移的な依存関係」があるため、このような新しいテーブルADDRESSが作成されます。

CREATE TABLE ADDRESS(
   Zip           VARCHAR(12),
   STREET        VARCHAR(200),
   CITY          VARCHAR(100),
   STATE         VARCHAR(100),
   PRIMARY KEY (Zip)
);

これは私が本当に混乱しているところです。郵便番号を主キーとして使用する理由主キーは一意である必要があります。同じ郵便番号の2つのアドレスを使用することはできませんか?

どちらか

  • 郵便番号の仕組みがわかりません
  • 主キーの仕組みがわかりません
  • この例は明らかに間違っています
  • 他のことはわかりません。
2
Ricola

この例は根本的な誤りを犯しています。データを主キーとして使用しています。一意のIDを作成して使用する必要があります。

コメントは、郵便番号が特定の通りにマップすると仮定することがどれほど正しいかを議論しています。それが正しいかどうかに関係なく、簡単な事実は、一意のIDなしでこれを機能させるには、現在だけでなく、永遠に正しい必要があるということです。これがまさにこれが間違っている理由です。あなたはおそらく未来を知ることができません。一意のIDを使用してください。

郵便番号が、現在正規化しているデータを一意に識別している場合は、自然なキーがあります。しかし、レコードを1つだけ追加すると、それが破壊される可能性があります。データのインポート時に自然キーを使用して、一意のID関係を構築できます。アプリケーションがユーザーからデータを収集しているときに、関係が本物であることを確認できる場合は使用しないでください。

人々は、これら2つのユースケースの構造化データを常に混乱させています。運用システムでは、一意のIDを常に優先する必要があります。問題は、それらが常に存在するとは限らないことです。そうでない場合は、正規化するときにデータフィールドを自然キーとして選択することで一意性を構築できます。しかし、その構築された独自性は常に脆弱です。それは今しか本当ではないかもしれません。一意のIDを生成するために、今は真実であるという事実を使用しても問題ありません。ただし、その後は新しいデータに一意のIDを適切に割り当てる必要があります。

さらにデータが追加されても、一意のIDは侵食されません。多くの場合、自然キーが使用します。現実とは無関係に自然な鍵の仮定が成り立つと主張するシステムを開発している開発者は、オペレーターが回避しなければならないという問題を引き起こすことがよくあります。しないでください。

13
candied_orange

主キーとして郵便番号を使用することは正しくありません。チュートリアルの作成者は正しいです。というのは、テーブルを注意深く調べて、何を分割すればグランドスキームの大量の重複データを減らすことができるかを判断する必要があるからです。ただし、Zipコードは一意ではありません。複数の顧客が同じZipコードに住んでいる可能性が高いからです。郵便局が使用する余分な4桁が追加されたとしても、それは常に一意であるとは限りません。世帯に住む複数の人が顧客になる可能性があるため、住所自体も一意ではありません。実際、アドレスがこのように分割される場合、複合キーの任意の組み合わせでは重複キーの可能性がまだ除去されないため、テーブルの一意のIDを作成するのが最善の方法です。 tutorialspointの例は、3nFの良い例または正しい例ではありません。

各正規化形式で探すべき基本は次のとおりです。

  • 1nF:列が水平にならないようにします。
  • 2nF:目的が1つだけになるまでテーブルを分割します。顧客と注文が分離されるように注文を含む顧客テーブルを分解するようなものです。
  • 3nF:「推移的」とは、基本的に、主キーを確認せずに1つの列を別の列で決定できることを意味します。顧客注文テーブルと同様に、orderID、顧客、製造元、および製品を列として持つことができます。製品はメーカーによって決定される場合があるため、製品列またはその逆は実際に注文番号に依存する必要はありません。これは、productIDまたは製造元が主キーになる2つのテーブルに分割できるテーブルになります。新しいテーブルの主キーは、注文テーブルの外部キーとして使用されます。
  • 4nF:各列にデータのみがあることを確認します。メーカー表を使ってみましょう。製造元の列が主キーである場合、同じ行/列に複数の製品が存在する可能性があります。これは最良の例ではないと思いますが、あなたがアイデアを得ることを願っています。したがって、4nFの場合、複数の製品のように、同じ場所に複数のデータが存在しないようにする必要があります。

3nFと4nFは、厳密な基準として企業によって常に使用されるとは限りませんが、可能な場合は知って使用することをお勧めします。また、他の人が述べたように、列の1つではなくIDを主キーとして使用すると非常に便利です。たとえば、顧客の姓、名、ユーザー名から複合キーを作成したり、SSNなどの機密情報を保存したりする代わりに、自動生成されたIDを主キーとして使用できます。

4
Steven Mcdonald

この例は明らかに間違っています。

これは過剰正規化の良い例です。理論的に可能なすべてのものを正規化することで、将来は成り立たないソリューションを作成できます。

かなり恒久的に見える可能性のある米国の郵便番号でさえも(私は米国の郵便番号の専門家ではありませんが、チュートリアルの作成者に疑いの利益を与えます)、通りを定義する可能性があります。一般的な。

一部の国では、ユーザーが住所を入力できるように郵便番号表を用意しておくのが理にかなっていますが、住所はレコードごとに保存する必要があり、キーから参照する必要はありません。

しかし、通りは名前を変更し、再構築され、新しい住宅がそれに沿って建設されると2つの郵便番号に分割されます。

しばらくすると、データベース内の住所の1つが変更されます。おそらく通りの名前が変更されます。これで、郵便番号のエントリを編集し、その郵便番号を使用する他のすべての住所が間違っているため、後で理由がわからなくなり、変更前の住所の手がかりがなくなります。

私が育った場所では、電話番号の最初の4桁から郵便番号を取得できます。チュートリアルの作成者のロジックで説明すると、両方ともCustomersテーブルに含まれていません。

3
Bent