8

新しいプロジェクトを開始しましたが、非常に正規化されたデータベースがあります。ルックアップできるものはすべて、ルックアップ テーブルへの外部キーとして格納されます。これは正規化されていて問題ありませんが、最も単純なクエリに対して 5 つのテーブル結合を行うことになります。

    from va in VehicleActions
    join vat in VehicleActionTypes on va.VehicleActionTypeId equals vat.VehicleActionTypeId
    join ai in ActivityInvolvements on va.VehicleActionId equals ai.VehicleActionId
    join a in Agencies on va.AgencyId equals a.AgencyId
    join vd in VehicleDescriptions on ai.VehicleDescriptionId equals vd.VehicleDescriptionId
    join s in States on vd.LicensePlateStateId equals s.StateId
    where va.CreatedDate > DateTime.Now.AddHours(-DateTime.Now.Hour)
    select new {va.VehicleActionId,a.AgencyCode,vat.Description,vat.Code,
vd.LicensePlateNumber,LPNState = s.Code,va.LatestDateTime,va.CreatedDate}

いくつかのものを非正規化することをお勧めします。州コードのように。私が生きている間に州コードが変更されることはありません。3文字の代理店コードと同様の話。これらは代理店の代理店によって配布され、変更されることはありません。

状態コードの問題と 5 つのテーブル結合について DBA に連絡したとき。「正常化された」「結合が速い」という反応が返ってきました。

非正規化する説得力のある議論はありますか? 他に何もなければ、私は正気のためにそれをします。

T-SQL での同じクエリ:

    SELECT VehicleAction.VehicleActionID
      , Agency.AgencyCode AS ActionAgency
      , VehicleActionType.Description
      , VehicleDescription.LicensePlateNumber
      , State.Code AS LPNState
      , VehicleAction.LatestDateTime AS ActionLatestDateTime
      , VehicleAction.CreatedDate
FROM VehicleAction INNER JOIN
     VehicleActionType ON VehicleAction.VehicleActionTypeId = VehicleActionType.VehicleActionTypeId INNER JOIN
     ActivityInvolvement ON VehicleAction.VehicleActionId = ActivityInvolvement.VehicleActionId INNER JOIN
     Agency ON VehicleAction.AgencyId = Agency.AgencyId INNER JOIN
     VehicleDescription ON ActivityInvolvement.VehicleDescriptionId = VehicleDescription.VehicleDescriptionId INNER JOIN
     State ON VehicleDescription.LicensePlateStateId = State.StateId
Where VehicleAction.CreatedDate >= floor(cast(getdate() as float))
4

7 に答える 7

6

あなたがやりたいことを非正規化と呼ぶかどうかさえわかりません-人工的な外部キー(StateId、AgencyId)を自然な外部キー(State Abbreviation、Agency Code)に置き換えたいだけのようです。整数フィールドの代わりに varchar フィールドを使用すると、結合/クエリのパフォーマンスが低下しますが、(a) 自然な FK がとにかく必要なものであるため、ほとんどの場合、テーブルに結合する必要さえない場合、それは大したことではなく、( b)データベースが目立つようにするには、データベースがかなり大きい/負荷が高い必要があります。

しかし、このような変更を行う前に、現在および将来のニーズを完全に理解する必要があるという点で、djna は正しいです。3 文字の代理店コードは、5 年後も変わることはありませんか? 本当に、本当にそうですか?

于 2009-10-15T21:51:09.207 に答える
6

あなたの現在のイディオムに合わせて物事を形作りたいと思うことに注意してください。今のところ、なじみのないコードは扱いにくく、理解を妨げているように見えます。やがて順応する可能性があります。

パフォーマンスなどの現在の (または既知の将来の) 要件が満たされていない場合、それはまったく別の問題です。しかし、何でもパフォーマンスを調整できることを忘れないでください。目的は、物事をできるだけ速くすることではなく、十分に速くすることです。

于 2009-10-15T21:34:48.933 に答える
6

パフォーマンス (および健全性) の理由から、非正規化が必要になる場合があります。すべてのテーブル/ニーズなどを見ないとわかりにくい...

しかし、(いくつかの結合を行うために) いくつかの便利なビューを構築し、それらを使用してより単純なクエリを記述できるようにしないのはなぜでしょうか?

于 2009-10-15T21:34:34.423 に答える
3

さて、パフォーマンスはどうですか?パフォーマンスに問題がない場合は、5つのテーブルをビューに結合し、データが必要なときにビューからSELECTを実行します。

州の略語は、意味のあるキーで問題ないと思う場合の1つです。行数が制限され、データを完全に制御している(つまり、外部ソースからデータが入力されていない)非常に単純なルックアップテーブルの場合、キー値がプロキシできるように、意味のある4文字または5文字のキーを作成することがあります。一部のクエリの完全に記述的なルックアップ値。

于 2009-10-16T01:35:00.053 に答える
3

ビュー(またはパラメーター化を取得するためのインラインテーブル値関数)を作成します。いずれにせよ、私は通常、ビューを使用するかどうかに関係なく、すべてのコードをSP(一部のコードが生成されます)に配置します。つまり、結合を作成するのは1回だけです。

于 2009-10-16T01:39:24.013 に答える
3

この以前の投稿は、あなたが抱えている問題と同様の問題を扱っていました。うまくいけば、それはあなたに役立つでしょう.

「超正規化」データの処理

正規化に対する私自身の見解は、可能な限り正規化することですが、非正規化はパフォーマンスのためだけに行うことです。そして、パフォーマンスの非正規化は避けるべきものです。非正規化する前に、プロファイリング、正しいインデックスの設定などのルートに進みます。

正気...それは過大評価されています。特に私たちの職業では。

于 2009-10-15T21:33:35.770 に答える
2

3文字のコードが変更される可能性があるという(この「正規化」の)議論は、コードが変更された場合に何をするか、および人工キーシナリオがこの不測の事態にどのように対処するかについての計画がなければ、あまり説得力がありません。キーとしてのコード。完全に一時的なスキーマを実装していない限り(これは実行が非常に難しく、例では提案されていません)、正規化がどのように役立つかは私にはわかりません。コードネームが衝突する可能性のある複数のソースや標準の機関と連携する場合、または「州」が最終的に州、州、部門、州、またはエスタドの2文字のコードを意味する場合、それは別の問題です。次に、独自のキーが必要になるか、そのコードよりも多くの情報を含む2列のキーが必要になります。

于 2009-10-16T01:19:41.610 に答える