2015-11-03 7 views
7

Ich habe eine ziemlich große Tabelle (rund 1 Milliarde Zeilen), und ich muss den ID-Typ von SERIAL zu BIGSERIAL zu aktualisieren; Rate mal, warum?:).postgreSQL gleichzeitig Spalte Typ von Int zu Bigint

Grundsätzlich könnte dies mit diesem Befehl:

execute "ALTER TABLE my_table ALTER COLUMN id SET DATA TYPE bigint" 

meinen Tisch Trotzdem immer, dass sperren würde und über meinen Web-Service setzen.

Gibt es eine ziemlich einfache Möglichkeit, diese Operation gleichzeitig auszuführen (egal wie lange es dauert)?

Antwort

3

Wenn Sie keine Fremdschlüssel haben Sie Ihre ID zeigen Sie könnten neue Spalte hinzufügen, füllen Sie es, fallen alte und benennen abst:

alter table my_table add column new_id bigint; 

begin; update my_table set new_id = id where id between 0 and 100000; commit; 
begin; update my_table set new_id = id where id between 100001 and 200000; commit; 
begin; update my_table set new_id = id where id between 200001 and 300000; commit; 
begin; update my_table set new_id = id where id between 300001 and 400000; commit; 
... 

create unique index my_table_pk_idx on my_table(new_id); 

begin; 
alter table my_table drop constraint my_table_pk; 
alter table my_table alter column new_id set default nextval('my_table_id_seq'::regclass); 
update my_table set new_id = id where new_id is null; 
alter table my_table add constraint my_table_pk primary key using index my_table_pk_idx; 
alter table my_table drop column id; 
alter table my_table rename column new_id to id; 
commit; 
+0

Dank ist diese Lösung recht elegant. Es scheint mir, dass es immer noch ein Problem gibt. Wenn neue Zeilen in unsere Tabelle eingefügt werden, während wir die Spalten new_id füllen, wird der Wert new_id nicht festgelegt und die Erstellung des eindeutigen Index schlägt möglicherweise fehl. Können wir eine Trigger-Einstellung new_id bei der Einfügung hinzufügen, bis wir den nexval-Standardwert hinzufügen? –

+0

Eindeutiger Index ignoriert "Null" -Werte, daher ist kein Trigger erforderlich. –

+0

Was ist, wenn 'alter table my_table Spalte hinzufügen new_id bigint;' dauert lange (es dauert mehr als 1 Stunde und noch nicht fertig), und andere Leseoperationen blockieren? –