在oracle中mysql set数据类型的等价物是什么?

wbrvyc0a  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(327)

在mysql中,我们可以使用set datatype为任何特定行的每一列选择多个值,如下所示:

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文档参考原始链接

zdwk9cvp

zdwk9cvp1#

在mysql中,set数据类型是一种命名的位Map数据类型。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 )
);

您必须记住或构建一个函数来Map位图值和天数。
另一种选择是使用查找表:

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 ) 
);
avkwfej4

avkwfej42#

sentinel的答案(我投了赞成票)解决了这个问题。
但是,我将后退一步,并以“如何在oracle中表示这种类型的数据”来解决这个问题,建议解决这个问题的更好方法是不模拟set数据类型。
set数据类型可能违反了第一个范式。这不一定是对其用法的道德判断;这些解决方案使某些查询更容易和/或更高效,而其他查询更困难和/或效率更低。但是标准形式是建立在多年的rdbms经验基础上的。对于广泛的应用,遵循前三个范式是避免平衡问题的好方法。
可以在oracle中实现的规范化解决方案(无需跳转来模拟位字段枚举)可能包括 Staff 带有id的表 AvailabilityCode 表中的每个单独值都有一行,以及 StaffAvailability ,两者之间的交叉引用,每个要与人员id关联的availabilitycode值对应一行。

相关问题