データベースを設計する際に留意すべき重要なことは何ですか?
他の人もあなたの洞察から恩恵を受けることができると確信しているので、あなたの答えを私のニーズに限定したくありません. しかし、マルチクライアント コミュニティ主導のサイト用のコンテンツ管理システムを計画しています。
データベースを設計する際に留意すべき重要なことは何ですか?
他の人もあなたの洞察から恩恵を受けることができると確信しているので、あなたの答えを私のニーズに限定したくありません. しかし、マルチクライアント コミュニティ主導のサイト用のコンテンツ管理システムを計画しています。
「痛くなるまで正常化し、うまくいくまで脱正常化する」
(OLTP を想定)
データ構造の正規化。(パフォーマンスの非正規化は、通常、必要に応じて後で行うことができます)
制約(、、、、、および)を使用してCHECK
、最初に正しいデータのみがデータベースに格納されるようにしてください。より高速なハードウェアをいつでも購入できますが、より正確なデータを購入することはできません。NOT NULL
FOREIGN KEY
PRIMARY KEY
DEFAULT
一貫した命名基準を事前に確立します。長い目で見れば、不必要な思考の数分を節約できます。(これは皮肉に聞こえるかもしれませんが、私は真剣です。)
また、非常に一般的でない限り、省略しないでください。データベースを、ナンバー プレートのメッセージを推測するゲームに変えないでください。1年経つとわからなくなるのがすごい。
それに対して実行する SQL クエリを想像してみてください。
あなたはそれをたくさんするので、これは重要です!
私が心に留めておくべきいくつかのこと。すべてのテーブルにレコードを一意に識別する方法があることを確認してください (これを行うことで膨大な時間を節約できます)。正規化しますが、全体を遅くしたい場合を除き、大きな複数列の自然キーで結合しないでください。代わりに、親テーブルで自動生成された数値キーを使用してください。
はい、実行する必要があるクエリとレポートの種類について考えてください。拡張性を考えてください。注文テーブルに 10 個を超える製品列は必要ないように思えるかもしれませんが、11 個必要な場合はどうなるでしょうか。注文テーブルと注文詳細テーブルを用意することをお勧めします。
すべてのデータ整合性ルールがデータベースに組み込まれていることを確認してください。すべてのデータ変更がユーザー インターフェイスから行われるわけではなく、設計者がすべてのルールを GUI に配置しても問題ないと判断したため、非常に多くのひどく混乱したデータベースを修正する必要がありました。
設計時に考慮すべき最も重要なことは、まずデータの整合性を確保する方法 (データが無意味であればデータベースは役に立たない) であり、次にパフォーマンスを確保する方法です。パフォーマンスを低下させたい場合を除き、オブジェクト モデルを使用してリレーショナル データベースを設計しないでください。
次に重要なことは、データ保護とセキュリティです。ユーザーはデータベース テーブルに直接アクセスできません。設計に動的 SQL が必要な場合は、そのアクセスが必要になります。これは、SQL インジェクション攻撃などによる潜在的なハッキングの観点からは悪いことですが、さらに重要なことは、内部の人々が詐欺を犯すためにデータベースを開くことです。データを暗号化する必要があるフィールドはありますか (クレジット カード情報、パスワード、社会保障番号は、暗号化せずに保存してはならない項目の 1 つです)。それをどのように行う予定ですか、また、データを見る必要がないときに人々が復号化しないようにするために、復号化を監査する方法をどのように計画していますか? 通過しなければならない法的な手続きはありますか ( HIPPAとSarbanes Oxleyが思い浮かびます)。
これを支持する投稿がいくつかあるので、もう1つ追加します...
すべてのテーブルにID列を配置するという罠にはまらないでください。現代のデータベース設計理論が実際の主キーを使用する理由は非常に多くあり、厳密には学術的な理由ではありません。私は数百のテーブルを含むデータベースを使用してきましたが、その多くは数百万の行テーブルであり、1000を超える同時ユーザーがいて、実際の主キーを使用しても「故障」しませんでした。
すべてのテーブルでID列を使用すると、データベースをトラバースするためにマルチテーブル結合を実行する必要があり、これは非常に面倒になります。また、ずさんなデータベース設計を促進する傾向があり、それを超えると、行の重複で問題が発生することがよくあります。もう1つの問題は、外部システムを処理するときに、これらのIDを通信する必要があることです。
サロゲートIDの場所があります-タイプコードテーブルと概念テーブル(たとえば、ルールに実際の識別子がない場合、システムルールのテーブルはIDを使用できます)。どこでもそれらを使用することは間違いIMOです。
それは長年の議論ですが、それはその価値についての私の意見です。
データ モデリングに関する非常に優れた本を入手してください。この本は、「現実世界」でデータ モデリングがどのように行われるかを教えようとする .NET 開発者ではなく、真のデータベース開発者によって書かれています。
データベース設計の問題領域は、このようなフォーラムで十分に取り上げるには大きすぎます。それにもかかわらず、私はあなたにいくつかの個人的な指針を与えます:
正規化に関する上記の投稿を聞いてください。パフォーマンス上の理由からそうしなければならないと思うので、決して非正規化しないでください。実際のパフォーマンスの問題が発生した後にのみ、非正規化する必要があります (理想的には、本番環境ではなく QA 環境で)。それでも、最初にクエリを作成するか、インデックス作成を改善するためのより良い方法があるかもしれないことを考慮してください。
可能な限りデータを制限します。列はできるだけ NOT NULL にする必要があります。CHECK 制約と FOREIGN KEY は、必要な場所で使用してください。これを行わないと、データベースに不正なデータが入り込み、多くの頭痛の種と特殊なケースのプログラミングが発生します。
実際にテーブルの設計を開始する前に、データについてよく考えてください。プロセスがどのように流れ、どのデータを追跡する必要があるかを適切に把握します。一見エンティティだと思っていたものが、実は 2 つのエンティティであることがよくあります。例として、私が取り組んでいるシステムでは、前の設計者が Member テーブルを作成し、アプリケーションからのすべての情報が Member テーブルの一部でした。メンバーはアプリケーションにあったデータを変更したいかもしれませんが、元のアプリケーションがどのように見えるかを追跡する必要があるため、アプリケーションは実際には独自のエンティティであり、メンバーは最初に入力された可能性のあるエンティティです。アプリケーション。要するに、テーブルの作成を開始するだけでなく、広範なデータ分析を行います。
データは永遠です。処理は行き来します。
リレーショナル モデルを現実世界の忠実度の高い表現にします。これは何よりも重要です。
処理は何年にもわたって変化し、進化します。しかし、データ (およびデータ モデル) は、同じペースと柔軟性で進化することはできません。処理を追加することはできますが、魔法のように情報を追加することはできません。情報を削除したくありません (ただし、無視することはできます)。
適切なモデルを取得します。ダイアグラム内のエンティティと関係は、技術に詳しくないカジュアルなユーザーにとって合理的な意味を持つ必要があります。アプリケーションのプログラミングも、シンプルで明確かつ正確でなければなりません。
モデルに苦労している場合は、問題を回避するために大規模で複雑なクエリを作成したり、(さらに悪いことに) ストアド プロシージャを作成したりしないでください。手続き上の回避策は、コストのかかる間違いです。自分が何を持っているか、何をしたいかを理解し、YAGNI の原則を適用して物事を本質的なものに絞り込みます。
実用的であること。あなたの目標が何であるかを心に留めておいてください。私はいくつかの好みがあります:
しかし、これらは目的を達成するための手段であり (多くの場合矛盾しており、慎重にバランスを取る必要があります)、主なことは、要件によって設計を推進することです。別個のエンティティとは何か、別のエンティティの一部とは何か、キャット フードとは何か (アイデンティティを気にするものではない) の選択は、完全に要件に依存します。
「データベースの経験則 - ダウンは常にアクロスに勝る!」
例: 郵送先住所、配送先住所、および請求先住所の列を持つ顧客テーブルがある場合... 住所タイプを持つ別の CustomerAddress テーブルを作成します。
CancellationReason01、CancellationReason02、CancellationReason03 を含む CancellationDetails テーブルがある場合は、別の CancellationReason テーブルを作成します。
私はこれが述べられていることを知っていますが、ノーマライゼーション、ノーマライゼーション、ノーマライゼーションが鍵です。何らかの理由でデータを正規化されていない形式で保存する必要があると感じた場合は、そうしないでください。これは、ビューまたは別のレポート データベースで処理する必要があります。私のもう 1 つの重要なアドバイスは、可能な限り text/ntext フィールドを避けることです。
できるだけ多くのメタデータがモデルにエンコードされていることを確認してください。データモデルを見ただけで、ほぼすべてのビジネスルールや概念を推測できるはずです。
つまり、ユーザーの現実を反映する名前を選択するように注意してください(ただし、モデルに役立つ場合は、現実の認識を変更することを恐れないでください)。
データベースで可能なすべての制約をエンコードします。賢明なデータのみを提供するためにアプリケーション層に依存しないでください。そもそも、賢明なデータだけが存在できることを確認してください。
モデル内のデータを集約しないでください。モデルを可能な限りアトミックに保ちます。オンザフライで集約するか、通常の集約ジョブを集約テーブルに実行します。
スキーマ間の適切なパーティションを選択します。一部のパーティショニングは外部キーと関係があり、一部は純粋な物理的分離によるものです。
主キー以外のフィールドで行を検索する場合は、必ずそれらにインデックスを付けてください。
オブジェクト指向言語ですか?したがって、データベースの前にオブジェクトをモデル化してみてください。これにより、モデルに集中することができます。
大量に実行するクエリがある場合は、それらをストアド プロシージャにします。ほとんどの場合、それらはより速く実行されます。
可能な限り前もって要件を理解してください。次に、要件が変更された場合、または SQL を使用しないデータベースなど、まったく異なる種類のデータベースに移行した場合にのみ変更する必要がある論理スキーマを設計します。次に、特定の DBMS 製品、ボリューム、負荷、および速度要件を考慮に入れた物理設計に設計を改良および拡張します。
正規化する方法を学びますが、正規化のルールを破るタイミングについても学びます。
正規化が重要であり、パフォーマンスやその他の保守性の理由から戦術的な非正規化に従うことを強く主張します。ただし、数個以上のテーブルを持つことを期待している場合は、テーブルの数が増えるにつれて作業がずっと楽になる正規化について 1 つの警告を提供したいと思います。
注意点は、各テーブルの主キーを単一の数値列にすることです (DB のフレーバーに適しています)。学術的な正規化では、エンティティ (テーブル) のあらゆる属性 (列) を組み合わせて、記述されているもの (行) のインスタンスを一意に識別できるようにするという考え方があり、最終的に複数列の複合主キーを作成できます。 . そのため、その複合キーを外部キーとして他のテーブルに移行するたびに、それを参照するすべてのテーブルでそれらの複数の列を複製することになります。テーブルが半ダースしかない場合は、これでうまくいくかもしれません。しかし、それ以上大きくなるとすぐに壊れてしまいます。
したがって、複数列の複合主キーの代わりに、一連の数値の主キーを使用してください。たとえそのアプローチが厳密な正規化の教えに反する場合でもです。
大量の列を主キーとして使用しないでください
主キーをシーケンス生成番号にすることができる限り。
覚えておくべき重要なことは、構造が変わる可能性があるということです。ですから、自分を窮地に陥らせないでください。何をするにしても、ある程度の「余裕」を残し、いつかデータを別の構造に移行する手段を確保してください。
正規化は、モデリングしているものにのみ関連することに注意してください。おそらく、ドメイン内のオブジェクトのコレクションをモデル化しています。同じデータがたまたま複数回適用されるため、データが繰り返される一連のイベントを記録している可能性があります。2 つのことを混同しないでください。
データについて知ることは良いことであり、正規化することに同意します。
別のテーブルに非常に大きなテキスト フィールドを保持することをお勧めします。たとえば、契約がある場合、契約に関する多くの情報を 1 つのテーブルに保持し、法的な (そして非常に大きな) ドキュメントを別のテーブルに保持したい場合があります。メイン テーブルのインデックスを法律文書に挿入するだけです。