質問: 予約システムを製作しています。 以下のようなテーブル構成です。 不要なカラムは無視、テーブル名などはわかりやすく変更しています。 * 空き時間テーブル(times) - id (INT) - jikan (DATETIME) * 通常予約テーブル(yoyakus) - id (INT) - time_id (INT) - time_idにユニークインデックス * 特殊予約テーブル(special_yoyakus) - id (INT) - time_id (INT) - time_idにユニークインデックス 通常予約と特殊予約は、予約の中身が違うため、別テーブルになっています。 ただ、予約する時間は、同じ時間を奪い合うようなかたちです。 例えば、2016/01/01 07:00の時間に空き時間がある場合、timesテーブルに id: 1(オートインクリメント) jikan: 2016-01-01 07:00:00 のレコードが作成され、そこに通常予約が発生すると、yoyakusテーブルに id: 1(オートインクリメント) time_id: 1 が作成されるようなかたちです。 このとき、通常予約と特殊予約が同時に発生した場合に、システム的に同じ時間に2重で予約が入らないようにしたいです。 yoyakusテーブルとspecial_yoyakusテーブルにはそれぞれtime_idにユニークインデックスが入っているため、通常予約・特殊予約同士で2重になることはないですが、通常予約テーブルと特殊予約テーブル間で2重にならないよい方法があれば教えて下さい。
回答: データベースのユニークキー制約に頼るのであれば、別の方が回答している様に、通常予約と特殊予約を、1つの予約テーブルにまとめてしまう方法をおすすめします。 この場合、通常と特殊を区別する為に、予約区分の様な項目を設けます。 参照する特に、別のテーブルの様に扱いたいのであれば、予約区分を条件にして、通常予約だけを参照するVIEWと特殊予約だけを参照するVIEWを定義することで解決します。 質問と同じテーブル構成とすることが前提であれば、データベースの制約を使うのは難しいので、モデルクラスに、通常予約と特殊予約をまたいでtime_idの重複チェックをする様に、コーディングしてはどうでしょうか。(同様の仕組みを、データベース上にトリガーとして定義する方法もあります。) 別の考え方として、同じ時間帯に複数の予約を入れ無い様にする目的であれば、予約のプライマリーキーを、空き時間テーブルから参照する外部キー項目を設け、空き時間テーブルの予約IDが埋まっている時間帯には、新たな予約は入れることができない、という形にすることもできます。