Составной первичный ключ, одно поле которого имеет тип данных DATETIME.

У меня есть следующая настройка таблицы:

CREATE TABLE IF NOT EXISTS `appointment` (
  `idappointment` int(11) NOT NULL AUTO_INCREMENT,
  `appdate` datetime NOT NULL,
  `appnote` varchar(255) DEFAULT 'Please enter a relevant note',
  `chair_idchair` int(11) NOT NULL,
  PRIMARY KEY (`idappointment`,`chair_idchair`),
  KEY `fk_appointment_chair_idx` (`chair_idchair`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;

Типичными значениями поля appdate являются: 2013-07-05 08:30:00 и 2013-07-05 09:00:00, поэтому значения метки времени отсутствуют, и все встречи различаются с фиксированным интервалом времени.

Для моего приложения мне нужно убедиться, что ни один стул не забронирован дважды в один и тот же интервал времени, по этой причине я подумал о создании составного первичного ключа, состоящего из поля appdate и поля chair_idchair, а затем установить этот составной первичный ключ как уникальный.

Мой вопрос заключается в том, как это сделать в MySQL и, что более важно, действительно ли это лучший способ гарантировать, что никакие двойные бронирования не могут быть забронированы со стороны БД. Я не хочу просто полагаться на приложение для этой проверки, поскольку пользователи будут бронировать одновременно из нескольких мест.


person Letholdrus    schedule 05.07.2013    source источник
comment
Ура, просто примечание: затем установите этот составной первичный ключ как уникальный - первичные ключи уникальны по определению. (Только для любопытных пользователей Google.)   -  person Sz.    schedule 05.04.2014


Ответы (2)


Создание составного первичного ключа, содержащего appdate и chair_idchair, не решит проблему. Если appdate для одной записи, если 2013-07-05 08:30:00, тогда будет разрешена другая запись с appdate 2013-07-05 08:31:00 для того же идентификатора кресла, что неверно.

Чтобы преодолеть это, перед вставкой какой-либо записи вам нужно будет проверить, есть ли какая-либо встреча, время которой перекрывается с текущей встречей по запросу, и только тогда вы должны разрешить вставку.

Например. если продолжительность встречи составляет 30 минут, то, прежде чем вводить какую-либо встречу, вам нужно будет проверить, есть ли какая-либо встреча для того же кресла, время которой составляет менее 30 минут от нового времени встречи.

TIMEDIFF() функция mysql может помочь вам в этом.

person Darshan Mehta    schedule 05.07.2013

Как заметил Даршан, составной индекс, подобный этому, не обеспечит уникальность appdate. Вам лучше использовать столбец автоинкремента для ПК. И добавьте еще один индекс на appdate (при необходимости уникальный).

Таким образом, это будет так же легко реализовать, и когда ваш клиент решит, что вам нужно иметь 2 записи с одинаковыми appdate в базе данных, их будет легче изменить.

Если вы хотите обеспечить уникальность appdate через базу данных, вы можете создать триггер перед вставкой/обновлением, чтобы нормализовать значение appdate (например, преобразовать его из 2013-07-05 12:33:41' to2013-07-05 12:30:00`). А затем поместите уникальное ограничение с индексом.

person Vatev    schedule 05.07.2013