Авторизация:

Хранение времени работы заведения в БДRSS-трансляция

Поиск

Найти сообщения:  За сутки  |  Без ответов
Автор Сообщение
Ссылка30.12.2010 в 13:39
Подскажите, пожалуйста, как в БД оптимальнее хранить время работы заведений.

Например, такие:
Вт, Чт, Сб: 17.40-19.00
пн. - вс.: с 16:00 до 04:00
пт. - сб.: с 23:00 до 06:00
пн. - чт.: с 16:00 до 23:00

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

Например, требуется найти все заведения работающие во Вторник в 18.30.

Спасибо.
Ссылка30.12.2010 в 13:41  [Отредактировано: 30.12.2010 в 13:43]
Каждая строка - запись времени работы ОТ и ДО. т.е. 2 поля типа time - начало промежутка и конец промежутка. id записи, id заведения. К каждому заведению можно привязать несколько таких записей. Соответственно на каждый день надо от одной записи. 2 если с перерывом.
Ссылка30.12.2010 в 14:09
Т.е. такая структура БД?

Код:
1
2
3
4
5
6
7
8
9
10
CREATE TABLE `vremya_raboty` (
  `id` int(11) NOT NULL,
  `id_zavedenie` int(11) NOT NULL,
  `den_nedeli` tinyint(4) NOT NULL,
  `ot_time` time NOT NULL,
  `do_time` time NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id_zavedenie` (`id_zavedenie`),
  KEY `den_nedeli` (`den_nedeli`)
) ENGINE=MyISAM;

Получается такое время работы: ( Пн: от 18:00 до 6:00 )
еще нужно разбивать на две записи: ( Пн: от 18:00 до 24:00 ) and (Вт: от 00:00 до 6:00)
Ссылка30.12.2010 в 14:58
storier, вроде того, да. Вообще можно просто интами попробовать сделать. Тогда не придется разбивать при переходе через сутки. Начало будет 1800, конец - 600.
Ссылка30.12.2010 в 23:03
Цитата (frig):
Вообще можно просто интами попробовать сделать

Зачем?

Цитата (frig):
Тогда не придется разбивать при переходе через сутки. Начало будет 1800, конец - 600

Какая разница если хранить время в его собственном формате? А разбивать или нет по суткам зависит не от способа хранения, а от принципа учета.
Будет храниться: ***или 5 18:00 06:00 - какая разница от типа данных? Зачем извращаться с переводом из шестидесятиричной системы в десятичную и наоборот?

Вот, например, в табельном учете (что на заводах и шахтах) бывает такая переходящая смена (через полночь) учитывается только в сутках, когда началась, а бывает разбивается по суткам принадлежности. И при расчете ЗП такое рабочее время может по разному учитываться.

Так и тут, способ отображения переходящих через полночь будет целиком зависеть от поставленной задачи. Судя по головному сообщению, удобней все-таки разделять независимо от типа данных для времени - запрос все равно будет проще построить при разделенных строках.
Ссылка31.12.2010 в 09:05  [Отредактировано: 31.12.2010 в 09:05]
Цитата (shapod):
Зачем?

Согласен, туплю. Это все ТС меня сбил :-))
Ссылка03.04.2011 в 15:11


Подскажите, структуру БД(mysql) для хранения времени работы из следующей формы для большого количества заведений.
Спасибо.
Ссылка03.04.2011 в 15:18
Если поиск потом не будет нужен (какое работает по понедельникам, какое по воскресеньям, какое с 10 до 11 в воскресенье) - то хранить данные только для вывода надо и поэтому храните их в любом виде, хоть в виде сериализованного php-массива.

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

Но, наверное, не имеет смысла делать 3 таблицы. Id дня недели: 0-6, id временных интервалов от 0-23 сразу известны.
Ссылка03.04.2011 в 15:33
storier, наверное, не имеет, но тут надо хорошенько подумать все же, мне приходят на ум пара гипотетических ситуаций, когда легче будет вынимать данные из трех таблиц, чем из одной таблицы и с применением массивов дней недели и интервалов.. но они гипотетические, надо знать о чем проект и что планируется делать в будущем. Так что вам решать
Ссылка03.04.2011 в 15:41  [Отредактировано: 03.04.2011 в 15:46]
Crist, каталог заведений.

Один из критериев поиска заведений, это временной: что работает в данный момент, что работает до хх часов, что работает с хх часов.

У некоторых время работы переходит через сутки.
Ссылка03.04.2011 в 16:17  [Отредактировано: 03.04.2011 в 16:19]
Ем.. на картинке что - декартовая система координат )..
Где х є [1;12]; y є [1;5]; x,y є N.. этим и можно воспользоваться, для 1 заведения будет один слой описывающий некую фигуру по некоторому уравнению, задача с уравнениями становится проще, так как заведомо известно, что фигура будет только с прямыми углами При выборе графика работы для 1 заведения получается функция, описывающая его работу на этой плоскости ..

и того:

таблица Заведения
Ид Название Уравнение графика работы

таблица Графики - эта таблица ненужна, данные статические и можно описать массивом в одном файле.

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

Остаётся придумать функцию для описания уравнения в зависимости от выбранных дней и часов на плоскости с чекбоксами.

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

..
Но можно пойти в "лоб" и делать таблицу типо:
Ид Название заведения Пн_8_9 Пн_9_10 .. Пт_18_19 Пт_19_20
Получится громоздкая таблица, но тоже вполне будет работать .. тут всем будет понятно, если для заведения в ячейке Чт_10_11 стоит "1" - то в четверг с 10 до 11 утра оно работает

УПД: на реализацию первого предложенного варианта уйдёт времени раза в 3-4 больше чем на второй, но первый прикольнее, будет выглядит впечатляюще, да и от процесса воплощения масса удовольствия
Ссылка03.04.2011 в 16:21  [Отредактировано: 03.04.2011 в 16:22]
А чего бы не заносить информацию таким образом?

Рабочие Часы Заведения:

-> заведение
-> ->день
-> -> ->время начала работы с...
-> -> ->продолжительность работы
-> -> ->перерыв на обед с...
-> -> ->продолжительность обеда
Ссылка03.04.2011 в 16:40
kirilev, я больше получаю удовольствия от простых и оптимальных способов решения задач .

TomNorman, спасибо, тоже вариант. Нужно посмотреть насколько удобно будет искать по такой таблице.
Ссылка03.04.2011 в 17:25  [Отредактировано: 03.04.2011 в 17:46]
Вот мой вариант решения.
Таблица:
— id — id заведения
— timefrom — время начала работы
— timeto — время окончания работы

Время является числом типа INT(5) UNSIGNED (в MySQL в данном случае можно использовать тип MEDIUMINT(5) UNSIGNED), и задается в формате: WHHMM, где W — номер дня недели (например на английский манер: 0 — вс, 1 — пн, и т.д., ну или можно нашу отечественную нумерацию дней недели выбрать: 0 — пн, 1 — вт, и т.д.), HH — часы, MM — минуты.

Например, организация X (id = 1) работает с 9:00 утра до 2:00 ночи, технический перерыв с 13:00 до 14:30. В нашей таблице, например, для понедельника это будет (если выбрана английския нумерация дней недели):
1 - ***- ***
1 - ***- ***

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

SELECT id FROM organisations WHERE ***BETWEEN timefrom AND timeto;

Все, этого достаточно.
Но вот если в задачу добавятся еще и праздничные дни, когда те или иные организации не работают, или работают по специальному графику, понадобится заводить отдельную таблицу для исключений, и усложнять запрос.
Ссылка03.04.2011 в 19:30
tvv, отличное решение, спасибо.

Я так и сделаю,
только может вынести день недели в отдельный столбец
где будет 0-пн, 1-вт, ...., 6-вс, 7-пн-пт, 8-пн-вс ?
Ссылка03.04.2011 в 20:36  [Отредактировано: 03.04.2011 в 20:37]
Цитата (storier):
только может вынести день недели в отдельный столбец
где будет 0-пн, 1-вт, ...., 6-вс, 7-пн-пт, 8-пн-вс ?

Не нужно, это избыточно.
И рекомендую использовать английский вариант: 0 — вс, 1 — пн, и т.д., так как тогда будет удобно пользоваться стандартными функциями для работы с датой/временем. Хотя это уже менее значимо.
Ссылка11.01.2012 в 04:54
Цитата (tvv):
Например, организация X (id = 1) работает с 9:00 утра до 2:00 ночи, технический перерыв с 13:00 до 14:30. В нашей таблице, например, для понедельника это будет (если выбрана английския нумерация дней недели):
1 - ***- ***
1 - ***- ***

Для данного примера надо делать 3 записи в таблице:
1 - ***- ***
1 - ***- ***
1 - ***- ***

Потому что запрос:

SELECT id FROM organisations WHERE findtime BETWEEN timefrom AND timeto;

не всегда будет выдавать правильный результат.

Например, организация X (id = 1) в субботу работает с 9:00 утра до 2:00 ночи, технический перерыв с 13:00 до 14:30.
Если сделать 2 записи:
1 - ***- ***
1 - ***- 00200

то запрос на поиск организаций, которые работают в 1:00 ночи в воскресенье (findtime = 00100) не выдаст нужный результат.

Если сделать 3 записи:
1 - ***- ***
1 - ***- ***
1 - 00000 - 00200

тогда
SELECT id FROM organisations WHERE 00100 BETWEEN timefrom AND timeto;

отработает правильно
Ссылка11.01.2012 в 14:45
Мы когда-то делали так,
разделили неделю на минуты, тоесть получилось у нас 0..7*24*60=10080
таким образом пишем время, где в 1 величине полностью хранится времья за период (в минутах, в данном случаи дня недели), с интервалом в 1 мин., можно и в 5 мин., тогда получится 0..7*24*12=2016
работать с таким подходом достаточно просто, запроси принимают вида с простой конструкцией beetween, тоесть работать будет очень быстро

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

вообщето я рекомендую почитать про cross-таблицы, их еще называют "шахматки"
Ссылка12.01.2012 в 04:14
Цитата (MMM_Corp):
Мы когда-то делали так,
разделили неделю на минуты, тоесть получилось у нас 0..7*24*60=10080

в вашем подходе, также, как и при хранении времени работы заведения в формате WHHMM, есть один небольшой недостаток, на который я пытался указать в предыдущем посте:
в случае, если график работы переходит через сутки (например, с 17:00 до 02:00), то может возникнуть ситуация, что будет переход не только через сутки, но и через неделю.
В английской нумерации недели: суббота - 6, воскресенье - 0. Если учреждение работает в субботу с 17:00 до 02:00, то при записи этого интервала в БД его надо разбить на 2 записи:
1. с 17:00 субботы до 23:59 субботы
2. с 00:00 воскресенья до 02:00 воскресенья
иначе конструкция beetween не отработает, т.к. timefrom будет больше timeto и в вашем подходе тоже.

Об этом почему то никто не упоминает...