Каково влияние изменения таблицы и превращения столбца Identity в первичный ключ? - PullRequest
1 голос
/ 02 мая 2019

Я исправляю проблемы в новой базе данных, созданной третьей стороной.

СТОРОННОЕ ПРИМЕЧАНИЕ: я только что присоединился к компании, которая первоначально наняла третье лицо. Новой базе данных менее двух недель, и она была запущена в мои первые несколько дней работы.

Эта база данных должна была соответствовать схеме старой базы данных, к сожалению, третья сторона забыла включить несколько ограничений, триггеров и индексов.

Обе базы данных являются SQL Server 2012

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

Текущее производство

CREATE TABLE [dbo].[Table](
    [field] [varchar](255) NULL,
    [data] [varchar](255) NULL,
    [id] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
GO

Таблица из старой базы данных

CREATE TABLE [dbo].[Table](
    [id] [int] NOT NULL,
    [field] [varchar](255) NULL,
    [data] [varchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
  1. Будет ли это серьезно повлиять на изменение производственной таблицы и добавление обратно в первичный ключ вместе с индексом, существующим в старой базе данных? Есть ли руководство по лучшей практике для этого?

  2. Это подходящий sql для изменения производственной таблицы

ALTER TABLE [dbo].[Table] ADD PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
  1. Есть ли программная причина, по которой сторонний разработчик мог бы решить использовать IDENTITY вместо репликации первичного ключа в новой схеме?

РЕДАКТИРОВАТЬ: Мой план основан на рекомендации, приведенной в ответах

Учитывая, что обработка запроса должна быть выполнена, я буду запускать Alters в нерабочие часы. Я решил использовать ALTER вместо очистки таблицы и ее повторного заполнения, основываясь на бизнес-потребностях моей среды.

Я подтвердил, что столбец IDENTITY в настоящее время уникален, используя этот запрос

SELECT DISTINCT(id), COUNT(id)
FROM Table
GROUP BY id
HAVING Count(id) > 1

Если вышеприведенное остается верным, то я буду запускать следующее в непиковые часы:

ALTER TABLE [dbo].[Table] ADD CONSTRAINT PK_Table PRIMARY KEY CLUSTERED
(
    [id] ASC
)

Ответы [ 3 ]

0 голосов
/ 02 мая 2019

Столбец идентификации в SQL Server не гарантированно является уникальным.В документации четко указано:

Свойство удостоверения в столбце не гарантирует следующее:

  • Уникальность значения - уникальность должна бытьобеспечивается применением ограничения PRIMARY KEY или UNIQUE или индекса UNIQUE.

Столбцы идентификаторов почти всегда объявляются первичными ключами, но они необязательно должны быть.

Во-вторых, если вы сделаете столбец первичным ключом, то он обычно будет кластеризованным (если другой кластеризованный индекс уже не существует).Как объясняется в документации :

При создании первичного ключа автоматически создается соответствующий уникальный кластеризованный индекс или некластеризованный индекс, если он указан как таковой.

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

Может оказаться более производительным очистить таблицу, добавить правильные ограничения и повторнозагрузить данные.

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

0 голосов
/ 02 мая 2019

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

Присвойте имя первичному ключу вместо анонимного имени, генерируемого системой.

Подумайте, какова цель таблицы и данных? Где это используется?

0 голосов
/ 02 мая 2019
  1. Добавление CLUSTERED INDEX к таблице является дорогостоящим.Это приведет к переупорядочению страниц, что означает интенсивный ввод-вывод, что в зависимости от таблицы может занять некоторое время.Скорее всего, это приведет к блокировке таблицы на некоторое время.
  2. Да, это правильный синтаксис, однако я рекомендую дать вашему ключу имя.Это меняет синтаксис на:

    ALTER TABLE [dbo].[SampleTable] ADD CONSTRAINT PK_SampleTable PRIMARY KEY CLUSTERED (ID ASC);

  3. Я не могу отвечать за решения других людей, я боюсь.

...