Я обычно использую идентификаторы автоинкремента как первичные ключи в базах данных. Я пытаюсь узнать о преимуществах использования GUID. Я прочитал эту статью: https://betterexplained.com/articles/the-quick-guide-to-guids/
Я понимаю, что эти GUID используются для идентификации объектов на уровне приложения. Они также хранятся в качестве первичного ключа на уровне базы данных. Например, скажем, у меня был следующий класс:
public class Person
{
public GUID ID;
public string Name;
..
//Person Methods follow
}
Скажем, я хотел создать нового человека в памяти, а затем вставить человека в базу данных. Могу ли я просто сделать это:
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);
Скажем, у меня была база данных, содержащая миллионы и миллионы строк с GUID в качестве первичного ключа. Это всегда будет уникальным? Я правильно понимаю GUID?
Я читал эту статью ранее: http://enterprisecraftsmanship.com/2014/11/15/cqs-with-database-generated-ids/ . Меня это немного смущает, так как кажется, что я рекомендую счастливую среду между GUID и целыми числами в качестве первичных ключей.
Изменить 06/06/18
Я пришел к выводу, что направляющие больше подходят для моих требований, чем целые. Я использую CQRS больше в эти дни, и GUID лучше вписываются.
Я заметил, что некоторые разработчики моделируют GUID как строки в модели домена, например, здесь: https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/ Buyer.cs - в данном случае: IdentityGuid - это GUID, смоделированный как строка. Есть ли причина делать это иначе, чем указано здесь: Использовать объект пользовательского значения или Guid в качестве идентификатора объекта в распределенной системе? , Является ли "нормальным" моделирование GUID в виде строки или я должен моделировать его как GUID в модели и базе данных?
источник
Ответы:
GUID по определению являются «глобально уникальными идентификаторами». В Java есть похожая, но немного другая концепция, называемая UUID «Универсально уникальные идентификаторы». Имена являются взаимозаменяемыми для любого практического использования.
Идентификаторы GUID являются центральными в том, как Microsoft предусмотрела кластеризацию базы данных для работы, и если вам нужно включить данные из иногда подключенных источников, они действительно помогают предотвратить коллизии данных.
Некоторые факты про-GUID:
Некоторое уродство с GUID
GUID увеличит ваши индексы, поэтому стоимость дискового пространства при индексации столбца будет выше. Случайные GUID фрагментируют ваши индексы.
Если вы знаете, что не собираетесь синхронизировать данные из разных сетей, GUID может нести больше накладных расходов, чем они того стоят.
Если вам необходимо принимать данные от иногда подключенных клиентов, они могут быть намного более надежными для предотвращения конфликтов ключей, чем полагаться на настройку диапазонов последовательности для этих клиентов.
источник
Всегда? нет не всегда; это конечная последовательность битов.
Миллионы и миллионы, вы, вероятно, в безопасности. Миллион миллионов, и вероятность столкновения становится значительной. Однако есть и хорошие новости: к тому времени, когда это произойдет, вам уже не хватит места на диске.
Вы можете; это не совсем хорошая идея. Ваша модель домена обычно не должна генерировать случайные числа; они должны быть входными данными для вашей модели.
Кроме того, когда вы имеете дело с ненадежной сетью, где вы можете получить дубликаты сообщений, детерминистически UUID защитит вас от дублирования сущностей. Но если вы назначите каждому новое случайное число, у вас будет больше работы для выявления дублирования.
Смотрите описание имени на основе uuid в RFC 4122
Я не думаю, что это имеет большое значение. Для большей части вашей доменной модели это идентификатор ; единственный вопрос, который вы спрашиваете, это то же самое, что и какой-либо другой идентификатор. Ваша модель домена обычно не будет смотреть на представление идентификатора в памяти.
Если GUID доступен как «примитивный тип» в настройке вашего домена, я бы использовал его; это позволяет вспомогательному контексту выбирать подходящие оптимизации, которые могут быть доступны.
Однако следует признать, что представление идентификатора, как в памяти, так и в хранилище, является решением, которое вы принимаете в своей реализации, и, следовательно, вы должны предпринимать шаги для обеспечения того, чтобы след кода был связан с этим. решение невелико - см. Parnas 1972 .
источник
GUID или UUID , скорее всего, будут уникальными из-за того, как они генерируются, и они обеспечивают безопасный способ гарантировать уникальность без связи с центральным органом.
Преимущества GUID в качестве первичного ключа:
В приведенном вами примере:
Указание GUID до времени вставки может сохранить двустороннюю передачу в базу данных при вставке последовательных дочерних записей и позволит вам зафиксировать их в одной и той же транзакции.
Ущерб GUID в качестве первичного ключа:
Если ваше приложение не нуждается в сегментировании или кластеризации, было бы лучше придерживаться меньших, более простых типов данных, таких как int или bigint.
Многие базы данных имеют свои собственные внутренние реализации, которые пытаются смягчить проблемы с хранилищем, вызванные GUID, и SQL Server даже имеет функцию newsequentialid, помогающую упорядочить UUID, позволяющую лучше использовать индексы, и они, как правило, имеют лучшие характеристики производительности.
Кроме того, с точки зрения тестера, пользователя или разработчика, работающего с приложением, использование идентификатора через GUID значительно улучшит связь. Представьте, что вам нужно прочитать GUID по телефону.
В конце концов, если крупномасштабная кластеризация или запутывание URL-адресов не является требованием, более прагматично придерживаться автоматически увеличивающихся идентификаторов.
источник
Я бы сказал, нет, не используйте GUID в качестве первичных ключей. Я сейчас имею дело с такими БД, и они являются одной из основных причин проблем с производительностью.
Дополнительные 12 байтов суммируются быстро; помните, что большинство PK будут FK в других таблицах, и только три FK в таблице теперь имеют дополнительно 48 байтов для каждой строки. Это складывается в таблице и в индексах. Это также добавляет в дисковый ввод-вывод. Эти дополнительные 12 байтов должны быть прочитаны и записаны.
И если вы не используете последовательные направляющие, а PK кластеризованы (что происходит по умолчанию), SQL время от времени придется перемещать целые страницы данных, чтобы втиснуть больше в нужное «место». Для базы данных с высокой степенью транзакций, с большим количеством вставок, обновлений и удалений, все идет быстро.
Если вам нужен какой-то уникальный идентификатор для синхронизации или что-то еще, добавьте столбец guid. Только не делай это ПК.
источник
Это, безусловно, самая важная причина для использования GUID.
Тот факт, что вы можете создать уникальный идентификатор без знания вашего кода или связи с вашим постоянным уровнем, является огромным преимуществом.
Вы можете быть уверены, что объект Person, который вы только что сгенерировали на своем сервере, ПК, ноутбуке, автономном устройстве или что-то еще, уникален для всех ваших серверов по всему миру, как бы он ни был распределен.
Вы можете вставить его в любую базу данных rdb или no-sql, файл, отправить его в любой веб-сервис или сразу же выбросить как ненужное
Нет, вы никогда не столкнетесь.
Да, вставки могут быть немного медленнее, так как с индексом, возможно, придется возиться.
Да, это больше, чем int.
Я знаю, что многие люди испытывают сильные чувства к автоинсталляциям, и это спорная тема с администраторами
Но я действительно не могу утверждать достаточно сильно, насколько превосходные гиды. Вы должны использовать направляющие по умолчанию в любом приложении.
У авто инков есть много недостатков
Вы используете распределенную базу данных No-Sql. Вы просто не можете поговорить со всеми другими экземплярами, чтобы узнать, каков следующий номер.
Вы используете систему очереди сообщений. Вещи нужны идентификаторы, прежде чем они попадают в БД
Вы создаете несколько элементов и редактируете их перед сохранением. Каждому нужен идентификатор, прежде чем вы нажмете на БД
Вы хотите удалить и заново вставить строки. Убедитесь, что вы не подсчитываете свои автоматические идентификаторы и не заканчиваете!
Вы не хотите показывать, сколько заказов вы приняли в этом году для каждого пользователя
Вы хотите переместить анонимизированные данные из производства в тестирование и сохранить отношения в целости и сохранности. Но не удаляйте все существующие тестовые данные.
Вы хотите объединить свой продукт с одним арендатором в многопользовательскую базу данных, но у каждого есть заказ 56.
Вы создаете объекты, которые сохраняются, но эфемерны. (неполные заказы), опять же, не используйте все свои целые вещи с вещами, которых больше не существует.
Список бесконечен, и все они - реальные проблемы, которые постоянно случаются с людьми. в отличие от исчерпания дискового пространства из-за немного больших столбцов FK
Наконец, огромная проблема с инттами - вы исчерпали их !!! хорошо в теории вы не, есть нагрузки. Но на практике вы делаете это потому, что люди не относятся к ним как к случайным числам без смысла. они делают такие вещи, как
о, я не хочу, чтобы клиенты думали, что мы новички. начать с 10 000
Мне пришлось импортировать загрузку данных, поэтому я увеличил начальное значение до 1 м, чтобы мы знали, что импортируется
нам нужны категории данных. каждый период начинается с следующего миллиона, поэтому мы можем использовать первые цифры в качестве магического числа
Я удалил и снова импортировал все данные с новыми идентификаторами. Да, даже журналы аудита.
используйте этот номер, который является составным ключом, в качестве идентификатора этой другой вещи
источник
Вот где вы должны остановиться, прямо там и переосмыслить.
Ваш первичный ключ базы данных НИКОГДА не должен иметь делового значения. Это должно быть бессмысленно по определению.
Поэтому добавьте GUID в качестве вашего бизнес-ключа и обычный первичный ключ (обычно длинный int) в качестве первичного ключа базы данных. Вы всегда можете поместить уникальный индекс в GUID, чтобы обеспечить уникальность.
Конечно, это говорит о теории баз данных, но это хорошая практика. Я имел дело с базами данных, где первичные ключи имели деловое значение (например, один клиент думал сохранить некоторые ресурсы базы данных, используя их в качестве номеров сотрудников, номеров клиентов и т. Д. И т. Д.), И это всегда приводит к проблемам.
источник
Всегда используйте сгенерированные базой данных автоинкрементные первичные ключи (PK).
Зачем использовать автоинкремент вместо GUID / UUID?
Но как тогда обращаться с осколками, кластерами и т. Д.?
PK с 3 столбцами для кластерной таблицы может быть ...
Но что насчет...?
Многократные поездки в базу данных - большинству приложений не нужно однозначно идентифицировать создаваемую запись, пока она не будет вставлена в базу данных, поскольку этот поток / сеанс / что-либо работает только с одной за раз. Если приложению действительно нужна эта возможность, используйте созданный приложением временный PK, который не отправляется в базу данных . Пусть база данных затем поместит свой собственный автоинкрементный PK в строку, когда она будет вставлена. Вставки будут использовать временные PK, а обновления и удаления будут использовать постоянные PK, назначенные базой данных.
Производительность. Компьютеры могут обрабатывать простые целые числа гораздо быстрее, чем что-либо еще, из-за значительно большей области, если это возможно, значений на элемент в GUID (37) по сравнению с целым числом (10). Помните также, что каждый символ в GUID должен быть сначала преобразован в число, которое будет обработано процессором.
Распространенные злоупотребления первичными ключами У PK есть только одна цель ... абсолютно уникально идентифицировать строку в таблице. Все остальное - слишком распространенное злоупотребление.
Обнаружение пропавших записей
Сортировка
источник
Как и у всего, у этого есть свои преимущества и недостатки:
Добро:
Ваши ключи всегда имеют одинаковую длину (очень большие базы данных могут иметь очень большие ключи)
Уникальность в значительной степени гарантирована - даже если вы генерируете их из отдельной системы и / или не прочитали последний идентификатор из базы данных
Плохо:
Как уже упоминалось выше - большие индексы и хранилище данных.
Вы не можете заказать по идентификатору, вы должны заказать что-то еще. Больше индексов, возможно, менее эффективно.
Они менее читабельны. Целые числа обычно легче анализировать, запоминать и вводить для людей. Использование идентификаторов GUID в качестве идентификаторов в предложениях WHERE для нескольких соединенных таблиц может привести к потере сознания.
Как и все, используйте их там, где это уместно, не будьте догматичными - во многих ситуациях автоматическое увеличение целых чисел лучше, иногда GUID - это здорово.
источник
Да, вы можете использовать GUID в качестве первичного ключа. Недостатком является размер и быстрая фрагментация индекса.
Если вам не нужна уникальность в базах данных (например, в кластере), предпочтительным является целое число.
источник
Вот мой взгляд на эту проблему: решение - это промежуточное звено между значениями GUID и int, в которых используется лучшее из обоих.
Класс генерирует псевдослучайное (но увеличивающееся со временем) значение Id, которое похоже на Comb GUID .
Ключевое преимущество заключается в том, что он позволяет генерировать значения Id на клиенте, а не использовать значения автоинкрементации, генерируемые на сервере (что требует обратной передачи) с практически нулевым риском дублирования значений.
Сгенерированные значения используют только 8 байтов, а не 16 для GUID, и не зависят от одного конкретного порядка сортировки базы данных (например, Sql Server для GUID ). Значения могут быть расширены для использования всего длинного диапазона без знака, но это может вызвать проблемы с любой базой данных или другим хранилищем данных, которое имеет только целочисленные типы со знаком.
источник