2016-06-01 5 views
2

Скажите, что таблица встреч_записей для списка менеджеров (или HR) с помощью startDatetime и endDatetime, а затем как можно сконструировать таблицу так, чтобы она не принимала следующую запись, которая перекрывается для тот же менеджер, если он/она имеет назначение с каким-либо другим лицом.SQL-интервью: предотвращение перекрытия диапазона дат

Если менеджер: имеет назначение от 2016-01-01 11:00 to 2016-01-01 14:00 с Employee-1 затем, если Employee-2 (или someother сотрудник) пытается назначить встречу с 20-16-01-01 13:00 to 16:00, то она не должна позволять.

Примечание: речь идет о проектировании таблицы, поэтому триггеры/процедуры не поощряются.

+6

Для обеспечения соблюдения этого ограничения вам нужен триггер или определенную пользователем функцию (по крайней мере, в большинстве баз данных). –

+0

Если это вопрос SQL-запроса, вы можете просто ответить, что во время разработки это невозможно. –

+0

Вы можете сделать это в SQL Server, если вы также моделируете периоды свободного времени, имеете перекрестные ссылки внешних ключей, которые связывают каждый период времени с его предшественником и преемником, и пишут некоторые поистине ужасные утверждения «MERGE» для введения вставки/удаления (где, чаще всего, вам нужно разделить бесплатный период, обновив его, вставив новую строку и вставив новую встречу, все в одном заявлении, чтобы внешние ключи остались довольными). Это выполнимо, но часто затраты выше стоимости. –

ответ

1

Вместо того, чтобы вставлять диапазоны, вы можете вставлять кусочки времени. Вы можете сделать кусочки настолько широкими, насколько хотите, но притворяйтесь, что можете заказать менеджеру по 30 минут за раз. Чтобы забронировать с 11:30 до 12:00, вы должны вставить строку со значением времени в 11:30. Чтобы забронировать с 11:30 до 12:30, вы должны вставить две строки, одну в 11:30, другую в 12:00. Затем вы можете просто использовать ограничение первичного ключа или уникальное ограничение для предотвращения бронирования.

create table appointment_booking (
    manager char not null, 
    startSlice DateTime, 
    visiting_employee varchar2(255), 
    primary key (manager, startSlice) 
) 

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

0

ПРОВЕРКА CONSTRAINT + ФУНКЦИЯ (это так близко, как я могу добраться до DDL ответа)

Вы можете создать скалярную функцию - «SCHEDULE_OPENING_EXISTS()», который берет начало, конец, EmployeeID как входы , и выводит значение true или false.

Затем вы можете создать проверочное ограничение на столе

CREATE TABLE... 
    WITH CHECK ADD CONSTRAINT OPENING_EXISTS 
    CHECK (SCHEDULE_OPENING_EXISTS(begin, end, employeeID)) = 'True') 

Триггеры

Я стараюсь избегать триггеров, где я могу. Они не злые как таковые, но они добавляют новый уровень сложности вашему приложению. Если вы не можете этого избежать, вам понадобится INSTEAD OF INSERT, а также INSTEAD OF UPDATE (предположительно). Technet Ссылка здесь: https://technet.microsoft.com/en-us/library/ms179288%28v=sql.105%29.aspx

Имейте в виду, если вы отклоните попытку вставки/обновления, нужно ли вам обмениваться информацией с пользователем.

Stored Procedures/ИНТЕРФЕЙС:

Будет ли хранимая процедура работы для вашей ситуации? Пример сценария:

  1. Пользовательский интерфейс - пользователь должен видеть расписание человека (ов), с которым они планируют встречу.

  2. Из пользовательского интерфейса - попытка вставки/обновления с использованием сохраненной процедуры. Попросите его перепроверить (в последнюю минуту) открытие (вернуть сбой, если открытие больше не существует), а затем условно вставить/обновить, если открытие все еще существует (вернуть сообщение об успешном завершении).

Если процедура возвращает ошибку в UI, обрабатывать, что в пользовательском интерфейсе, повторно запрашивая видимый график всех сторон, сопровождаемое сообщением об ошибке.

+0

примечание: вопрос о (проверке) ограничениях, моделировании данных и DDL в SQL. Приложение или пользовательский интерфейс здесь неактуальны, и поэтому хранятся процедуры. – wildplasser

+0

@wildplasser - добавлена ​​опция CHECK CONSTRAINT для ответа ... не полностью DDL, но ... ближе. – Chains

0

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

Это, как говорится, до тех пор, пока приложение может ссылаться на несколько таблиц, я думаю, что ответ Крис Стил является отличным началом, что я буду опираться на ...

Я хотел бы 2 таблицы. Первая таблица делит день на части (фрагменты) в зависимости от бизнес-потребностей организации. Каждый срез будет основным ключом этой таблицы. Я лично выберу 15-минутные кусочки, которые приравниваются к 96 дням. Каждая дневная часть в этой таблице будет иметь «начало блока» и время «блокировки», на которое ссылается приложение планирования, когда пользователь выбрал фактическое время начала и фактическое время окончания собрания. Приложение будет необходимо применить логику такой, как два «ИЛИ» оператор между 3 «и» заявлениями для того, чтобы увидеть, если конкретный blockID будет вставлен в назначениях таблицы:

  • фактического пуск> = начало блока и фактическое начать < конца блока
  • фактический конец> начало блока и фактический конец < конца блока
  • фактическое начало старта < блок и фактический конец> конца блока

Это немного отличается от ответа Криса Стила в го при этом использует две таблицы. Фактические метки времени все еще могут быть вставлены в таблицу ваших приложений, но логика применяется только к ним при сравнении с таблицей TimeBlocks. В моей сервировки, я предпочитаю ломая даты в составные части для анализа кросс-платформенной (наша организация использует несколько СУБД, а также SAS для аналитики):

CREATE TABLE TimeBlocks (
      blockID Number(X) NOT NULL, 
      blockStart DateTime NOT NULL, 
      blockEnd DateTime NOT NULL, 
    primary key (blockID) 
); 


CREATE TABLE Appointments (
      mgrID INT NOT NULL, 
      yr INT NOT NULL, 
      mnth INT NOT NULL, 
      day INT NOT NULL, 
      blockID INT NOT NULL, 
      ApptStart DateTime NOT NULL, 
      ApptEnd DateTime NOT NULL 
      empID INT NOT NULL, 
    primary key (mgrID, yr, mnth, day, blockID), 
    CONSTRAINT timecheck 
      check (ApptStart < ApptEnd) 
);