ORACLE SQL-创建不相交的专业化

ORACLE SQL-创建不相交的专业化,sql,oracle,Sql,Oracle,以下是我对表格的期望。物品可以拆分为“电脑”或“衣服”。 计算机具有“计算机类型”和“操作系统”属性。 衣服只有“衣服类型”。因为我想将它们作为子类型,所以它们都将“item_id”作为外键 我的计划是从父项派生这两个子表,并将(我正在处理的导入数据)插入到相应的表中。“item”表存储所有“items”,但子表将引用给定的item ID并进行填充 表:项目(项目id) 表:具有自身属性的计算机(子类型) 表:具有自身属性的衣服(子类型) 我在这里看到另一个帖子: 因此,我想知道(因为我的方法

以下是我对表格的期望。物品可以拆分为“电脑”或“衣服”。 计算机具有“计算机类型”和“操作系统”属性。 衣服只有“衣服类型”。因为我想将它们作为子类型,所以它们都将“item_id”作为外键

我的计划是从父项派生这两个子表,并将(我正在处理的导入数据)插入到相应的表中。“item”表存储所有“items”,但子表将引用给定的item ID并进行填充

表:项目(项目id)

表:具有自身属性的计算机(子类型)

表:具有自身属性的衣服(子类型)

我在这里看到另一个帖子:


因此,我想知道(因为我的方法与他的方法类似)是否应该在两个分离的表中创建具有外键的表,并相应地使用“select”。或者有没有一种方法不用单独的表来存储单个属性。

您可以尝试使用3个表、一个检查约束(对于“supertype”表)和外键约束来实现这一点。然而,一个好的替代方法可能是对象关系方法:创建3种类型,并且只有一个表可以容纳所有数据

示例(Oracle 12c)

测试:插入

begin
-- "standard" INSERTs
  insert into items ( item ) 
    values ( computer_t( 'iMac', 'Mac OS' ) );
  insert into items ( item )
    values ( clothes_t( 'coat', 'black' ) ); 
-- object of SUPERtype can be inserted
  insert into items ( item )
    values ( item_t( 'supertype' ) ); 
end;
/

-- Unknown types cannot be inserted. Good.
insert into items ( item )
    values ( unknown_t( 'type unknown!', 'not available', 999 ) ); 
-- ORA-00904: "UNKNOWN_T": invalid identifier
insert into items ( item )
    values ( item_t( 'supertype', 'not available') ); 
-- ORA-02315: incorrect number of arguments for default constructor
对于查询,请使用适当的函数。一个简单的SELECT*FROM items可能不会提供您需要的结果,例如

SQL> select * from items;
ID  ITEM                        
1   oracle.sql.STRUCT@2d901eb0  
2   oracle.sql.STRUCT@3ba987b8  
3   oracle.sql.STRUCT@3f191845
质疑

“或者有没有一种方法不需要单独的表来存储单个属性。”

没有好办法避免使用单独的表。糟糕的方法包括使用所谓的通用数据模型(实体属性值模式)或某种形式的准结构化存储,如JSON或XML

这些方法不好有几个原因

  • 很难理解数据模型。模型是 嵌入数据的存储方式,而不是以 桌子和钥匙
  • 我们无法在此类服务器上强制执行密钥和数据完整性约束 模型
  • 针对这种“模型”编写查询比较困难,因为SQL是一种适合静态数据模型的强类型语言。由于没有进行适当的数据建模而节省的时间浪费在编写处理低质量数据所需的复杂查询上(因为上一点)
  • 一个健壮的解决方案将在具有全范围键的子类型表之间强制执行arc

     create table items
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , item_name varchar2(30) not null
        , constraint item_uk unique (item_id, item_type)
        , constraint item_type_ck check (item_type in ('CLOTHES', 'COMPUTER'))
    );
    
    两把钥匙?为什么是两把钥匙?因此,我们可以在父记录和子记录之间实施一对一的关系:

     create table clothes
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , size not null varchar2(5)
        , colour not null varchar2(5)
        , category not null varchar2(5)
        , constraint clothes_type_ck check (item_type = 'CLOTHES')
        , constraint clothes_item_fk foreign key (item_id, item_type)
            references items (item_id, item_type)
    );
    
    create table computers
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , ram_gb not null number
        , storage_gb not null number
        , os not null varchar2(10)
        , constraint computers_type_ck check (item_type = 'COMPUTER')
        , constraint computers_item_fk foreign key (item_id, item_type)
            references items (item_id, item_type)
    );
    

    ITEMS上的主键确保给定的
    item\u id
    只有一条记录。unique键为子表提供了一个参考点,因此我们不能让COMPUTERS记录和Cloth记录指向相同的ITEMS记录

    更新您的问题添加适当的数据样本和预期结果我不认为向学生提供ORDBMS解决方案有帮助语法不直观,可能会混淆他们对SQL的学习。很高兴我不是唯一一个发现此解决方案技术性很强的人。非常感谢您的帮助。@TLG123:以后再看:)@APC-很高兴看到您(诚实地)给出的答案。我总是觉得“arc”所需的附加列有点麻烦。当您需要这些断言时,它们在哪里?非常感谢。我能够将此应用于我的数据。
     create table items
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , item_name varchar2(30) not null
        , constraint item_uk unique (item_id, item_type)
        , constraint item_type_ck check (item_type in ('CLOTHES', 'COMPUTER'))
    );
    
     create table clothes
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , size not null varchar2(5)
        , colour not null varchar2(5)
        , category not null varchar2(5)
        , constraint clothes_type_ck check (item_type = 'CLOTHES')
        , constraint clothes_item_fk foreign key (item_id, item_type)
            references items (item_id, item_type)
    );
    
    create table computers
       (item_id number not null primary key
        , item_type varchar2(10) not null 
        , ram_gb not null number
        , storage_gb not null number
        , os not null varchar2(10)
        , constraint computers_type_ck check (item_type = 'COMPUTER')
        , constraint computers_item_fk foreign key (item_id, item_type)
            references items (item_id, item_type)
    );