2008-10-27 101 views
3

您如何模拟预订的酒店房间与客人的关系(在PostgreSQL中,如果有关系)?一个房间可以有几个客人,但至少有一个。建模数据库中的1到1..n关系

当然,人们可以通过外键booking_id与客人联系预订。但是,如何在DBMS级强制执行一个房间必须至少有一个客人?

可能是不可能的?

+0

如果从不有空房间,您必须拥有一家非常高效的酒店。 – 2008-10-27 11:28:28

+0

这些是预订的房间 – 2008-10-27 11:30:46

+0

您的设计...有问题。 – Will 2008-10-27 11:36:50

回答

5

其实,如果你阅读这个问题,它说明预定的酒店房间。这是很容易做到如下:

Rooms: 
    room_id primary key not null 
    blah 
    blah 

Guests: 
    guest_id primary key not null 
    yada 
    yada 

BookedRooms: 
    room_id primary key foreign key (Rooms:room_id) 
    primary_guest_id foreign key (Guests:guest_id) 

OtherGuestsInRooms: 
    room_id foreign key (BookedRooms:room_id) 
    guest_id foreign key (Guests:guest_id) 

这样的话,你可以强制至少有一个客人,而OtherGuests是0或更多的关系预订房间。如果没有客人,您无法创建预订房间,并且您无法在未预订客房的情况下添加其他客人。

如果你想要一个n对n的关系,它应该被规范化为一个单独的表,其中包含1对n和n对1的两个表。

0

怎么样一个房间没有出租?你要找的是预订,预定至少需要一位客人。

我想你要问的是你是否可以保证没有添加预订记录,除非你至少有一个客人,并且你不能在没有保留的情况下添加客人。对于大多数DBMS系统来说,这是一个Catch-22。

1

您可以将其中一位来宾指定为“主要”来宾,并将其映射到Rooms表中的一列。当然,对于一个酒店来说这是一个荒谬的规则,在那里有一个房间有0位客人是完全有效的(我可以支付房间而不是呆在那里)...

4

在这种情况下,我建议您正在建模的实体实际上是一个单一的实体,而不是两个房间和客人的实体。

所以该表将像

BOOKING 
------- 
booking id 
room id 
guest id (FK to table of guests for booking) 
first date of occupancy 
last date of occupancy 

凡客的id是不是空的, 和你有另一个表来保存每次预订的客人......

GUESTS 
------ 
guest id 
customer id (FK to customer table) 
1

我想你的意思是说房间预订至少是一个客人。 ANSI标准的SQL将允许你表达约束作为断言是这样的:

create assertion x as check 
    (not exists (select * from booking b 
       where not exists 
        (select * from booking_guest bg 
        where bg.booking_id = b.booking_id))); 

不过,我不认为Postgres的支持(我不知道任何当前的DBMS一样)。

有使用物化视图和检查约束的方式,但我从来没有见过这在实践中完成的:

1)创建一个物化视图

select booking_id from booking b 
where not exists 
    (select * from booking_guest bg 
    where bg.booking_id = b.booking_id); 

2)添加一个检查约束物化视图:

check (boooking_id is null) 

如果要是有没有关联的客人预订过物化视图不是空的,即这种约束将失败。但是,您需要注意此方法的性能。

0

我想说你应该创建一个bookings表和三个主键。但不是指预订房间,您可以参考beds表格。

bookings: 
    bed_id: foreign_key primary 
    guest_id: foreign_key primary 
    day: date primary 
    bill_id: foreign_key not null 

beds: 
    room_id: foreign_key primary 

由于作为primary意味着被要求,而且由于这是一个客人和一间可以进行相关的唯一方法,它可以确保不能有一个没有预约的客人。

请注意,只有一个day字段。这要求您每天都会为客人创建一个预订房间,但也可以确保没有任何事情会被意外预订两次。一张床可以在任何给定的一天只有一个客户预订(这不是真的房间)

bill_id是否有这样,您可以将预订引用到特定的帐单记录,也可以引用其他事情如迷你吧费用。