如何排除不可预订日期?

先说一个场景需求,我需要预定一辆车去自驾游。现在就要根据指定日期把没空的去除掉来展示结果
是老系统,可能表设计不怎么合理。大家请谅解。
我先说说表结构
有一个表car 是存放车辆信息 并且有一个字段代表什么时间段有空 字段free_time
0 365天都有空
1 周一到周五有空
2 周六周日有空
3 仅周六有空
4 仅周日有空
5 周六周日和节假日有空

还有一个表 norent 是单独存某一天没有空的日期 date 比如2023-09-25这天 id_car车是没有空的
现在给定参数 2023-10-03 请查询有空的车辆。请问怎么写比较好呢?
我能想到的是
先根据日期得到 是哪个时间段,然后给car表加上where free_time = 1 然后连表 norent查询
但是数据量大了起来 性能有点慢 各位大哥 还有什么好的建议吗

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 8

子查询?

select * from car where free_time = 1 and not exists (select 1 from norent where car.id = norent.id_car and `date` = '2023-10-03')
7个月前 评论
xiaofeishu (楼主) 7个月前
小猪蹄子 (作者) 7个月前

把free_time的条件一个个筛出来,然后联下表?

$date = '2023-10-03';
$carbonDate = Carbon::parse($date);
$freeTime = [];
if(!$carbonDate->isWeekend()){
    $freeTime[] = 1;
}
if($carbonDate->isWeekend()){
    $freeTime[] = 2;
}
if($carbonDate->isSaturday()){
    $freeTime[] = 3;
}
if($carbonDate->isSunday()){
    $freeTime[] = 4;
}
if($this->isHoliday($date) || $carbonDate->isWeekend()){
    $freeTime[] = 5;
}
Car::query()->leftJoin('norent','car.id','=','norent.id_car')
    ->whereIn('car.free_time',$freeTime)
    ->where('norent.date','!=',$date)
    ->get();

protected function isHoliday($date):bool
{
    //判断是否是节假日
    return true;//false
}
7个月前 评论
xiaofeishu (楼主) 7个月前

笨一点 弄个冗余表 任务跑出没被预定的时候全部日期 以及对应日期可用车辆 然后 预定和取消的时候 把对应日期的车辆干掉 这样前端接口查询时速度肯定是优化了的 但是 增加了冗余表和维护成本 如何取舍看自己了

7个月前 评论
sanders

可以考虑添加索引降低扫描行数。尤其是 norent 表,根据你的需求应该在 车辆和日期上有唯一索引,如果还因扫描行数多导致查询慢就说不过去了。

7个月前 评论

用redis的bitmap :joy:

7个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!