Как добавить столбец идентификаторов в существующую таблицу базы данных с большим количеством строк - PullRequest
6 голосов
/ 23 августа 2011

У меня есть таблица базы данных, в которой ~ 40 000 000 строк.Я хочу добавить столбец идентификации в эту таблицу.Как сделать это в удобной для журнала форме?

Когда я делаю следующее:

ALTER TABLE table_1
  ADD id INT IDENTITY

это просто заполняет все пространство журнала.

Есть ли какие-либоспособ сделать это в дружественной манере?База данных находится на SQL Server 2008.

Спасибо, Мохан.

Ответы [ 3 ]

4 голосов
/ 23 августа 2011

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

  1. Добавить столбец с целыми числами без идентификаторов (метаданные)только изменить).
  2. Напишите код, чтобы обновить его уникальными последовательными целыми числами в пакетах.Это уменьшит размер каждой отдельной транзакции и уменьшит размер журнала (при условии простой модели восстановления).Мой код ниже делает это партиями по 100, надеюсь, у вас есть существующий ПК, который вы можете использовать, чтобы выбрать, где вы остановились, вместо повторных сканирований, которые будут все больше и больше дойти до конца.
  3. используйте ALTER TABLE ... ALTER COLUMN, чтобы пометить столбец как NOT NULL.Это потребует, чтобы вся таблица была заблокирована и отсканирована для проверки изменений, но не требовала большого количества регистрации.
  4. Используйте ALTER TABLE ... SWITCH, чтобы сделать столбец идентичным столбцом.Это только метаданные изменения.

Пример кода ниже

/*Set up test table with just one column*/

CREATE TABLE table_1 ( original_column INT )
INSERT  INTO table_1
        SELECT DISTINCT
                number
        FROM    master..spt_values



/*Step 1 */
ALTER TABLE table_1 ADD id INT NULL



/*Step 2 */
DECLARE @Counter INT = 0 ,
    @PrevCounter INT = -1

WHILE @PrevCounter <> @Counter 
    BEGIN
        SET @PrevCounter = @Counter;
        WITH    T AS ( SELECT TOP 100
                                * ,
                                ROW_NUMBER() OVER ( ORDER BY @@SPID )
                                + @Counter AS new_id
                       FROM     table_1
                       WHERE    id IS NULL
                     )
            UPDATE  T
            SET     id = new_id
        SET @Counter = @Counter + @@ROWCOUNT
    END


BEGIN TRY;
    BEGIN TRANSACTION ;
     /*Step 3 */
    ALTER TABLE table_1 ALTER COLUMN id INT NOT NULL

    /*Step 4 */
    DECLARE @TableScript NVARCHAR(MAX) = '
    CREATE TABLE dbo.Destination(
        original_column INT,
        id INT IDENTITY(' + CAST(@Counter + 1 AS VARCHAR) + ',1)
        )

        ALTER TABLE dbo.table_1 SWITCH TO dbo.Destination;
    '       

    EXEC(@TableScript)


    DROP TABLE table_1 ;

    EXECUTE sp_rename N'dbo.Destination', N'table_1', 'OBJECT' ;


    COMMIT TRANSACTION ;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 
        ROLLBACK TRANSACTION ;
    PRINT ERROR_MESSAGE() ;
END CATCH ;
1 голос
/ 17 декабря 2015

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

1 голос
/ 20 июля 2012

Существует два способа добавления столбца идентификаторов в таблицу с существующими данными:

  1. Создайте новую таблицу с идентификатором, скопируйте данные в эту новую таблицу, затем удалите существующую таблицу, а затем переименуйте временную таблицу.

  2. Создание нового столбца с идентификатором и удаление существующего столбца

Ссылка: http://cavemansblog.wordpress.com/2009/04/02/sql-how-to-add-an-identity-column-to-a-table-with-data/

...