Переход от int к GUID в качестве первичных ключей

Я использую несколько ссылочных таблиц с целочисленными первичными ключами. Теперь я хочу изменить int на GUID, оставив все ссылки нетронутыми. Как это сделать проще всего?

Спасибо!

Добавление

Я понимаю процесс в целом, поэтому мне нужны более подробные советы, например, как заполнить новый столбец GUID. Использование значения по умолчанию newid () правильно, но что делать с уже существующими строками?

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

DdW 08.02.2017 11:44
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
9
1
3 441
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Во первых: Господи, почему?!?!?

Во-вторых, вам нужно сначала добавить столбец GUID во все таблицы, а затем заполнить их на основе значения int. После этого вы можете установить идентификаторы GUID для первичных / внешних ключей, а затем удалить столбцы int.

Чтобы обновить значение, сделайте что-то вроде

  1. Установите новые идентификаторы GUID в таблице первичных ключей
  2. Запустите это:

.

UPDATE foreignTable f
SET f.guidCol = p.guidCol
FROM primaryTable p
WHERE p.intCol = f.intCol

Я согласен с Гленном. Я бы придерживался целых чисел для ПК. Используйте bigints, если вам нужно больше записей. Если вам нужен глобальный идентификатор, используйте что-то вроде URI для вторичного ключа и придерживайтесь целых чисел для PK.

Mark Cidade 26.09.2008 11:45

Но как установить новые идентификаторы GUID в таблице первичных ключей?

Alexander Prokofyev 26.09.2008 12:24

2 Александр Прокофьев: Установите для всех столбцов PK "guid" стандартную клаузулу "newid ()". 2 marxidad: использование Guid вместо (большого) int очень полезно, если вам нужно создать каскадные записи в среде, отличной от DB (например, приложение winforms).

TcKs 26.09.2008 12:43

2 TcKs: А как насчет старых записей, где GUID имеют нулевые значения?

Alexander Prokofyev 26.09.2008 13:05

ОБНОВЛЕНИЕ some_table SET some_guid_column = newid () ГДЕ some_guid_column IS NULL

TcKs 26.09.2008 13:59

Гленн, есть несколько сценариев, когда вам нужен уникальный идентификатор в качестве первичного ключа, например: Microsoft Sync Framework или любой проект, в котором вам нужно синхронизировать главную базу данных с несколькими базами данных клиентов. Кстати: вот почему я подхожу к этому SO-вопросу, у меня есть одна основная база данных с int в качестве первичного ключа, но теперь мне нужно развернуть несколько клиентских баз данных и синхронизировать их с главной базой данных.

Alexandre 01.04.2015 19:56

Да, я с Гленном ... На самом деле я не решался опубликовать то же самое, прежде чем он опубликовал это ...

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


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

Отличным примером гибкости является использование имен пользователей в качестве первичного ключа. Даже если они уникальны, приятно иметь возможность их изменить. Что, если пользователи используют адрес электронной почты в качестве имени пользователя? Возможность изменить имя пользователя и не повлиять на все ваши запросы - большой плюс, и я подозреваю, что то же самое может быть верно и с вашими GUID ....

У меня лучший опыт использования специального значения для PK. Потому что тогда нет проблем с изменением какого-либо значения в записи (например, из-за того, что пользователь допустил опечатку).

TcKs 26.09.2008 12:03

Я думаю, это нужно делать вручную. Или вы можете написать для него какую-нибудь утилиту. Сценарий должен быть:

  • Дублируйте столбцы PK / FK "int" с новыми столбцами "guid".
  • Создает новые значения для столбцов PK "guid".
  • Обновите значения в столбцах FK "guid" с указанными значениями (вы найдете записи через PK "int").
  • Удалите ссылки (отношения) с "int" столбцами PK / FK.
  • Создайте аналогичные ссылки (отношения) с "guid" столбцами PK / FK.
  • Удалите столбцы "int" PK / FK.
Ответ принят как подходящий
  • Создайте новый столбец для руководства значение в главной таблице. Использовать тип данных uniqueidentifier, сделайте это не null со значением по умолчанию newid (), поэтому все существующие строки будут заполнены.
  • Создать новые столбцы uniqueidentifier в дочерних таблицах.
  • Запустите операторы обновления, чтобы построить отношения гильдии, используя существующие отношения int для ссылки на сущности.
  • Отбросьте исходные столбцы int.

Кроме того, оставьте немного места на страницах данных / индексов (укажите fillfactor <100), поскольку идентификаторы не являются последовательными, как столбцы идентификаторов int. Это означает, что вставки могут быть где угодно в диапазоне данных и вызовут разделение страниц, если ваши страницы заполнены на 100%.

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

Раньше у меня была сомнительная привилегия делать это, и в основном мне пришлось экспортировать всю чертову базу данных в XML. Затем у меня было приложение Java, которое использует функцию nextLong () java.util.Random для замены первичного ключа их новыми ключами guid. После этого я импортировал все обратно в базу данных.

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

Это очень хороший выбор. Я перешел с longs на UUID для одного из своих приложений и не жалею об этом. Если вы используете MS SQL Server, он включен в стандарт (я использую postgresql, и он входит в стандарт только с версии 8.3).

Как упоминалось в Гленн Славен, вы можете воссоздать UUID из ключей, которые есть в ваших текущих записях. Имейте в виду, что они не будут уникальными, но так легко сохранить отношения нетронутыми. Новые записи, которые вы создадите после переезда, будут уникальными.

НЕ ДЕЛАЙТЕ ЭТО! Мы начали с использования GUID, а теперь почти закончили переход на INT как PK; мы сохраняем GUID для целей ведения журнала (и для некоторых таблиц, например, «обсуждаемой реляционной целостности»;)), но увеличение скорости использования int было феноменальным.

Это стало действительно очевидным только тогда, когда количество строк в таблице перешло в миллионы, заметьте.

Нашей самой большой глупостью было использование NEWID () в качестве PK нашей (последовательной) таблицы журнала - когда мы осознали нашу ошибку, мы сильно огорчились.

Может некорректные показатели? Разве у вас не был кластерный индекс на guid PK вместо лучшего FK. Часто это ошибка.

TcKs 26.09.2008 14:02

Другие вопросы по теме