预订系统使房间不可用的有效方式

时间:2015-06-30 09:47:55

标签: sql database

我正在创建一个预订系统:

客户 CUST_ID, CUST_NAME, cust_etc .....

ROOM_ID, ROOM_NAME, room_etc

预订 booking_id, 房间号, CUST_NO arrive_date, depart_date

预订表将允许我仅在日历上显示可用性。问题是我想阻止某些时间段被预订。我能看到的唯一方法是在预订表中放入一个条目但不分配cust_id。如果有人能告诉我这是否是最好和最有效的方式,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

我建议按以下方式进行:

  1. 创建一个表格,用于存储任何预订不可用的日期。我们称之为booking_prevention。 额外价值:我建议添加一个描述列,其中包含有关当时事件的详细信息。
  2. 如果日期与表booking_prevention中的日期重叠,则创建一个阻止向预订表添加新记录的触发器。
  3. 示例架构:

    预订: booking_id,room_no,cust_no arrival_date,depart_date

    Booking_prevention: bk_prev_id,date_start,date_end,description

    使用PostgreSQL进行测试:

    -- Creating a function that would go through every record in booking_prevention table
    CREATE FUNCTION trg_prevent_booking ()
    RETURNS TRIGGER
    STABLE
    AS $$
    DECLARE 
        r record; 
    BEGIN
    FOR r IN 
        SELECT date_start, date_end FROM booking_prevention 
    LOOP 
        IF ((NEW.arrive_date, NEW.depart_date) OVERLAPS (r.date_start, r.date_end)) 
        THEN 
            RAISE EXCEPTION 'You can not book a room on those days! Check booking_prevention table for details'
        END IF; 
    END LOOP; 
    RETURN NEW;
    END;        
    $$
    LANGUAGE plpgsql;
    
    -- Creating a trigger that fires for each row on booking
    CREATE TRIGGER prevent_booking BEFORE INSERT ON booking FOR EACH ROW EXECUTE PROCEDURE trg_prevent_booking();
    

    booking_prevention表中的值:

    SELECT * FROM booking_prevention;
    
     id | date_start |  date_end  | description |
    ----+------------+------------+--------------
      1 | 2015-06-10 | 2015-06-20 | Maintenance |
    

    使用新预订进行测试:

    INSERT INTO booking VALUES (default, 5, 1001, '2015-06-03', '2015-06-11');
    ERROR:  You can not book a room on those days! Check booking_prevention table for details
    
    INSERT INTO booking VALUES (default, 5, 1001, '2015-06-03', '2015-06-09');
    INSERT 0 1
    

    考虑优化功能。一个好的开始方法是限制每次触发器触发时记录必须循环的行。

    在错误消息中,您还可以从描述中输入值。根据您的需要进行调整。

    修改

    本节是在OP评论担心效率后添加的。

    保持booking_prevention表较小且查找效率较高的一种好方法是创建一个表,该表将保存来自具有date_end < current_date的预防表的记录。假设您过去不允许系统预订房间,这些记录不再需要检查(我猜这是公平的假设)。

    只要您需要存储过去有关预防日期的详细信息,此方法就很有用。如果情况并非如此 - 您可以随时从booking_prevention表中删除。