Я пытаюсь начать заниматься веб-разработкой, пытаясь разработать систему управления отелем.

Я использую MySQL 5.5.44 (Raspberry Pi Debian) и PHP PDO для связи.

Внешние ключи и первичные ключи сбивают меня с толку до чертиков.

Это мой дизайн БД (график, созданный с помощью DbVisualizer)

HotelDB

Проблемы:

У меня есть опция в зоне для участников веб-сайта, где пользователь может отменить бронирование. Для этого я хочу скопировать отмененное бронирование (строка в таблице бронирований) в таблицу отмены, и это работает, НО после этого я хочу удалить отмененное бронирование из таблицы бронирований. Вот где начинается моя дилемма. Я не могу удалить родительскую строку из таблицы бронирований, так как идентификатор бронирования в таблице отмены и таблица платежей связаны через ссылки (FK и PK).

Мне нужно, чтобы BookingID был PK, поскольку это единственное уникальное значение во всей системе. У клиента может быть уникальный идентификатор, но у него может быть несколько заказов, и PK должен быть уникальным в таблице. Несколько заказов на одного клиента позволяют одному и тому же идентификатору клиента несколько раз присутствовать в таблице. Но BookingID всегда уникален, даже если это тот же Клиент. Вот почему мне нужен идентификатор бронирования.

Как мне заставить это работать?

Как я могу сохранить BookingID как FK и PK в таблицах платежей и отмен, но при этом избавиться от строки в таблице бронирований?

Нужно ли мне переделывать схему БД? Если да, то как бы вы это сделали?

Вот DESCRIBE таблиц:

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)

Я надеюсь, что вы, ребята, сможете помочь новичку в его амбициозном проекте.

Спасибо.

2
Zombievirus 10 Май 2016 в 15:02

2 ответа

Лучший ответ

Полностью отбросьте таблицу cancellations, затем добавьте один из следующего в таблицу bookings:

  • cancelled_at отметка времени, допускающая значение NULL

    SELECT * FROM bookings WHERE cancelled_at IS NULL
    
  • is_cancelled логическое значение по умолчанию false

    SELECT * FROM bookings WHERE is_cancelled = 0
    
2
Jeff Puckett 9 Мар 2018 в 18:05

Я бы добавил поле даты и времени отменено и включил его в таблицу бронирования. Я уверен, что вы все равно захотите узнать, когда он был отменен. Тогда наличие Boolean для него также было бы лишним. На самом деле это просто предпочтение, некоторые люди думают, что логические значения облегчают чтение SQL, но вам придется добавить ограничения, такие как отмененное резервирование без отметки времени.

3
Brandon Parman 10 Май 2016 в 13:46