База непрерывно собирает данные, периодически очищаю таблицу от ненужного старого. У каждой строки, в период времени между чистками, есть уникальный порядковый номер. Номера растут и после очистки нужно бы сдвинуть серийные номера к началу нумерации. При этом убирая "зазоры" в нумерации, зазоры появляются из-за удалений во время чистки.Как эффективнее сделать это?
Мануал Postgresql в разделе "8.1.4. Serial Types" описывает способ создания уникальных серийных номеров для каждой строки в базе.
http://www.postgresql.org/files/documentation/pdf/8.4/postgr...
Например, вот так:
CREATE TABLE tblnm ( sn SERIAL UNIQUE , event_day TIMESTAMP, event_description VARCHAR ) ;
Если есть более подходящий способ нумерации - могу способ из мануала заменить на другой.Сделал вот такой пример, модель того как у меня всё это могло бы работать:
-- очистка примера
DROP TABLE tblnm ;
DROP TABLE tblnm_buffer ;-- создать таблицу, со столбцом 'sn' для серийных номеров
CREATE TABLE tblnm ( sn SERIAL UNIQUE , event_day timestamp ) ;-- заполнить данными три строки примера
INSERT INTO tblnm ( event_day ) VALUES ( timestamp '2010-10-22' ) ;
INSERT INTO tblnm ( event_day ) VALUES ( timestamp '2010-10-22' ) ;
INSERT INTO tblnm ( event_day ) VALUES ( timestamp '2010-10-30' ) ;
-- три записи имеют порядковые/серийные номера
SELECT * FROM tblnm ;-- очистка
DELETE FROM tblnm WHERE event_day < timestamp '2010-10-30' ;-- Сдвиг/сброс номеров с отбросом ненужных данных.
-- Номера будут сдвинуты, но порядок нумерации нарушится.
-- Допустимо, но некрасиво.
-- Причина: SQL в ответе на запрос не гарантирует
-- хронологический порядок строк и, да, порядок бывает другой.
BEGIN ;
-- переименовать таблицу, создать пустую таблицу
ALTER TABLE tblnm RENAME TO tblnm_buffer ;
CREATE TABLE tblnm ( sn SERIAL UNIQUE , event_day timestamp ) ;
-- перенести оставщееся из таблицы старой в новую
INSERT INTO tblnm ( event_day ) SELECT event_day FROM tblnm_buffer;
END ;-- Из старой таблицы запись с номером 3
-- перешла в новую таблицу и новый номер = 1.
-- Т.е. остались только нужные данные и
-- номера сдвинуты к началу нумерации,
-- нумерация оставщихся снова с единицы.
SELECT * FROM tblnm ;Можно сдвиг и уплотнение нумерации, выполнение блока BEGIN-END оптимизировать, ускорить?
>[оверквотинг удален]
> INSERT INTO tblnm ( event_day ) SELECT event_day
> FROM tblnm_buffer;
> END ;
> -- Из старой таблицы запись с номером 3
> -- перешла в новую таблицу и новый номер = 1.
> -- Т.е. остались только нужные данные и
> -- номера сдвинуты к началу нумерации,
> -- нумерация оставщихся снова с единицы.
> SELECT * FROM tblnm ;
убираете sequence с таблицы, если это поле является primary key (что чаще всего), удаляете primary key, убиваете сам sequece.
ставите на таблицу те данные которые быть должны
создаёте новый seq со стартовым +1 от максимального в таблице
привязываете seq
привязываете primary,если необходимо.
постановка задачи -- изврат
Спасибо. Действительно ведь:BEGIN ;
ALTER TABLE tblnm DROP COLUMN sn ;
ALTER TABLE tblnm ADD COLUMN sn SERIAL UNIQUE ;
END;Использование типа serial unique приводит к автоматическому выполнению нужных операций с последовательностями. Как я понимаю.
> Спасибо. Действительно ведь:
>BEGIN ;
> ALTER TABLE tblnm DROP COLUMN sn ;
> ALTER TABLE tblnm ADD COLUMN sn SERIAL UNIQUE ;
> END;
> Использование типа serial unique приводит к автоматическому выполнению нужных операций
> с последовательностями. Как я понимаю.А установить новый текущий номер для последовательности это слишком сложно?
SELECT pg_catalog.setval('ефиду_seq', 12345, true);
>> Спасибо. Действительно ведь:
>>BEGIN ;
>> ALTER TABLE tblnm DROP COLUMN sn ;
>> ALTER TABLE tblnm ADD COLUMN sn SERIAL UNIQUE ;
>> END;
>> Использование типа serial unique приводит к автоматическому выполнению нужных операций
>> с последовательностями. Как я понимаю.
> А установить новый текущий номер для последовательности это слишком сложно?
> SELECT pg_catalog.setval('ефиду_seq', 12345, true);тогда у него при попытке записи случится неприятное -- "поле с таким номером уже существует"
а так-то да -- seq отредактировал и рад.