Идентификационные столбцы или UDF, который явно генерирует уникальный идентификатор?

11

Я нахожусь в середине дискуссии о том, что лучше сделать PRIMARY KEYиз Identity Columns , нашу из UDF, которая явно генерирует уникальный идентификатор.

  • Я выступаю за колонку идентичности.
  • Мой партнер выступает за создание значений вручную, утверждает он
    • положив UDF на другой стол, где мы можем иметь UDF
      • заблокировать ресурс
      • увеличить таблицу ID с одним полем называется ID_Valueпутем1
      • использовать это как глобальный уникальный идентификатор
    • Или сделать таблицу id+1при вставке
    • Что проще перемещать данные между серверами и / или средами, не имеющими ограничения идентификации; перемещение из одной БД, где есть данные, в другую аналогичную БД с, скажем, промежуточными или фиктивными данными. Для тестирования в непроизводственной сфере мы можем захотеть перенести все записи со вчерашнего дня на подготовительную для тестирования.

Какая реализация имеет больше смысла?

kacalapy
источник

Ответы:

21

Твой коллега идиот.

Решение не будет масштабируемым, UDF не является одновременным ( та же причина, что и эта ). И как вы справляетесь с многострочными вставками: для этого потребуется вызов UDF на строку

А миграция на другие RDBMS не часто происходит в реальной жизни ... вы также можете не использовать SQL Server сейчас и использовать последовательности в Oracle и надеяться, что вы не мигрируете.

Редактировать:

В вашем обновлении говорится, что перемещение данных предназначено для обновления непроизводственных баз данных.

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

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

ГБН
источник
11

Используйте значение личности. Генерация вашей собственной таблицы последовательности и значений последовательности потребует больших затрат ресурсов и вызовет много блокировок и блокировок при попытке генерирования чисел.

Идентичность существует по причине, используйте ее.

Когда выйдет SQL Denali, он будет поддерживать последовательности, которые будут более эффективными, чем идентичность, но вы не сможете создать что-то более эффективное самостоятельно.

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

mrdenny
источник
Если вы переходите от «производства» к «тестированию» и имеете поле идентификации, вы рискуете перезаписать или столкнуть данные. Это все, что я говорю. Да, это не должно быть проблемой в этом направлении, но я просто говорю, что это может произойти.
Jcolebrand
Правда, у вас будет одинаковое число для разных значений строк в dev, test, qa, uat и production. Ну и что? Если эти значения важны (например, для справочной таблицы), то жестко запрограммируйте их вручную, что не должно быть проблемой, так как не следует помещать значения в эти таблицы очень часто. Если вам необходимо управлять значениями идентификаторов между средами, чтобы избежать коллизий, сбросьте значения идентификаторов между средами при восстановлении с производства.
Мрденный
5

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

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

Марк Байерс
источник
4

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

Вы всегда можете создать «супер таблицу», которая использует идентификатор в качестве PK и имеет столбец типа и любую другую информацию. Когда вам нужен новый идентификатор (предполагается, что вы имеете в виду уникальные IDS для разных таблиц), просто вставьте в эту таблицу и возьмите, SCOPE_IDENTITY()а затем вставьте в нужную таблицу.

По сути, вы создаете таблицу: MasterID с идентификатором PK, когда вам нужно вставить строку в ваш Table1, INSERT INTO MasterIDsи получить идентификатор, сгенерированный этой строкой, используя, SCOPE_IDENTITY()а затем вставить в Table1, используя это значение в качестве PK.

Table1 будет иметь не идентифицирующий int PK. Вы должны выполнить тот же процесс для вставки в Table2 и т. Д. Пусть SQL Server управляет значениями идентификаторов в таблице MasterID , которые затем можно использовать в других таблицах. MasterID могут содержать другие таблицы, например type (чтобы вы могли знать, какая таблица, Table1 или Table2 и т. Д. Использует это значение идентификатора).

Пол Уайт 9
источник
3

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

Джо Филлипс
источник
2

Идентичность была сделана, чтобы соответствовать вашему сценарию. У вас есть такие инструменты, как репликация для обмена данными между сервером и средой, которые объединяют все это.


источник
1

Я только что закончил работу, где я заменил identityстолбец SQL Server на обычное intполе и сам управлял распределением идентификаторов.

Я видел довольно впечатляющий прирост производительности. В отличие от OP, у меня нет UDF для генерации идентификатора. Но принцип почти такой же: есть часть программного обеспечения, которая поддерживает пул идентификаторов. Когда они заканчиваются, он получает другой пакет, запрашивая у базы данных следующее значение Low и увеличивает его до следующего High .

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

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

отметка
источник
0

Я использую идентификационные данные в течение многих лет и серьезно подумываю заменить идентификационный номер на UNIQUEIDENTIFIER. Это кошмар, когда вам нужно изменить тип данных, если кто-то спроектировал его как компактную базу данных и кошмар, если вам нужно добавить идентификацию в столбец, также вы не можете обновить столбец идентификации. Представьте, что вы поставили int и ваша база данных превысила 2 миллиарда записей, опять кошмар, чтобы измениться (подумайте о ФК)! Изменять что-либо с помощью индивидуальности - это кошмар и не очень удобно, если вы не используете bigint! UNIQUEIDENTIFIER vs Identity = удобство и надежность по сравнению с, возможно, заметным улучшением производительности (тест производительности не выполнялся).

Обновление: после того, как я увидел это, я определенно склоняюсь к УНИКАЛЬНОМУ УСТРОЙСТВУ. Это не показывает реальной выгоды от идентификации Bigint и кучу преимуществ для UNIQUEIDENTIFIER! Разные версии SQL Server могут иметь разные результаты. Это просто прелесть - иметь уникальный идентификатор во всех базах данных и системах (надежность)! Перемещайте, копируйте, трансформируйте данные как вам угодно! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

Хрвое Батрнек
источник
64-битный INT будет длиться очень долго ...
Vérace