【发布时间】:2020-04-08 02:47:31
【问题描述】:
当谈到 SQL 时,我是一个绝对的初学者,我正在尝试弄清楚如何进行简单的完整性检查。我正在建模一个包含四个表的酒店注册系统:Hotel、Room、Booking 和 Guest。我感兴趣的是预订表,它有属性hotelNo、guestNo、dateFrom、dateTo、roomNo,其中前三个是复合主键。那么问题来了,在现行制度下,两个人可能同时预定了同一个房间,这在现实生活中显然是个问题。我想一个解决方案可能开始看起来像
CREATE TABLE Booking(
-- All the attribute definitions go here...
CONSTRAINT OneGuestAtATime
CHECK (NOT EXISTS(SELECT(dateFrom FROM Booking ...))) -- I become unsure of what to do around here
);
请记住,虽然我是一名计算机工程专业的学生,但我以前从未使用过 SQL,因此我们将不胜感激:)
编辑:我认为我的问题将通过对效果的约束来解决
CASE 1(重叠):“如果我尝试插入的记录的 dateFrom 或 dateTo 属性介于表中先前给定记录的 dateFrom 和 dateTo 属性之间,则拒绝此插入,因为两者之间存在一些重叠两次预订。”
CASE 2(超集):“如果我试图插入记录 X,并且表中已经有一条名为 Y 的记录,使得它的 Y.dateFrom > X.dateFrom 和 Y.dateTo
不过,我不确定如何将其转换为 SQL。
编辑 2:表格
CREATE TABLE Hotel (
hotelNo NUMBER NOT NULL,
hotelName VARCHAR2(1024) NOT NULL,
city VARCHAR2(1024) NOT NULL,
--
PRIMARY KEY (hotelNo)
);
CREATE TABLE Room (
roomNo NUMBER(4,0) NOT NULL,
hotelNo NUMBER(5,0) NOT NULL,
type VARCHAR2(1024),
price NUMBER(6,2) NOT NULL,
--
PRIMARY KEY (roomNo, hotelNo),
FOREIGN KEY (hotelNo) REFERENCES Hotel
);
CREATE TABLE Guest(
guestNo NUMBER(8,0) NOT NULL,
guestName VARCHAR(1024) NOT NULL,
guestAddress VARCHAR(1024) NOT NULL,
--
PRIMARY KEY (guestNo)
);
CREATE TABLE Booking(
hotelNo NUMBER(8,0) NOT NULL,
guestNo NUMBER(8,0) NOT NULL,
dateFrom DATE NOT NULL,
dateTo DATE NOT NULL,
roomNo NUMBER(4,0) NOT NULL,
--
PRIMARY KEY (hotelNo, guestNo, dateFrom),
FOREIGN KEY (hotelNo) REFERENCES Hotel,
FOREIGN KEY (guestNo) REFERENCES Guest,
FOREIGN KEY (hotelNo, roomNo) REFERENCES Room(hotelNo, roomNo),
--
CONSTRAINT DateIntegrity
CHECK (dateFrom < dateTo)
【问题讨论】:
-
hotelNo、dateFrom和roomNo上的唯一约束怎么样。那么您不能在同一日期多次预订同一个房间。 -
我目前对这三个有唯一约束(因为它们是我的复合主键),但这不能解决以下问题:客人 A 从 2020 年 1 月 1 日到 2020 年 2 月 1 日预订房间 100 ;客人 B 在 2020 年 1 月 2 日至 2020 年 2 月 2 日期间预订了 100 号房间。到目前为止,我没有违反限制条件,但显然客人 A 和 B 的预订存在重叠。
-
在您的问题中,您写道:预订表 ... 属性 hotelNo、guestNo、dateFrom ... 是复合主键 但在您的评论中,您声称 hotelNo , dateFrom 和 roomNo 组成主键。也许edit您的问题并发布表的详细信息,包括列名及其数据类型以及主键和外键。
-
我认为说 a,b,c 是复合主键 c 相当于说 a,b 和 c 组成主键 K。我不太明白其中的区别,因此如果造成混淆,我深表歉意。