Guids vs Авто увеличенные целые - PullRequest
12 голосов
/ 02 февраля 2012

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

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

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

спасибо

Ответы [ 2 ]

31 голосов
/ 02 февраля 2012

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

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

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

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

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

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

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

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

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

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

ИТОГО: 25 МБ против 106 МБ - и это только на одном столе!

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

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

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

2 голосов
/ 02 февраля 2012

У GUID есть несколько «кодирующих» преимуществ по сравнению с auto incs.

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

Таким образом, вы можете создать новую запись в памяти, узнать ее и передать фактическое хранилище какой-либо службе, а затем с радостью использовать ее, чтобы добавить локально связанные данные, а затем передать их той же или другой другой службе.Подход, который вещи вроде EF разбирают для вас под прикрытием, связан с необходимостью вставки записи в базу данных, а затем получения идентификатора, назначенного ей СУБД, для передачи в нисходящий поток.Этого можно избежать, если у вас есть другой уникальный ключ, а auto inc - это суррогат, но это не бесплатный обед.

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

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

...