powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проектирование простой базы телефонной книги
5 сообщений из 5, страница 1 из 1
Проектирование простой базы телефонной книги
    #39295231
memset
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Реквестирую советы от гуру ER-моделинга. Есть такой скрипт создания БД. В базе таблица subscriber (абонент) связан с таблицей address отношением многие-ко-многим (несколько людей могут жить по одному адресу, один человек в разное время может бить по разным адресам). Первичные ключи в Postgres задаются как SERIAL (автоинкремент). Связь реализована таблицей sub_link. В ней поле sub_id - внешний ключ для sub_id в таблице "абонент".

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

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

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

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
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
);
...
Рейтинг: 0 / 0
Проектирование простой базы телефонной книги
    #39295260
AnSi_Sr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
memset,
1) контроль по КЛАДР ;
2) не всегда удобно работать с сильно нормализованной базой данных, т.е. в данном случае вместо М-М можно подумать над схемой 1-М или даже 1->1.
...
Рейтинг: 0 / 0
Проектирование простой базы телефонной книги
    #39295283
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
memsetПервичные ключи в Postgres задаются как SERIAL (автоинкремент).
Это вы что-то придумали, неверное утверждение.
Конструкция (а не тип) `serial` является обёрткой, которая позволяет определить колонку типа `integer` и повесить на неё последовательность с `DEFAULT` выражением.

Ключи указываются независимо от `serial`, если не указать, то ключа не будет.
...
Рейтинг: 0 / 0
Проектирование простой базы телефонной книги
    #39295303
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
memsetКак устранить проблему с возможностью повторного ввода одного и того же адреса?
Суррогатные ключи не устраняют дубликатов (к чему вы и пришли). При наличии сурогатного ключа, как правило, добавляется ещё хотя бы один уникальный ключ на бизнес данные. В вашем случае — всё, кроме `addr_id`, из таблицы `address`.

memsetКак получить SERIAL ключ только что вставленных записей из первых двух таблиц и не просесть по производительности?
Посмотрите на конструкцию `RETURNING` тут и тут .
...
Рейтинг: 0 / 0
Проектирование простой базы телефонной книги
    #39295692
memset
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я запутался с конструкцией WITH. Прежде всего я создал уникальный ключ на таблице адресов:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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)
);



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

Пытаюсь сделать как-то так:

Код: plsql
1.
2.
3.
4.
WITH t AS (
        INSERT INTO subscriber(name, fname, lname) VALUES ("xxx", "yyy", "zzz")
        RETURNING *
)



Но не понимаю, как при помощи WITH сделать последовательную вставку в несколько таблиц.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проектирование простой базы телефонной книги
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]