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を
考える場合、非常にやっかいなような気がしてきました。
何か別のよい設計のヒントがあればご教授願えないでしょうか。
宜しくお願いいたします。
No.1
- 回答日時:
開始時刻のほうの秒だけを常に00秒より大きな値にして設定すれば?
たとえば常に30秒に設定すれば10:00-12:00と12:00-15:00は10:00:30-12:00:00と12:00:30-15:00:00なので重複しませんし、設定時間の変更時に参照しても分単位での値は元の指定値と同じです
あるいは重複確認を値の一致ではなく大小比較で行うことで、時間帯の重複しない開始・終了時刻の一致は重複とみなさないことも可能
ありがとうございます!
秒についてはそのようにすれば、確かに入力時の分にも影響ありませんね。
重複確認についてはお教えいただいた大小比較で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回の検索をおこなうのもどうなのでしょうか。
No.2
- 回答日時:
>1.2.の問い合わせで件数が0でしたら重複なしと判断できるのですが、
>いちいち2回の検索をおこなうのもどうなのでしょうか。
ORでつないで1回で検索すれば?
~指定時刻(開始)が開始時刻と終了時刻の間 OR 指定時刻(終了)が開始時刻と終了時刻の間
ふたたびありがとうございます。
なるほど、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')
理論的にはこれで合っていますでしょうか。
No.3
- 回答日時:
BETWEENでは常に以上・以下での比較になってしまい、入力開始時刻が終了時刻に一致するだけのものも対象になってしまうのでは?
それよりも、開始時刻同士の一致のみと終了時刻同士の一致のみを条件に含めば開始・終了が両方一致のものも含まれます
~(指定時刻(開始)が開始時刻以上で終了時刻より小) OR (指定時刻(終了)が開始時刻より大で終了時刻以下)
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'
は、終了時刻が入力した開始時刻以前のものは関係ありません。
(今回の予約時間が始まる前に終わってます。)
⇒上記以外とは、今回の予約時間が終わる前に始まり(今回の予約開始前か予約開始後かは問わない)
今回の予約時間が始まる前には終わっていない(今回の予約終了後か予約終了前かは問わない)
予約が既にあるということを調べています。
ありがとうございます!
なるほど、そういう発想で検索すればよかったのですね。
目からウロコです。
確かにそれでいけます!
自身の論理思考の足りなさが恥ずかしい限りです・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PostgreSQLのtimestamp型で時間...
-
Access にて "mm:ss.0" 形式の ...
-
MySQLで期間のUNIQUEってできま...
-
予約システムでの時間の設計に...
-
SELECT INTOで一度に複数の変数...
-
sqlに記述できない文字
-
truncate tableを使って複数の...
-
【SQL】他テーブルに含まれる値...
-
フラグをたてるってどういうこ...
-
UPDATEで既存のレコードに文字...
-
テーブル名が可変の場合のクエ...
-
Accessで最新のレコード...
-
オラクルのUPDATEで複数テーブル
-
MySQL: 複数テーブルのcount
-
ACCESSのVBAにてExcelに行...
-
2つのテーブルをLIKE演算子のよ...
-
Accessで今日から5日後
-
pandasでsqlite3にテーブル作成...
-
Excel VBAのユーザーフォームで...
-
IDとパスワードについて。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PostgreSQLのtimestamp型で時間...
-
Access にて "mm:ss.0" 形式の ...
-
今って秋田新幹線へ動いてますか?
-
MySQLで期間のUNIQUEってできま...
-
SELECT の仕方 (今月のデー...
-
予約システムでの時間の設計に...
-
開始日と終了日が設定されてい...
-
絶対参照と相対参照の違いを教...
-
SQL文の書き方
-
オラクルのnumber
-
GROUP BYを使って書けますでし...
-
MS_ACCESSでINSTR関数を使いたい。
-
フラグをたてるってどういうこ...
-
SELECT INTOで一度に複数の変数...
-
【SQL】他テーブルに含まれる値...
-
sqlに記述できない文字
-
既存データをINSERT文にして出...
-
truncate tableを使って複数の...
-
オラクルのUPDATEで複数テーブル
-
UPDATEで既存のレコードに文字...
おすすめ情報