Проектирование простой базы адресной книги

Есть такой скрипт создания БД. В базе таблица subscriber (абонент) связан с таблицей address отношением многие-ко-многим (несколько людей могут жить по одному адресу, один человек в разное время может бить по разным адресам). Первичные ключи в Postgres задаются как SERIAL (автоинкремент). Связь реализована таблицей sub_link. В ней поле sub_id - внешний ключ для sub_id в таблице "абонент".

При добавлении записей в каком заполнять таблицы? Сначала создать запись в таблице абонента, потом в таблице адреса, и только затем заполнять таблицу связи?

Как устранить проблему с возможностью повторного ввода одного и того же адреса? На клиенте проверять ввод и предлагать связать нового абонента с существующим адресом?

При добавлении записей в таблицы subscriber и address надо настроить таблицу связи и создать там запись (ид абонента, ид адреса). Как получить SERIAL ключ только что вставленных записей из первых двух таблиц и не просесть по производительности?

CREATE TABLE phone
(
    phone_id SERIAL PRIMARY KEY,
    phone    CHAR(15),
    sub_id   INT,   -- subscriber id --
    cat_id   INT    -- category id --
);
 
CREATE TABLE category
(
    cat_id   SERIAL PRIMARY KEY,    -- category id --
    cat_name CHAR(15)       -- category name --
);
 
CREATE TABLE  subscriber
(
    sub_id  SERIAL PRIMARY KEY,
    name    CHAR(20),
    fname   CHAR(20),   -- first name --
    lname   CHAR(20),   -- last name --
);
 
CREATE TABLE address
(
    addr_id       SERIAL PRIMARY KEY,
    country       CHAR(20),
    city          CHAR(20),
    street        CHAR(20),
    house_num     INT,
    apartment_num INT
);
 
-- many-to-many relation --
CREATE TABLE sub_link
(
    sub_id   INT REFERENCES subscriber(sub_id),
    addr_id  INT
);

Это был первоначальный вариант. Потом я создал ключ на таблице адресов:

CREATE TABLE address
(
        addr_id       SERIAL PRIMARY KEY,
        country       CHAR(20),
        city          CHAR(20),
        street        CHAR(20),
        house_num     INT,
        apartment_num INT,
        UNIQUE (country, city, street, house_num, apartment_num)
);

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

Как решить эту проблему?

Опции просмотра комментариев

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

Проверяйте наличие значения

Проверяйте наличие значения до вставки. Обычная и нормальная практика.

Как устранить проблему с

Как устранить проблему с возможностью повторного ввода одного и того же адреса? На клиенте проверять ввод и предлагать связать нового абонента с существующим адресом? - Unique - нормальный вариант, с обработкой исключения.

При добавлении записей в таблицы subscriber и address надо настроить таблицу связи и создать там запись (ид абонента, ид адреса). Как получить SERIAL ключ только что вставленных записей из первых двух таблиц и не просесть по производительности? - Insert returning в помощь

Опции просмотра комментариев

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

Back to top

(С) Виктор Вислобоков, 2008-2023