代码之家  ›  专栏  ›  技术社区  ›  JoeCool

在超类表中发现行的子类

  •  2
  • JoeCool  · 技术社区  · 17 年前

    我有一个电子设备表,作为一个通用的超类,然后为电话、笔记本电脑、相机等分开子类表,扩展超类并提供设备上的特定信息(使用超类表中的外键设备ID),换句话说, Class Table Inheritance .我的问题是,我应该在超类中有一个“deviceType”列吗?这是多余的,因为你 能够 通过查看特定deviceid出现在哪个子类表中来发现设备类型,但这似乎是为了找到如此简单的内容而进行的不必要的连接量。

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

    另一个问题是约束…如何约束它,使设备仅为子类型一次?如中所述,如何阻止将与相机表中已存在的行具有相同设备ID的行添加到笔记本电脑表中?同样,对于一个好的用户界面,这是不可能实现的,但是数据库约束总是更好的选择。

    谢谢!

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

    增加澄清


    第一个是超类表:

    通用设备

    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英寸屏幕的笔记本电脑,而Canon和Ikon设备都是分别具有6.5和8百万像素的摄像头。

    问题是,如果您首先不知道设备是什么类型的,那么您所拥有的只是genericdevice表中的一行。让我们以第一行为例。你知道这台设备是由惠普公司生产的,于2009年5月6日发货,但你最初并不知道它是什么类型的设备。但是,您可以通过搜索子表,直到找到deviceid=1的行来解决这个问题。笔记本电脑桌上有这样一行,所以惠普设备实际上必须是那台笔记本电脑。但是,这似乎是发现设备类型的不必要的麻烦(特别是如果您有20多个子类,您必须通过搜索来查看deviceid匹配的位置)。相反,你可以这样做:

    通用设备

    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设备类型存储了两次。 一次使用genericdevice表中的deviceType字段,一次简单地通过这样一个事实:在deviceid=1的膝上型电脑表中有一行。

    3 回复  |  直到 17 年前
        1
  •  1
  •   James Jones    17 年前

    “但这似乎是一个 要查找的连接数不必要 拿出这么简单的东西。”

    你明白了。

    我一直在你的立场,我很幸运仍然有这个网站的书签,以防我需要再次参考它。它甚至包括有关如何设置所需约束的信息。

    假设您使用的是SQL Server,下面是: Implementing Table Inheritance in SQL Server

        2
  •  2
  •   KM.    17 年前

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

    编辑

    我在genericdevice表中放了一个type列,但我将它设置为一个代码或数字ID,并将fk设置为devicetype表,而不是像“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
    
        3
  •  0
  •   John Saunders    17 年前

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

    我将在任何实际需要它来加速查询的子表中维护deviceType的副本。我不认为仅仅为了得到deviceType而加入到父系统中会减慢速度。另外,您可能会使用父表中的许多列,在这种情况下,多列不会损害任何内容。

    副本将由插入和更新时的触发器维护。


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

    推荐文章