2009-05-27 9 views
4

Il a été un certain temps depuis mes cours de conception de base de données dans ma deuxième année à Uni. et je n'ai pas fait de design entre-temps, donc mes compétences sont au mieux rouillées en ce moment. J'ai commencé à travailler sur un projet personnel impliquant le système horaire de chemin de fer et semblent être coincé à la conception de la table qui ressemble à quelque chose comme ça -Conception de base de données pour le système de calendrier de transport

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

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

TrainHopTbl 
-------------- 
    TrnNumber - {Primary Key} 
    StationCode - {Primary Key} 
    ArrTime 
    DepTime 
    HopIndex 

La plupart des champs sont alphanumberic à l'exception des champs de temps et la HopIndex dans TrainHopTbl. Comme vous pouvez le voir, la conception préliminaire est très grossière et loin d'être terminée.

Les utilisateurs pourront trouver des trains en fonction du nom/numéro de train ou en spécifiant la station source et la destination. La première requête peut être facilement traitée mais j'ai des problèmes pour écrire une requête pour la deuxième recherche où l'utilisateur donne la paire src/dest et le serveur retourne une liste de trains qui fonctionnent sur cette route. Ces informations seront extraites de TrainHopTbl qui contient la liste des sauts pour le train particulier, comme si -

TrainHopTbl 
-------------- 
Num StnCode ArrTime DepTime HopIndex 
121 WDC  0900  0910  1 
121 BAL  1005  1010  2 
121 NYC  1145  -   3 

Si l'utilisateur entre WDC/NYC que la paire src/dest alors la requête doit retourner train Nombre 121 puisque c'est une route valide. Tout pointeur/lien/suggestion de livre sur la conception d'une base de données serait utile.

Heck, à ce stade même des requêtes exécutables ou des réaménagements entiers seraient utiles car je semble être coincé dans une ornière que je trouve difficile à sortir et cela a complètement bloqué mes progrès.

+0

+1 Question clairement posée, exemples et cas d'utilisation fournis. –

Répondre

3

J'emmènerais votre SourceStn et DestStn de votre TrainTbl - c'est un fouillis inutile.

Quoi qu'il en soit, vous pouvez obtenir ce que vous cherchez avec:

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 

Edit: Je ne l'ai pas pris en compte les transferts ici. Votre question mentionnait simplement les trains directs. Faites-moi savoir si vous voulez des transferts, aussi bien.

+0

+1 bonne solution. Réduit les itinéraires bien, mettra en cache joliment, s'assure que les trains retournés vont dans le bon dir. –

+0

Puis-je suggérer un ORDER BY hopindex/une autre indication du temps de trajet? –

+0

C'est un bon ajout. Si vous avez enregistré ArrTime et DepTime en tant qu'heures, vous pouvez utiliser datediff pour connaître la durée totale du trajet. Pour l'instant, je vais le commander par le nombre d'arrêts et l'heure de départ. – Eric

-2

Il semble que vous essayez de résoudre un problème de graphe dur avec la base de données. Il pourrait être beaucoup plus facile d'ajouter un champ à la table de train qui stocke la liste des arrêts sous forme de chaîne

"WDC, BAL, NYC" 

Ensuite, vous avez juste besoin de trouver des trains qui contiennent les deux sous-chaînes que vous recherchez, dans ce case "WDC" et "NYC". Cela restreint beaucoup votre recherche, au point où vous pourriez considérer les trains résultant dans le code en dehors de SQL.

Sans faire plus de recherches que je suis prêt à faire maintenant, ce que vous faites serait alors faire est

SELECT d'où contient « WDC » et contient « NYC »

Je ne sais pas meilleure façon de faire Contient ... commentaires quelqu'un?

+1

Que faire si un train a 20 arrêts? Pensez même au train de banlieue de Boston - ce serait inefficace, hein? Pourquoi ne pas utiliser set transactions au lieu d'essayer d'analyser les chaînes en SQL? Tant que c'est le même Train # et que l'HopIndex est dans le bon ordre, la vie devrait être passionnante (sans tenir compte des transferts). – Eric

+0

Eric, je suis désolé - je vous ai perdu à "régler les transactions". Vous voulez élaborer? – aks

2

Je n'ai pas encore réfléchi à cela, donc cette réponse pourrait être loin.

Je pense que le TrainHopTbl enregistre les nœuds dans un réseau, où il serait plus utile d'enregistrer les bords dans un réseau. Un bord aurait un numéro de train, une station de départ, une heure de départ, une station d'arrivée et une heure d'arrivée. Et peut-être un indice de saut comme celui que vous avez.

Ainsi,

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

décrirait le "hop" de Washington à Baltimore, un bord dans le réseau de houblon.

(Aussi, je qualifierais hop une « jambe », mais qui est nommant simplement le choix.)

En ayant le houblon lient deux stations ensemble, il devient lien possible une série de sauts qui vous fait de un endroit à un autre en un seul voyage. Certains voyages pourraient même impliquer de changer de train une certaine station, à condition que l'heure d'arrivée soit un peu avant l'heure de départ pour le prochain saut. L'inconvénient de ceci est qu'il y a un peu plus de redondance dans les codes de la station. Je n'ai pas compris si cette redondance est nuisible ou non.

+0

L'approche "edge" semble bonne mais cela signifierait une refonte complète de la requête proposée par Eric. En ce qui concerne la redondance dans les codes des stations, je ne pense pas qu'il existe d'autre approche et comme la plupart des codes ont entre 3 et 4 caractères, cela n'aura pas beaucoup d'impact sur la taille. – aks