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