Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проектирование простой базы телефонной книги / 5 сообщений из 5, страница 1 из 1
21.08.2016, 23:48
    #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
22.08.2016, 06:04
    #39295260
AnSi_Sr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проектирование простой базы телефонной книги
memset,
1) контроль по КЛАДР ;
2) не всегда удобно работать с сильно нормализованной базой данных, т.е. в данном случае вместо М-М можно подумать над схемой 1-М или даже 1->1.
...
Рейтинг: 0 / 0
22.08.2016, 08:44
    #39295283
vyegorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проектирование простой базы телефонной книги
memsetПервичные ключи в Postgres задаются как SERIAL (автоинкремент).
Это вы что-то придумали, неверное утверждение.
Конструкция (а не тип) `serial` является обёрткой, которая позволяет определить колонку типа `integer` и повесить на неё последовательность с `DEFAULT` выражением.

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

memsetКак получить SERIAL ключ только что вставленных записей из первых двух таблиц и не просесть по производительности?
Посмотрите на конструкцию `RETURNING` тут и тут .
...
Рейтинг: 0 / 0
22.08.2016, 17:18
    #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
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проектирование простой базы телефонной книги / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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