我有一个数据库,其中所有内容都与外键相关联,因此Postgres确切知道数据库是如何布局的。
好吧,我们说我有Table1和Table2。
表1有3个字段。 RID,table2_rid,数据
因此table1.table2_rid引用table2.RID,这用外键表示。在RID
字段中都是主键,并且是串行类型。
我想知道的是如何“压缩”主键?比如说你添加5条记录并删除了3号记录。你的主键看起来像是
1
2
4
5
那么,如何在任何地方进行更新,以便将主键(和相应的外键)压缩到
中1
2
3
4
答案 0 :(得分:2)
最好是主键永远不会改变:重新编号是PITA。
如果你需要一个人类身份证,一个没有差距的人,A。Elein Mustain会显示how to create a gapless sequence。
答案 1 :(得分:1)
查看on update cascade
和on delete cascade
。
create table table_1 (
id integer
primary key,
name char(30)
);
create table table_2 (
id integer
primary key,
table_1_id integer
references table_1
on update cascade
on delete cascade,
detail char(30)
);
答案 2 :(得分:1)
除了非常罕见的情况,PK序列中的差距恰到好处,意图摆脱它们是一个坏主意。
答案 3 :(得分:1)
您可能不希望这样做,gapless sequences are problematic for performance。
如果您想稍后执行清理步骤,可以使用rank()
窗口功能来达到预期的效果。
CREATE TABLE table1 (id integer primary key);
INSERT INTO table1 values (1),(2),(4),(5);
CREATE TABLE table2 (
id serial primary key,
rid integer references table1(id) ON UPDATE CASCADE
);
insert into table2 (rid) values (1),(1),(4),(4),(4),(5);
UPDATE table1
SET id = gapless_id
FROM (
SELECT *, row_number() OVER () FROM table1
) AS x(old_id, gapless_id)
WHERE id = x.old_id;
结果:
regress=# select * from table1 ;
id
----
1
2
3
4
(4 rows)
如果你的FK不是ON UPDATE CASCADE
,你可以ALTER TABLE
来制作它们。这将是非常缓慢的,特别是如果外键上没有索引。更快的方法是在两次通过中进行更改:
LOCK TABLE table1;
row_number()
使用新ID填充它,如上所示new_id
id
new_id
列重命名为id