Идентификация ядра asp.net - столбец идентификатора - nvarchar (450) - почему?

В таблице dbo.AspNetUsers, используемой ASP.NET Core Identity, столбец Id определяется как nvarchar(450), как показано на изображении ниже.

В чем причина этого, ведь в этой колонке хранятся гуиды? Если я создаю внешний ключ, ссылающийся на этот столбец Id, я действительно не хочу делать столбец излишне большим. Или есть сценарий, когда потребуется Id столбцов такого размера?

Таблица пользователей ASP.NET Core Identity


person nomad    schedule 25.03.2018    source источник
comment
3 года спустя, и никто не знает, почему мы продолжаем использовать более дорогой nvachar(450) вместо varchar(36) для наших гидов...   -  person TheLegendaryCopyCoder    schedule 02.07.2021


Ответы (1)


Я понятия не имею, почему это 450 в длину, но на самом деле это не имеет значения. Тип NVARCHAR имеет динамический размер, поэтому число, которое он передает, на самом деле является максимальной длиной. Он будет потреблять только количество байтов, необходимое для хранения данных, которые он хранит, независимо от «длины».

person Chris Pratt    schedule 26.03.2018
comment
Спасибо за это. Я понимаю, что вы можете изменить тип столбца (docs.microsoft.com/en-us/aspnet/core/security/authentication/). Вы бы порекомендовали вместо этого изменить идентификатор на Int? Я не думаю, что использование строки в качестве первичного ключа является хорошей идеей с точки зрения производительности (а также размера). - person nomad; 27.03.2018
comment
На самом деле это не имеет большого значения. Это по-прежнему индексированный столбец, поэтому на самом деле он не менее эффективен для запросов, чем int PK. Конечно, int занимает меньше места, но дополнительные несколько байтов вряд ли будут иметь значение по сравнению с общим размером вашей базы данных. Я обычно использую целые числа, но только потому, что предпочитаю работать с числовыми идентификаторами, а не обязательно для производительности или по какой-либо другой реальной причине. - person Chris Pratt; 27.03.2018
comment
Это на самом деле имеет значение! Создание миграций по умолчанию для таблиц Identity приведет к тому, что PK МОГУТ в некоторых ситуациях превышать максимальную длину ключа в 900 байт. - person Stefan Balan; 18.07.2019
comment
@StefanBalan: PK по умолчанию — это GUID. В любом случае, они никогда не должны превышать 32-40 в длину. Однако, даже если бы они были 450 в длину, это составляет 900 байт. Юникод занимает 2 байта на символ: 2 * 450 == 900. - person Chris Pratt; 18.07.2019
comment
Это может повлиять на создание составных ПК. Любой составной ключ, созданный с помощью AspNetUsers.Id, будет генерировать сообщение Warning! The maximum key length for a clustered index is 900 bytes.. Я считаю, что они сделали это 450 nvarchar, чтобы максимально увеличить размер PK и, следовательно, не дать людям создавать составные PK, которые включают столбец Id. Но это всего лишь предположение. Как сказал @ChrisPratt, по умолчанию AspNetUsers.Id являются GUID, так что у вас есть это. - person CrnaStena; 17.10.2019
comment
Интересный. Это кажется правдоподобным объяснением, поскольку создание составного ключа с пользователем Identity разрушило бы все виды хаоса. - person Chris Pratt; 17.10.2019
comment
Они не стали бы nvarchar(450) отговаривать людей от создания индексов с использованием Id пользователя, поскольку они сами делают это в AspNetUserRoles.PK_AspNetUserRoles, что составляет 1800 байт: UserID+RoleId - person Ian Boyd; 08.05.2020
comment
Он должен использовать целые числа, после чего должен быть столбец GUID. Странное решение. - person niico; 02.01.2021
comment
Нисколько. Они выбрали тип колонны, который может вместить что угодно. Если бы это был int, это не сработало бы для людей, которые хотели бы использовать гиды. Если бы это было руководство, оно не сработало бы для людей, которым нужны целые числа. - person Chris Pratt; 02.01.2021
comment
@niico Раньше я думал так же, как и вы, но обнаружил несколько замечательных преимуществ использования guid PK в ваших таблицах. Одним из таких преимуществ является то, что вы можете объединить несколько экземпляров одной и той же базы данных в один без (теоретически) конфликтов. Еще одно действительно большое преимущество заключается в том, что никто не может угадать последовательность ваших полей guid (int PK-> 1,2,3,4,5...), что делает ваше приложение более безопасным с самого начала. - person TheLegendaryCopyCoder; 02.07.2021
comment
@TheLegendaryCopyCoder Раньше я думал так же, как ты, лол. Я везде использовал идентификатор GUID. Однако Identity Id НЕ ЯВЛЯЕТСЯ GUID, это varchar (450) с GUID IN IT. Производительность идентификаторов GUID/varchar значительно хуже, чем при использовании int, в этом проблема. - person niico; 02.07.2021
comment
@niico ага. Отмеченный. В настоящее время я использую varchar (36) PK, заполненный сгенерированным С# guid. Да, производительность 32-битного int PK по сравнению с 288-битным+ varchar PK будет снижена. - person TheLegendaryCopyCoder; 03.07.2021