Можно ли ссылаться на внешний ключ родительской таблицы? - PullRequest
0 голосов
/ 16 мая 2018
CREATE TABLE Product 
(
    "Product_id" int,
    "Stock_quantity" int,
    "Product_name" varchar(50),
    "Model" varchar(50),
    "Average_rating" float(3),
    "RAM" int,
    "Color" varchar(20),
    "Price" float(10),
    PRIMARY KEY ("Product_id")
);

CREATE TABLE Sale 
(
    "Sale_id" int,
    "Sale_date" date,
    "Employee_id" int,
    "Customer_id" int,
    "Product_id" int,
    "Product_quantity" int,
    "Rating" int,
    PRIMARY KEY ("Sale_id"),
    FOREIGN KEY("Employee_id") REFERENCES Employee("Employee_id") ,
    FOREIGN KEY("Customer_id") REFERENCES Customer("Customer_id") ,
    FOREIGN KEY("Product_id") REFERENCES Product("Product_id")
);

CREATE TABLE Computer  
(
    "Type" varchar(10),
    "Processor" varchar(20),
    "Monitor_size" int
)  inherits(Product);

CREATE TABLE Mobile 
(
    "Os" varchar(30),
    "Screen_size" int
) inherits(Product);

Вот мои таблицы, при вставке строк продажи я получаю эту ошибку.

ОШИБКА: вставка или обновление таблицы «продажа» нарушает ограничение внешнего ключа «PK_Product_id»
Состояние SQL: 23503
Подробно: Ключ (Product_id) = (12) отсутствует в таблице «product».

Там написано, что строки нет, но я вижу их при просмотре таблицы:

However pgAdmin claims that there is no rows at table.

Я вставил каждый продукт как компьютер или мобильный телефон, а не как продукт.

1 Ответ

0 голосов
/ 16 мая 2018

Вы сталкиваетесь с одной из множества странностей с наследованием: в иерархии наследования нет «глобальных» ограничений, следовательно, вы не можете иметь внешний ключ для иерархии наследования.

Первичный ключ, который вы определилина product не не распространяется на computer.

Даже если SELECT на product добавит результаты также для потомков наследования, они не являются частьютаблица parent и, следовательно, не может использоваться в качестве цели для внешнего ключа.Внешний ключ находится между sale и product только , потомки наследования исключены.

Не существует подходящего способа сделать это с наследованием.

ЭтоЛучше, чтобы computer не был потомком наследования продукта, но имел внешний ключ к product (с уникальным ограничением на него), так что данные для объекта компьютера будутразделить между двумя таблицами.Это несколько неудобно для запросов, но вы можете использовать внешний ключ таким образом.

Вот пример:

CREATE TABLE product (
   product_id integer PRIMARY KEY,
   prodname text NOT NULL
);

CREATE TABLE computer (
   product_id integer PRIMARY KEY,
   processor text NOT NULL,
   FOREIGN KEY (product_id) REFERENCES product(product_id)
);

CREATE TABLE sale (
   sale_id integer PRIMARY KEY,
   product_id integer NOT NULL REFERENCES product(product_id)
);

Теперь нет прямой ссылки на внешний ключ от sale доcomputer, но поскольку product_id из computer и product идентичны, вы всегда можете найти уникальный компьютер для sale, если он существует:

SELECT p.prodname, c.processor
FROM sale s
   JOIN product p USING (product_id)
   LEFT JOIN computer c USING (product_id)
WHERE sale_id = 42;

Если у вас есть больше«подтипы» товара, вы можете добавить больше левых соединений.

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