2016-06-01 7 views
0

Я работаю над db, который получает данные от пользователей в отношении общественного транспорта. Пользователь может отправить много информации, но то, что имеет значение для обеспечения целостности внутри БД:Обеспечить целостность в Postgresql, если данные объединяются

  • вид транспортного средства (метро, ​​автобус)
  • номер транспортного средства
  • (автобус/метро) остановки где пользователь отправляет данные

До сих пор я обеспечиваю целостность на сервере, но производительность не очень хорошая, и мне бы хотелось, чтобы это произошло в самой db. Я хочу реализовать механизм, который проверяет, когда пользователь отправляет какую-либо информацию, если предоставленные данные существуют в db и является правильным: например, я хочу проверить, предоставила ли она существующее транспортное средство с правильным типом, и правильная остановка.

Дело в том, что автомобиль может быть двух типов (автобус или метро), и он может иметь номер. Для каждого автомобиля есть список остановок.

Так что я думал, что список транспортных средств должен быть столом один, Транспортные средства. Список остановок живет внутри другого стола, Остановки.

Каждое транспортное средство имеет массив целых чисел, относящихся к основным ключам стопов.

Я изо всех сил пытался найти для этого рабочее решение. Некоторые говорят, что для реализации ограничений внешнего ключа, но я действительно не знаю, как это сделать. Некоторые другие говорят, чтобы реализовать триггеры. Как мне продолжить? Благодаря!

ответ

0

Как насчет трех таблиц? У вас есть транспортные средства, остановки и тот факт, что определенные транспортные средства посещают определенную остановку.

BEGIN; 

CREATE TABLE vehicles (
    vtype char, 
    vnum int, 
    PRIMARY KEY (vtype, vnum) 
); 

CREATE TABLE stops (
    vtype char, 
    stopnum int, 
    location text, 
    PRIMARY KEY (vtype, stopnum) 
); 

CREATE TABLE vehicle_stops (
    vtype char, 
    vnum int NOT NULL, 
    stopnum int NOT NULL, 
    CONSTRAINT valid_vehicle FOREIGN KEY (vtype, vnum) REFERENCES vehicles, 
    CONSTRAINT valid_stop FOREIGN KEY (vtype, stopnum) REFERENCES stops, 
    PRIMARY KEY (vtype,vnum,stopnum) 
); 

INSERT INTO vehicles VALUES 
    ('B', 453), 
    ('S', 111); 

INSERT INTO stops VALUES 
    ('B', 1001, 'Trafalgar Square'), 
    ('B', 1002, 'Marylebone'), 
    ('S', 2001, 'Charing Cross'), 
    ('S', 2002, 'Embankment'); 

INSERT INTO vehicle_stops VALUES 
    ('B', 453, 1001), 
    ('B', 453, 1002), 
    ('S', 111, 2001), 
    ('S', 111, 2002); 

INSERT INTO vehicle_stops VALUES ('B', 111, 2001); 

ROLLBACK; 

Там мы идем - 453 автобус идет на Трафальгарскую площадь и Marylebone, и 111 поезда метро (или поезд метро, ​​как мы называем их в Лондоне) идет на Чаринг-Кросс и набережной.

Внешние ключи на vehicle_stops не позволят вам ввести плохую комбинацию транспортных средств/стоп (например, в последней вставке).

+0

Таким образом, я мог бы использовать ограничения транспортного средства в таблице, где храню данные, отправленные пользователем! Можно ли добавить внешний ключ внутри упоров, поэтому мы ссылаемся на транспортные средства внутри таблицы транспортных средств, а также на возможность добавления «ON UPDATE» и «ON DELETE»? – Chris

+0

Нет, 'остановки' не должны ссылаться на« транспортные средства », то есть на цели« vehicle_stops ». –

0

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

Для получения божественной производительности, hoever, важно иметь возобновлемую схему в первую очередь.

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

Если число столкновений возможно, вам нужно иметь обе клавиши.

Я бы предположил, что есть остановки, где останавливаются различные транспортные средства.Тогда наличие таблицы соответствия, которая связывает транспортные средства и остановки (от столов стол), будет разумным способом отражения этого отношения.

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

Таким образом, вы бы (псевдо-код для иллюстрации):

  • данные таблицы:
    foreign key (pk_vehicle_stop_match) REFERENCES vehicle_stop_match(pk)

  • vehicle_stop_match стол:
    foreign key (fk_vehicle) REFERENCES vehicles(pk)
    foreign key (fk_stop) REFERENCES stops(pk)

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