予約システムでの時間の設計について

このQ&Aのポイント
  • 予約システムで部屋の利用予約を時間単位で行うためには、重複する時間の予約を制限し、日を跨ぐ予約を禁止する必要があります。
  • データ保持方法には、開始時刻と終了時刻の精度を考慮し、秒まで保存するか分まで保存するかを検討する必要があります。
  • テーブル設計においては、開始時刻と終了時刻の重複をチェックするSQLを考慮する必要があります。
回答を見る
  • ベストアンサー

予約システムでの時間の設計について

MYSQLで部屋を利用するための予約システムを作ろうと考えております。 設計として下記を考えてみたのですがおかしいでしょうか。 要件は下記のとおりです。 ・A、B、C3つの部屋の利用予約を時間単位でおこなう ・重複する時間は予約できない ・日を跨ぐ予約はできない テーブル設計 トランID(int)|開始時刻(datetime)|終了時刻(datetime)|部屋ID(int) 時間についてはdatetime式で2013-03-22 12:00:00 と保存させる予定です。 入力を簡素にするため、時刻は時、分個別のプルダウンで30分刻みにしようと考えています。 そこで分からなくなってきたのがデータ保持の方法なのですが、 例えば10:00-12:00と予約入力された場合、datetime式ですと秒まで保存されますので 2012-03-22 10:00:00 - 2012-03-22 12:00:00 となりますよね。 そうなりますと、別の予約で12:00-15:00を確保したい場合、開始時刻は重複してしまうことに なりますので、テーブルには2013-03-22 10:00:01 - 2013-03-22 11:59:59と登録したほうが いいのでしょうか。 ただ、これだと時間を変更したい場合の修正の際に困ったことになりそうです。 またこの設計の場合、 開始時刻と終了時刻が他の予約と重複していないかのSQLを 考える場合、非常にやっかいなような気がしてきました。 何か別のよい設計のヒントがあればご教授願えないでしょうか。 宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.5

普通(かどうかは知りませんが)こういう要件のときは、 部屋ID=A で '2013-03-22 11:00:00' から '2013-03-22 15:00:00' と画面で入力されたとすると、 SELECT count(*) FROM 予約テーブル WHERE 部屋ID=A AND 開始時刻<'2013-03-22 15:00:00' AND 終了時刻>'2013-03-22 11:00:00' の結果が0でなければ重複しているとしてエラーにします。 00:00は含まれないので、データの持ち方は、00分00秒でOKです。 なにをやっているかの補足: AND 開始時刻<'2013-03-22 15:00:00' は、開始時刻が入力した終了時刻以降のものは関係ありません。 (今回の予約時間が終わってから始まります。) AND 終了時刻>'2013-03-22 11:00:00' は、終了時刻が入力した開始時刻以前のものは関係ありません。 (今回の予約時間が始まる前に終わってます。) ⇒上記以外とは、今回の予約時間が終わる前に始まり(今回の予約開始前か予約開始後かは問わない) 今回の予約時間が始まる前には終わっていない(今回の予約終了後か予約終了前かは問わない) 予約が既にあるということを調べています。

begin96
質問者

お礼

ありがとうございます! なるほど、そういう発想で検索すればよかったのですね。 目からウロコです。 確かにそれでいけます! 自身の論理思考の足りなさが恥ずかしい限りです・・。

その他の回答 (4)

  • OKWavex
  • ベストアンサー率22% (1222/5383)
回答No.4

さらに指定時刻(開始)と指定時刻(終了)の間に含まれる開始終了時刻も対象にする必要があるでしょう

begin96
質問者

お礼

何度もありがとうございます! ご指摘のとおり、BETWEENですと確かにそのようになってしまいました・・。 秒を00でなく30と入れてしまえばBETWEENでも何とかなりそうですが・・。 だんだん頭が混乱してきました!

  • OKWavex
  • ベストアンサー率22% (1222/5383)
回答No.3

BETWEENでは常に以上・以下での比較になってしまい、入力開始時刻が終了時刻に一致するだけのものも対象になってしまうのでは? それよりも、開始時刻同士の一致のみと終了時刻同士の一致のみを条件に含めば開始・終了が両方一致のものも含まれます ~(指定時刻(開始)が開始時刻以上で終了時刻より小) OR (指定時刻(終了)が開始時刻より大で終了時刻以下)

  • OKWavex
  • ベストアンサー率22% (1222/5383)
回答No.2

>1.2.の問い合わせで件数が0でしたら重複なしと判断できるのですが、 >いちいち2回の検索をおこなうのもどうなのでしょうか。 ORでつないで1回で検索すれば? ~指定時刻(開始)が開始時刻と終了時刻の間 OR 指定時刻(終了)が開始時刻と終了時刻の間

begin96
質問者

お礼

ふたたびありがとうございます。 なるほど、ORを使えばよかったんですね。 しかし、先ほどのSQLですと別の予約を完全に跨いでしまう時間が入力された場合にはヒットしないことに気づきました。 そこで、ORとbetweenを使ってまた考えてみました。 SELECT * FROM 予約テーブル WHERE 部屋ID=A AND ( 開始日時 BETWEEN '2013-03-22 11:00:00' AND '2013-03-22 15:00:00' OR 終了日時 BETWEEN '2013-03-22 11:00:00' AND '2013-03-22 15:00:00') 理論的にはこれで合っていますでしょうか。

  • OKWavex
  • ベストアンサー率22% (1222/5383)
回答No.1

開始時刻のほうの秒だけを常に00秒より大きな値にして設定すれば? たとえば常に30秒に設定すれば10:00-12:00と12:00-15:00は10:00:30-12:00:00と12:00:30-15:00:00なので重複しませんし、設定時間の変更時に参照しても分単位での値は元の指定値と同じです あるいは重複確認を値の一致ではなく大小比較で行うことで、時間帯の重複しない開始・終了時刻の一致は重複とみなさないことも可能

begin96
質問者

お礼

ありがとうございます! 秒についてはそのようにすれば、確かに入力時の分にも影響ありませんね。 重複確認についてはお教えいただいた大小比較で2回のselect分を発行する方法を考えました。 1.入力された開始時刻が重複していないか SELECT * FROM 予約テーブル WHERE 部屋ID=A AND (開始時刻<'2013-03-22 11:00:00' AND 終了時刻>'2013-03-22 11:00:00') 2.入力された終了時刻が重複していないか SELECT * FROM 予約テーブル WHERE 部屋ID=A AND (開始時刻<'2013-03-22 15:00:00' AND 終了時刻>'2013-03-22 15:00:00') 1.2.の問い合わせで件数が0でしたら重複なしと判断できるのですが、 いちいち2回の検索をおこなうのもどうなのでしょうか。

関連するQ&A

  • 自身の結果に自身で検索?

    php+mysqlにてある予約システムを作っている者です。 mysqlのクエリ作成で行き詰ってしまったので、ご質問させていただきます。 予約テーブルにはカラムid(key)、roomID(部屋番号),startTime(予約開始日時)、endTime(予約終了日時)があります。 部屋テーブルにはカラムid(部屋番号)、部屋名等があります。 実現したいのは、予約日時が被っている部屋id、予約テーブルのidの抽出(重複した予約)です。 一覧画面にて、予約に対して重複があるかないかを表示したいです。 予約テーブルのstartTimeが他の予約開始日時から予約終了日時までの間になければ、 重複予約はないということになると考えています。 しかし行き詰ってしまった原因は、検索対象がない??ことです。 仮に開始時間だけでもWHERE句に入れられれば、 $検索対象予約開始日時 BETWEEN startTime AND endTime で検索できそうだと想像つくのですが、 その検索対象開始日時は予約テーブル内全部の予約開始日時なのです。 単純に考えると、予約テーブルのidとstartTimeを1件ずつ取得し、全件をBETWEENで検索ループなのでしょうが、 なんとかSQL1文で済ませられないかと思い、質問させていただきました。 疑問点が伝わるか不安な文章で大変申し訳ありませんが、お知恵をお貸しください。

    • ベストアンサー
    • MySQL
  • シスアド<会議室の予約>

    使える会議室を抽出するため、予約済み会議室を検索する次の条件文がある。使用希望条件は[ ]で示される。  [利用日]=利用日    かつ  [開始時刻]<終了時刻    かつ  [終了時刻]>開始時刻 上記の条件文は穴埋め式の解答を入れたものです。 疑問点(1)予約済み会議の終了と同時に希望の会議を始めたり、希望の会議の終了時刻と予約済み会議の開始時刻が同時であるはできないので上の条件式の<と>に=を入れるべきではないのでしょうか。 疑問点(2)開始時刻、終了時刻の条件はどちらかでもひっかかるとだめなので2番目のかつは「または」ではないのでしょうか。 ちなみにこれはシスアド14年秋午後問です。よろしくお願いします。

  • 日付が重複したものは一つしか表示しないquery

    int型のidが入ったカラムAとdatetime型の日付が入ったカラムBを持ったテーブルから同じ日のidの重複をなくしたBで新しい順位ソートされたものをSELECTするクエリが分かりません。 A|B 1|2010-12-11 10:00:00 2|2010-12-05 10:00:00 1|2010-12-05 10:00:00 ⇒日付が重複しないので表示する 2|2010-12-05 10:00:00 ⇒二番目の項目と重複するので表示しない 4|2010-12-03 10:00:00 宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • 施設予約システム

    いつもお世話になっております。 PHP初心者のものです。今度仕事で予約システムをPHPで作成 することになりました。 概要としましては、カレンダーで表示され時刻毎にテーブル わけされていて、空室なしの場合は×、ありの場合は○で 表示され、予約を行った場合には予約完了しましたのメールが 送信されるようなものです。それほど複雑な機能はいらないのですが 、このようなシステムのサンプルなどがありましたら教えて 頂けないでしょうか? どうぞよろしくお願い致します。

    • ベストアンサー
    • PHP
  • メーカーのショールームの滞在時間

    オフィス家具を扱っているメーカーのショールームに近々伺う予定です。1日で何件もまわります、どこも予約が必要で、営業担当が付いてくるらしいですが、ショールームで商品を見ていい時間ってどのくらいなのでしょうか? 10分でも1時間でも3時間でもいいのでしょうか? 開始時刻だけ予約で、終了時刻の予約は全くありません。 よろしくお願いします。

  • ファイルメーカーによる勤務時間計算を簡単にする方法についてお尋ねします

     出勤退庁が全く不定時な特殊派遣業務の管理作業をファイルメーカーPro9で行っております。  派遣報酬は時間制で、 実働時間(30分単位)×職務別時間制定額+深夜(22時~5時)従事時間×深夜加算定額  により構成されています。  不定時な出勤退庁の例は下記のとおりです。 (勤務)開始時刻~終了時刻(実働時間、深夜時間)      9:00~18:00(実働9.0H、深夜0)      20:00~3:00(実働7.0H、深夜5.0H)       23:00~7:30(実働8.5H、深夜6.0H)        23:30~4:00(実働4.5H、深夜4.5H)        1:00~4:30(実働3.5H、深夜3.5H)        2:00~9:00(実働7.0H、深夜3.0H)        21:00~7:00(実働10.0H、深夜7.0H)        まず実働時間の計算ですが、入力は上記の時刻どおり行うため、翌日にまたがる勤務のときはそのままだと実働時間がマイナスになります。 これを避けるため、その場合は終了時刻に1日(86400秒)を加算する次の式を定義しております。  出退庁時刻等の定義は、次のとおりです。 出勤時刻→「開始時刻」 退庁時刻→「終了時刻・入力」と「終了時刻・換算」 実働時間→「実働時間・時刻」と「実働時間・数値」 終了時刻・換算=If( 開始時刻>終了時刻・入力; 終了時刻・入力 + 86400; 終了時刻・入力 )  そして実働時間は 実働時間・時刻=終了時刻・換算-開始時刻  とし、これを数値化するため、 実働時間・数値=Hour(実働時間・時刻 ) + Round(Minute(実働時間・時刻) / 60; 2 )  としております。  さて最大の問題は前記実働時間中の深夜従事時間の算出です。  まずフィールド定義を 深夜開始=Time(22; 0;0) 深夜終了=Time(5; 0; 0) 深夜終了29時=Time(29; 0; 0 ) 深夜従事時間=深夜時間 深夜時間の数値=深夜時間・数値  とし、次の式により深夜従事時間を求めています。 深夜時間=If(終了時刻・換算 > 深夜開始; If( 終了時刻・換算> 深夜終了29時; 深夜終了29時;終了時刻・換算 )-If( 開始時刻>深夜開始; 開始時刻; 深夜開始 );0) + If( 終了時刻・換算>深夜終了; 深夜終了; 終了時刻・換算 )- If(開始時刻 <深夜終了; 開始時刻; 深夜終了 )  これを数値化するため、 深夜時間・数値=Hour(深夜時間) + Round( Minute(深夜時間) / 60; 2 )  以上が一連の式の流れですが、これらの式は何とも冗長で分かりにくいので、もっと簡単で分かりやすい計算式ができないか、悪戦苦闘しましたがいい智恵が浮かびません。  思い余ってファイルメーカーの時間計算に詳しい方のご指導をいただきたく投稿しました。  よろしくお願いします。

  • MySQLのテーブル設計で迷っています(桁数)

    MySQLのテーブル設計で迷っています。 クリエイト文のカッコの中は桁数を表しているのでしょうか?それともバイト数でしょうか?桁数であれば、それぞれの型で何桁まで設定できますでしょうか? int型のnoを18桁に変更したいのですが、調べているうちに迷ってしまいました。 型 バイト 最小値 最大値 TINYINT 1 -128 127 SMALLINT 2 -32768 32767 MEDIUMINT 3 -8388608 8388607 INT 4 -2147483648 2147483647 BIGINT 8 -9223372036854775808 9223372036854775807 CREATE TABLE `user` ( `no` int(8) unsigned NOT NULL auto_increment, `id` varchar(24) NOT NULL default '', `email` varchar(255) NOT NULL default '', `reg_date` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`no`) ) TYPE=MyISAM;

    • ベストアンサー
    • MySQL
  • アクセスVBAでの時刻の計算

    開始時刻と終了時刻をテーブルに保存するために、フォームの入力欄に、操作者は3つ入力します。 A開始時刻の時 B開始時刻の分 C完了までの時間(分間) 開始時刻は、A時B分でそのままテーブルに保存できます。 終了時刻は、(A時B分+C分の計算結果の時部)時(A時B分+C分の計算結果の分部)分 としてテーブルに保存できますが、どのように表記したらよいのでしょうか? よろしくお願いいたします。 ( Windows XP : Access 2002 )

  • 予約可能時間の出し方

    php独学(数ヶ月)の初心者です。 予約を管理するプログラムを自分でつくっています。 調べても調べてもどの関数をどのように使えば 良いかわからないまま数日がたってしまいました。 (初心者のため知らずに勉強し始めてしまった非推奨のmysql関数等を とりあえずまだ使用しています。mysql関数で教えていただければと思います。 ある程度理解を深めた時点できちんと勉強しなおします) ■予約の概要 コースごとに取得できる予約時間が決まっています。 予約時間の30分後から矯正が始まり、その1時間後に終了します。 (予約時間に来店、30分間マシーンに乗り、その後先生の矯正が 1時間ある。) ■作成したDB [DB01]予約時間テンプレート:time1 コースごとに取得できる予約時間が決まっています。 (以下はあるコースの予約可能時間のテンプレです。) id, time(time型) 1,10:15 2,11:45 3,14:30 4,16:00 5,17:30 6,19:00 [DB02]予約済みを貯めたDB:booked (時間はすべてtime型) id,name,time,start,finish,course 203,tanaka,10:00,10:30,11:30,a 101,abe,14:30,15:00,16:00,a 112,yoshida,17:00,17:30,18:30,c ■質問 [DB01]のうち予約可能な時間のみ<select>文で表示させたい。 ちなみ(予約可能な時間)は、11:45,16:00,19:00の3つです。 色々考えましたが、今の自分の実力では上記を実行させるコードが断片的に しか分からずお手上げとなりました。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 複数テーブルからのデータ取得

    MySQLで 4つのテーブルからデータを取得する方法を教えてください。 4つのテーブルの構造は全く同じです。 構造的には id・・・int name・・・varcher(30) point・・・int start・・・datetime end・・・datetime tableA,tableB,tableC,tableDの4つのテーブルからpointのデータを昇順に取得したいです。 よろしくお願いします。