2016-08-17 130 views
1

每次執行INSERT或UPSERT(ON CONFLICT UPDATE)時,每個表上的增量列會增加之前更新的次數。PostgreSQL在每次更新時自動增加

舉例來說,如果我有這個表:

id int4 
title text 
description text 
updated_at timestamp 
created_at timestamp 

然後運行這些查詢:

INSERT INTO notifications (title, description) VALUES ('something', 'whatever'); // Generates increments ID=1 

UPDATE notifications title='something else' WHERE id = 1; // Repeat this query 20 times with different values. 

INSERT INTO notifications (title, description) VALUES ('something more', 'whatever again'); // Generates increments ID=22 

這是一個相當大的問題。我們正在運行的腳本每天處理超過100,000個通知。這可以在每個插入之間創建大約10,000的間隔,所以我們可能從100行開始,但當我們達到1,000行時,我們有一個自動遞增的主鍵ID值超過100000的最後一行。

如果這種情況繼續發生,我們將快速耗盡表上的自動增量值。

我們的PostgreSQL服務器是否配置錯誤?使用Postgres 9.5.3。

我正在使用Eloquent Schema Builder(例如$table->increments('id'))來創建表格,我不知道這與它有什麼關係。

+0

「*如果這種情況持續,我們會很快耗盡我們表格上的自動增量值*」我懷疑這一點。如果你每秒鐘燒錄10,000個** ** 24/7(沒有任何停頓),那麼需要29.247.120年才能用完(bigint)值 –

回答

5

無論什麼時候嘗試插入,序列都會增加,而不管它是否成功。一個簡單的update(在你的例子中)將不會增加它,但insert on conflict update將因insertupdate之前嘗試。

一個解決方案是將id更改爲bigint。另一種方法是不要使用序列並自己管理它。而另一家是做手工UPSERT:

with s as (
    select id 
    from notifications 
    where title = 'something' 
), i as (
    insert into notifications (title, description) 
    select 'something', 'whatever' 
    where not exists (select 1 from s) 
) 
update notifications 
set title = 'something else' 
where id = (select id from s) 

這個假設title是獨一無二的。

相關問題