Если я отброшу свой кластерный ПК и добавлю новый, в каком порядке будут располагаться мои строки?
В SQL Server я смотрю на TableA, который в настоящее время имеет кластерный первичный ключ с уникальным идентификатором. GUID не имеет значения ни в каком контексте.
(Я дам вам секунду, чтобы почистить клавиатуру, монитор и установить газировку.)
Я хотел бы удалить этот первичный ключ и добавить новый уникальный целочисленный первичный ключ в таблицу. Мой вопрос заключается в следующем: когда я удаляю индекс, изменяю столбец с uniqueidentifier на int и добавляю новый кластеризованный уникальный первичный ключ в измененный столбец, будут ли новые значения PK в порядке вставки в таблицу или они будут быть в каком-то другом порядке? Это правильный путь сюда? Будет ли это работать? (Я вроде как новичок в отношении создания / модификации таблицы.)
4 ответа
Когда вы отбрасываете кластеризованный индекс, таблица становится кучей. Поскольку кучи имеют очень отличную физическую структуру от индексов, данные должны быть скопированы в новую структуру. Кучи не имеют никакого порядка вообще. Когда вы добавляете обратно новый кластеризованный индекс, данные будут скопированы из кучи в новый индекс, и порядок будет определяться новым кластеризованным ключом.
Если вы хотите сохранить существующий порядок, все, что вам нужно сделать, это правильно назначить новые целочисленные идентификаторы:
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 будет соответствовать порядку направляющих. Вы можете удалить столбец Guid и добавить кластеризованный индекс в новый столбец Integer, и физический порядок записей будет сохранен.
По определению кластеризованный индекс налагает физический порядок на реальные страницы данных; так что, да, если вы отбросите кластерный индекс и создадите новый, это приведет к физическому переупорядочению данных.
В вашем случае, я думаю, можно с уверенностью предположить, что произойдет следующее:
- Существующий кластерный индекс будет удален, но фактические данные на диске не будут перемещаться из-за этого.
- Вы измените тип столбца (или удалите существующий столбец и создадите новый), установив для него значения цены, чтобы они не были нулевыми, уникальными, первичными ключами, идентификационными данными и автоинкрементами (это жизненно важно, иначе SQL Server даже не позволит вам добавьте это, поскольку это не будет знать, что поместить в это).
- На этом этапе столбец будет автоматически заполнен SQL Server. Я не знаю точно, что здесь произойдет, но я думаю, что это будет заполнено в том порядке, в котором строки физически хранятся в базе данных. Но я просто догадываюсь об этом.
- Проблема в том, что при использовании UID порядок может быть довольно грязным; так что вы не знаете, как на самом деле хранятся данные сейчас, и вы не знаете, как они будут храниться позже; если мои предположения о заполнении столбцов верны, не будет большого переупорядочения... но это может произойти; и, даже если я прав, создание индекса в любом случае займет некоторое время, если таблица достаточно велика.
Итог: вы будете иметь огромное влияние, и вы можете получить строки из неупорядоченного SELECT в том же порядке, в котором вы их получили сейчас. Вам придется попробовать.
Если вы создадите таблицу с кластеризованным первичным ключом, а затем отбросите кластеризованный PK, физический порядок данных в таблице будет без изменений. Однако физический порядок результатов запроса не обязательно будет таким же, как порядок в таблице, поэтому этот порядок довольно бессмысленный.
Если затем добавить столбец целых чисел и создать кластерный первичный ключ для этого, таблица будет переупорядочена в любом порядке, в котором сортируется ключ. Это может быть, а может и не совпадать с физическим порядком, указанным в GUID, в зависимости от того, как назначен ключ. Вы можете явно назначить его в зависимости от порядка сортировки ключа GUID (например, используя row_number() поверх старого порядка ключей), или вы можете назначить его другим способом. Если вы не предпримете шаги, чтобы убедиться, что порядок явно сделан таким же, физический порядок или строки в таблице не гарантируют порядок вашего нового ключа.
Кластерный индекс по определению определяет физический порядок данных, поэтому при создании нового кластеризованного индекса данные будут переупорядочены; если это большой стол, планируйте это на некоторое время.