INT vs Unique-идентификатор поля ID в базе данных
Я создаю новую базу данных для веб-сайта, используя SQL Server 2005 (возможно, SQL Server 2008 в ближайшем будущем). Как разработчик приложений, я видел много баз данных, которые используют integer (или bigint и т. д.) для поля ID таблицы, которое будет использоваться для связей. Но в последнее время я также видел базы данных, которые используют unique identifier (GUID) для поля ID.
Мой вопрос в том, есть ли у одного преимущество перед другим? Будут ли поля
integer быстрее использоваться для запросов и объединения, и т.д.?UPDATE: чтобы было понятно, это для первичного ключа в таблицах.
6 ответов:
GUID проблематичны в качестве кластеризованных ключей из-за высокой случайности. Эта проблема была рассмотрена полом Рэндалом в последней колонке вопросов и ответов журнала Technet: я хотел бы использовать GUID в качестве ключа кластеризованного индекса, но другие утверждают, что это может привести к проблемам производительности с индексами. Верно ли это, и если да, то можете ли вы объяснить почему?
Теперь имейте в виду, что речь идет именно о кластеризованных индексах. Вы говорите, что хотите использовать столбец как "ID", то есть неясно, подразумеваете ли вы его как кластерный ключ или просто первичный ключ. Обычно они перекрываются, поэтому я предположу, что вы хотите использовать его в качестве кластеризованного индекса. Причины, по которым это плохой выбор, объясняются в ссылке на статью, о которой я упоминал выше.Для некластеризованных индексов GUID все еще имеют некоторые проблемы, но не такие большие, как когда они являются крайним левым кластеризованным ключом таблицы. Опять же, случайность GUID вводит разбиение страниц и фрагментацию, будь то на некластеризованном уровне индекса только (гораздо меньшая проблема).
Есть много городских легенд, окружающих использование GUID, которые осуждают их на основе их размера (16 байт) по сравнению с int (4 байта) и обещают ужасную производительность doom, если они будут использоваться. Это несколько преувеличено. Ключ размера 16 может быть очень формантным ключом до сих пор, на правильно разработанной модели данных. В то время как верно, что быть в 4 раза больше, чем int приводит к большему количеству более низкой плотности не-листовых страниц в индексах, это не является реальной проблемой для подавляющего большинства столов. Структура b-дерева-это естественно хорошо сбалансированное дерево, и глубина обхода дерева редко является проблемой, поэтому поиск значения, основанного на ключе GUID, в отличие от ключа INT, аналогичен по производительности. Обход листа-страницы (т. е. сканирование таблицы) не просматривает не-листовые страницы, и влияние размера GUID на размер страницы обычно довольно мало, так как сама запись значительно больше, чем дополнительные 12 байт, введенные GUID. Так что я бы взял ... слышу-говорят советы, основанные на 'составляет 16 байт против 4' с, довольно большой, зерном соли. Проанализируйте каждый отдельный случай и решите, действительно ли влияние размера имеет значение: сколькодругих столбцов в таблице (т. е. как сильно влияет размер GUID на листовые страницы) и сколько ссылок его используют (т. е. сколькодругих таблиц увеличится из-за того, что им нужно хранить больший внешний ключ).
Я называю все эти детали в некотором роде импровизированная защита GUIDs, потому что в последнее время они получают много плохой прессы, и некоторые из них незаслуженно. Они имеют свои достоинства и незаменимы в любой распределенной системе (в тот момент, когда вы говорите о движении данных, будь то репликация или синхронизация фреймворка или что-то еще). Я видел, как плохие решения принимались на основе плохой репутации GUID, когда их избегали без должного рассмотрения. Но верно, Если вам нужно использовать GUID в качестве кластеризованного ключа, убедитесь, что вы решаете проблему случайности: по возможности используйте последовательные GUID.
И, наконец, чтобы ответить на ваш вопрос: Если у вас нет конкретной причины использовать GUID, используйте INTs.
GUID займет больше места и будет медленнее, чем int - даже если вы используете функцию newsequentialid (). Если вы собираетесь выполнять репликацию или использовать платформу синхронизации, вам в значительной степени придется использовать guid.
INTs - это 4 байта, BIGINTs-8 байт, а GUID-16 байт. Чем больше места требуется для представления данных, тем больше ресурсов требуется для их обработки-дисковое пространство, память и т. д. Поэтому (а) они медленнее, но (б) это, вероятно, имеет значение только в том случае, если объем является проблемой (миллионы строк или тысячи транзакций за очень, очень короткое время.)
Преимущество GUID состоит в том, что они (в значительной степени) глобально уникальны. Создайте guid, используя правильный алгоритм (и SQL Server xxxx будет использовать правильный алгоритм), и никакие два GUID никогда не будут одинаковыми-независимо от того, сколько компьютеров вы их генерируете, независимо от того, как часто. (Это не применимо после 72 лет использования-я забываю детали.)
Если вам нужны уникальные идентификаторы, генерируемые на нескольких серверах, могут быть полезны GUID. Если вам нужен mondo perforance и менее 2 миллиардов значений, ints, вероятно, в порядке. Наконец, и, возможно, самое главное, если ваши данные имеют естественные ключи, придерживайтесь их и забудьте о суррогате ценности.
Если вы положительно, абсолютно должны иметь уникальный идентификатор, то GUID. То есть, если вы когда-нибудь собираетесь объединять, синхронизировать, реплицировать, вам, вероятно, следует использовать GUID.
Для менее надежных вещей, int, должно быть достаточно в зависимости от того, насколько большой будет расти таблица.
Как и в большинстве случаев, правильный ответ-это зависит.
Используйте их для репликации и т. д, нет как первичные ключи.
- против: пробел, не строго монотонный, разбиение страниц, закладки / Риды и т. д.
- для: Эр...
Полностью согласен с Джбруксом. Я хочу сказать, что когда ваша таблица большая и вы используете selects с соединениями, особенно с производными таблицами, использование GUID может значительно снизить производительность.
Comments