0

私はプログラミングに不慣れな同僚と仕事をしていて、ORM(およびSRP)の概念のいくつかを説明しようとしていますが、どういうわけか失敗しています。これはRailsアプリです。

私が作業しているアプリケーションのクラス階層は次のようになります。

-CallFlow --Route
(polymorphic)
--- RouteOptions

さまざまなルートに固有の属性があり、各RouteTypeには独自のオプションのセットがあります。理想的には、call_flowsのテーブル、各ルートタイプのテーブル、そしてオプションのあるルートタイプのテーブル、そのルートタイプのオプションテーブルがあります。本当にラフなモックアップ:

ここに画像の説明を入力してください

Simple_routeとoutbound_routeにはオプションがありません。オプションがあるルートのうち、それはhas_many関係であり、そのルートのオプションの配列を提供します。

逆に、私の同僚は、各ルートに固有のすべてのフィールドをcall_flowsテーブルに配置したいと考えています。これはそのモードのモックアップです:

ここに画像の説明を入力してください

したがって、すべてのレコードに適用されるわけではないフィールドを持つ1つの大きなcall_flowsテーブルがあります。実際、ほんの一握りの意志だけです。モデリングの決定の背後にある私の理由は次のとおりです。

  • 基本的な正規化パターンに従います
  • null値の量が減り、データベースのサイズが減ります
  • 変更する方が柔軟です
  • 基本的なSRPの原則に従います

私は何かが足りないのですか?新しいプログラマーがDBの正規化の重要性を理解するのに役立つリソースがあればいいのにと思います。

ありがとう!

4

3 に答える 3

3

正規化の背後にあるコアコンセプトはData DependencyvsFunctional Dependencyです。正規化されたスキーマでは、依存関係のみが機能依存性であり、ビジネスまたはデータのセマンティクスによって決定されます。たとえば、RouteOptionsはRouteに依存します。

正規化されていないテーブルでは、すべてのデータがすべての場所に格納されるため、データの依存関係と機能の依存関係があります。このような場合、トランザクションを実行して、データモデルに一貫性があることを100%の信頼度で表明することは非常に困難です。

例を見てみましょう。新しいルートオプションを追加します。これはあなたの取引です。正規化されたテーブルで、RouteOptionテーブルに新しいレコードを作成し、同じレコードにRoute_IDを入力します。トランザクション後、データモデルに一貫性があることを100%確信しています。

正規化されていないスキーマを使用します。同じRoutOptionテーブルと、複数のテーブルの列を含むRouteSummaryテーブルがあるとします。このスキーマで上記のトランザクションを実行すると、データモデルに一貫性がなくなります。RouteSummaryテーブルを更新するには「覚えておく」必要があります。数日後、RouteOptionを持つ他のテーブルが作成されます。既存のトランザクションは、この新しいテーブルについて認識しません。

正規化されていないスキーマの場所もあります。これは、データストアがトランザクションではない場合です。これが主に分析上の理由で使用される読み取り専用スキーマである場合、トランザクションは発生しないため、データに一貫性がなくなるリスクはありません。したがって、そのユースケースでは問題ありません。

于 2012-09-06T21:23:07.583 に答える
1

追加の*_optionsテーブルを追加することで何が得られるのかよくわかりません。つまり、ルートのタイプのテーブルに入れることができなかった、ここに入るものです。

そうは言っても、さまざまなルートタイプやオプションなどで説明するような複雑な構造は、NoSQLのスキーマレスストレージアプローチにはるかに適しているように思えます。このような場合、ルートコレクションを作成するだけで、それぞれがプロパティやオプションなどに関して独自の構造を持つことができます。

于 2012-09-06T20:58:23.473 に答える
1

あなたのケースは、「Generalization Specialization」、または略してGen-Specとして知られているデザインパターンのインスタンスのように見えます。データベーステーブルを使用してgen-specをモデル化する方法の問題は、SOで常に発生します。

JavaなどのOOPLでgen-specをモデル化する場合は、サブクラス継承機能を使用して詳細を処理します。一般化されたオブジェクトを処理するクラスを定義してから、各サブクラスがその親スーパークラスを拡張するサブクラスのコレクションを定義するだけです。それは簡単で簡単です。

残念ながら、リレーショナルデータモデルにはサブクラスの継承が組み込まれておらず、SQLデータベースシステムにはそのような機能はありません。しかし、あなたは運が悪いわけではありません。OOPのクラス構造に対応する方法で、gen-specをモデル化するようにテーブルを設計できます。次に、一般化されたクラスに新しいアイテムが追加されたときに、独自の継承メカニズムを実装するように調整する必要があります。詳細は以下の通りです。

Martin Fowlerは、継承を模倣する3つの異なるテーブルデザインを識別します。あなたが好むデザインは、ファウラーがクラステーブル継承と呼んでいるものに近いものです。同僚が好む設計は、ファウラーが単一テーブル継承と呼ぶものに近いものです。それぞれに長所と短所があります。

クラステーブル継承の興味深い部分は、共有主キーと呼ばれます。ここで、サブクラステーブルには2つの役割を果たすキーがあります。これは主キーであり、スーパークラステーブルへの外部キー参照でもあります。新しいエントリが作成されると、アプリケーションはキー値をスーパークラステーブルから適切なサブクラステーブルに伝播する必要があります。

スムーズな部分は、データを結合し直す必要がある場合に発生します。共有主キーに基づく参加は、スムーズで簡単、そして高速です。

于 2012-09-07T06:26:10.917 に答える