2013-03-20 2 views
1

Я работаю с базой данных PostgreSQL 8.4.13.
Недавно у меня было около 86,5 миллионов записей в таблице. Я удалил почти все из них - осталось всего 5000 записей. Я побежал:Перезапустить номера первичных ключей существующих строк после удаления большей части большой таблицы

vacuum full 

после удаления строк и вернулся дискового пространства ОС (thx to suggestion from fellow SO member)

Но я вижу, что мои идентификационные номера все еще застряли в миллионы. Для экс:

id |  date_time  | event_id | secs_since_1970 | value 
---------+-------------------------+----------+-----------------+----------- 
61216287 | 2013/03/18 16:42:42:041 |  6 | 1363646562.04 | 46.4082 
61216289 | 2013/03/18 16:42:43:041 |  6 | 1363646563.04 | 55.4496 
61216290 | 2013/03/18 16:42:44:041 |  6 | 1363646564.04 | 40.0553 
61216291 | 2013/03/18 16:42:45:041 |  6 | 1363646565.04 | 38.5694 

В попытке запуска значение id в 1 снова для остальных строк, я попытался:

cluster mytable_pkey on mytable; 

где mytable это имя моего стола. Но это не помогло. Итак, мой вопрос (ы) является/являются:

  1. Есть ли способ, чтобы получить индекс (значение ИН), чтобы начать в 1 раз?
  2. Если я добавлю или обновляю таблицу новой записью, начнется ли она с 1 или возьмет следующее самое высокое целочисленное значение (скажем, 61216292 в приведенном выше примере)?

Описание моего стола выглядит следующим образом: в нем нет ограничений FK и последовательности.

jbossql=> \d mytable; 
      Table "public.mytable" 
Column  |   Type   | Modifiers 
-----------------+------------------------+----------- 
id    | bigint     | not null 
date_time  | character varying(255) | 
event_id  | bigint     | 
secs_since_1970 | double precision  | 
value   | real     | 
Indexes: 
    "mydata_pkey" PRIMARY KEY, btree (id) CLUSTER 
+1

Показать выходные данные '=> \ d mytable' –

+1

Если ваш ПК (серийный номер?) * Не *, на который ссылается FK другой таблицы, вы * можете * попытаться перенумеровать его и сбросить последовательность до MAX (id) , Но я бы не советовал (не нужен и не подвержен несчастным случаям). – wildplasser

+2

Возможно, вам следует изучить смысл терминов ['index'] (http://www.postgresql.org/docs/current/interactive/indexes.html), [' primary key'] (http: // www .postgresql.org/docs/current/interactive/ddl-constraints.html # AEN2493), ['serial'] (http://www.postgresql.org/docs/current/interactive/datatype-numeric.html#DATATYPE- SERIAL) и потенциально также ['foreign key'] (http://www.postgresql.org/docs/current/interactive/ddl-constraints.html#DDL-CONSTRAINTS-FK). –

ответ

2

Отбросьте основной ключ и создайте временную последовательность.

alter table mytable drop constraint mydata_pkey; 
create temporary sequence temp_seq; 

Используйте последовательность обновления:

update mytable 
set id = nextval('temp_seq'); 

Воссоздать первичный ключ и уронить последовательность

alter table mytable add primary key (id); 
drop sequence temp_seq; 

Если есть внешний ключ зависимость от этой таблицы, то вы должны сначала обработайте его, и обновление будет более сложной процедурой.

2

Определяется ли ваш основной ключ с помощью последовательного порта? Если это так, создается неявная последовательность. Вы можете использовать ALTER SEQUENCE (см.: http://www.postgresql.org/docs/8.2/static/sql-altersequence.html для синтаксиса), чтобы изменить начальный номер на 1.

На основании того, что у вас осталось несколько записей (только что заметил 5000 слева), вы НЕ хотите сбросить этот число до номера до последнего идентификатора остальных записей, потому что тогда эта последовательность будет генерировать не уникальные числа. Точка использования последовательности заключается в том, что она дает вам транзакционный способ увеличить число и гарантировать, что последовательные операции получат уникальные инкрементированные числа.

+0

В моей таблице нет последовательности. Редактировал мой вопрос и опубликовал таблицу desc. –

2
DROP SCHEMA tmp CASCADE; 
CREATE SCHEMA tmp ; 
SET search_path=tmp; 

     -- 
     -- Note: "deferrable initially deferred" appears to be the default 
     -- 
CREATE TABLE funky 
     (id SERIAL NOT NULL PRIMARY KEY DEFERRABLE INITIALLY DEFERRED 
     , tekst varchar 
     ); 
     -- create some data with gaps in it 
INSERT INTO funky(id, tekst) 
SELECT gs, 'Number:' || gs::text 
FROM generate_series(1,100,10) gs 
     ; 

     -- set the sequence to the max occuring id 
SELECT setval('funky_id_seq' , mx.mx) 
FROM (SELECT max(id) AS mx FROM funky) mx 
     ; 

SELECT * FROM funky ; 

     -- compress the keyspace, making the ids consecutive 
UPDATE funky xy 
SET id = self.newid 
FROM (
     SELECT id AS id 
     , row_number() OVER (ORDER BY id) AS newid 
     FROM funky 
     ) self 
WHERE self.id = xy.id 
     ; 

     -- set the sequence to the new max occuring id 
SELECT setval('funky_id_seq' , mx.mx) 
FROM (SELECT max(id) AS mx FROM funky) mx 
     ; 

SELECT * FROM funky ; 

Результат:

CREATE TABLE 
INSERT 0 10 
setval 
-------- 
    91 
(1 row) 

id | tekst 
----+----------- 
    1 | Number:1 
11 | Number:11 
21 | Number:21 
31 | Number:31 
41 | Number:41 
51 | Number:51 
61 | Number:61 
71 | Number:71 
81 | Number:81 
91 | Number:91 
(10 rows) 

UPDATE 10 
setval 
-------- 
    10 
(1 row) 

id | tekst 
----+----------- 
    1 | Number:1 
    2 | Number:11 
    3 | Number:21 
    4 | Number:31 
    5 | Number:41 
    6 | Number:51 
    7 | Number:61 
    8 | Number:71 
    9 | Number:81 
10 | Number:91 
(10 rows) 

ПРЕДУПРЕЖДЕНИЕ ПРЕДУПРЕЖДЕНИЕ ПРЕДУПРЕЖДЕНИЕ ПРЕДУПРЕЖДЕНИЕ Achtung:

Изменение ключевых значений, как правило, страшная мысль. Избегайте его любой ценой.