Sql 交通时刻表系统数据库设计

Sql 交通时刻表系统数据库设计,sql,database-design,timetable,Sql,Database Design,Timetable,我在大学二年级上数据库设计课已经有一段时间了。在此期间,我还没有做过任何设计,所以我的技能目前充其量只是生锈了。我开始从事一个涉及铁路时刻表系统的个人项目,似乎被困在类似于以下内容的表格设计上: StationTbl ------------ StnName StnCity StnCode - {Primary Key} TrainTbl --------- TrnName TrnNumber - {Primary Key} SourceStn DestStn

我在大学二年级上数据库设计课已经有一段时间了。在此期间,我还没有做过任何设计,所以我的技能目前充其量只是生锈了。我开始从事一个涉及铁路时刻表系统的个人项目,似乎被困在类似于以下内容的表格设计上:

StationTbl
------------
  StnName
  StnCity
  StnCode -  {Primary Key}

TrainTbl
---------
  TrnName
  TrnNumber -  {Primary Key}
  SourceStn
  DestStn
  DaysofWeek 

TrainHopTbl
--------------
  TrnNumber   -  {Primary Key}
  StationCode -  {Primary Key}
  ArrTime
  DepTime
  HopIndex
除了TrainHopTbl中的时间字段和HopIndex之外,大多数字段都是字母数字。正如你所见,初步设计非常粗糙,远未完成

用户可以根据列车名称/编号或指定源站和目的站来查找列车。第一个查询很容易处理,但是我在为第二个搜索编写查询时遇到了问题,在第二个搜索中,用户给出src/dest对,服务器返回在该路线上运行的列车列表。该信息将从TrainHopTbl中提取,TrainHopTbl包含特定列车的跃点列表,如下所示-

TrainHopTbl
--------------
Num StnCode  ArrTime  DepTime  HopIndex
121  WDC     0900      0910        1
121  BAL     1005      1010        2
121  NYC     1145       -          3
如果用户输入WDC/NYC作为src/dest对,则查询应返回121号列车,因为它是有效的路线


任何关于数据库设计的指针/链接/书籍建议都会有所帮助。见鬼,在这一点上,即使是可运行的查询或整个重新设计也会有所帮助,因为我似乎陷入了一个难以摆脱的陈规陋习,这完全阻碍了我的进度。

您似乎在试图解决数据库的硬图问题。向train表中添加一个以字符串形式存储站点列表的字段可能会容易得多

"WDC, BAL, NYC"
然后您只需要找到包含您正在查找的两个子字符串的序列,在本例中为WDC和NYC。这缩小了你的搜索范围,你可以在SQL之外的代码中考虑结果。 如果不做比我现在愿意做的更多的研究,那么你所做的就是

从包含WDC和包含NYC的位置选择


我不知道最好的方法是。。。有人评论吗?

我会把你的SourceStn和DestStn从火车上拿出来,这是不必要的混乱

无论如何,您可以通过以下方式获得您想要的:

select 
    src.TrnNumber,
    srcSt.StnName as SourceStation, 
    srcSt.StnCity as SourceCity,
    src.DepTime,
    destSt.StnName as DestinationStation,
    destSt.StnCity as DestinationCity,
    dest.ArrTime,
    (abs(dest.HopIndex - src.HopIndex)) as Stops
from
    TrainHopTbl src
    inner join TrainHopTbl dest on
        src.TrnNumber = dest.TrnNumber
    inner join StationTbl srcSt on
        src.StnCode = srcSt.StationCode
    inner join StationTbl destSt on
        dest.StnCode = destSt.StationCode
where
    src.StnCode = 'WDC'
    and dest.StnCode = 'NYC'
    and src.HopIndex < dest.HopIndex
order by
    Stops asc,
    DepTime asc

编辑:我在这里没有考虑转账。你的问题提到的只是直达路线的火车。如果你想转学,也请告诉我。

我还没有仔细考虑过这一点,所以这个回答可能太离谱了

我认为TrainHopTbl记录网络中的节点,在网络中记录边缘更有用。边缘将包含列车号、出发站、出发时间、到达站和到达时间。也许还有一个像你现在这样的跳跃索引

所以

Num:121,Hopindex:1,DepStnCode:WDC,DepTime:910,ArrStnCode:BAL,ArrTime:1005

将描述从华盛顿到巴尔的摩的跳跃,这是跳跃网络中的一个优势

此外,我会称一跳为一条腿,但这只是命名选择

通过将两个跳站连接在一起,就可以连接一系列跳站,让你在一次旅行中从一个地方到另一个地方。有些行程甚至可能需要在某个车站换车,前提是到达时间比下一站的出发时间早一点


不利的一面是,车站代码中有更多的冗余。我还没有弄清楚这种冗余是否有害。

+1提供了明确的问题、示例和用例。如果一列火车有20站怎么办?想想波士顿的通勤铁路,效率会相当低,是吗?为什么不使用set事务,而不是尝试在SQL中解析字符串?只要是同一列火车,并且HopIndex的顺序正确,生活就应该是美好的,不考虑转会。埃里克,对不起,我在设定的交易中失去了你。想详细说明吗?+1个不错的解决方案。很好地缩小路线范围,将很好地缓存,确保返回的列车以正确的方向运行。我可以建议通过hopindex/一些其他指示旅行时间的命令吗?这是一个很好的补充。如果将ArrTime和DepTime存储为times,则可以使用datediff查找总旅行时间。目前,我会按到站和出发时间来订购。目前我只看直达路线的列车。转移是可选的,目前不需要。我只是想把一个像样的数据库设计形式化,这样在项目的后期不会弄乱我的代码。@Eric-你能把传输的解决方案包括进来吗?edge方法听起来不错,但这意味着对Eric提出的查询进行完全的重新设计。关于站点代码中的冗余,我认为没有其他方法,因为大多数代码都是3-4个字符长,所以不会对大小产生太大影响。