首页 > 解决方案 > 酒店预订的数据库设计问题

问题描述

我目前正在设计(作为大学课程的作业)一个用于在线预订全球酒店的数据库,我偶然发现了一个问题。

在描述之前,这里是迄今为止关系模型的表格:

GUEST
guest_ID varchar PK
email varchar
guest_password varchar
first_name varchar
last_name varchar
mobile_num varchar
member_status varchar
pref_language varchar
pref_currency_code varchar

HOTEL
hotel_ID varchar PK
hotel_name varchar
ratings_avg int
phone_num varchar
email varchar
currency_code varchar
street_name varchar
street_num varchar
zip_code varchar
city varchar
country varchar

ROOM
room_ID varchar PK
hotel_ID varchar FK to Hotel
room_name varchar
low_season_rate numeric
high_season_rate numeric
max_persons int

BOOKING guest_ID
varchar FK to Guest
room_ID varchar FK to Room
check_in date
check_out date
(前 4 个组合为 PK)
persons_num int

PAYMENT
guest_ID varchar FK to Guest
room_ID varchar FK to Room
date_paid timestamp
amount numeric

EVALUATION
guest_ID varchar FK 到 Guest
hotel_ID varchar FK 到 Hotel
eval_date 日期
(前 3 个作为 PK 的组合)
rating int
guest_comment text

我想出这个设计思路是这样的:客人会预订属于酒店的房间,支付房间费用,然后,如果他们愿意,在入住后对酒店进行评估。

所以我认为预订和付款是客人和房间之间的关系,而评价是客人和酒店之间的关系。

这种设计似乎存在的问题是付款和评估与预订完全切断,因此即使没有预先存在的预订,他们的桌子也可以填满。我现在看到的方式是,客人支付房间住宿(=预订)并评估酒店住宿(=预订),所以我认为这些表应该参考预订表。

但是 Booking 是一个关系,我可以在一个实体和另一个关系之间形成一个关系吗?还是我缺少另一种解决方案?

我欢迎任何关于这个主题的想法。

标签: sqldatabasepostgresqlentity-relationship

解决方案


首先,您的付款和评估不会从预订中“切断”。您可以在多个联接中建立关系。其次,请记住在数据库之上有一个应用程序将强制执行一些逻辑,例如在没有客人的情况下不进行预订以及在没有预订的情况下不让客人进行。

如果出于某种原因,您的要求要求您使用键、约束和触发器严格执行数据库中的所有内容,您将需要对您的模式进行一些处理。我对此有以下几点建议:

我喜欢我的表上的标识键,这样数据库就不必强制执行组合键关系,我在应用程序层执行此操作(它让我有更多的自由在以后对模式和应用程序进行意外更改)。

您可能希望从 ROOM 表中取出费率。如果它们被更新,它们将不再适用于同一酒店和房间的先前预订。

付款和评估只需要与预订有直接关系。如果没有实际逗留,您将无法拥有其中任何一个。

imo 一个独特的预订是日期范围的酒店和房间,所以预订应该对酒店和房间有一个 fk。

您如何处理与 BOOKING 相关的 GUEST 有点棘手。预计 GUEST 能够拥有多个 BOOKING (imo),因此您可以在 BOOKING 上为 GUEST 设置一个 fk,这样 BOOKING 现在对于酒店、房间、GUEST 和日期范围是唯一的。

但是,如果 BOOKING 可以有 1 位以上的 GUEST,则需要进行关系查找。只需 GUESTid 和 BOOKINGid,因此您可以拥有 many::many 并且仍然将 GUESTs 关联到 BOOKINGs

只要您可以使用连接在所有表之间建立关系连接,它们就不需要都与所有其他表直接相关。


推荐阅读