Лучший способ сгенерировать уникальный идентификатор для группы строк?

#sql #sql-server

#sql #sql-сервер

Вопрос:

Это очень упрощено, но у меня есть массив элементов веб-службы, которые выглядят примерно так:

 [12345, 34131, 13431]
  

и я собираюсь перебирать массив и вставлять их одну за другой в базу данных, и я хочу, чтобы эта таблица выглядела следующим образом. Эти значения будут привязаны к уникальному идентификатору, показывающему, что они были

 1 12345
1 34131
1 13431
  

и затем, если бы появился другой массив, он вставил бы все свои числа с уникальным идентификатором 2 …. в основном это делается для отслеживания групп.

Потенциально это будет выполняться несколькими процессами одновременно, так каков был бы наилучший способ сгенерировать уникальный идентификатор, а также гарантировать, что два процесса не могли использовать один и тот же?

Комментарии:

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

2. Вы изучали использование ПОСЛЕДОВАТЕЛЬНОСТИ? Или вам нужен идентификатор, использующий тип uniqueidentifier?

3. Если он функционирует только как идентификатор группы, вы могли бы использовать фактический guid / uniqueidentifier вместо целочисленного значения.

Ответ №1:

Вы должны исправить свою модель данных. Скажем, отсутствует объект batches .

 create table batches (
    batch_id int identity(1, 1) primary key,
    created_at datetime default getdate()
);
  

У вас может быть и другая информация.

И в вашей таблице должна быть ссылка на внешний ключ, batch_id на batches .

Тогда ваш код должен выполнять следующее:

  • Вставьте новую строку в batches . Начался новый пакет.
  • Извлеките только что созданный идентификатор.
  • Используйте этот идентификатор для строк, которые вы хотите вставить.

Хотя вы могли бы сделать это с помощью последовательности, отдельная таблица имеет для меня больше смысла. Вы связываете кучу строк вместе во что-то. Это что-то должно быть представлено в модели данных.

Комментарии:

1. … и исходная таблица должна определять внешний ключ, указывающий на batches . Трижды приветствую нормализацию! 😀

Ответ №2:

Вы можете объявить это: DECLARE @UniqueID УНИКАЛЬНЫЙ ИДЕНТИФИКАТОР = NEWID();

и используйте это как свой уникальный идентификатор при вставке вашего пакета

Ответ №3:

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

Что-то вроде:

 CREATE PROCEDURE getNextID
     @NextNumber INT          OUTPUT
    ,@id_type    VARCHAR(20)
AS
BEGIN
  SET NOCOUNT ON;

    DECLARE @NextValue TABLE (NextNumber int);

BEGIN TRANSACTION;

    UPDATE id_sequence
      SET last_used_number = ISNULL(@NextNumber, 0)   1
     OUTPUT inserted.last_used_number INTO @NextValue(NextNumber)
    WHERE id_type = @id_type

    SELECT @NextNumber = NextNumber FROM @NextValue

COMMIT TRANSACTION;

END