Хранение рабочих часов в базе данных


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

например:

бизнес A имеет следующие часы работы

  • понедельник: 9 утра - 5 вечера
  • вторник: 9 утра - 5 вечера
  • среда: 9 утра - 5 вечера
  • четверг: 9 утра - 5 вечера
  • пятница: 9 утра - 5 вечера
  • суббота: 9 утра - 12 полудня
  • воскресенье: Закрыто

В настоящее время у меня есть модель данных, похожая на следующую

CREATE TABLE "business_hours" (
    "id" integer NOT NULL PRIMARY KEY,
    "day" varchar(16) NOT NULL,
    "open_time" time,
    "close_time" time
)

где "день" ограничен выбором 7 дней недели в коде (через ORM). Чтобы проверить, если бизнес закрыт в определенный день он проверяет, если open_time и close_time равны нулю. Это связано с бизнесом через промежуточную таблицу (многие к многим).

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

5 57

5 ответов:

в целом, я не вижу в этом ничего плохого. Кроме...

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

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

Так что я думаю, я бы сделал:

CREATE TABLE "business_hours" (
     "id" integer NOT NULL PRIMARY KEY,
     "business_id" integer NOT NULL FOREIGN KEY REFERENCES "businesses",
     "day" integer NOT NULL,
     "open_time" time,
     "close_time" time
)

в моей бизнес-логике я бы применил ограничение, которое имеет каждый" бизнес"по крайней мере 7 "рабочее время". (по крайней мере потому что Джон Скит прав, вы можете захотеть праздничные часы.) Хотя вы можете ослабить это ограничение, просто оставив "рабочие часы" в течение нескольких дней, когда бизнес закрыт.

одна ситуация, которая не охватывается этой схемой, - это несколько периодов открытия в день. Например, местный паб открыт с 12:00-14:30 и 17:00-23:00.

может быть, театральная касса открыта для дневного спектакля и вечернего представления.

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

Как насчет времени открытия, которое пересекает полночь. Скажем, бар открыт 19:00-02:00. Вы не можете просто сравнить время открытия и закрытия с временем, которое вы хотите проверить.

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

некоторые варианты включают;

  • схемы, как то, что у вас есть, но с возможностью иметь несколько периодов для одного день. Он будет обслуживать обеденный перерыв, но будет неудобно запускать запрос, который дает вам часы работы для данного дня, скажем, для презентации пользователю.
  • растровый стиль подхода; "000000000111111110000000" для 9-5. Недостатком такого подхода является то, что вы должны выбрать определенную степень детализации, т. е. целые часы или полчаса или, действительно, минуты. Чем мельче гранулярность, тем труднее считывать данные для человека. Вы можете использовать побитовые операторы для хранения этого значения как одно число, а не строка целых чисел, но опять же это вредит разборчивости.

я узнал, что если вы хотите, чтобы разметка данных google распознавала ваши данные, вы должны следовать этим рекомендациям:

https://schema.org/openingHours

http://schema.org/OpeningHoursSpecification содержит "действительные даты", что очень полезно для некоторых предприятий.

https://schema.org/docs/search_results.html#q=hours

вы должны быть в порядке без первичного ключа, если вы не позволяя компаниям делиться одними и теми же часами с таблицей join - интересно, что в конечном итоге у вас будет конечное количество комбинаций; я не уверен, сколько это будет :p

С одним из моих проектов я использовал столбцы:

[uInt]business_id, [uTinyInt]day, [char (11)] timeRange

Если вы хотите поддерживать OpeningHoursSpecification, вам нужно будет добавить validFrom и validThrough.

диапазон времени отформатирован как: чч:мм-чч:мм

вот функция, которая анализирует его, вы также можете изменить эту функцию, чтобы проанализировать только один open / close, если вы сохраняете их как отдельные столбцы в БД.

из моего опыта я бы рекомендовал вам разрешить несколько раз в течение дня, позволяют как сказать, если они явно закрыты в этот день, или открыт 24 часа или 24/7. Я сказал, что если в БД отсутствовал день, то в тот день бизнес был закрыт.

/**
 * parseTimeRange
 * parses a time range in the form of
 * '08:55-22:00'
 * @param $timeRange 'hh:mm-hh:mm' '08:55-22:00'
 * @return mixed ['hourStart'=>, 'minuteStart'=>, 'hourEnd'=>, 'minuteEnd'=>]
 */
function parseTimeRange($timeRange)
{
    // no validating just parsing
    preg_match('/(?P<hourStart>\d{1,2}):(?P<minuteStart>\d{2})-(?P<hourEnd>\d{1,2}):(?P<minuteEnd>\d{2})/', $timeRange, $matches);

    return $matches;
}

можно подумать о факторинге в праздники, включив дополнительные поля для месяца года / дня месяца / недели месяца. Неделя месяца имеет некоторые незначительные тонкости "последний" может, например, быть Неделя 4 или 5 в зависимости от года.