Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: Помогите собрать схему БД для расписания электричек.  (Прочитано 58451 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« : 12-08-2010 11:41 » 

Здравствуйте! Просьба помочь в составлении схемы БД для рассписания электричек.
Помощь нужна в правильной организации таблиц маршрутов и расстояний.
Расстояния нужны для информации пользователей системы (Например, человек подошел к системе, ввел заданный пункт, система ему вывела на экран все маршруты на сегодня до этого пункта + расстояние до него), а также от расстояния зависит стоимость проезда, и хочется сделать так, чтобы система не зависела от конкретного пункта отправления (Например, если система будет находиться в Минске, то можно сохранять расстояние от Минска до пунктов движения - это плохой вариант). Теперь давайте поподробнее.
У нас есть следующая схема движения электричек

в данном случае минимизированная схема - для простоты. Цифры - это расстояние между пунктами.
Составленная мною схема БД для маршрутов выглядит так:

т.е. маршруты будут вводиться руками, промежуточные станции, которые включаются в этот маршрут, тоже, а вот расстояние между станцией отправления и станцией куда следует пассажир должно каким-то образом подсчитываться автоматически (Вот я у Вас и прошу помочь разобраться каким таким образом?). Навреное нужно добавить еще одну таблицу с расстояниями между двумя соседними пунктами, но я не могу понять как это организовать, поэтому спрашиваю у Вас. (Возможно нужно даже 2 таблицы добавить, а потом воспользоваться декартовым произведением или чем-нибудь в этом роде). Принимаются все варианты, даже очень сложные.
Если что-то непонятное написал уточняйте... Заранее спасибо.
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #1 : 12-08-2010 11:56 » 

Первые 2 секунды просмотра выявили, что таблица "Станции" имеет внешний ключ на таблицу "Маршруты", что не верно, должно быть наоборот.


Для вычисления расстояний в таблицы "станции" добавь:
1. добавь поле "направление" (название линии) причем линия это любая ветка из Минска (т.е. противоположные красные ветки от Минска это разные направления)
2. поле "расстояние" и заноси туда расстояние от этой станции до Минска (т.е. для Олехновичи это будет 47).

Тогда расстояние между ЛЮБЫМИ станциями будет мериться так:
ЕСЛИ начальная и конечная станции маршрута лежат на разных ветках, то просто складываем значения поля "расстояние" из таблицы "станции" для начала и конца маршрута
ЕСЛИ же начальная и конечная станции маршрута лежат на одной и той же ветке, то берем модуль разности значений поля "расстояние" из таблицы "станции" для начала и конца маршрута
Записан

С уважением Lapulya
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #2 : 12-08-2010 12:12 » 

Ой, сорри не прочитал, что такой вариант (храним расстояния от Минска) не катит, но все равно станция не должна содержать внешних ключей на маршрут.

Хотя... боюсь что уж совсем общий вариант сделать не получится... или от просто будет хардкорным. Т.е. можно пронумеровать станции в разрезе каждой ветки и потом высчитывать путь. Или для каждой станции хранить предшественника и последователя и по ним выстраивать маршрут и высчитывать расстояний.

Подробней описать сейчас времени нет. Вечером может подробней распишу.
« Последнее редактирование: 12-08-2010 12:17 от lapulya » Записан

С уважением Lapulya
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 12-08-2010 12:41 » 

Нужно хранить несколько вещей.

1) Взвешенный граф дорожной сети. Это будет одна таблица - станции. Другая таблица - железная дорога между станциями.

Станция
Молодечно
Олехновичи
Радошковичи

Станция 1Станция 2Расстояние
МолодечноОлехновичи30
ОлехновичиРадошковичи13

Это базовая структура информации. На неё накладываются маршруты.

2) Маршрут представляет собой либо указание начальной и конечной остановки (тогда поиск промежуточных станций идёт вручную), либо полный перечень станций в порядке их прохода.

Если маршрут задаётся переменным числом станций, то опять две таблицы:
Маршрут
Электричка 1

МаршрутПорядковый пункт маршрутаСтанция
Электричка 11Молодечно
Электричка 12Олехновичи
Электричка 13Радошковичи
Электричка 14Олехновичи
Электричка 15Молодечно
Пример кольцевого маршрута.

Вычисление расстояния поездки по таблице маршрута и расстояний делается не очень сложным запросом.

3) Расписание лучше представить отдельной подсистемой данных и увязать её с маршрутами через вспомогательные таблицы.
« Последнее редактирование: 12-08-2010 12:47 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #4 : 12-08-2010 15:17 » 

Dimka, суть понял, только не могу понять для чего таблица Станция в 1?
Записан
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #5 : 12-08-2010 15:18 » 

lapulya, буду очень признателен, если подробнее опишешь свой вариант.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 12-08-2010 15:51 » 

Dimka, а хорошо ли повторять имя станции во всех таблицах, разве не делается так: станциям присвоен уникальный ID, а дальше используются ID станций, а не имена ?
Или так делается только для огромных по объёму баз?
Записан

Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 12-08-2010 15:54 » 

Man1BLR, Алексей1153++, именно для этого и есть таблица Станция - во всех остальных таблицах именно ID, а названия в посте - для наглядности
Записан
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #8 : 12-08-2010 15:56 » 

Kivals, ха))), только что хотел написать, что наверное Dimka для этого и создал таблицу станции))))
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 12-08-2010 15:59 » 

Kivals, Man1BLR, ну я так и подумал )) Можно было бы для наглядности и поле ID показать в первой таблице

(да оптимизационный рефлекс сработал Отлично )
Записан

Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 12-08-2010 16:01 » 

Я бы наверное вторую таблицу делал зеркальную:
МолодечноОлехновичи30
ОлехновичиМолодечно30
И в таблице 4 хранил бы ссылки на таблицу 2
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #11 : 12-08-2010 16:02 » 

под маршрутом надо понимать две разные вещи:

1) это совокупность станций по пути следования из точки A в точку B по одной ветке, где A и B - конечные станции этой ветки. (т.е. маршрут электрички)
2) совокупность станций из точки A в точку B, где A и B - произвольные станции на схеме (т.е. машрут пассажира).

иными словами, конечный маршрут пассажира может состоять из отрезков маршрутов различных электричек. а задача о прокладке маршрута для пассажира - это задача о поиске наикратчайшего пути на графе. никаким запросом это не решается, это классическая комбинаторика.
Записан

x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #12 : 12-08-2010 16:04 » 

хотя, если "маршруты будут вводиться руками, промежуточные станции, которые включаются в этот маршрут, тоже" - то это, наверное, несущественно. т.е. если пассажир вводит не первую и последнюю станции, а весь маршрут со всеми промежуточными станциями сам, руками.
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 12-08-2010 16:06 » 

маршрут можно хранить в виде строки , перечислив ID станций через разделитель. А обработкой пущай программа занимается
Записан

Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #14 : 12-08-2010 16:06 » 

Цитата
это задача о поиске наикратчайшего пути на графе. никаким запросом это не решается, это классическая комбинаторика

Стоп. О поиске наикратчайшего пути на графе никто и не говорил. Задача системы достать из БД имеющиеся актуальные маршруты на данный момент и показать их пользователю, а пользователь уже сам решает какой маршрут он предпочтет. Ага
« Последнее редактирование: 12-08-2010 16:10 от Man1BLR » Записан
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #15 : 12-08-2010 16:08 » 

Цитата
маршрут можно хранить в виде строки , перечислив ID станций через разделитель. А обработкой пущай программа занимается

Задача построить реляционную БД, а не плоский файл.
« Последнее редактирование: 12-08-2010 16:10 от Man1BLR » Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #16 : 12-08-2010 16:11 » 

Man1BLR, да ну? у вас на упрощённой схеме 17 станций. на боевой, надо думать, поболее. если пассажир едет по одной ветке - нет вопросов, он просто выбирает ветку. а если ему надо попасть из Руденска в Борисов, например? у вас в базе такого маршрута нет. или вы собираетесь хранить все возможные маршруты между всеми станциями?

выходит, что у вас пассажир тупо выбирает ветку, выбирает на ней две станции, система возвращает ему расстояние (и стоимость). если ему надо попасть на другую ветку - значит он сначала будет считать по одной, потом по другой.

если это курсовая - сойдёт. если реальный проект - это не прокатит. слишком неудобно.
Записан

Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #17 : 12-08-2010 16:15 » 

x77, естественно это не реальный прокет, это даже не курсовая, просто я учусь на программиста и вот летом делать нечего, придумал сам себе проект, конечно же хочется приблизить его как можно больше к реальности.

Цитата
выходит, что у вас пассажир тупо выбирает ветку, выбирает на ней две станции, система возвращает ему расстояние (и стоимость). если ему надо попасть на другую ветку - значит он сначала будет считать по одной, потом по другой.

Получается что да.
« Последнее редактирование: 12-08-2010 16:19 от Man1BLR » Записан
Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #18 : 12-08-2010 16:16 » 

У меня еще один небольшой вопрос по поводу решения Dimka. Получается что в таблице2 Станция1 и Станция2 - это внешние ключи ссылающиеся на таблицу1, так можно?  Здесь была моя ладья...
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #19 : 12-08-2010 16:19 » 

не можно, а нужно Улыбаюсь
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 12-08-2010 16:23 » 

там как-то вот так будет )

СтанцияIDst (PK)
Молодечно1
Олехновичи2
Радошковичи3

IDst1IDst2Расстояние
1230
2313

Записан

Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #21 : 12-08-2010 17:19 » 

Теоритически, между теорией и практикой нет различий.
Но на практике они есть. (Jan L.A. van de Snepscheut)


Дело в том, что 2 внешних ключа ссылающихся на 1 таблицу не может быть! Для примера возьмем 2 таблицы, которые составил Алексей1153++ выше. Получается, что IDst1 - это FK, который ссылается на столбец IDst, но и IDst2 - это тоже FK, который ссылается на столбец IDst, а такого не может быть, такой связи нигде нет и в MS SQL такой фокус провернуть нельзя.

Не верите, проверьте сами, файл сценария прилагается.

* Пример.sql (1.01 Кб - загружено 822 раз.)
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #22 : 12-08-2010 17:28 » 

Цитата
IDst1 - это FK, который ссылается на столбец IDst, но и IDst2 - это тоже FK, который ссылается на столбец IDst, а такого не может быть

почему не может? всю жизнь так и было. какую ошибку M$ выдаёт, дословно?
Записан

Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #23 : 12-08-2010 17:30 » new

Ну если дословно то:

Сообщение 8148, уровень 16, состояние 0, строка 1
Более одного ограничения столбца FOREIGN KEY указано для столбца "Расстояние", таблица "ДорожнаяСеть".


Вот только причем тут столбец "Расстояние".  Здесь была моя ладья...
« Последнее редактирование: 12-08-2010 17:32 от Man1BLR » Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #24 : 12-08-2010 17:44 » 

да при том, что вы все ключи определяете для него. смотрите синтаксис CREATE TABLE.

первичный ключ: job_id smallint PRIMARY KEY,
внешний ключ: job_id smallint NOT NULL DEFAULT 1 REFERENCES jobs(job_id),

и т.д. у вас просто синтаксис кривой Ага
Записан

Man1BLR
Участник

by
Offline Offline
Пол: Мужской

« Ответ #25 : 12-08-2010 18:25 » 

Действительно были ошибки - запятые не поставил, просто не думал, что они играют важную роль, такуюже как в С и С++ - ";".

А по поводу синтаксиса, то я считаю, что объявление ограничений PK и FK в таком стиле очень даже привлекательно, хотя бы по 3-м причинам:

  • упращается работа при создании первичного ключа, состаящего из нескольких столбцов (ведь первичный ключ с несколькими столбцами не может быть объявлен как ограничение столбца)
  • ты контролируешь название внешнего или первичного ограничения
  • проще понимать устройство оператора CREATE TABLE

Вот пример создания таблицы:
Код:
-- создание таблицы, которая задает расстояние между пунктами
CREATE TABLE ДорожнаяСеть
(
Станция1 int NOT NULL,
Станция2 int NOT NULL,
Расстояние int NOT NULL,

CONSTRAINT PK_ОтСтанции1ДоСтанции2
PRIMARY KEY (Станция1, Станция2),

CONSTRAINT FK_Станция1
FOREIGN KEY (Станция1)
REFERENCES Станции(КодСтанции),

CONSTRAINT FK_Станция2
FOREIGN KEY (Станция2)
REFERENCES Станции(КодСтанции)
)
GO

Очень даже симпотичный синтаксис. В прочем на вкус и цвет товарища нет.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 12-08-2010 18:29 » 

ох, и увлечение ключами. А нужно ли

Код:
	
CONSTRAINT FK_Станция1
FOREIGN KEY (Станция1)
REFERENCES Станции(КодСтанции),

CONSTRAINT FK_Станция2
FOREIGN KEY (Станция2)
REFERENCES Станции(КодСтанции)

? Вроде нафик

Я не очень часто с базами воюю, но интуиция мне подсказала так ) Или я не прав?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 12-08-2010 18:32 » 

А, всё, понял. Целостность охота блюсти.

Только название таблице больше подойдёт не "ДорожнаяСеть", а "РасстояниеМеждуСтанциями" ))
« Последнее редактирование: 12-08-2010 18:35 от Алексей1153++ » Записан

Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #28 : 12-08-2010 18:34 » 

Алексей1153++, вообще-то для целосночти базы - желательно. Если такая связь есть - СУБД не даст удалить станцию из Станции, если на нее есть ссылки по FK в других таблицах. Иначе - останутся неразрешенные ссылки (при наличии FK легче обрабатывать exceptions).
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #29 : 12-08-2010 20:46 » 

Я бы наверное вторую таблицу делал зеркальную:
МолодечноОлехновичи30
ОлехновичиМолодечно30

IMHO с точки зрения поддержки целостности данных не лучшее решение. Нужно надеяться, что данные будут вводиться, корректироваться и удаляться парами, причем согласованно, не допуская различий в третьем столбце. Практика показывает, что если это не учебная база в десяток строк, а реальная система, то следует ожидать проблем.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines