Как установить связи между таблицами в базе данных Postgesql, в частности, между таблицей File и другими таблицами?

Как лучше всего организовать структуру базы данных PostgreSQL для связывания таблиц File, Product и Offer? В настоящее время у меня есть таблица File, содержащая данные о конкретных файлах, и две другие таблицы, которые должны иметь доступ к нескольким файлам из таблицы File (например, Product и Offer). Как можно наилучшим образом установить связь между этими таблицами, чтобы избежать создания избыточных полей в таблице File или ненужных связей?
  • 25 января 2024 г. 15:42
Ответы на вопрос 2
Для установления связи между таблицами в PostgreSQL вы можете использовать внешние ключи (foreign keys). Внешний ключ – это колонка (или набор колонок) в одной таблице, которая ссылается на первичный ключ (или уникальный ключ) в другой таблице. Это устанавливает связь типа "один к одному", "один ко многим" или "многие ко многим".

Для связи таблиц `File`, `Product` и `Offer`, возможно, вам понадобится создать связь "многие ко многим", если предположить, что один продукт может иметь множество файлов (например, изображения, документацию, и т.д.), и один файл может быть связан с несколькими продуктами (или предложениями).

Вы можете сделать это, создав связующие таблицы для каждой связи "многие ко многим". Например:

1. Создайте таблицы `Product`, `Offer`, и `File` с их соответствующими столбцами. Убедитесь, что у каждой таблицы есть первичный ключ (обычно это столбец с типом SERIAL или INTEGER с автоинкрементом).

```sql
CREATE TABLE Product (
    product_id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    description TEXT
    -- Другие поля...
);

CREATE TABLE Offer (
    offer_id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    details TEXT
    -- Другие поля...
);

CREATE TABLE File (
    file_id SERIAL PRIMARY KEY,
    file_path VARCHAR(255),
    file_type VARCHAR(50)
    -- Другие поля...
);
```

2. Создайте связующие таблицы: `ProductFile` и `OfferFile`. Каждая связующая таблица будет содержать два внешних ключа (один связан с `File`, другой с `Product` или `Offer`), и вместе они будут составлять составной первичный ключ.

```sql
CREATE TABLE ProductFile (
    product_id INT,
    file_id INT,
    PRIMARY KEY (product_id, file_id),
    FOREIGN KEY (product_id) REFERENCES Product (product_id) ON DELETE CASCADE,
    FOREIGN KEY (file_id) REFERENCES File (file_id) ON DELETE CASCADE
);
-- Связь многие ко многим между Product и File.

CREATE TABLE OfferFile (
    offer_id INT,
    file_id INT,
    PRIMARY KEY (offer_id, file_id),
    FOREIGN KEY (offer_id) REFERENCES Offer (offer_id) ON DELETE CASCADE,
    FOREIGN KEY (file_id) REFERENCES File (file_id) ON DELETE CASCADE
);
-- Связь многие ко многим между Offer и File.
```

В данном случае, использование `ON DELETE CASCADE` гарантирует, что если запись в `Product` или `File` будет удалена, все связанные записи в связующей таблице также будут удалены. Вы можете использовать другие опции, такие как `ON DELETE SET NULL` или `ON DELETE NO ACTION`, в зависимости от ваших требований.

Так как у вас есть связующие таблицы, вам не нужно создавать излишние поля в таблице `File`, и это позволяет устанавливать множественные связи между `Product`, `Offer` и `File`, что является более гибким и надежным решением.
Я бы выбрал вариант с несколькими полями в таблице Files. Он позволяет указать FOREIGN KEY и, соответственно, получить автоматический контроль целостности связей. 
И при отсутствии связи в поле должен быть не 0, а NULL.
Похожие вопросы