公交车路线查询系统后台数据库设计.docx
- 文档编号:13104826
- 上传时间:2023-06-11
- 格式:DOCX
- 页数:50
- 大小:330.85KB
公交车路线查询系统后台数据库设计.docx
《公交车路线查询系统后台数据库设计.docx》由会员分享,可在线阅读,更多相关《公交车路线查询系统后台数据库设计.docx(50页珍藏版)》请在冰点文库上搜索。
公交车路线查询系统后台数据库设计
公交车路线查询系统后台数据库设计--查询算法
1.公交车路线信息在数据库中的存储方式
显然,如果在数据库中简单的使用表bus_route(路线名,路线经过的站点,费用)来保存公交车路线的线路信息,则很难使用查询语句实现乘车线路查询,因此,应该对线路的信息进行处理后再保存到数据库中,笔者使用的方法是用站点-路线关系表stop_route(站点,路线名,站点在路线中的位置)来存储公交车路线,例如,如果有以下3条路线
R1:
S1->S2->S3->S4->S5
R2:
S6->S7->S2->S8
R3:
S8->S9->S10
则对应的站点-路线关系表stop_route为
Stop
Route
Position
S1
R1
1
S2
R1
2
S3
R1
3
S4
R1
4
S5
R1
5
S6
R2
1
S7
R2
2
S2
R2
3
S8
R2
4
S8
R3
1
S9
R3
2
S10
R3
3
注:
Stop为站点名,Route为路线名,Position为站点在路线中的位置
2.直达乘车路线查询算法
基于表stop_route可以很方便实现直达乘车路线的查询,以下是用于查询直达乘车路线的存储过程InquiryT0:
createprocInquiryT0(@StartStopvarchar(32),@EndStopvarchar(32))
as
begin
select
sr1.Stopas启始站点,
sr2.Stopas目的站点,
sr1.Routeas乘坐线路,
sr2.Position-sr1.Positionas经过的站点数
from
stop_routesr1,
stop_routesr2
where
sr1.Route=sr2.Route
andsr1.Position andsr1.Stop=@StartStop andsr2.Stop=@EndStop end 3.查询换乘路线算法 (1)直达路线视图 直达路线视图可以理解为一张存储了所有直达路线的表(如果两个站点之间存在直达路线,那么在直达路线视图中就有一行与之相对应)。 例如R1,R2,R3对应的RouteT0如下: 起点 终点 乘坐路线 站点数 S3 S4 R1 1 S3 S5 R1 2 S4 S5 R1 1 S1 S2 R1 1 S1 S3 R1 2 S1 S4 R1 3 S1 S5 R1 4 S2 S3 R1 1 S2 S4 R1 2 S2 S5 R1 3 S2 S8 R2 1 S6 S2 R2 2 S6 S7 R2 1 S6 S8 R2 3 S7 S2 R2 1 S7 S8 R2 2 S8 S10 R3 2 S8 S9 R3 1 S9 S10 R3 1 RouteT0定义如下: createviewRouteT0 as select sr1.StopasStartStop,--启始站点 sr2.StopasEndStop,--目的站点 sr1.RouteasRoute,--乘坐线路 sr2.Position-sr1.PositionasStopCount--经过的站点数 from stop_routesr1, stop_routesr2 where sr1.Route=sr2.Route andsr1.Position (2)换乘路线算法 显然,一条换乘路线由若干段直达路线组成(每段路线的终点与下一段路线的起点相同),因此,基于直达路线视图RouteT0可以很方便实现换乘查询,以下是实现一次换乘查询的存储过程InquiryT1: createprocInquiryT1(@StartStopvarchar(32),@EndStopvarchar(32)) as begin select r1.StartStopas启始站点, r1.Routeas乘坐路线1, r1.EndStopas中转站点, r2.Routeas乘坐路线2, r2.EndStopas目的站点, r1.StopCount+r2.StopCountas总站点数 from RouteT0r1, RouteT0r2 where r1.StartStop=@StartStop andr1.EndStop=r2.StartStop andr2.EndStop=@EndStop end 同理可以得到二次换乘的查询语句 createprocInquiryT2(@StartStopvarchar(32),@EndStopvarchar(32)) as begin select r1.StartStopas启始站点, r1.Routeas乘坐路线1, r1.EndStopas中转站点1, r2.Routeas乘坐路线2, r2.EndStopas中转站点2, r3.Routeas乘坐路线3, r3.EndStopas目的站点, r1.StopCount+r2.StopCount+r3.StopCountas总站点数 from RouteT0r1, RouteT0r2, RouteT0r3 where r1.StartStop=@StartStop andr1.EndStop=r2.StartStop andr2.EndStop=r3.StartStop andr3.EndStop=@EndStop end 4.测试 execInquiryT0'S1','S2' execInquiryT1'S1','S8' execInquiryT2'S1','S9' 运行结果: 公交车路线查询系统后台数据库设计--关联地名和站点 在《公交车路线查询系统后台数据库设计——查询算法》一文中,已经实现了查询站点到站点的路线查询算法,但是,现实中用户不一定使用站点进行查询,而是使用地名。 因此,公交车查询系统数据库必需记录地名与站点的对应关系,在查询时将地名映射为站点。 根据实际情况,某一地点附近通常有几个站点,因此,地名与站点之间是多对多的关系。 显然,只需创建一个地名站点关系表stop_spot(Stop,Spot)用于储存这个关系即可。 数据库关系图如下: 注: Route: 路线表 Stop: 站点表 Spot: 地名表 stop_route: 路线-站点关系表 stop_spot: 地名-站点关系表 1.路线和地名信息维护: 以下函数用于维护公交车路线和地名的相关信息 字符串分割函数(信息处理及路线查询的存储过程都需要使用到该函数): /* 函数功能: 将@String以@SplitChar为分隔点分割为字符串数组,结果保留在表变量中 例如SplitString('A/B','/')返回表: Valuevindex A1 B2 */ CREATEfunctionSplitString( @Stringvarchar(2048), @SplitCharchar ) returns@restable( Valuevarchar(128), vindexint ) as begin declare@indexint,@unitvarchar(128),@inextint,@lenint,@iint set@index=1 set@i=1 set@len=len(@String) while@index<=@len begin set@inext=charindex(@SplitChar,@String,@index) if@inext=0set@inext=@len+1 if@inext>@index begin set@unit=ltrim(rtrim(substring(@String,@index,@inext-@index))) if@unit<>'' begin insertinto@res(value,vindex)values(@unit,@i) set@i=@i+1 end end set@index=@inext+1 end return end 插入新的公车路线: /* 插入新的公交车路线 Route: 路线名 Stops: 公交车经过的所有站点,站点用'-'隔开 */ CREATEprocInsertRoute(@Routevarchar(32),@Stops_Strvarchar(1024)) as begin declare@stopstable(namevarchar(32),positionint) insert@stops(name,position) selectValue,vIndexfromdbo.SplitString(@Stops_Str,'-') begintrant1 savetransp1 --插入路线信息 insertintoRoute(name)values(@Route) if(@@error<>0) begin rollbacktransp1 committrant1 raiserror('插入路线时发生错误',16,1) return end --插入不存在的站点 insertStop(name) selectdistinctnamefrom@stopssswherenamenotin(selectnamefromStop) if(@@error<>0) begin rollbacktransp1 committrant1 raiserror('插入路线时发生错误',16,1) return end insertstop_route(Stop,Route,Position) selectss.name,@Route,ss.positionfrom@stopsss if(@@error<>0) begin rollbacktransp1 committrant1 raiserror('插入路线时发生错误',16,1) return end committrant1 end 插入新地名函数: /* 插入新地名 @name: 地名 @Stops: 地名附近的所有站点,多个站点用'/'隔开 @Remark: 与地名相关的说明 */ CREATEprocInsertSpot( @namevarchar(64), @Stops_Strvarchar(1024), @Remarkvarchar(1024) ) as begin declare@stopstable(namevarchar(32)) insert@stopsselectdistinctValuefromdbo.SplitString(@Stops_Str,'/') declare@nvarchar(32) set@n='' selecttop1@n=namefrom@stopsswherenamenotin(selectnamefromstop) if(@n<>'') begin raiserror('站点%s不存在',16,1,@n) return end insertintoSpot(name,remark)values(@name,@remark) insertstop_spot(Stop,Spot) selects.name,@namefrom@stopss if(@@error<>0) begin raiserror('插入地点时发生错误',16,1) return end end 2.路线查询 在《公交车路线查询系统后台数据库设计——查询算法》一文中,使用储存过程InquiryT0,InquiryT1和InquiryT2实现了站点到站点的查询,但是地名可能对应多个站点,因此,当进行地点到地点的查询相当于站点集到站点集的查询。 因此,为了支持使用地名进行查询,将InquiryT0,InquiryT1和InquiryT2修改为站点集到站点集的查询: 直达路线查询: /* 查询站点@StartStops到站点@EndStops之间的直达乘车路线,多个站点用'/'分开,如: execInquiryT0'站点1/站点2','站点3/站点4' */ CREATEprocInquiryT0(@StartStopsvarchar(32),@EndStopsvarchar(32)) as begin declare@ss_tabtable(namevarchar(32)) declare@es_tabtable(namevarchar(32)) insert@ss_tabselectValuefromdbo.SplitString(@StartStops,'/') insert@es_tabselectValuefromdbo.SplitString(@EndStops,'/') if(exists(select*from@ss_tabsst,@es_tabestwheresst.name=est.name)) begin raiserror('起点集和终点集中含有相同的站点',16,1) return end select sst.nameas启始站点, est.nameas目的站点, r.Routeas乘坐线路, r.StopCountas经过的站点数 from @ss_tabsst, @es_tabest, RouteT0r where sst.name=r.StartStop andr.EndStop=est.name end 一次换乘查询: /* 查询站点@StartStops到站点@EndStops之间的一次换乘乘车路线,多个站点用'/'分开,如: execInquiryT1'站点1/站点2','站点3/站点4' */ CREATEprocInquiryT1(@StartStopsvarchar(32),@EndStopsvarchar(32)) as begin declare@ss_tabtable(namevarchar(32)) declare@es_tabtable(namevarchar(32)) insert@ss_tabselectValuefromdbo.SplitString(@StartStops,'/') insert@es_tabselectValuefromdbo.SplitString(@EndStops,'/') if(exists(select*from@ss_tabsst,@es_tabestwheresst.name=est.name)) begin raiserror('起点集和终点集中含有相同的站点',16,1) return end declare@stopstable(namevarchar(32)) insert@stopsselectnamefrom@ss_tab insert@stopsselectnamefrom@es_tab select sst.nameas起始站点, r1.Routeas乘坐路线1, r1.EndStopas中转站点1, r2.Routeas乘坐路线2, est.nameas目的站点, r1.StopCount+r2.StopCountas总站点数 from @ss_tabsst, @es_tabest, (select*fromRouteT0whereEndStopnotin(selectnamefrom@stops))r1, RouteT0r2 where sst.name=r1.StartStop andr1.EndStop=r2.StartStop andr2.EndStop=est.name andr1.Route<>r2.Route end 二次换乘查询: /* 查询站点@StartStops到站点@EndStops之间的二次换乘乘车路线,多个站点用'/'分开,如: execInquiryT2'站点1/站点2','站点3/站点4' */ CREATEprocInquiryT2(@StartStopsvarchar(32),@EndStopsvarchar(32)) as begin declare@ss_tabtable(namevarchar(32)) declare@es_tabtable(namevarchar(32)) insert@ss_tabselectValuefromdbo.SplitString(@StartStops,'/') insert@es_tabselectValuefromdbo.SplitString(@EndStops,'/') if(exists(select*from@ss_tabsst,@es_tabestwheresst.name=est.name)) begin raiserror('起点集和终点集中含有相同的站点',16,1) return end declare@stopstable(namevarchar(32)) insert@stopsselectnamefrom@ss_tab insert@stopsselectnamefrom@es_tab select r1.StartStopas启始站点, r1.Routeas乘坐路线1, r1.EndStopas中转站点1, r2.Routeas乘坐路线2, r2.EndStopas中转站点2, r3.Routeas乘坐路线3, r3.EndStopas目的站点, r1.StopCount+r2.StopCount+r3.StopCountas总站点数 from @ss_tabsst, @es_tabest, (select*fromRouteT0whereEndStopnotin(selectnamefrom@stops))r1, (select*fromRouteT0whereEndStopnotin(selectnamefrom@stops))r2, RouteT0r3 where sst.name=r1.StartStop andr1.EndStop=r2.StartStop andr2.EndStop=r3.StartStop andr3.EndStop=est.name andr1.Route<>r2.Route andr2.Route<>r3.Route andr3.Route<>r1.Route end 综合查询: /* 查询站点@StartStops到站点@EndStops之间的乘车路线,先查询直达路线, 如不存在,则查询一次换乘路线,如果直达和一次换乘均不存在,则查询二次换乘 多个站点用'/'分开,如: execInquiry'站点1/站点2','站点3/站点4' */ CREATEprocInquiry(@StartStopsvarchar(32),@EndStopsvarchar(32)) as begin execInquiryT0@StartStops,@EndStops if(@@rowcount=0) begin execInquiryT1@StartStops,@EndStops if(@@rowcount=0) begin execInquiryT2@StartStops,@EndStops end end end 如要进行地名到地名的路线查询,必需先调用GetStopsOfSpot获取地名对应的所有站点,在调用Inquiry进行查询。 获取地名对应的站点: /* 获取地名对应的站点,如有多个站点,用'/'隔开 */ CREATEfunctionGetStopsOfSpot(@Spotvarchar(32)) returnsvarchar(1024) as begin declare@stopsvarchar(1024) set@stops='' select@stops=@stops+'/'+stopfromstop_spotwhereSpot=@Spot returnsubstring(@stops,2,len(@stops)-1) end 使用地名查询乘车路线示例: declare@spsvarchar(1024),@epsvarchar(1024) set@sps=dbo.GetStopsOfSpot('起始地点名称') set@eps=dbo.GetStopsOfSpot('目的地点名称') execInquiry@sps,@eps 公交车路线查询系统后台数据库设计--引入步行路线 在《查询算法》和《关联地名和站点》两篇文章中,已经实现了通过地名或站点进行路线查询的算法,但是在现实中,从起点到终点不一定全程都是乘车,例如,有以下3条路线: R1: S1->S2->S3->S4->S5 R2: S6->S7->S2->S8 R3: S8->S9->S10 假如现在要从站点S1到S7,如果用Inquiry查询路线,显然没有合适的乘车方案。 但是S2和S7相距仅仅一个站的距离,可以用步行代替,因此可以先从S1乘坐R1到S2再步行到S7。 为了实现在乘车路线中插入步行路线,在数据库使用WalkRoute(StartStop,EndStop,Distance,Remark)(StartStop-起始站
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 公交车 路线 查询 系统 后台数据库 设计
![提示](https://static.bingdoc.com/images/bang_tan.gif)