更改表中主键的条目以匹配 COUNT Postgresql 中的行数

问题描述 投票:0回答:1

我们有下表的定义

CREATE TABLE Log
(
    LogId             serial      not null,
    JobId             integer     not null,
    Time              timestamp   without time zone,
    LogText           text        not null,
    primary key (LogId)
);
create index log_name_idx on Log (JobId);

LogId 已达到串行最大值(20 亿) 我们必须手动删除较旧的条目并清理表,因为我们从 PostgreSQL 日志中收到以下错误

##ERROR:  integer out of range
##STATEMENT:  INSERT INTO Log (JobId, Time, LogText) VALUES .....

整数指的是 LogId,因为它已达到最大正整数/serial4 值 2,147,483,647。

现在我们遇到以下问题: logid 列(也是主键)的最新条目最大为 (2,147,483,647)。 我们希望重新创建主键列的条目,以便它与该表的行数匹配。这个数字是 953,811,856。仍然很大,但如果这个问题得到解决,我们可以自动化删除和清理表的过程。

在删除和真空之后,几乎一半的条目及其匹配的主键被删除,如果您愿意,我们希望“重新对齐”主键与表的其余剩余值,这意味着我们希望表中最旧的剩余条目的 LogID 字段上的数字为 1,并将其增加到最新的行条目,达到 953811856。

请注意,LogId 是串行数据类型,我不知道为什么我们从日志中得到的错误引用了一个整数。最好的客人,因为整数和序列4具有相同的最大值。

我们尝试在测试环境中将串行序列更改为 1,即使这有效并且在表中添加了新条目,最终也会在主键中创建重复条目,因为我们尚未完全删除所有先前条目来自 LogId 列。

postgresql primary-key
1个回答
0
投票

切换到

bigserial
/
bigint generated by default as identity
- 这将使您的限制达到
9223372036854775807
演示:

alter table log alter column LogId type bigint;
select pg_get_serial_sequence('public.log','logid');
alter sequence public.log_logid_seq as bigint;

或者,切换到

identity
:

alter table log alter column LogId type bigint;
alter table log alter column LogId drop default;
alter table log alter column LogId 
  add generated by default as identity;

与完全更改类型或添加另一列来构建多列主键相比,这里的好处是指向该表的所有外键列保持不变。您可以查找它们并在另一步骤中切换到 bigint。

在表定义中指定类型

serial
仅意味着
int
您希望Postgres为其创建和维护序列 - 它不是真正不同的类型,所以您的猜测

最佳猜测,因为integer 和serial4 具有相同的最大值。

是对的。

bigserial
的情况也类似:同样的事情,但是
bigint

定期

vacuum
、重新编号和倒带序列的想法听起来很危险,因为它必须级联各处的引用。任何外部引用或内部弱链接(用于保存外键但没有
references
约束的列)都会中断。切换到
bigint
,您可以完整保留所有标识符和对它们的所有引用。

© www.soinside.com 2019 - 2024. All rights reserved.