web-dev-qa-db-ja.com

営業時間をデータベースに保存する

私は現在、営業時間をデータベースに保存するための最良の方法を探しています。

例えば:

ビジネスAの営業時間は次のとおりです

  • 月曜日:午前9時〜午後5時
  • 火曜日:午前9時〜午後5時
  • 水曜日:午前9時から午後5時
  • 木曜日:午前9時から午後5時
  • 金曜日:午前9時〜午後5時
  • 土曜日:午前9時〜正午
  • 日曜日:定休日

現在、私は次のようなデータモデルを持っています

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

ここで、「日」は(ORMを使用して)コード内の7日間の選択に制限されます。特定の日に休業かどうかをテストするために、open_timeとclose_timeがNULLかどうかを確認します。中間テーブル(多対多の関係)を介してビジネスに関連付けられます。

このデータベーススキームに関する提案はありますか?それについて何かが私には正しくないようです。

72
user128000

全体として、これには何の問題もありません。を除いて...

  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「営業時間」という制約を適用します。 (少なくともJon Skeetは正しいので、休日の時間を必要とするかもしれません。)「営業時間」を単に残すことによってこの制約を緩和したいかもしれません休業日.

48
Frank Krueger

このスキーマでカバーされない状況の1つは、1日に複数の開始期間です。たとえば、地元のパブは12:00-14:30と17:00-23:00に営業しています。

劇場の興行収入は、マチネーと夜の公演のために開いているかもしれません。

その時点で、同じ日に複数のエントリを作成できるかどうか、または同じ行で異なる時間を表す必要があるかどうかを判断する必要があります。

深夜を越える営業時間はどうですか。バーの営業時間は19:00〜02:00だとしましょう。開始時間と終了時間をテストする時間と比較することはできませんでした。

22
davidsheldon

格納する必要があるものと、実際のデータがどのように見えるかによって異なります。
ビジネスが特定の時点で営業しているかどうかを判断できるようにする必要がある場合、スキームをレイアウトどおりに照会するのは少し面倒かもしれません。ただし、さらに重要なのは、昼間の休業に対応する必要があるということです。

いくつかのオプションが含まれます。

  • あなたが持っているもののようなスキームですが、同じ日に複数の期間を持つオプションがあります。それは昼休みに対応しますが、ユーザーへのプレゼンテーションなど、特定の日の営業時間を提供するクエリを実行するのは面倒です。
  • ビットマップスタイルのアプローチ。 9-5の場合は「000000000111111110000000」。このアプローチの欠点は、特定の粒度、つまり、1時間または30分、実際には数分を選択する必要があることです。粒度が細かいほど、人間にとってデータの読み取りが難しくなります。ビットごとの演算子を使用して、この値を整数の文字列ではなく単一の数値として保存することもできますが、やはり読みやすさが損なわれます。
10
Frans

Googleデータマークアップにデータを認識させるには、次のガイドラインに従う必要があることを学びました。

https://schema.org/openingHours

http://schema.org/OpeningHoursSpecification 「有効な日付」が含まれており、一部の企業にとって非常に便利です。

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

ビジネスが結合テーブルと同じ時間を共有することを許可していない限り、主キーがなくても問題ありません。興味深いことに、最終的には組み合わせの数が有限になります。私はそれがいくつになるのか分かりません:p

私のプロジェクトの1つで、列を使用しました。

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

OpeningHoursSpecificationをサポートする場合は、validFromとvalidThroughを追加する必要があります。

時間範囲の形式は次のとおりです。hh:mm-hh:mm

これを解析する関数を次に示します。DB内の個別の列として保持する場合、この関数を変更して、単一のオープン/クローズのみを解析することもできます。

私の経験から、1日以内に複数回許可し、その日に明示的に閉鎖されているか、24時間または24時間オープンされているかを確認する方法を考慮してください。私は、DBで1日が欠落している場合、その日は営業が終了したと言っていました。

/**
 * 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;
}
9
CTS_AE

年の月/月の日/月の週に追加のフィールドを含めることにより、休日のファクタリングを検討することができます。月の週には、「最後の」いくつかの小分類があります。たとえば、年に応じて週4または5になります。

0
Einstein