2008-10-27 95 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是否有這樣,您可以將預訂引用到特定的帳單記錄,也可以引用其他事情如迷你吧費用。