如何开发可限制每日预约量的预约预订系统
开发具备每日预约量限制的预订系统方案
1. 数据模型设计
- 核心表结构:
appointments预约记录表:存储用户预约信息,字段至少包含id(主键)、user_id(预约用户ID)、booking_time(预约时间,精确到日期或具体时段)、created_at(创建时间)booking_limits预约配置表:存储每日预约上限规则,字段包含id(主键)、max_daily_bookings(每日最大预约数,比如示例中的50)、effective_date(生效日期,支持不同日期设置不同上限,若全局统一规则可省略该字段)
2. 核心业务逻辑实现
日期可预约校验
用户选择日期时,后端需实时校验该日期剩余可预约名额:
-- 查询指定日期已完成的预约数量 SELECT COUNT(*) AS booked_count FROM appointments WHERE DATE(booking_time) = '目标日期'; -- 获取该日期对应的预约上限 SELECT max_daily_bookings FROM booking_limits WHERE effective_date <= '目标日期' ORDER BY effective_date DESC LIMIT 1;
如果 booked_count >= max_daily_bookings,则标记该日期为不可预约状态。
预约创建时的原子校验
为避免并发场景下超量预约(比如两个用户同时查询到剩余1个名额并提交),必须在插入预约数据时做原子性校验:
-- 事务包裹实现原子校验+插入 START TRANSACTION; SET @booked = (SELECT COUNT(*) FROM appointments WHERE DATE(booking_time) = '2024-05-20'); SET @max = (SELECT max_daily_bookings FROM booking_limits WHERE effective_date <= '2024-05-20' ORDER BY effective_date DESC LIMIT 1); IF @booked < @max THEN INSERT INTO appointments (user_id, booking_time) VALUES ('用户ID', '2024-05-20 14:00:00'); END IF; COMMIT;
或者用更简洁的原子插入语句(无需显式事务,主流数据库支持):
INSERT INTO appointments (user_id, booking_time) SELECT '用户ID', '2024-05-20 14:00:00' WHERE (SELECT COUNT(*) FROM appointments WHERE DATE(booking_time) = '2024-05-20') < (SELECT max_daily_bookings FROM booking_limits WHERE effective_date <= '2024-05-20' ORDER BY effective_date DESC LIMIT 1);
插入后判断受影响行数,若为0则说明名额已满,返回用户错误提示。
3. 前端交互处理
- 日历渲染:后端提前返回所有可预约日期列表(过滤掉已达上限的日期),前端将不可预约日期设为灰色不可点击状态
- 实时校验:用户手动选择日期后,即时请求后端校验接口,若名额已满,弹出提示“今日预约名额已用尽,请选择其他日期”
- 按钮控制:根据日期校验结果,动态禁用/启用预约提交按钮
4. 并发与边界问题处理
- 数据库锁机制:使用
SELECT ... FOR UPDATE锁定查询的预约统计行,保证校验和插入的原子性,避免脏读 - 取消预约逻辑:用户取消预约时直接删除对应记录即可,后续校验会自动统计剩余名额
- 性能优化:每日凌晨归档历史预约数据,避免查询时数据量过大拖慢响应速度
- 异常拦截:对重复提交、超时提交等场景做拦截,避免无效请求占用资源
5. 测试要点
- 并发压测:模拟100个用户同时提交当日第50个预约,验证仅一个用户能成功创建
- 边界测试:测试当日预约量为49时,两个用户同时提交的场景
- 跨日期测试:验证不同日期的预约限制独立生效
- 取消恢复测试:取消一个预约后,验证当日剩余名额正确增加1个
内容的提问来源于stack exchange,提问作者Eiser
相关产品推荐
相关产品推荐

