发现超类表中行的子类

时间:2009-07-06 18:41:52

标签: database-design class-table-inheritance

我有一个电子设备表,作为通用超类,然后分离电话,笔记本电脑,相机等的子类表,扩展超类并在设备上提供特定信息(使用超类中的外键deviceID)表),换句话说,Class Table Inheritance。我的问题是,我应该在超类中有一个“deviceType”列吗?这将是多余的,因为你可以通过查看特定deviceID出现在哪个子类表中来发现设备类型,但这似乎是一个不必要的连接数量,以找出这么简单的东西。

一般来说,某个人看一个随机的通用设备并想知道它是什么类型可能是不寻常的,但将设计留在那个人很难轻易找到的地方似乎也很奇怪。

另一个问题是约束......如何限制它以便设备只被子类型化一次?就像在,什么是停止添加到Laptop表的行,其中deviceID与Camera表中已存在的行相同?同样,对于良好的用户界面来说,这甚至不可能实现,但数据库约束总是更可取。

谢谢!

P.S。如果我们确实使用deviceType列,为了帮助数据完整性,它将链接到我们支持的所有设备类型的枚举表,而不是自由文本字段。

已添加以供澄清


首先是超类表:

GenericDevice

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

以下是两个示例子类:

笔记本

laptopID    deviceID    screenSize
   1           1           17

相机

cameraID      deviceID     megapixels
   1             2            6.5
   2             3            8

请注意GenericDevice表中“deviceID”的迁移密钥。这允许从通用表到任何子类表的一对一关系,具体取决于它实际上是什么类型的设备。因此,您可以加入这些表格,看看HP设备是一台17英寸屏幕的笔记本电脑,佳能和Ikon设备分别是6.5和800万像素的摄像头。

问题是如果你不知道一个设备是什么类型,并且你拥有的只是GenericDevice表中的一行。我们以第一行为例。您知道该设备是由HP生产的,并于05/06/09发货,但您最初并不知道它是什么类型的设备。但是你可以通过搜索子表来找出它,直到你找到一个deviceID = 1的行.Compapable表包含这样一行,所以HP设备实际上必须是那台笔记本电脑。但这似乎是简单地发现设备类型的不必要的麻烦(特别是如果你有20多个子类,你必须搜索以查看deviceID匹配的位置)。相反,你可以这样做:

GenericDevice

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

现在您可以立即看到HP设备的类型。但现在你有重复的数据(含蓄)。要了解原因,请考虑用户是否进行了此更改:

GenericDevice

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

(第一行的deviceType切换到摄像机)
现在您有相互矛盾的信息 - 上表显示HP设备是一台摄像头,但笔记本电脑桌中的设备有一排。 换句话说,您实际上是两次存储HP设备的类型。一旦使用GenericDevice表中的deviceType字段,并且只是因为LaptopID中有一行带有deviceID的事实= 1。

3 个答案:

答案 0 :(得分:2)

只将类型存储在一个表,父或子,只需选择一个。如果你将它保存在两个地方,你必须让它们保持同步,为什么不把所有的儿童信息保存在父母中?这让它更容易;-)(这是一个笑话,不要把所有东西放在父表中!)

编辑

我将一个Type列放入GenericDevice表中,但是我将它设置为DeviceType表的代码或数字ID和FK,而不是像“laptop”或“camera”这样的单词。还要确保品牌使用代码或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

答案 1 :(得分:1)

  

“但这似乎是一个   找到不必要的连接数量   这么简单。“

你明白了。

我一直在你的鞋子里,幸运的是我仍然将这个网站加入书签,以防我需要再次参考。它甚至包括有关如何设置您正在寻找的约束的信息。

假设您正在使用SQL Server,请转到: Implementing Table Inheritance in SQL Server

答案 2 :(得分:0)

我会在父表中维护一个deviceType列,因为您可能有多个设备类型映射到同一子表。

我会在实际需要它来加速查询的任何子表中保留deviceType的副本。我不会假设有一点联系到父母只是为了让deviceType真的减慢了。此外,您最终可能会使用父表中的许多列,在这种情况下,还有一列不会对任何内容产生任何影响。

复制将由插入和更新时的触发器维护。


您提到更新deviceType导致数据完整性问题的问题。答案是,“不要那样做”。如果设备类型无法更改,则更新触发器应该不允许更改。