【问题标题】:Hotel Management Database Design Problems酒店管理数据库设计问题
【发布时间】:2018-03-10 02:05:48
【问题描述】:

我正在尝试通过开发酒店管理系统来开始 Web 开发。

我使用 MySQL 5.5.44 (Raspberry Pi Debian) 和 PHP PDO 进行通信。

外键和主键把我搞糊涂了。

这是我的数据库设计(通过 DbVisualizer 创建的图表)

问题是:

我在网站的会员区有一个选项,用户可以在其中取消预订。为此,我想将取消的预订(预订表中的行)复制到取消表中,但这样做之后我想从预订表中删除取消的预订。现在这是我的困境开始的地方。我无法从预订表中删除父行,因为取消表中的预订 ID 和付款表通过参考(FK 和 PK)连接。

我需要 BookingID 作为 PK,因为它是整个系统中唯一的唯一值。一个客户可能有一个唯一的 ID,但他可以有多个预订,并且 PK 在表中必须是唯一的。每个客户的多个预订允许相同的客户 ID 在表中多次出现。但是 BookingID 始终是唯一的,即使它是同一个 Customer。这就是我需要预订 ID 的原因。

我如何让它工作?

如何将 BookingID 在 Payments 和 Cancellation 表中保留为 FK 和 PK,但仍摆脱 Bookings 表中的行?

我必须重新设计 DB-Schema 吗?如果是,你会怎么做?

这里是表格的DESCRIBEs:

mysql> describe Bookings;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| BookingID  | int(11)      | NO   | PRI | 0       |       |
| Arrival    | datetime     | YES  |     | NULL    |       |
| Checkout   | datetime     | YES  |     | NULL    |       |
| RoomNumber | int(11)      | YES  | MUL | NULL    |       |
| CustomerID | int(11)      | YES  | MUL | NULL    |       |
| Breakfast  | int(11)      | YES  |     | NULL    |       |
| Nights     | int(11)      | YES  |     | NULL    |       |
| Comment    | varchar(400) | YES  |     | NULL    |       |
| BookType   | varchar(50)  | YES  | MUL | NULL    |       |
| BookTime   | datetime     | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
10 rows in set (0.00 sec)


mysql> describe Cancellations;
+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| BookingID  | int(11)  | NO   | PRI | 0       |       |
| Arrival    | datetime | YES  |     | NULL    |       |
| Checkout   | datetime | YES  |     | NULL    |       |
| RoomNumber | int(11)  | YES  | MUL | NULL    |       |
| CustomerID | int(11)  | YES  | MUL | NULL    |       |
| Breakfast  | int(11)  | YES  |     | NULL    |       |
| Nights     | int(11)  | YES  |     | NULL    |       |
| BookTime   | datetime | YES  |     | NULL    |       |
| CancelTime | datetime | YES  |     | NULL    |       |
+------------+----------+------+-----+---------+-------+
9 rows in set (0.00 sec)

mysql> describe Payments;
+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| BookingID  | int(11)       | NO   | PRI | 0       |       |
| CustomerID | int(11)       | YES  | MUL | NULL    |       |
| Amount     | decimal(10,0) | YES  |     | NULL    |       |
| Paid       | varchar(10)   | YES  |     | NULL    |       |
| PayTime    | datetime      | YES  |     | NULL    |       |
| Invoice    | varchar(50)   | YES  |     | NULL    |       |
| Cancelled  | varchar(10)   | YES  |     | NULL    |       |
+------------+---------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

我希望你们可以帮助初学者完成他雄心勃勃的项目。

谢谢。

【问题讨论】:

  • BookingsCancellations 成为两个单独的表似乎有点不自然。它们包含相同的数据并代表相同的事物。为什么要把它们分开? Bookings 可以简单地拥有某种“状态”列,其中“已取消”可以是有效状态。最多,如果Cancellation 有额外的数据,不一定是Booking 的一部分,那么给它一个FK 到Bookings 并将额外的数据存储在其中。但不要将相同的数据复制到多个表中。手动保持数据同步既困难又不必要。
  • 我只想在预订表中有“成功”的预订。所以我决定分开,但我想这是个坏主意。

标签: mysql sql database


【解决方案1】:

我会添加一个日期时间取消字段并将其包含在预订表中。我敢肯定,无论如何,您都会想跟踪它何时被取消。然后为它使用布尔值也只是多余的。虽然这实际上只是一种偏好,但有些人认为布尔值使 SQL 更易于阅读,但您必须添加约束,例如取消没有时间戳的预订。

【讨论】:

  • 这正是我所做的!我现在在 Bookings 表中包含了一个名为 CancelTime 的 DATETIME 字段。没有布尔字段,取消表现在已成为历史。我检查 CancelTime 字段是否为 NULL 以验证状态。这似乎是最简单的方法!
【解决方案2】:

完全删除cancellations 表,然后将以下一个添加到bookings 表中:

  • cancelled_at时间戳可为空

    SELECT * FROM bookings WHERE cancelled_at IS NULL
    
  • is_cancelled布尔默认false

    SELECT * FROM bookings WHERE is_cancelled = 0
    

【讨论】:

  • 我不知道布尔值是可能的...我会调查的。谢谢
  • 是的,它们很有用。实际上,由于您还想将cancel_time 添加到该表中,因此您可以检查它是否为空并跳过布尔值。
  • 啊好吧!谢谢!我只需将 CancelTime 添加到 Bookings 并删除 Cancellations!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多