Гиды против Auto Incremented ints

Мне интересно, есть ли наилучшая практика кодирования в отношении обращения к идентификаторам родительских > дочерних объектов в коде, где в записях БД используется автоматическое инкрементное int в качестве идентификатора (при первоначальном сохранении). Конечно, когда в коде вы не можете угадать, что такое идентификатор, и поэтому он должен оставить его пустым и, предположительно, сохранить все эти элементы в транзакции, сначала захватив родительский идентификатор, а затем установив его для всех детей, прежде чем сохранять их

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

Есть ли простой способ справиться с объектами в коде с помощью auto-ints в качестве их ключей db?

спасибо

Ответ 1

GUID могут показаться естественным выбором для вашего основного ключа - и, если вы действительно должны, вы, вероятно, можете поспорить, чтобы использовать его для ПЕРВИЧНОГО КЛЮЧА таблицы. То, что я настоятельно рекомендовал не делать, использует столбец GUID как ключ кластеризации, который SQL Server делает по умолчанию, если только вы не указали это не так.

Вам действительно нужно оставить две проблемы:

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

2) ключ кластеризации (столбец или столбцы, которые определяют "кластеризованный индекс" в таблице) - это физическое хранилище, и здесь небольшая, стабильная, когда-либо -выполнение типа данных - ваш лучший выбор - INT или BIGINT в качестве опции по умолчанию.

По умолчанию первичный ключ в таблице SQL Server также используется в качестве ключа кластеризации, но это не обязательно так! Я лично видел значительный прирост производительности при распаде предыдущего основного/кластерного ключа на основе GUID на два отдельных ключа - основной (логический) ключ в GUID и ключ кластеризации (упорядочения) на отдельной INT IDENTITY (1, 1).

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

Да, я знаю - там newsequentialid() в SQL Server 2005 и выше - но даже это не является поистине и полностью последовательным и, следовательно, также страдает от тех же проблем, что и GUID, - это немного менее заметно.

Тогда возникает еще одна проблема: ключ кластеризации в таблице будет добавлен к каждой записи и для каждого некластеризованного индекса в вашей таблице, поэтому вы действительно хотите убедиться, что это как можно меньше, Как правило, INT с 2+ миллиардами строк должен быть достаточным для подавляющего большинства таблиц - и по сравнению с GUID в качестве ключа кластеризации вы можете сэкономить сотни мегабайт памяти на диске и в памяти сервера.

Быстрый расчет - использование INT против GUID в качестве основного и кластеризованного ключа:

  • Базовая таблица с 1'000'000 строк (3,8 МБ против 15,26 МБ)
  • 6 некластеризованных индексов (22,89 МБ против 91,55 МБ).

ВСЕГО: 25 МБ против 106 МБ - и это только на одной таблице!

Еще немного еды для размышлений - отличный материал от Кимберли Триппа - прочитайте его, прочитайте снова, переваривайте! Это действительно SQL Server индексирование евангелия.

Также: с точки зрения С#/.NET - это зависит от того, как вы получаете доступ к базе данных SQL Server. Если вы используете что-то вроде Linq-to-SQL или Entity Framework v4, ваши объекты .NET будут автоматически обновляться с вставленными идентификаторами (из столбца INT IDENTITY) - без необходимости делать что-либо вообще. Так что для меня это еще одна причина, почему вы должны чувствовать необходимость использования GUID....

GUID ужасно плохой, поскольку ключи кластеризации SQL Server - не просто плохие - действительно, действительно, AWFUL

Ответ 2

Есть несколько преимуществ "кодирования" для GUID с помощью auto incs.

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

Итак, вы можете создать новую запись в памяти, узнать ее сейчас и передать фактическое хранилище на какую-то службу, а затем с радостью использовать его, чтобы добавить локальные данные, а затем передать их той же или другой службе. Корролар, который, как и EF, подходит для вас под крышкой, имеет дело с необходимостью вставить запись в db, а затем получить идентификатор, назначенный ему DBMS, для перехода к функциям downstream. Вы можете избежать этого, если у вас есть еще один уникальный ключ, а auto inc - суррогат, но это не бесплатный обед в любом случае.

Если я не делал рассылки, и мое приложение должно было быть подключено к базе данных, а auto inc - это истинный суррогат (не отображаемый как номер заказа или некоторая такая нумерация), а int охватывал диапазон, и нет возможности сказать, что два или мои клиенты сливаются и хотят объединить свои базы данных, тогда я бы не стал беспокоиться о руководстве.

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