2

一般的なスーパークラスとして機能する電子デバイスのテーブルがあり、電話、ラップトップ、カメラなどのサブクラス テーブルを分離して、スーパークラスを拡張し、デバイスに関する特定の情報を提供します (スーパークラス テーブルの外部キー deviceID を使用)。つまり、Class Table Inheritanceです。私の質問は、スーパークラスに「deviceType」列が必要ですか? 特定のデバイス ID がどのサブクラス テーブルに表示されるかを確認することでデバイス タイプを検出できるため、冗長になりますが、非常に単純なものを検出するには、不要な量の結合が必要になるようです。

一般的に、ランダムな汎用デバイスを見て、それが何のタイプなのか疑問に思う人はおそらく珍しいでしょうが、その人が簡単にそれを見つけるのが難しい設計のままにしておくのも奇妙に思えます。

別の問題は制約です...デバイスのサブタイプが1回だけになるように制約するにはどうすればよいですか? 同様に、Camera テーブルに既に存在する行と同じ deviceID を持つ行が Laptop テーブルに追加されるのを止めるにはどうすればよいでしょうか? 繰り返しますが、これが優れた UI で可能になる可能性はほとんどありませんが、データベースの制約は常に望ましいものです。

ありがとう!

PS deviceType 列を使用する場合、データの整合性を高めるために、フリー テキスト フィールドではなく、サポートするすべてのデバイス タイプの列挙テーブルにリンクされます。

明確化のために追加


最初はスーパークラス テーブルです。

汎用デバイス

deviceID    brand     shipDate
   1        HP        05/06/09
   2        Canon     11/16/08
   3        Ikon      02/27/09

次に、2 つのサブクラスの例を示します。

ラップトップ

laptopID    deviceID    screenSize
   1           1           17

カメラ

cameraID      deviceID     megapixels
   1             2            6.5
   2             3            8

GenericDevice テーブルから移行された "deviceID" のキーに注意してください。これにより、実際のデバイスのタイプに応じて、ジェネリック テーブルから任意のサブクラス テーブルへの 1 対 1 の関係が可能になります。したがって、これらの表を結合すると、HP デバイスは 17 インチ画面のラップトップであり、Canon デバイスと Ikon デバイスは両方とも、それぞれ 6.5 メガピクセルと 8 メガピクセルのカメラであることがわかります。

問題は、そもそもデバイスの種類がわからない場合に、どのようにしてデバイスの種類を特定するかということです。GenericDevice テーブルの行しかありません。例として最初の行を見てみましょう。デバイスが HP 製で、2009 年 5 月 6 日に出荷されたことはわかっていますが、最初はデバイスの種類がわかりません。しかし、deviceID = 1 の行が見つかるまで子テーブルを検索することで、それを見つけることができます。ラップトップ テーブルにはそのような行が含まれているため、HP デバイスは実際にはそのラップトップである必要があります。しかし、単純にデバイス タイプを検出するのは不必要な問題のように思えます (特に、deviceID が一致する場所を確認するために検索する必要がある 20 以上のサブクラスがある場合)。代わりに、これを行うことができます:

汎用デバイス

deviceID    brand     shipDate   deviceType
   1        HP        05/06/09      laptop
   2        Canon     11/16/08      camera
   3        Ikon      02/27/09      camera

これで、HP デバイスのタイプをすぐに確認できます。しかし、今では重複データがあります (暗黙的に)。理由を確認するには、ユーザーがこの変更を行ったかどうかを検討してください。

汎用デバイス

deviceID    brand     shipDate   deviceType
   1        HP        05/06/09      camera
   2        Canon     11/16/08      camera
   3        Ikon      02/27/09      camera

(最初の行の deviceType は camera に切り替えられました)
これで、矛盾する情報が得られました。この上の表では、HP デバイスはカメラであると示されていますが、ラップトップ テーブルにはデバイスの行があります。つまり、事実上、HP デバイスのタイプを 2 回保存しています。1 回は GenericDevice テーブルの deviceType フィールドを使用し、1 回は単純に、Laptop テーブルに deviceID = 1 の行があるという事実によって。

4

3 に答える 3

2

タイプを親または子の 1 つのテーブルにのみ保存し、1 つだけ選択します。2 つの場所に保管する場合は、それらを同期しておく必要があります。親にすべての子情報を保管しないのはなぜですか? それはそれをさらに簡単にします;-) (冗談です、親テーブルにすべてを入れないでください!)

編集

Type 列を GenericDevice テーブルに入れますが、「ラップトップ」や「カメラ」などの単語ではなく、コードまたは数値 ID と DeviceType テーブルの FK にします。また、ブランドがコードまたは ID とブランド テーブルへの FK を使用していることを確認してください。

GenericDevice
deviceID    brand     shipDate   deviceType 
1           1         05/06/09   L
2           2         11/16/08   C
3           3         02/27/09   C

DeviceTypes
deviceType   deviceDescription
L            Laptop
C            camera

Brands
BrandID   BrandName
1         HP
2         Canon
3         Ikon

予想される異なる値の数に基づいて、コード/ID データ型を選択します。

価値があるのは、次のようにクエリを実行できることです (deviceType 列を使用せずに)。

SELECT
    g.deviceID,g.shipDate
        ,l.screenSize
        ,c.megapixels
    FROM GenericDevice          g
        LEFT OUTER JOIN Laptop  l ON g.deviceID=l.deviceID
        LEFT OUTER JOIN Camera  c ON g.deviceID=c.deviceID
    WHERE g.deviceID=1234
于 2009-07-06T18:45:35.413 に答える
1

「しかし、これほど単純なものを見つけるには、不必要な量の結合が必要になるようです。」

了解しました。

私はあなたの立場に立っていますが、幸いにも、もう一度参照する必要がある場合に備えて、このサイトをブックマークしています。探している制約を設定する方法に関する情報も含まれています。

SQL Serverを使用していると仮定すると、次のようになります 。SQLServerでのテーブル継承の実装

于 2009-07-06T20:30:46.183 に答える
0

複数のデバイス タイプが同じ子テーブルにマップされている可能性があるため、親テーブルに deviceType 列を保持します。

クエリを高速化するために実際に必要な子テーブルに deviceType の複製を保持します。deviceType を取得するためだけに親に少し参加すると、本当に遅くなるとは思いません。また、親テーブルから多くの列を使用することになるかもしれません。その場合、もう 1 つの列があっても問題はありません。

複製は、挿入と更新のトリガーによって維持されます。


データの整合性の問題を引き起こす deviceType の更新の問題について言及しています。答えは、「そうしないでください」です。デバイス タイプを変更できない場合は、更新トリガーで変更を許可しないでください。

于 2009-07-06T18:43:57.820 に答える