0

私は本当にこれをよく理解することができません。私はインターネット上で多くの例を見ていますが、その理由を説明していません。たとえば、アプリケーション、顧客、マネージャの2種類のユーザーがあります。 「user_type」列をユーザー表に組み込む代わりに、別の「user_type」表を作成する利点は何ですか。もう1つの例は、製品表にカテゴリー・フィールドを入れる代わりに、製品のカテゴリー別の表を作成することです。私は本当にこれについて私の頭を得ることができません。 db正規化の利点は何ですか?また、データベース内の重複データの欠点は何ですか?データベースを正規化することの利点は何ですか?

+1

単一の列の代わりにuser_typeテーブルを作成することは、正規化とは関係ありません。 – sqlvogel

答えて

0

正規化の目的は、異常なデータがデータベースに入らないようにすることです。このような非常に簡単なユーザエンティティを取る、など

:マネージャー(M)またはペオン(P):

create table Users(
    ID  int auto_generated primary key, 
    LastName varchar(16) not null, 
    FirstName varchar(16) not null 
); 

今では、ユーザーの2種類があることができ判明。また、管理者にとっては、どれくらい多くの人が直接に報告しているのかを知る必要があります。彼らはフォークリフトのライセンスを持っているかどうかを知る必要があります。

create table Users(
    ID   int auto_generated primary key, 
    LastName  varchar(16) not null, 
    FirstName varchar(16) not null, 
    UserType  char(1) not null, 
    DirectReps int, 
    HasFLLicense boolean 
); 

これは、あなたの頭の中で起こっているすべての種類のアラームを開始する必要があります。何がうまくいかない?

  • (この時点で)UserTypeの有効な値は 'M'または 'P'のみです。ただし、このフィールドには任意の1文字を含めることができます。この列に「小切手」を作成することはできますが、それは後で説明する別の問題を作り出します。
  • DirectRepsフィールドとHasFLLicenseフィールドは、UserTypeフィールドにそれぞれ 'M'または 'P'が含まれている場合にのみ適用されます。これを内部的に強制する方法はありません。トリガーやアプリケーションコードで処理する必要があります。

これらの新しい制約を適用する簡単な方法はありません。そして、私たちはどれほど慎重であっても、遅かれ早かれ、MやP以外のUserType値やDirectRepsやHasFLLicenseの値が不適切になることを知っています。これは異常なデータです。

詳細を見ると、フィールドLastName、FirstName、およびUserTypeには、IDにのみ機能的な依存関係があります。ただし、DirectRepsおよびHasFLLicenseもUserTypeに依存します。この新しいテーブルは2nfにありません。

この表を正規化するにはいくつかの方法がありますが、ここでは取り上げません。言うまでもなく、UserType値が 'M'で、UserType値が 'P'でなければHasFLLicense値が存在しない限り、DirectReps値は存在しないように最終結果を行う必要があることは言うまでもありません(もちろん、Here) 。

今ちょうど正規化されたテーブルを見てみましょう:

create table Users(
    ID   int auto_generated primary key, 
    LastName  varchar(16) not null, 
    FirstName varchar(16) not null, 
    UserType  char(1) check(UserType in('M', 'P') 
); 

もテーブルからUserTypeフィールドを削除するが、今のところそれをここに残して聞かせいくつかの正規化の方法があります。どこに位置していても、以下が適用されます。

遅かれ早かれ、3番目のタイプが必要と考えられるときに問題が発生します。そして、別のポイントで、別のポイントで別のポイントで、あなたはそのアイデアを得ます。毎回、チェック制約を書き換えるためにalter tableコマンドを発行する必要があります。これは、あなたのリビングルームのソファを交換するだけで、家を完全に解体して再建するようなものです。このテーブルにアクセスするすべてのコード(ビューを含む)は、最低でも再コンパイルし、場合によっては書き換えなければなりません。それに直面して、alter tableの操作は簡単です。

どのくらい良く、すべてのユーザータイプのレコードを含むルックアップテーブルを持っている:

create table UserTypes(
    ID  char(1) not null primary key, -- 'M' or 'P' or whatever 
    Name varchar(16) not null, -- "Manager" or "Peon" or whatever 
    ...  -- other possible attributes 
); 

その後UserTypeフィールドが定義されることがあります。

UserType  char(1) not null references UserTypes(ID) 

今タイプ 'A' を追加したり、 'F'また​​はUserTypesテーブルにレコードを挿入するだけのことです。既存のコードは影響を受けません。もちろん、新しいタイプを扱うためには最終的にアプリケーションコードを変更する必要がありますが、アプリ開発者は余裕でこれを行うことができます。

現在の要件だけでは設計しないでください。合理的に期待される将来の要件についても設計する。

1

重複データの欠点は、データのコピーがどこにあるかを覚えておき、情報が変更されたときにそのすべてを更新する必要があることです。正規化は、別々のテーブルを作成するよりも、重複排除に関するものです。

あなたのuser_typeの例では、userテーブルのカラムにそれを置くことができます。ユーザーが複数のユーザータイプを持つことができる場合は、追加のテーブルが便利です。

関連する問題