Как обеспечить последовательную запись данных без пропусков в идентификаторах?

Как создать таблицу с 100 записями, начиная с id 1 и без пропусков в автоинкрементном значении id?
  • 28 января 2024 г. 18:38
Ответы на вопрос 3
Для обеспечения последовательной записи данных без пропусков в идентификаторах (ID), предполагая использование системы управления базами данных (СУБД) с поддержкой автоинкрементных значений, к примеру, MySQL, следует использовать стандартный механизм автоинкремента и создать таблицу с автоинкрементным полем. Механизм автоинкремента в такой СУБД обычно гарантирует, что каждый новый записываемый ID будет на единицу больше предыдущего, начиная с определённого значения (например, 1). 

Вот как можно создать таблицу с автоинкрементным полем ID и затем заполнить её 100 записями:

```sql
-- Создание таблицы с автоинкрементным ID
CREATE TABLE example_table (
  id INT NOT NULL AUTO_INCREMENT,
  some_data VARCHAR(255),
  PRIMARY KEY (id)
);

-- Заполнение таблицы 100 записями
BEGIN;
INSERT INTO example_table (some_data) VALUES ('Data 1');
-- повторить запрос для каждой записи, например, используя цикл в приложении или скрипте
COMMIT;
```

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

В случае использования цикла в SQL, можно воспользоваться процедурой:

```sql
DELIMITER //
CREATE PROCEDURE FillTable()
BEGIN
  DECLARE i INT DEFAULT 1;
  WHILE i <= 100 DO
    INSERT INTO example_table (some_data) VALUES (CONCAT('Data ', i));
    SET i = i + 1;
  END WHILE;
END //
DELIMITER ;

CALL FillTable();
```

Этот SQL-скрипт создаст хранимую процедуру, которая внесёт 100 записей в `example_table`, каждая со своим уникальным и последовательным идентификатором (`id` от 1 до 100) и некоторыми данными (`some_data`).

Важно отметить, что гарантировать отсутствие пропусков в ID можно только в случае, если не происходит удаления строк. При удалении строк из таблицы с автоинкрементным полем возникнут пропуски, так как СУБД не переназначает ID уже существующих записей после удаления.

Если необходимо, чтобы после удаления не было пропусков, необходимо или вообще избегать удаления записей (например, помечать записи как неактивные вместо их удаления), или после удаления проводить операцию перенумерации существующих записей, что может быть ресурсоёмкой операцией и может нарушить ссылочную целостность в случае наличия внешних ключей.
Пример: 

Попробуйте помучить ТГ: @act_chat_bot
Таблицы на основе г енераторов или sequences обычно ствавят главной задачей - обеспечить
уникальность id в первую очередь
. С эти sequence справляется.

Гарантировать блокировку или захват sequence они не могут так как Postgres создавался
как много-пользовательская БД
. Тоесть много сессий обладают правом в любой момент
взять из sequence следующее значение
. Поэтому требование хронологии - это как эксклюзивный
лок объекта. Слишком жесткое требование. И никому не нужное. Если б так БД работали то
они теряли бы в производительности и ждали-бы чтоб какая-то главная сессия отпустила таблицу.

Выход есть - брать ранг записи извне . Тоесть само приложение должно быть поставщиком
таких номеров. А БД будет просто их вставлять.

Еще вариант - в уже после загрузки обновить одно полей одной транзакцией как row_number
сортируя по любому признаку.
Похожие вопросы