在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设置别无选择,但我不敢相信他们没有!那么有人可以帮我澄清一下吗?
答案 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值对应。