0

シナリオはタイムカード。従業員は TimeCardHeader テーブルで出勤および退勤しますが、TimeCardDetail テーブルには Details を入力します。ただし、少なくとも 2 種類の詳細を入力できます... これが私の質問です。それぞれの種類を表す 2 つのテーブルを作成するか、それともテーブルの意味を解釈するブール フラグを持つ 1 つのテーブルを作成するか?

フィールドは次のとおりです (この例は小さく、他のフィールドには多くのフィールドがあります)。

    Id (PK)
    Version
    StartTime
    EndTime
    LaborDetailDescription
    LaborType: Can be direct or indirect.

LaborType が Indirect の場合、残りのフィールドは次のとおりです。

    IndirectNumber (FK)

LaborType が Direct の場合、残りのフィールドは次のとおりです。

    JobNumber (FK)
    JobType
    DirectType: Can be Production or Setup

DirectType が Production の場合、残りのフィールドは次のとおりです。

    GoodQty
    ScrapQty

DirectType が Setup の場合、残りのフィールドは次のとおりです。

    SetupPercent

それで...これらすべてのフィールドを含む1つのテーブルを作成しますが、タイプが設定されているときに一部のフィールドが空白になります(つまり、コード、レポート、クエリなどでデータベースを解釈する必要があります)、または2つ作成しますか?テーブル DirectLaborDetail および IndirectLaborDetail を作成し、データを適切なテーブルにきれいに格納しますか? この場合、DirectLabor も DirectLaborSetup と DirectLaborProduction に分割されます。

私はいくつかの次元に沿ってこの質問をしています:

  1. データベース設計原則に従った理論上の純度。
  2. パフォーマンスの問題。
  3. クエリ作成の難しさ (これには、それに対するコーディングも含まれます)。
  4. ここに記載していないその他の考慮事項。

編集:詳細が追加されました...

オプション1

/*I intentionally left out the type information*/
CREATE TABLE TimeCardDetail
(
    Id,
    Version,
    TimeCardHeaderId, /*Not depicted here, FK*/
    StartTime,
    EndTime,
    LaborDetailDescription,
    LaborType, /*FK*/
    IndirectId, /*FK*/
    JobId, /*FK*/
    DirectType, /*FK*/
    GoodQty,
    ScrapQty,
    SetupPercent
);

オプション 2

CREATE TABLE TimeCardDetail
(
    Id,
    Version,
    StartTime,
    EndTime,
    LaborDetailDescription
);

CREATE TABLE DirectLaborDetail
(
    Id,
    Version,
    TimeCardHeaderId, /*Not depicted here, FK*/
    JobId, /*FK*/
    DirectType, /*FK*/
    GoodQty,
    ScrapQty,
    SetupPercent,
    TimeCardDetailId /*FK*/
);

CREATE TABLE IndirectLaborDetail
(
    Id,
    Version,
    TimeCardHeaderId, /*Not depicted here, FK*/
    IndirectId, /*FK*/
    TimeCardDetailId, /*FK*/
);

私は人間としてこれを好みます。データのビジネス上の意味を明確に理解できると同時に、すべてが適切な場所にあり、解釈の必要がないからです。特定の TimeCardHeader のすべての詳細を表示するには、2 つのテーブルを調べる必要があるため、クエリは少し興味深いものになります。しかし、それは本当に今日のコンピューティング能力の問題なのでしょうか?

オプション 3

関係を逆にすることを除いて、オプション 2 と同様です...

CREATE TABLE TimeCardDetail
(
    Id,
    Version,
    TimeCardHeaderId, /*Not depicted here, FK*/
    StartTime,
    EndTime,
    Description,
    LaborType, /*FK*/
    FKId, /*would link to the DirectLabordetail or IndirectLaborDetail depending on LaborType*/
);

FKId は LaborType に応じて意味を持つため、このオプションは使用しません。

4

1 に答える 1

1

すべての列を含む単一のテーブルを使用し、そのうちのいくつかに値をロードするか、必要でない場合は空のままにします。このソリューションは、あなたの生活を楽にします。

異なる LaborTypes で常に個別に詳細を照会すると思われる場合にのみ、2 つのテーブル ソリューションが適切な選択になりますが、その場合でも、パフォーマンスが向上するかどうかを判断する必要があります (2 つの小さなテーブルは、データベースの処理が容易です)。 ) 開発の点で失われた価値があります (2 つのテーブルへの挿入、2 つのテーブルのクエリなど)。

あなたのポイントについて:

  1. 理論上の純度。そのようなものが存在するかどうかはわかりませんが、両方のアプローチが理論的に有効です。実践により、どちらがあなたのケースに最適かがわかります。

  2. パフォーマンス。2 つのテーブルは小さくなり、クエリが高速になりますが、より多くのコードを維持する必要があります。数百万/数十億の行がなくなるまで、パフォーマンスについてあまり心配しません。単一のテーブルではパフォーマンスの問題が発生する可能性がありますが、インデックス、パーティション、キャッシュはとにかく役に立ちます。

  3. クエリ作成の難しさ。私の提案は、次のような表です。

    Id (PK)
    Version
    StartTime
    EndTime
    LaborDetailDescription
    LaborType (FK) 
    IndirectNumber (FK)
    JobNumber (FK)
    JobType
    DirectType (FK) 
    GoodQty
    ScrapQty
    SetupPercent
    

    LaborType と DirectType の FK を 2 つの小さなルックアップ テーブルに追加すると、LaborType_id と DirectType_id のみをテーブルに格納できます。また、不足している外部キーについては、Indirect LaboryType の IndirectNumber がないため、参照整合性を維持するためにダミー レコードを作成するだけです。同様のテーブルを維持するのは非常に簡単だと思います。FK にいくつかの結合が必要になるだけです。

  4. たぶん、でも今は始めるのに十分だと思います

于 2013-10-24T13:39:40.413 に答える