Если я удалю свой кластеризованный первичный ключ и добавлю новый, в каком порядке будут мои строки?

Если я удалю свой кластеризованный первичный ключ и добавлю новый, в каком порядке будут мои строки?

В SQL Server я смотрю на TableA, которая в данный момент имеет кластеризованный первичный ключ uniqueidentifier. GUID не имеет значения ни в каком контексте.

(Я дам вам секунду, чтобы вы почистили клавиатуру и монитор и поставили газировку.)

Я хотел бы удалить этот первичный ключ и добавить новый уникальный целочисленный первичный ключ в таблицу. У меня такой вопрос: когда я удаляю индекс, изменяю столбец с uniqueidentifier на int и добавляю новый кластеризованный уникальный первичный ключ в измененный столбец, будут ли новые значения PK в порядке вставки в таблицу или в каком-то другом порядке? Правильный ли это способ? Будет ли это работать? (Я немного нубкин в отношении создания/изменения таблиц.)

решение1

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

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

ALTER TABLE Table ADD Integer_Id INT;
GO

WITH cte AS (
  SELECT ROW_NUMBER() OVER (ORDER BY Guid_Id) as RowOrderByGuid,
    Guid_Id
  FROM Table)
UPDATE t
  SET t.Integer_Id = c.RowOrderByGuid
FROM Table t
JOIN cte c ON t.Guid_Id = c.Guid_Id;

Теперь порядок Integer_Ids будет соответствовать порядку Guids. Вы можете удалить столбец Guid и добавить кластеризованный индекс на новый столбец Integer, и физический порядок записей будет сохранен.

решение2

По определению кластеризованный индекс накладывает физический порядок на фактические страницы данных; поэтому, да, если вы удалите кластеризованный индекс и создадите новый, это приведет к физическому переупорядочению данных.

В вашем случае, я думаю, можно с уверенностью предположить следующее:

  • Существующий кластеризованный индекс будет удален, но из-за этого реальные данные на диске не будут перемещены.
  • Вы измените тип столбца (или удалите существующий столбец и создадите новый), установив ограничения, чтобы он не был нулевым, уникальным, первичным ключом, идентификационным и автоинкрементным (это крайне важно, иначе SQL Server даже не позволит вам добавить его, поскольку не будет знать, что в него поместить).
  • В этот момент столбец будет автоматически заполнен SQL Server. Я не знаю наверняка, что здесь произойдет, но ядуматьон будет заполнен в том порядке, в котором строки физически хранятся в базе данных. Но я только предполагаю об этом.
  • Проблема в том, что упорядочивание может быть довольно запутанным, когда задействованы UID; поэтому вы не знаете, как данные хранятся сейчас, и не знаете, как они будут храниться позже; если мои догадки о заполнении столбцов верны, то существенного переупорядочивания не произойдет... но это может произойти; и даже если я прав, построение индекса в любом случае займет некоторое время, если таблица достаточно большая.

Итог: выволяиметь огромное влияние, и вымогполучить строки из неупорядоченного SELECT в том же порядке, в котором вы получаете их сейчас. Вам придется попробовать.

решение3

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

решение4

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

Если затем добавить столбец целочисленного типа и создать на нем кластеризованный первичный ключ, таблица будет переупорядочена в том порядке, в котором сортирует ключ. Это может быть или не быть тот же физический порядок, что и GUID, в зависимости от того, как назначен ключ. Вы можете явно назначить его на основе порядка сортировки ключа GUID (например, используя row_number() поверх старого порядка ключей), или вы можете назначить его каким-то другим способом. Если вы не предпримете шагов для обеспечения того, чтобы порядок был явно сделан таким же, физический порядок или строки в таблице не гарантированно будут определять порядок вашего нового ключа.

Связанный контент