【发布时间】:2018-10-29 09:50:38
【问题描述】:
基本上,我有一个带有唯一城市特征 ID 的 table1,现在我有一个 table2 用于该国家/地区的特征。
我需要为国家表创建新的ID(这些需要与城市共享相同的序列,以便在交叉引用表时ID匹配)
如何使 table2 在该城市中具有与 table1 相同的 id,然后为其他地方的功能设置新的 id?本质上共享序列
编辑:表已经创建,我如何更新 table2
【问题讨论】:
标签: sql postgresql
基本上,我有一个带有唯一城市特征 ID 的 table1,现在我有一个 table2 用于该国家/地区的特征。
我需要为国家表创建新的ID(这些需要与城市共享相同的序列,以便在交叉引用表时ID匹配)
如何使 table2 在该城市中具有与 table1 相同的 id,然后为其他地方的功能设置新的 id?本质上共享序列
编辑:表已经创建,我如何更新 table2
【问题讨论】:
标签: sql postgresql
如果您手动创建一个序列并将其作为默认值分配给 ID 列,那么它就可以工作。但是要重用现有值,这意味着我们必须创建一个触发器来分配现有值或从共享序列中获取新值。
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.
编辑:如果我们可以进行后期处理,那么这种方法可以用于为缺少的 ID 列分配值:
update bar
SET id = coalesce((select id from foo where bar.city_name = foo.city_name),nextval('baz'))
WHERE id is null
【讨论】:
如果你的表已经创建,你必须创建一个序列
create sequence seq_city_country;
然后使用以下代码将序列添加到您的 id 中
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) 为表 city 创建,您可以使用
ALTER TABLE country ALTER COLUMN id_country SET DEFAULT nextval('sequence_c');
【讨论】:
这听起来不像是非常好的(甚至可能的)数据库设计。相反,我建议创建一个连接表,将城市与各自的国家联系起来。因此,您的三个表可能如下所示:
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 分配这些值,然后使用正确的值维护联结表即可。
【讨论】:
id 和 country 表的两个 id 列将是自动递增序列。那么联结表的主键将是来自每个序列的值的组合。
CREATE SEQUENCE shared_seq;
CREATE TABLE a (
col1 bigint DEFAULT nextval('shared_seq'),
...
);
CREATE TABLE b (
col1 bigint DEFAULT nextval('shared_seq'),
...
);
【讨论】: