Oracle中的MySQL Set数据类型等效吗?

时间:2018-11-30 15:23:49

标签: mysql sql database oracle oracle12c

在MySQL中,我们可以使用Set数据类型为任何特定行的每一列选择多个值,如下所示:

CREATE TABLE `staff` ( `StaffID` int(5) NOT NULL AUTO_INCREMENT,
                  `Availability` set('Mon','Tue','Wed','Thur','Fri','SatAM','SatPM','Sun') DEFAULT NULL, 
                  PRIMARY KEY (`StaffID`))

那我就可以做

INSERT INTO `staff` (`Availability`) VALUES ('Tue,Wed,SatPM')

我试图在所有地方找到数据,但是找不到任何合适的数据类型来存储上述Oracle中的多个选定选项。 Oracle文档似乎表明MySQL设置别无选择,但我不敢相信他们没有!那么有人可以帮我澄清一下吗?

Oracle Documentation reference Original link

2 个答案:

答案 0 :(得分:3)

在MySQL中,设置数据类型是命名的位映射数据类型。 Oracle没有一个,但是如果您确实想使用约束的整数数据类型,可以模拟它:

CREATE TABLE staff (
    staffid INTEGER GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 NOCACHE ORDER ) NOT NULL PRIMARY KEY
  , availability INTEGER CHECK ( availability BETWEEN 0 AND 256 )
);

您必须记住或构建一个在位图值和日期之间进行映射的函数。

另一种选择是使用查找表:

create table availability as
with t1(id, mon, tue, wed, thu, fri, satam, satpm, sun) as (
select 0, 0, 0, 0, 0, 0, 0, 0, 0 from dual
union all
select id+1
     , sign(bitand(id+1,1))
     , sign(bitand(id+1,2))
     , sign(bitand(id+1,4))
     , sign(bitand(id+1,8))
     , sign(bitand(id+1,16))
     , sign(bitand(id+1,32))
     , sign(bitand(id+1,64))
     , sign(bitand(id+1,128))
  from t1 where id+1 <256
)
select * from t1;

alter table availability add primary key (id);

CREATE TABLE staff (
    staffid INTEGER GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 NOCACHE ORDER ) NOT NULL PRIMARY KEY
  , availability INTEGER 
  , CONSTRAINT staff_avail_fk FOREIGN KEY ( availability ) REFERENCES availability ( id ) 
);

答案 1 :(得分:2)

Sentinel的答案(我赞成)回答了字面上的问题。

但是,我将退后一步,并以“如何在Oracle中表示这种类型的数据”作为问题来解决,建议更好的解决方案是模拟Set数据类型。

可以说Set数据类型违反了第一范式。这不一定是对其用法的道德判断;这样的解决方案使某些查询更容易和/或更有效,而另一些更困难和/或效率更低。但是正常形式是基于RDBMS多年的经验而建立的。对于广泛的应用程序,遵循前三种常规形式是避免出现平衡问题的好方法。

可以在Oracle中实现的规范化解决方案(无需跳过箍来模拟位字段枚举)可能包括带有ID的Staff表,每个单独的一行的AvailabilityCode表集合中的值,以及StaffAvailability(两者之间的交叉引用),其中每个行都与您要与Staff id关联的每个AvailabilityCode值对应。