INT против уникального идентификатора для поля идентификатора в базе данных - PullRequest
32 голосов
/ 20 июля 2009

Я создаю новую базу данных для веб-сайта, используя SQL Server 2005 (возможно, SQL Server 2008 в ближайшем будущем). Как разработчик приложений, я видел много баз данных, которые используют integer (или bigint и т. Д.) Для поля идентификатора таблицы, которая будет использоваться для отношений. Но в последнее время я также видел базы данных, которые используют unique identifier (GUID) для поля идентификатора.

У меня вопрос: есть ли у одного преимущество над другим? Будут ли поля integer быстрее запрашивать, объединять и т. Д .?

ОБНОВЛЕНИЕ: Чтобы было понятно, это для первичного ключа в таблицах.

Ответы [ 6 ]

52 голосов
/ 20 июля 2009

GUID проблематичны как кластерные ключи из-за высокой случайности. Эта проблема была рассмотрена Полом Рэндалом в последнем столбце вопросов и ответов журнала Technet Magazine: Я хотел бы использовать GUID в качестве ключа кластеризованного индекса, но другие утверждают, что это может привести к проблемам с производительностью индексов. Это правда, и если да, то можете ли вы объяснить, почему?

Теперь имейте в виду, что речь идет именно о кластеризованных индексах. Вы говорите, что хотите использовать столбец как «ID», поэтому неясно, имеете ли вы в виду его как кластерный ключ или просто первичный ключ. Обычно эти два перекрываются, поэтому я предполагаю, что вы хотите использовать его в качестве кластерного индекса. Причины такого неудачного выбора объясняются в ссылке на статью, о которой я упоминал выше.

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

Существует множество городских легенд, связанных с использованием GUID, которые осуждают их на основании их размера (16 байт) по сравнению с int (4 байт) и обещают ужасную гибель производительности, если они используются. Это немного преувеличено. Ключ размера 16 может быть очень полезным ключом в правильно спроектированной модели данных. Хотя верно то, что, будучи в 4 раза больше целого, приводит к большему количеству неконечных страниц с меньшей плотностью в индексах, это не представляет реальной проблемы для подавляющего большинства таблиц. Структура b-дерева - это естественно хорошо сбалансированное дерево, и глубина обхода дерева редко является проблемой, поэтому поиск значения на основе ключа GUID в отличие от ключа INT схож по производительности. Обход листовой страницы (т. Е. Сканирование таблицы) не учитывает не листовые страницы, и влияние размера GUID на размер страницы, как правило, довольно мало, поскольку сама запись значительно больше, чем введенные дополнительные 12 байтов. по GUID. Поэтому я бы взял совет «услышь-скажи», основанный на «16 байтов против 4» с довольно большой долей соли. Проанализируйте каждый отдельный случай и решите, действительно ли влияние на размер имеет реальное значение: сколько других столбцов находится в таблице (т. Е. Какое влияние имеет размер GUID на листовых страницах) и сколько ссылок используют его (т.е. сколько других таблиц увеличится из-за того, что им нужно хранить больший внешний ключ).

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

И, наконец, чтобы ответить на ваш вопрос: , если у вас нет конкретной причины использовать GUID, используйте INT.

8 голосов
/ 20 июля 2009

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

6 голосов
/ 20 июля 2009

INT - это 4 байта, BIGINT - это 8 байтов, а GUIDS - 16 байтов. Чем больше места требуется для представления данных, тем больше ресурсов требуется для их обработки - места на диске, памяти и т. Д. Итак, (а) они медленнее, но (б) это, вероятно, имеет значение только в том случае, если объем является проблемой (миллионы строк или тысяч транзакций за очень-очень короткое время.)

Преимущество GUID в том, что они (в значительной степени) уникальны в глобальном масштабе. Сгенерируйте guid, используя правильный алгоритм (и SQL Server xxxx будет использовать правильный алгоритм), и никакие два руководства никогда не будут одинаковыми - независимо от того, сколько компьютеров вы их генерируете, независимо от того, как часто. (Это не применяется после 72 лет использования - я забыл детали.)

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

4 голосов
/ 20 июля 2009

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

Для менее надежных вещей должно хватить int, в зависимости от того, насколько большим будет стол.

Как и в большинстве случаев, правильный ответ зависит от этого.

3 голосов
/ 20 июля 2009

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

Кимберли Л Трипп артикул

  • Против: пробел, не строго монотонный, разбиение на страницы, закладки / RID и т. Д.
  • Для: э ...
2 голосов
/ 20 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...