2

以下の例を正確にどこまで正規化しますか? また、この例は正確にどのレベルの正規化を満たしていますか?

CREATE TABLE "public"."contact_info" (
  "id" SERIAL, 
  "home_phone" TEXT, 
  "mobile_phone" TEXT, 
  "work_phone" TEXT, 
  "fax_phone" TEXT, 
  "email" TEXT, 
  "line1" TEXT, 
  "line2" TEXT, 
  "city" TEXT, 
  "state_id" INTEGER, 
  "zipcode" TEXT, 
  "preferred_type" TEXT, 
  "first_name" TEXT, 
  "last_name" TEXT,
  CONSTRAINT "contact_info_pkey" PRIMARY KEY("id"), 
  CONSTRAINT "contact_info_fk_state_id" FOREIGN KEY ("state_id")
    REFERENCES "public"."states"("id")
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE
) WITH OIDS;

各レコードには、自宅、携帯電話、職場、またはファックス番号のレコードを 0 または 1 つだけ含めることができることに注意してください。各電話番号は、完全に機能的に私の主キーに依存しています。データベースの正規化について私が知っていることから、これは 5NF を満たしていると思いますが、6NF は失敗しています。

電話番号の定義は固定されているため (新しい電話番号の種類、複数の home_phone エントリなどはありません)、電話番号を (contact_info_id、phone_number、type) で追跡される別の関係に分割したい理由はありますか? ?

4

9 に答える 9

2

私はそれを正規化しません。得られるものはあまりありません。8 MB の RAM と 32 MB のハード ドライブを搭載した 8 ビット コンピュータでデータベースを実行することはもうありません。これは、この例に固有のものです。複雑なデータ構造は正規化する必要があります。

唯一の本当のスペースセーバーは電話番号であり、平均して10文字幅です。それを正規化してbigint-foreign-referenceに置き換えると、あまり得られないように見えますが、ランタイムは:Pに参加します。その上、電話番号のタイプを表す int が必要です。

于 2009-12-07T22:35:19.950 に答える
2

テーブル設計の一般的な経験則は次のとおりです。テーブルの一部の列に高い割合で NULL 値が含まれると予想される場合、これらの列はおそらく別のテーブルに配置する必要があります。とにかく、パフォーマンスの問題が発生しないと予想され、データベースを維持するときに役立つ場合は、非正規化された設計で問題ないかもしれません。

于 2009-12-07T22:38:23.967 に答える
2

このシステムは、各タイプの電話番号を 0 または 1 つだけ持つように定義したため、システムは、より正確なシステムよりも高いレベルの正規化を満たしています。

個人的には、ID、パブリック ID、タイプ、市外局番、交換局、接尾辞、内線番号を含む別のテーブルに電話番号を保存します。これらの値の特定の 1 つをすべて選択する必要がある場合、SQL でプログラム的に行うのははるかに面倒です。

同様に、人の名前を最初と最後の部分に分割することを選択しました (ただし、接頭辞、ミドル ネーム、および接尾辞は無視します)。1 つの列を論理的な部分に分割できれば、BCNF に合格していないと主張できます。

テーブルをどこまで正規化するかに関して行う必要がある選択は、主にデータへのアクセス方法によって異なります。ほとんどの人にとって、電話番号のような列を複数の部分に分割するのはやり過ぎですが、上記のポイントのいずれかがニーズに役立つと思われる場合は、それを検討してください.

PS。line1 と line2 とは何ですか?

于 2009-12-07T23:10:17.990 に答える
1

あなたが言うと:

各レコードには、自宅、携帯電話、職場、またはファックス番号のレコードを 0 または 1 つだけ含めることができることに注意してください。

...このテーブルのデザインは、これらのすべてのデータ値をこの連絡先レコードにしっかりとバインドするため、適切に一致します。

アプリケーションによっては、連絡先にさまざまな種類の複数のアドレス、さまざまな種類の複数の電話番号、さまざまな目的の複数の電子メール アドレス、さらには複数の電話番号や電子メール アドレスをアドレスに含めることができる、より柔軟な設計を提案できます。

しかしその後、私はいくつかの異なるアプリケーションに取り組みましたが、そのうちの 1 つだけが、そのような柔軟性を真剣に必要としていました (いや、実際にはそこまで到達しませんでした)。それは学校の記録でした。各連絡先レコードは 1 人の人物を表し、学生 (または元学生)、親、教師、ログイン ID、またはその他の関心のある人物のいずれかまたはすべてである可能性があります。そして、はい、私たちには、これらすべてのカテゴリーの人々がほとんどいる学校が1つありました。

しかし、別のアプリケーションでは、この多様性は必要ありませんでした。ソフトウェア ライセンスは電子メール アドレス、つまり個人に割り当てられていました。購入に関連付けられた1つの郵送先住所と、ひいてはその人があり、それはほとんどそれでした. ライセンスを電子メール アドレス (複数のライセンスを持つ 1 人) ごとに集約し、その後、複数の電子メール アドレスを持つ人々 (複数の電子メール アドレスを持つ 1 人) を集約する方法を追加しました。物理的な住所は請求情報とより密接に結びついていました。

于 2009-12-07T22:49:42.717 に答える
0

郵便番号が(city、state_id)を定義していると主張する人もいるかもしれません。そのため、これらは従属列として正規化する必要があります。ただし、USPS用のアプリを作成していない限り、これは通常実行されません。あなたの元の質問と同じです-4つの電話レコードを持っていてもそれほど害はありません、私はこのようにデザインを維持します。

于 2009-12-10T20:01:31.780 に答える
0

電話番号を分割します-他の人が言及したすべての理由に加えて-ユーザーが電話番号で検索したい場合、この設計でSQLを書くのは本当に面倒です(全体を検索したいと仮定すると複数の種類の電話番号)。

「連絡先情報」テーブルでは、ユーザーがこの種の検索を行う可能性が非常に高くなります。

于 2009-12-08T00:14:39.770 に答える
0

私が指摘したいことの 1 つは、TEXT 列を使用するのは少し無駄だということです。なぜ VARCHAR を使用しないのでしょうか?

正規化の利点は、検証用のコードの重複が減ることです。将来の変化が予想されるもう 1 つの場所は、2 つ目の住所を追加する必要がある場合です (ここには職場の電話がありますが、住所は自宅の住所であると見なされますか?)。

于 2009-12-07T22:36:21.727 に答える
0

idtype_of、およびnumberの3 つのフィールドを持つ別のテーブルを配置してみませんか。そうすれば、*_phone のものを取り除くことができます。何かのようなもの:

id      type_of      number
1       home         222 11 22
1       work         312 12 12
2       mobile       345 23 23
2       home         233 65 23
2       work         945 30 19

電子メールでも同じことを行うことをお勧めします。なぜなら、その人は電子メールを自宅に、職場に 1 つ、他の場所に 1 つ持つ可能性があるからです。

于 2009-12-07T22:50:59.403 に答える
0

contact_info_id電話番号を ( , phone_number, type) で追跡される別の関係に分割したい理由はありますか?

ビジネス ルールが変更され、複数の番号タイプを特定の個人に関連付けることができるようになる可能性。テーブルを正規化すると、制約を微調整するだけで済み、変更に対応するためのサポート コードの変更はほとんどまたはまったくありません。現在の形式では、主要なデータ モデルの変更とその後のアプリケーションの変更が発生し、非常にコストがかかります。

住所 (1 行目と 2 行目、都市、州、郵便番号) も正規化して、個人の自宅や会社の住所を保存できることを指摘したいと思います。たくさんのサマーハウスができます...

于 2009-12-07T22:40:20.643 に答える