我正在为公共汽车开发一个预订模块,但我在为其设计正确的数据库结构时遇到了麻烦。
举个例子:
巴士从A到D,在B和C中途停留。乘客可以预订任何路线的车票,即。从 A 到 B、C 到 D、A 到 D 等等。
所以每条路由可以有很多“子路由”,更大的包含更小的子路由。
我想以一种有助于轻松搜索空闲座位的方式设计路线和停靠点的表格结构。因此,如果有人预订了从 A 到 B 的座位,那么从 B 到 C 或 D 的座位仍然可用。
所有想法将不胜感激。
我正在为公共汽车开发一个预订模块,但我在为其设计正确的数据库结构时遇到了麻烦。
举个例子:
巴士从A到D,在B和C中途停留。乘客可以预订任何路线的车票,即。从 A 到 B、C 到 D、A 到 D 等等。
所以每条路由可以有很多“子路由”,更大的包含更小的子路由。
我想以一种有助于轻松搜索空闲座位的方式设计路线和停靠点的表格结构。因此,如果有人预订了从 A 到 B 的座位,那么从 B 到 C 或 D 的座位仍然可用。
所有想法将不胜感激。
我可能会采用类似于这个基本思想的“蛮力”结构:
(实际模型中应该存在更多字段。这只是一个简化版本,包含建立表之间关系所需的基本要素。)
车票通过 TICKET_STOP 表“覆盖”站点,例如,如果一个车票涵盖 3 个站点,那么 TICKET_STOP 将包含与该车票相关的 3 行。如果该票未涵盖其他 2 个站点,则那里将没有相关行,但没有什么可以阻止不同的票覆盖这些站点。
自由使用或自然键/识别关系确保两张票不能覆盖相同的座位/停靠组合。看看 LINE.LINE_ID 如何沿着菱形依赖的两个边缘“迁移”,只是在 TICKET_STOP 表中在其底部合并。
这种模型本身并不能保护您免受诸如单张票“跳过”一些站点的异常情况的影响——您必须通过应用程序逻辑强制执行一些规则。但是,它应该允许相当简单和快速地确定哪些座位在旅行的哪些部分是免费的,如下所示:
SELECT *
FROM
STOP CROSS JOIN SEAT
WHERE
STOP.LINE_ID = :line_id
AND SEAT.BUS_NO = :bus_no
AND NOT EXIST (
SELECT *
FROM TICKET_STOP
WHERE
TICKET_STOP.LINE_ID = :line_id
AND TICKET_STOP.BUS_ID = :bus_no
AND TICKET_STOP.TRIP_NO = :trip_no
AND TICKET_STOP.SEAT_NO = SEAT.SEAT_NO
AND TICKET_STOP.STOP_NO = STOP.STOP_NO
)
(将参数前缀替换:
为适合您的 DBMS 的前缀。)
此查询实质上为给定线路和公共汽车生成所有站点和座位组合,然后丢弃那些在给定行程中已经被某些票“覆盖”的那些。那些仍然“未被发现”的组合对于那次旅行是免费的。
您可以轻松地在子句中添加:STOP.STOP_NO IN ( ... )
或以限制对特定站点或座位的搜索。SEAT.SEAT_NO IN ( ... )
WHERE
从公交公司的角度来看:
通常,一条路线被视为一系列路段,例如 A 到 B、B 到 C、C 到 D 等。填充量是在每个路段上分别计算的。因此,如果巴士从 A 出发,而人们在 C 出发,则用户可以在 C 购买车票。
我们这样计算,每条路线都有ID,每个路段都属于这个路线ID。然后,如果用户购买了多个部分的票,则标记每个部分。然后对于下一个乘客系统,检查沿途的所有路段是否可用。