0

さて、今「ボックスアイテム」の表を作っています。

現在、ボックスアイテムは、使用目的/アイテムのステータスに応じて、「配送」ボックスまたは「返品」ボックスに関連付けられる場合があります。

ボックス アイテムに欠陥がある可能性があります。欠陥がある場合、ボックス アイテムの行にフラグが設定され (IsDefective)、ボックス アイテムは「返品」ボックスに入れられます (他のアイテムはそのベンダーに返品されます)。それ以外の場合、ボックス アイテムは最終的に「配送」ボックスに入れられます (他のアイテムが配送されます)。(配送ボックスと返品ボックスには独自のテーブルがあることに注意してください。すべてのボックスに共通のテーブルが 1 つあるわけではありませんが、可能であれば 3 つ目の可能性としてそれを検討する必要がありますか?)

今日ははっきりと考えていないだけかもしれませんが、この状況で何をすべきか疑問に思い始めました。

私の直感では、一度に 1 つのリレーションしか発生しない場合でも、考えられるリレーションごとに個別のフィールドが必要であることがわかります。これにより、ボックス アイテムのスキーマは次のようになります。

BoxItemID 説明 IsDefective ShippingBoxID ReturnBoxID など...

これによりリレーションが明確になりますが、無駄に思えます (リレーションは常に 1 つしか使用されないため)。そこで、BoxID 用のフィールドを 1 つだけ用意し、IsDefective フィールドに基づいて、それが参照している BoxID (配送または返品ボックス ID) を判断できると考えました。

BoxItemID 説明 IsDefective BoxID など...

これは無駄が少ないようですが、私には合いません。関係は明らかではありません。

それで、Stackoverflow のデータベースの達人であるあなたにそれを言います。この状況であなたはどうしますか?

編集: ご意見をお寄せいただきありがとうございます。いろいろ考えさせられました。1 つには、次にこのようなプロジェクトを開始するときに ORM を使用するつもりです。=) 2 つについては、私は今いないので、4 バイトをかじって 2 つのフィールドを使用します。

みんなありがとう!

4

7 に答える 7

2

私はサイコティック・ヴェノムとマットラントと一緒です。

ポリモーフィック ルート (別のフィールドの内容に基づいて、外部キーが指しているテーブルを特定する必要がある) に進むのは面倒です。そのための制約をコーディングするのは難しいかもしれません (ほとんどのデータベースがそれをネイティブにサポートするかどうかはわかりません。トリガーを使用する必要があると思います)。

テーブル間でアイテムが移動することはありますか? 1 つは返品用、もう 1 つは配送用で、同じ定義を持つ 2 つの表を使用するのが最も簡単な方法かもしれません。最初に提案した定義 (2 つの別個のフィールド) に固執したい場合は、完全に合理的です。

「時期尚早の最適化は諸悪の根源」など。無駄に思えますが、保存しているものを覚えておいてください。それらは ID であるため、おそらく単なる整数であり、おそらく 4 バイトです。レコードごとに 4 バイトを無駄にすることは、基本的には何もありません。実際、偶数アドレスなどに物を入れるためのパディングのために、その余分なフィールドをそこに入れるのは「自由」かもしれません。それはすべてDBの設計に依存します。

ポリモーフィック ルートを使用する非常に正当な理由がない限り (メモリがほとんどない組み込みシステムを使用している場合や、非常に遅い 9600bps リンクを介して複製する必要がある場合など)、最終的に発生する可能性のある頭痛の種に値するものではないでしょう。 . これらの特殊なケースをすべてクエリに書き込む必要があると、煩わしい場合があります。

簡単な例: isDefective フラグが設定されているかどうかに基づいて結合する場合、2 つのテーブル間で結合を行うのは面倒です。少なくとも私にとっては、2 つの列のうちの 1 つを単独で使用できるだけで、手間を省くことができるでしょう。

于 2008-09-22T02:03:56.637 に答える
1

あなたが話しているのは、ポリモーフィックな関係です。他の複数のテーブルを参照できる単一の ID。これをサポートするフレームワークはいくつかありますが、(潜在的に) データベースの整合性に悪影響を及ぼします (データベースまたはアプリケーションが参照整合性を維持する必要があるかどうかについては、まったく別の議論になる可能性があります)。

これはどうですか?

BoxItem:
BoxItemID, Description, IsDefective

Box:
BoxID, Description

BoxItemMap:
BoxID, BoxItemID, BoxItemType

次に、BoxItemType を列挙型にするか、アプリケーションで定数をボックスのタイプとして「返品」または「配送」として定義する整数にすることができます。

于 2008-09-22T01:43:29.963 に答える
1

ボックス用の単一のテーブルを作成し、ボックスの種類をボックス テーブルの列にすることを検討します。これにより、関係が簡素化され、ボックス タイプのクエリが簡単になります。したがって、ボックス項目には boxId への外部キーが 1 つしかありません。

于 2008-09-22T01:49:37.063 に答える
1

Hibernate がTable-per-subclassと呼ぶものを使用するので、DB は Boxes: BoxShippingBox、およびの 3 つのテーブルになりReturnBoxます。の FK はBoxItemを指しBoxます。

于 2008-09-22T08:46:57.153 に答える
0

上記のポリモーフィックの議論については同意します。あまり使用されない可能性はありますが、それでも実行可能なソリューションです。

基本的に、box と呼ばれるベース テーブルがあります。次に、配送用ボックスと返品用ボックスの 2 つのテーブルがあります。これらの 2 つは、それらに特別なフィールドを追加します。それらは 1:1 fk のボックスに関連付けられています。Boz ベース テーブルには、すべてのボックス タイプの共通フィールドがあります。

BoxItem をボックス テーブルに関連付けます。適切なボックス タイプを取得する方法は、キーに基づいて子ボックスをルート ボックスに結合するクエリを実行することです。ベースボックスと子ボックスの両方にあるレコードがそのタイプです。

ボックスタイプを作成するときは、正しく行われるように注意する必要があります。しかし、それがテストの目的です。それらを追加するためのコードは、一度書くだけで済みます。または ORM を使用します。

ほとんどすべての ORM がこの戦略をサポートしています。

于 2008-09-22T01:51:22.067 に答える
0

私はおそらく一緒に行きます:

BoxTable:
box_id, box_descrip, box_status_id ...
     1, Lovely Box, 1
     2, Borked box, 2
     3, Ugly Box, 3
     4, Flammable Box, 4

       BoxStatus:
       box_status_id, box_status_name, box_type_id, ....
                   1,Shippable, 1
                   2,Return, 2
                   3,Ugly, 2
                   4,Dangerous,3

                BoxType:
                box_type_id, box_type_name, ...
                          1, Shipping box, ...
                          2, Return box, ....
                          3, Hazmat box, ...

このように、ボックス ステータスによってボックス タイプが定義され、後でさらにいくつかのステータス レベルまたはボックス タイプに拡張する必要がある場合に柔軟に対応できます。

于 2008-09-22T02:12:55.850 に答える
0

IsDefective、ShippingBoxID、配送ボックス関連のフィールド、ReturnBoxID、および返品ボックス関連のフィールドを含む BoxItems テーブルを 1 つだけ使用します。一部のフィールドは、各レコードで常に NULL になります。

これは、次の開発者が混乱する可能性が低い、非常にシンプルで自明な設計です。理論的には、この設計は各行に空のフィールドが保証されているため非効率的です。実際には、データベースは各行に必要な最小限のストレージ サイズを持つ傾向があるため、(フィールド数が膨大でない限り) とにかく、この設計は可能な限り効率的であり、コーディングがはるかに簡単です。

于 2008-09-22T02:18:56.523 に答える