Преимущества и недостатки ключей базы данных GUID/UUID

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

Кто-нибудь много работал с GUID в базе данных? Какие преимущества я получу, пройдя этот путь, и каковы вероятные подводные камни?

Ответ 1

Преимущества:

  • Может генерировать их в автономном режиме.
  • Делает репликацию тривиальной (в отличие от int, что делает ее ДЕЙСТВИТЕЛЬНО трудной)
  • ORM обычно нравится им
  • Уникальные приложения. Поэтому мы можем использовать PK из нашего CMS (guid) в нашем приложении (также guid) и знаем, что мы НИКОГДА не собираемся столкнуться.

Недостатки:

  • Большее использование пространства, но пространство дешево (er)
  • Невозможно заказать по идентификатору, чтобы получить порядок вставки.
  • Может выглядеть уродливым в URL, но на самом деле, WTF вы кладете ключ REAL DB в URL-адрес!?
  • Сложнее выполнять ручную отладку, но не так сложно.

Лично я использую их для большинства ПК в любой системе приличного размера, но я получил "обучение" в системе, которая была реплицирована повсюду, поэтому мы ДОЛЖНЫ иметь их. YMMV.

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

  • уникальный идентификатор для строки (GUID/безотносительно). Никогда не отображается пользователю.
  • публичный идентификатор генерируется ONCE из некоторого поля (например, заголовок - делает его заголовком)

UPDATE: Таким образом, этот получает + 1, и я думал, что должен указать на большой недостаток GUID PK: Clustered Indexes.

Если у вас много записей и кластеризованный индекс в GUID, ваша производительность вставки будет SUCK, так как вы получаете вставки в случайных местах в списке элементов (это точка), а не в конце (что быстро)

Итак, если вам нужна производительность вставки, возможно, используйте auto-inc INT и сгенерируйте GUID, если вы хотите поделиться им с кем-то другим (т.е. показать его пользователю в URL-адресе).

Ответ 2

@Matt Sheppard:

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

Таким образом, у вас есть идентификатор клиента, который однозначно идентифицирует клиента, и вы убедитесь, что идентификатор известен клиенту (в счетах-фактурах), так что клиент и люди службы поддержки клиентов имеют общую ссылку, если они нуждаются в общении, Чтобы гарантировать отсутствие дублированных записей клиентов, вы добавляете ограничение уникальности в таблицу либо через первичный ключ в идентификаторе клиента, либо через ограничение NOT NULL + UNIQUE в столбце идентификатора клиента.

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

Некоторый "архитектор" может сказать вам, что "о, но мы справляемся с ограничением уникальности клиента в нашем уровне приложения!". Правильно. Мода относительно того, что языки программирования общего назначения и (особенно) рамки среднего уровня постоянно меняются и, как правило, никогда не будут жить в вашей базе данных. И есть очень хороший шанс, что вам в какой-то момент нужно будет получить доступ к базе данных, не проходя через настоящую заявку. == Проблемы. (Но, к счастью, вы и "архитектор" давно ушли, так что вас там не будет, чтобы очистить беспорядок.) Другими словами: сохраняйте очевидные ограничения в базе данных (а также в других уровнях, если у вас есть время).

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

Ответ 3

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

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

Существуют некоторые проблемы с производительностью, такие как фрагментация индекса. Но они легко разрешимы (гребенчатые гиды от jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862)

Редактировать объединил мои два ответа на этот вопрос

@Matt Sheppard Я думаю, что он означает, что вы можете дублировать строки с разными идентификаторами GUID в качестве первичных ключей. Это проблема с любым суррогатным ключом, а не только с GUID. И, как он сказал, легко решается путем добавления значимых уникальных ограничений для неключевых столбцов. Альтернативой является использование естественного ключа, и у этих есть реальные проблемы.

Ответ 4

GUID могут причинить вам массу проблем в будущем, если они используются как "uniqifiers", позволяя дублировать данные в ваши таблицы. Если вы хотите использовать GUID, пожалуйста, подумайте о сохранении ограничений UNIQUE для других столбцов.

Ответ 5

Почему никто не упоминает о производительности? Когда у вас есть несколько объединений, все на основе этих мерзких GUID, производительность будет проходить через пол, там: (

Ответ 6

Еще одна небольшая проблема, которую следует учитывать при использовании GUIDS в качестве первичных ключей, если вы также используете этот столбец как кластерный индекс (относительно распространенная практика). Вы собираетесь нанести удар по вставке из-за того, что характер руководства не будет начинаться последовательно в любом случае, таким образом, они будут разбиты на страницы и т.д., Когда вы вставляете. Просто подумайте, будет ли система иметь высокий IO...

Ответ 7

primary-keys-ids-versus-guids

Стоимость GUID как первичных ключей (SQL Server 2000)

Мифы, GUID и Autoincrement (MySQL 5)

Это действительно то, что вы хотите.

Преимущества UID

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

Недостатки GUID

  • Это 4 раза больше, чем традиционное 4-байтовое значение индекса; это может иметь серьезные последствия для производительности и хранения, если вы не будете осторожны.
  • Громоздко отлаживать (где userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Сгенерированные идентификаторы GUID должны быть частично последовательными для обеспечения максимальной производительности (например, newsequentialid() в SQL 2005) и для включения кластеризованных индексов

Ответ 8

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

RDBM обычно обеспечивают уникальность первичных ключей и обеспечивают поиск ключом в структуре под названием BTree, которая представляет собой дерево поиска с большим коэффициентом ветвления (двоичное дерево поиска имеет коэффициент ветвления 2). Теперь последовательный идентификатор целого числа приведет к тому, что вставки будут иметь место только на одной стороне дерева, оставив большую часть листовых узлов нетронутой. Добавление случайных UUID приведет к тому, что вставки будут разделены на листовые узлы по всему индексу.

Аналогично, если хранящиеся данные в основном являются временными, часто бывает, что самые последние данные должны быть доступны и объединены больше всего. При использовании случайных UUID шаблоны не выиграют от этого, и ударят больше строк индекса, тем самым требуя большего количества индексных страниц в памяти. При последовательных идентификаторах, если нужны самые последние данные, на страницах с горячим индексом потребуется меньше ОЗУ.