Как исправить ошибку с наследованием составных ключей - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть таблица: таблица портов и в ней я делаю составной ключ. как мне потом наследовать его, например, в таблицу ticket ? При попытке через ссылки выдает ошибку. Пожалуйста, помогите и объясните, как это исправить. На этом скриншоте я показываю вам ошибку, которую выдает datagrip при запуске кода. Ошибка в тикете :

[42830] ERROR: number of referencing and referenced columns for foreign key disagree

Таблица определений:

CREATE TABLE Capitan(
    ID_Capitan INT NOT NULL PRIMARY KEY CHECK(ID_Capitan > 0) UNIQUE,
    First_name VARCHAR(16) NOT NULL CHECK (First_name SIMILAR TO '[A-Z][a-z]+'),
    Second_name VARCHAR(16) NOT NULL CHECK (Second_name SIMILAR TO '[A-Z][a-z]+'),
    Third_name VARCHAR(16) NOT NULL CHECK (Third_name SIMILAR TO '[A-Z][a-z]+'),
    Passport_ID VARCHAR(20) NOT NULL UNIQUE,
    Years_of_experience INT NOT NULL CHECK(Years_of_experience > 0),
    Permission_to_operate_ships BOOLEAN NOT NULL
);
CREATE TABLE Ship(
    Number_of_ship INT NOT NULL CHECK(Number_of_ship > 0) UNIQUE,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'FR' OR Serial_of_ship SIMILAR TO 'PA'),
    Name_of_ship VARCHAR(20) NOT NULL CHECK (Name_of_ship SIMILAR TO '[A-Z][a-z]+') UNIQUE,
    Year_of_issue DATE NOT NULL,
    Cost_of_annual_maintenance INT NOT NULL CHECK(Cost_of_annual_maintenance > 0),
    Act_of_cancellation INT NULL CHECK(Act_of_cancellation > 0) UNIQUE,
    Status_of_ship VARCHAR(20) NOT NULL CHECK(Status_of_ship SIMILAR TO '[A-Z]([a-z]|[ \f\n\r\t\v])+'),
    ABC_Analysis CHAR(1) NOT NULL CHECK(ABC_Analysis SIMILAR TO 'A' OR ABC_Analysis SIMILAR TO 'B' OR ABC_Analysis SIMILAR TO 'C'),
    PRIMARY KEY (Number_of_ship,Serial_of_ship)
);
CREATE TABLE Port(
    Name_of_port VARCHAR(20) NOT NULL PRIMARY KEY CHECK(Name_of_port SIMILAR TO '[A-Z][a-z]+') UNIQUE,
    Country VARCHAR(20) NOT NULL CHECK(Country SIMILAR TO '[A-Z][a-z]+'),
    City VARCHAR(20) NOT NULL CHECK(City SIMILAR TO '[A-Z][A-z]+'),
    Latitude FLOAT NOT NULL,
    Longitude FLOAT NOT NULL,
    Cost_of_stay_in_port MONEY NOT NULL,
    Ship_unloading_cost MONEY NOT NULL
);
CREATE TABLE Voyage(
    Voyage_number INT NOT NULL PRIMARY KEY CHECK(Voyage_number > 0) UNIQUE,
    Departure_date TIMESTAMP NOT NULL,
    Arrival_date TIMESTAMP NOT NULL,
    Total_distance FLOAT NOT NULL CHECK(Total_distance > 0),
    Passed_passengers INT NULL CHECK(Passed_passengers > 0),
    Risen_passengers INT NULL CHECK(Risen_passengers > 0),
    Unloaded_tone FLOAT NULL CHECK(Unloaded_tone > 0),
    Loaded_tone FLOAT NULL CHECK(Loaded_tone > 0)
);
CREATE TABLE Client(
    ID_Client INT NOT NULL PRIMARY KEY CHECK(ID_Client > 0) UNIQUE ,
    First_name VARCHAR(16) NOT NULL CHECK (First_name SIMILAR TO '[A-Z][a-z]+'),
    Second_name VARCHAR(16) NOT NULL CHECK (Second_name SIMILAR TO '[A-Z][a-z]+'),
    Third_name VARCHAR(16) NOT NULL CHECK (Third_name SIMILAR TO '[A-Z][a-z]+'),
    Passport_ID VARCHAR(20) NOT NULL UNIQUE,
    Photograph BYTEA NOT NULL,
    Customers_internal_account VARCHAR(20) NOT NULL UNIQUE
);
CREATE TABLE Freight(
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'FR'),
    Tonnage_of_ship INT NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Passenger(
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'PA'),
    Number_of_cabins INT NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Cabin_class(
    Cabin_of_class VARCHAR(20) NOT NULL PRIMARY KEY,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'PA'),
    Number_of_places INT NOT NULL,
    Cost_of_cabin MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Type_of_cargo(
    Name_of_cargo VARCHAR(20) NOT NULL PRIMARY KEY,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'FR'),
    Number_of_goods INT NOT NULL,
    Cost_of_cargo MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Price_between_2_ports_FREIGHT(
    Name_of_cargo VARCHAR(20) NOT NULL REFERENCES Type_of_cargo,
    Arrival_port VARCHAR(20) NOT NULL REFERENCES Port,
    Depart_port VARCHAR(20) NOT NULL REFERENCES Port,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'FR'),
    Total_cost_of_cargo MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Price_between_2_ports_PASSENGER(
    Class_of_cabin VARCHAR(20) NOT NULL REFERENCES Cabin_class,
    Arrival_port VARCHAR(20) NOT NULL REFERENCES Port,
    Depart_port VARCHAR(20) NOT NULL REFERENCES Port,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL CHECK (Serial_of_ship SIMILAR TO 'PA'),
    Total_cost MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Table_of_ports(
    Serial_number INT NOT NULL,
    Voyage_number INT NOT NULL REFERENCES Voyage,
    Name_of_port VARCHAR(20) NOT NULL REFERENCES Port,
    Name_of_cargo VARCHAR(20) NULL REFERENCES Type_of_cargo,
    Class_of_cabin VARCHAR(20) NULL REFERENCES Cabin_class,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL,
    CONSTRAINT Table_of_ports_PK PRIMARY KEY (Serial_number,Voyage_number),
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Ticket(
    Identification_code VARCHAR(20) NOT NULL PRIMARY KEY UNIQUE,
    Voyage_number INT NOT NULL REFERENCES Voyage,
    Arrivel_number INT NOT NULL REFERENCES Table_of_ports,
    Depart_number INT NOT NULL REFERENCES Table_of_ports,
    ID_Client INT NOT NULL REFERENCES Client,
    Class_of_cabin VARCHAR(20) NOT NULL REFERENCES Cabin_class,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL,
    Cost_of_ticket MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Ship_declaration(
    Barcode INT NOT NULL PRIMARY KEY UNIQUE,
    Voyage_number INT NOT NULL REFERENCES Voyage,
    Arrivel_number INT NOT NULL REFERENCES Table_of_ports,
    Depart_number INT NOT NULL REFERENCES Table_of_ports,
    Name_of_cargo VARCHAR(20) NOT NULL REFERENCES Type_of_cargo,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL,
    ID_Client INT NOT NULL REFERENCES Client,
    Tonnage FLOAT NOT NULL,
    Cost_of_declaration MONEY NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);
CREATE TABLE Ships_voyage(
    Voyage_number INT NOT NULL REFERENCES Voyage,
    Number_of_ship INT NOT NULL,
    Serial_of_ship VARCHAR(2) NOT NULL,
    ID_Capitan INT NOT NULL REFERENCES Capitan,
    Presence_of_support BOOLEAN NOT NULL,
    FOREIGN KEY (Number_of_ship,Serial_of_ship) references Ship
);

1 Ответ

0 голосов
/ 16 апреля 2019

Table_of_ports определяется первичным ключом, который охватывает два столбца: (Serial_number,Voyage_number)

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

То же самое относится и к другим таблицам.

Между прочим, бессмысленно определять столбец как PRIMARY KEY UNIQUE. Таким образом, таблица имеет первичный ключ и - уникальное ограничение, определенное для того же столбца, и в этом нет необходимости, поскольку первичный ключ уже подразумевает уникальность. Так что просто опустите UNIQUE в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...