Как сделать так, чтобы таблица разделяла последовательность с другой таблицей в postgresql? - PullRequest
0 голосов
/ 29 октября 2018

В основном у меня есть таблица1 с уникальными идентификаторами функций для города, теперь у меня есть таблица2 для функций для этой страны.

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

Как заставить table2 иметь те же идентификаторы, что и table1 в этом городе, а затем новые идентификаторы для функций в других местах? По существу разделяю последовательность

Редактировать: таблицы уже созданы, как я могу обновить table2

Ответы [ 4 ]

0 голосов
/ 29 октября 2018

если ваши таблицы уже созданы, вы должны создать последовательность

create sequence seq_city_country;

, а затем добавьте последовательность к своим идентификаторам со следующим кодом

ALTER TABLE city ALTER COLUMN id_city SET DEFAULT nextval('seq_city_country');
ALTER TABLE country ALTER COLUMN id_country SET DEFAULT nextval('seq_city_country');

если ваша последовательность уже создана для таблицы города с помощью (sequence_c), вы можете использовать

  ALTER TABLE country ALTER COLUMN id_country SET DEFAULT nextval('sequence_c');
0 голосов
/ 29 октября 2018

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

create sequence baz;

create table foo(id bigint default nextval('baz'), value text);

create table bar(id bigint default nextval('baz'), value date);

insert into foo (value) values ('Hello');
insert into bar (value) values (now());
insert into foo (value) values ('World');
insert into bar (value) values (now());

select 'foo', id, value::text from foo 
union all
select 'bar', id, value::text from bar

И результат:

foo 1   Hello
bar 2   2018-10-29
foo 3   World
bar 4   2018-10-29

И в качестве бонуса:

drop sequence baz

ERROR: cannot drop sequence baz because other objects depend on it
  Detail: 
    default for table foo column id depends on sequence baz
    default for table bar column id depends on sequence baz
  Hint: Use DROP ... CASCADE to drop the dependent objects too.

Редактировать: Если мы можем выполнить постобработку, то этот подход можно использовать для назначения значений для отсутствующих столбцов идентификаторов:

update bar
SET id = coalesce((select id from foo where bar.city_name = foo.city_name),nextval('baz'))
WHERE id is null
0 голосов
/ 29 октября 2018
CREATE SEQUENCE shared_seq;

CREATE TABLE a (
   col1 bigint  DEFAULT nextval('shared_seq'),
   ...
);

CREATE TABLE b (
   col1 bigint  DEFAULT nextval('shared_seq'),
   ...
);
0 голосов
/ 29 октября 2018

Это не похоже на очень хороший (или даже возможный) дизайн базы данных. Вместо этого я предлагаю создать соединительную таблицу, которая связывает города с соответствующими странами. Итак, ваши три таблицы могут выглядеть так:

city (PK id, name, ...)
country (PK id, name, ...)
country_city (city_id, country_id)  PK (city_id -> city(id), country_id -> country(id))

При таком дизайне вам не нужно беспокоиться о последовательностях автоматического увеличения в таблицах city и country. Просто позвольте Postgres назначить эти значения, а затем просто поддерживайте таблицу соединений, используя правильные значения.

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