Часы работы дизайн базы данных - PullRequest
4 голосов
/ 25 января 2011

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

Пример.Открывается в понедельник в 6:00 и закрывается в пятницу в 18:00.

Или

Открывается в понедельник в 06:00 и закрывается в понедельник в 15:00.

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

StartDay, StartTime, EndDay и EndTime.

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

Пожалуйста, поделитесь своими мыслями.

РЕДАКТИРОВАТЬ: База данных Microsoft SQL Server 2008 R2

Ответы [ 7 ]

2 голосов
/ 25 января 2011

Подумайте о сохранении ваших StartDay и StartTime, но затем укажите количество часов, в течение которых он работает. Это гарантирует, что дата и время вашего закрытия будет после открытия.

OpenDate -- day of week? e.g. 1 for Monday
OpenTime -- time of day. e.g. 08:00
DurationInHours -- in hours or mins. e.g.   15.5
1 голос
/ 25 января 2011

На веб-сайте SimpleTalk есть статья Джо Селко, более здесь , в которой обсуждается аналогичная проблема и дается элегантное, если это сложное решение.Это, вероятно, применимо к вашей ситуации.

1 голос
/ 25 января 2011

Предполагая надежную структуру триггера

При вставке / обновлении вы проверяете, попадает ли новая дата начала или окончания в какой-либо из существующих диапазонов.Если это произойдет, вы откатите изменения.

CREATE TRIGGER [dbo].[mytable_iutrig] on [mytable] FOR INSERT, UPDATE AS

IF (SELECT COUNT(*)
FROM inserted, mytable
WHERE (inserted.startdate < mytable.enddate 
          AND inserted.startdate > mytable.startdate)
      OR (inserted.enddate < mytable.enddate 
          AND inserted.enddate > mytable.startdate)) > 0 
BEGIN
    RAISERROR --error number
    ROLLBACK TRANSACTION
END
0 голосов
/ 25 января 2011

Сначала логика, два пролета будут перекрываться, если начальное значение одного находится между началом / концом другого. Это намного проще, если мы объединили datetime вместо date1, time1 и date2, time2. Таким образом, запрос на поиск совпадения выглядит следующим образом.

select openingId
  from opening o1
  join opening o2 on o1.startDateTime 
             between o2.startDateTime
                 AND o2.endDateTime

Вы можете поместить это в триггер и выдать ошибку, если совпадение найдено.

0 голосов
/ 25 января 2011

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

0 голосов
/ 25 января 2011

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

0 голосов
/ 25 января 2011

Таблица с одним столбцом TimeOfChangeBetweenOpeningAndClosing?

Если серьезно, я бы, наверное, не слишком беспокоился о том, чтобы придумать единую структуру базы данных для представления всего, в конце концов вам, вероятно, понадобится система сповторения, запланированные закрытия и т. д. Сохраните объекты, представляющие их, а затем оцените их, чтобы узнать время закрытия / открытия.

...