Почему первичные ключи генерируются GUID aspnet_regsql? - PullRequest
6 голосов
/ 26 апреля 2011

Я занимаюсь разработкой веб-сайта ASP.NET в Visual Studio 2010 (с пакетом обновления 1, большое спасибо). Я хочу использовать встроенные в .NET поставщики членства и ролей для SQL Server 2008.

Итак, я очень давно занимаюсь разработкой технологий Microsoft и общаюсь с некоторыми из лучших администраторов баз данных SQL Server в бизнесе. Каждый из них сказал мне держаться подальше от GUIDS в качестве первичных ключей при создании таблицы базы данных, которая будет:

  1. Имеют очень большое количество записей.
  2. Большой объем вставок и удалений.

Причина: потому что первичный ключ - это кластеризованный индекс!

Это в основном означает, что каждая запись, вставленная в таблицу , должна подчиняться ограничениям индекса. Поэтому, если индекс отсортирован по ASC, запись с вновь сгенерированным GUID должна быть физически вставлена ​​в правильной последовательности в соответствующую таблицу данных.

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

Так что мой вопрос просто такой. Поскольку Microsoft и все DBS, которые мы знаем и любим, сказали GUID в качестве первичных ключей НЕТ ... почему инструмент ASPNET_REGSQL создает таблицы, используя GUID в качестве первичного ключа?

Или я что-то упустил? Есть ли в 2008 году новая функция механизма SQL Profiler, которая больше не рассматривает GUIDS как задачу?

Ответы [ 2 ]

3 голосов
/ 26 апреля 2011

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

Что касается того, что вы сказали о нескольких миллионах строк данных - с гидами все будет в порядке, если вы всегда просите сервер SQL вернуть одну строку данных. Самая большая проблема будет, когда вы запрашиваете какое-то большое подмножество данных или когда вы пакетно вставляете большое количество строк; Тогда вы, вероятно, будете делать много случайных операций ввода-вывода, чтобы получить все строки, соответствующие вашим критериям, или вставить все строки в случайные места, на которые в конечном итоге будут указывать направляющие. Кроме того, SQL не нужно «физически перемещать все эти строки вниз, чтобы вставить новую»; Данные хранятся на страницах, и SQL обычно придется изменять данные только на одной странице в файле данных, чтобы вставить строку, возможно, с обновлением пары других страниц, но это не то же самое, что вставка строки в массивный текстовый файл.

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

1 голос
/ 26 апреля 2011

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

Каждый из них сказал мне держаться подальше от GUIDS в качестве первичных ключей при создании базы данных ... потому что первичный ключ - это кластеризованный индекс!

Первичный ключ не должен использовать кластеризованный индекс, это просто тип индекса по умолчанию, используемый при создании первичного ключа.

Фактически, если вы посмотрите на схему базы данных, используемую SqlMembershipProvider, то увидите, что в столбце первичного ключа есть некластеризованный индекс.

Ниже приведен сценарий SQL из сценария InstallCommon.sql в %WINDIR%\Microsoft.NET\Framework\v4.0.30319:

  CREATE TABLE [dbo].aspnet_Users (
    ApplicationId    uniqueidentifier    NOT NULL FOREIGN KEY REFERENCES [dbo].aspnet_Applications(ApplicationId),
    UserId           uniqueidentifier    NOT NULL PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
    UserName         nvarchar(256)       NOT NULL,
    LoweredUserName  nvarchar(256)       NOT NULL,
    MobileAlias      nvarchar(16)        DEFAULT NULL,
    IsAnonymous      bit                 NOT NULL DEFAULT 0,
    LastActivityDate DATETIME            NOT NULL)

   CREATE UNIQUE CLUSTERED INDEX aspnet_Users_Index ON [dbo].aspnet_Users(ApplicationId, LoweredUserName)
   CREATE NONCLUSTERED INDEX aspnet_Users_Index2 ON [dbo].aspnet_Users(ApplicationId, LastActivityDate)

Обратите внимание, что столбец первичного ключа (UserId) создается с помощью оператора PRIMARY KEY NONCLUSTERED и что индекс CLUSTERED таблицы создается как составной индекс для ApplicationId и LoweredUserName.

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