10

私はジュニアです。開発者(5か月の仕事)、およびデータの正規化について質問があります。さて、私が理解しているように、データの正規化の背後にある一般的な原則は、データの冗長性が最小限に抑えられたRDBMSを作成することです。私のプロジェクトでは、DB担当者の1人がDBを作成しました。50以上のテーブルがあり、DB内のテーブルは通常、非常に断片化されています。テーブルには2つまたは3つの列があり、それだけです。さて、SQLクエリを書くことになると、各クエリはいくつかの異なるテーブルをくまなく調べてそれらを結合する必要があるため、それはちょっとした面倒になりました。これはデータの正規化の副作用なのだろうか?それとも、これは何か他のものを指しているのでしょうか?

私にとって最も簡単なことは、作成する必要のあるクエリに基づいてテーブルを作成することです。これにより、多くの冗長データを含むDBが作成されますが、満足のいくメディアがあるかどうか知りたいと思いました。

追記のように、自分の仕事について泣き言を言っているように出くわしたくはありませんが、これについてもっと知りたいと思っています。私の職場環境は最も友好的ではないので、同僚とこの質問をすることに抵抗があります。しかし、私はより経験豊富な人々からの考え、本、チュートリアルまたは意見をいただければ幸いです。

ありがとう。

4

7 に答える 7

4

データの正規化の背後にある一般的な原則は、データの冗長性が最小限に抑えられたRDBMSを作成することです。

部分的にのみ真実です。

正規化は「冗長性」についてではありません。

それは「異常の更新」についてです。

1NFは、「配列を使用しない」ルールです。1NFを壊すということは、行がアトミックではないことを意味しますが、コレクションとコレクション内の独立した更新はうまく機能しません。ロックと速度低下があります。

2NFは「1つの鍵」のルールです。各行には1つのキーがあり、行のすべてがキーに依存します。キーの一部に依存することはありません。一部の人々は、候補キーと自然キーおよび外部キーについて話すのが好きです。それらは存在する場合と存在しない場合があります。2NFは、すべての属性が1つのキーに依存している場合に満たされます。キーが単一列の代理キーである場合、この正規形は簡単に満たされます。

2NFに違反すると、キー全体ではなく、キーの一部に依存する列が作成されます。キーとして(部品番号、リビジョン番号)を持ち、色と重量の属性を持つテーブルがある場合。重量はキー全体に依存しますが、色は部品番号にのみ依存します。2NFの問題があり、一部のパーツの色は更新できますが、他のパーツの色は更新できず、データの異常が発生します。

3NFは「唯一の鍵」ルールです。派生データを1行に配置し、派生結果を変更すると、ソース列と一致しません。派生値を更新せずにソース列を変更すると、問題も発生します。はい、トリガーは3NF設計違反を許可するための悪いハックアラウンドです。それは重要ではありません。重要なのは、単に3NFを定義し、それが更新の問題を防ぐことを示すことです。

各クエリには、いくつかの異なるテーブルを組み合わせて結合することが含まれます。これはデータの正規化の副作用なのだろうか?

です。

于 2011-06-22T00:52:23.543 に答える
3

さて、私が理解しているように、データの正規化の背後にある一般的な原則は、データの冗長性が最小限に抑えられたRDBMSを作成することです。

うーん、わかりました。

私のプロジェクトでは、DB担当者の1人がDBを作成しました。50以上のテーブルがあり、DB内のテーブルは通常、非常に断片化されています。テーブルには2つまたは3つの列があり、それだけです。

テーブルの数は、デザインが良いか悪いかについては何も言いません。一部の企業は1つまたは2つを必要とします。他の人はもっと必要です。私は何千ものテーブルを持つフォーチュン500のデータベースに取り組んできました。

列の数は、デザインが良いか悪いかについては何も言いません。また、列の数は断片化とは関係ありません。列が比較的少ないテーブルは、一般的に良い兆候だと思います。必ずしも良い兆候ではありませんが、一般的には良い兆候です。

さて、SQLクエリを書くことになると、各クエリはいくつかの異なるテーブルをくまなく調べてそれらを結合する必要があるため、それはちょっとした面倒になりました。これはデータの正規化の副作用なのだろうか?それとも、これは何か他のものを指しているのでしょうか?

それには2つの異なる一般的な理由があります。

テーブルを正規化する場合、機能の依存関係を識別し、1つ以上の新しいテーブルで機能に依存する列を分離し、元のテーブルから削除することで、冗長性を減らします(データの整合性を高めます)。したがって、より低い正規形からより高い正規形に移動するという意味で、テーブルを正規化します。

  • 常にテーブルの数を増やし、
  • 常に元のテーブルの列数を減らし、
  • 人間のデータを取得するために結合が必要になる場合があります。

もう1つの一般的な方法は、文字列をID番号に置き換えることです。これは正規化とは何の関係もありません。(「ID番号の正規形」などはありません。)文字列をID番号に置き換える

  • 常にテーブルの数を増やし、
  • 元のテーブルの列数は変更されません(正規化と同時に行われない限り)。
  • 人間のデータを取得するには、常に結合が必要です。

このスレッドの他の部分には混乱があるようです。厳密に言えば、次のいずれもOPの質問に直接関係していないことを理解しています。

1NFは「1つの価値」の原則です。が「アトミック」であることとは何の関係もありません。リレーショナルモデルでは、アトミックは行を参照しません。値を参照します。

「1つの値」とは、行と列の各交差に1つの値が含まれることを意味します。(言い換えると、値は「アトミック」です。しかし、アトミックという言葉にはいくつかの不幸な意味があるため、ほとんどの現代の実務家はそれを避けています。)その値は単純である必要はありません。任意に複雑にすることができます。ただし、それ自体に意味のある部分がある場合、dbmsはそれらの部分を完全に無視するか、それらを操作する関数を提供します。(パーツを操作するための関数を作成する必要はありません。

最も簡単な例は日付だと思います。日付には、年、月、日で構成される部分があります。dbmsは、これらの部分を無視するか(のようにSELECT CURRENT_DATE)、それらを操作する関数を提供します(のようにSELECT EXTRACT(YEAR FROM CURRENT_DATE))。

「1つの価値」の原則をかわそうとする試みは、当然の結果、「繰り返しグループなし」の原則につながります。

繰り返しグループには、1つのドメインからの複数の値が含まれ、すべての値が同じ意味を持ちます。したがって、次のような表は、ある種の繰り返しグループの例です。(他の種類もあります。)「phone_1」と「phone_2」の両方の値は同じドメインからのものであり、同じ意味を持ちます。ユーザー「n」には電話番号(phone_1とphone_2)があります。(主キーは「user_id」です。)

user_id    phone_1           phone_2    
1          (111) 222-3333    (111) 222-3334
2          (111) 222-3335    (111) 222-3336

しかし、次の表は非常に似ていますが、繰り返しグループがありません。値は同じドメインからのものですが、同じ意味を持っていません。(主キーは「user_id」です。)

user_id    home_phone        work_phone    
3          (111) 222-3333    (111) 222-3334
4          (111) 222-3335    (111) 222-3336

2NFは「全体の鍵」の原則です。キーの数とは何の関係もありません。'n'列を持つテーブルは'n'キーを持つことができます。(たとえば、この他のSOの回答を参照してください。)リレーショナルモデル(および、拡張として、正規化の演習を行う場合)で、keyという単語が単独で表示される場合は、「候補キー」と考えてください。

代わりに、2NFは複数の列を持つ候補キーと関係があります。候補キーに複数の列がある場合、2NFでは、すべての非プライム属性が、候補キーの一部の列だけでなく、すべての候補キーのすべての列に機能的に依存している必要があります。(非プライム属性は、候補キーの一部ではない属性です。)

次の例は、2nfのウィキペディアのエントリを基にしています。(主キーは{従業員、スキル}です。)

Table: employee_skills
employee        skill            current_work_location
--
Jones           Typing           114 Main Street
Jones           Shorthand        114 Main Street
Jones           Whittling        114 Main Street
Bravo           Light Cleaning   73 Industrial Way
Ellis           Alchemy          73 Industrial Way
Ellis           Flying           73 Industrial Way
Harrison        Light Cleaning   73 Industrial Way

非プライム列current_work_locationが主キー{employee、skill}に機能的に依存していることは事実ですが、主キー「employee」の一部にのみ機能的に依存しています。そのテーブルは2NFにはありません。

各行に代理キーを割り当てて、2NFの問題を回避することはできません。(主キーはes_idです。以前の主キー{employee、skill}にはUNIQUE制約があります)。

Table: employee_skills
es_id   employee        skill            current_work_location
--
1       Jones           Typing           114 Main Street
2       Jones           Shorthand        114 Main Street
3       Jones           Whittling        114 Main Street
4       Bravo           Light Cleaning   73 Industrial Way
5       Ellis           Alchemy          73 Industrial Way
6       Ellis           Flying           73 Industrial Way
7       Harrison        Light Cleaning   73 Industrial Way

ID番号を追加しても、部分的な依存関係は削除されないことは明らかですemployee->current_work_location。部分的な依存関係を削除しない限り、このテーブルはまだ2NFにありません。

3NFは、「推移的な依存関係なし」の原則です。ここで採用されているウィキペディアの例からわかるように、派生データや計算データとは必ずしも関係ありません。(主キーは{トーナメント、年}です。このテーブルは3NFではありません。)

Table: tournament_winners
tournament             year  winner            winner_date_of_birth
--
Indiana Invitational   1998  Al Fredrickson    21 July 1975
Cleveland Open         1999  Bob Albertson     28 September 1968
Des Moines Masters     1999  Al Fredrickson    21 July 1975
Indiana Invitational   1999  Chip Masterson    14 March 1977

2つの依存関係は、このテーブルに推移的な依存関係があることを示しています。

  1. winer_date_of_birthの値は、機能的に主キーに依存しているように見えます。各主キー値は、winner_date_of_birthの唯一の値を決定します。だが 。。。
  2. winer_date_of_birthの値も、機能的に勝者に依存しているように見えます。勝者の各値は、winner_date_of_birthの唯一の値を決定します。

これらの2つの明らかな機能依存性と、トーナメント勝者、および生年月日という言葉の意味の理解を考えると、次のように言うことができます。

  • 勝者->winner_date_of_birthは機能依存性であり、
  • {トーナメント、年}->勝者は機能従属性であり、
  • {トーナメント、年}->winner_date_of_birthは推移的な依存関係です。
于 2011-06-24T23:15:57.720 に答える
2

データベースビューは、このジレンマにおいて非常に重要なツールです。 この優れた紹介は次のように述べています。

これが朗報です。正規化されたテーブルを操作する必要はありません。...(少なくともDBAにとっては)正規化されたデータテーブルの上に結合されたビューの抽象化レイヤーを作成し、ベーステーブルを完全に「舞台裏」に置いて見えないようにするのは非常に簡単です。

于 2011-06-22T03:09:30.070 に答える
1

データの正規化のように聞こえますが、その呼び出しを確実に行うには、スキーマやビジネスケースなどについて詳しく知る必要があります。データベースを制御できる場合は、テーブルをリンクする一般的なクエリを表すビューを作成できます。パフォーマンスを向上させるために、インデックス付きまたはマテリアライズドビューを作成できます(名前はデータベースプラットフォーム、この場合はOracleとSQL Serverによって異なります)。

ほぼすべてのデータベース入門書が、これらの概念に沿って役立ちます。Sql Serverを使用していて、詳細を知りたい場合は、SQL ServerBooksOnlineが優れたリソースです。

于 2011-06-22T00:50:53.933 に答える
0

多数のテーブルがあることは、十分に正規化されたデータベース設計の兆候であることは間違いありません。これはクエリを作成するときに苦痛になる可能性がありますが、データを同期から外すよりもはるかに優れています。

何千ものテーブルを持つデータベースから実行されるレポートを作成することがあります。毎晩、本番テーブルからデータウェアハウスにデータを実行してダンプするプログラムがあり、それに対してより簡単にレポートを作成できます。データウェアハウステーブルの正規化ははるかに少なく、これによりクエリの記述がはるかに簡単になります。状況に応じて、このようなことを検討することをお勧めします。

于 2011-06-22T00:48:43.873 に答える
0

データが表示されない場合、データが過度に正規化されているかどうかを判断するのは困難です(または、正しく正規化されていないだけです。フィールドを複数のテーブルに分散しても、データが正規化されているとは限りません)。ただし、一般的に言えば、表示するには複数のテーブルを結合する必要があります。十分に正規化されたデータベース内の有用なデータ。

テーブルを結合するビューを作成してから、ビューをクエリできます。これは、データを選択するときにおそらく役立ちます。

于 2011-06-22T00:51:27.287 に答える
0

適切に設計されたデータベースでは、クエリで必要な結合は非常に簡単にコーディングできるはずです。欠点は、冗長なSQLがあることです。利点は非常に大きいです:-

  • 一貫して簡単に更新できるテーブル。
  • ビジネスニーズに応じて迅速に変更します。適切に設計されたDBは通常、元の設計では考えられなかったクエリを処理できます。
  • 新しいエンティティにすばやく対応します。適切に設計されたデータベースに新しいデータエンティティと属性を追加するのは比較的簡単です。これは、非正規化されたデータベースに一見単純な変更を組み込むことは悪夢になる可能性があります。
于 2011-06-22T03:40:03.747 に答える