我正在为公交车开发预订模块,但我无法为其设计正确的数据库结构。
我们采取以下案例:
公共汽车从A到D在B和C中途停留。乘客可以预订任何路线的车票,即。从A到B,C到D,A到D等。
因此每条路线都可以有很多“子路径”,而较大路径则包含较小的路径。
我想以一种有助于轻松搜索免费座位的方式设计路线和停靠点的表格结构。因此,如果有人保留从A到B的座位,那么从B到C或D的座位仍然可用。
所有想法都将受到赞赏。
答案 0 :(得分:9)
我可能会采用类似于这个基本理念的“强力”结构:
(真实模型中应该存在更多字段。这只是一个简化版本,其中包含建立表间关系所必需的基本要素。)
票证“覆盖”通过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
子句,以限制对特定站点或座位的搜索。
答案 1 :(得分:6)
从公交公司的角度来看:
通常将一条路线视为一系列路段,例如A到B,B到C,C到D等。分别在每个路段上计算填充。因此,如果公共汽车离开A满,人们离开C,那么用户可以在C购票。
我们这样计算,每条路线都有ID,每个路段都属于这条路线ID。然后,如果用户购买多个部分的票证,则标记每个部分。然后,下一个乘客系统检查沿途的所有路段是否可用。