Должен ли я использовать имя пользователя или идентификатор пользователя для ссылки на аутентифицированных пользователей в ASP.NET?

StackOverflow https://stackoverflow.com/questions/4911

  •  08-06-2019
  •  | 
  •  

Вопрос

Поэтому на моем простом обучающем веб-сайте я использую встроенную систему аутентификации ASP.NET.

Теперь я добавляю таблицу пользователей для сохранения таких вещей, как его почтовый индекс, дата рождения и т. д.Мой вопрос:

  1. В новой таблице должен ли ключ быть именем пользователя (строка) или идентификатором пользователя, который представляет собой номер, похожий на GUID, который они используют в asp_ tables.
  2. Если лучше всего использовать это уродливое руководство, кто-нибудь знает, как его получить?кажется, оно не так легко доступно, как имя (System.Web.HttpContext.Current.User.Identity.Name)
  3. Если вы предлагаете мне не использовать ни одно из них (ни поля guid, ни поля userName, предоставляемые аутентификацией ASP.NET), то как мне это сделать с аутентификацией ASP.NET?Один из вариантов, который мне нравится, — использовать адрес электронной почты пользователя в качестве входа в систему, но как заставить систему аутентификации ASP.NET использовать адрес электронной почты вместо имени пользователя?(или здесь нечего делать, это просто я решил, что «знаю», что имя пользователя на самом деле является адресом электронной почты?

Пожалуйста, обрати внимание:

  • Я не спрашиваю, как получить GUID в .NET, я просто имею в виду столбец userID в asp_ tables в качестве руководства.
  • Имя пользователя уникально при аутентификации ASP.NET.
Это было полезно?

Решение

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

  1. Первичным ключом будет кластерный индекс, поэтому поиск сведений о пользователях по их имени будет очень быстрым.
  2. Это предотвратит появление повторяющихся имен пользователей.
  3. Вам не нужно беспокоиться об использовании двух разных фрагментов информации (имя пользователя или руководство).
  4. Это значительно облегчит написание кода, поскольку не придется искать два бита информации.

Другие советы

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

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

Вы должны использовать UserID.Это свойство ProviderUserKey MembershipUser.

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());

Я бы использовал идентификатор пользователя.Если вы хотите использовать имя пользователя, вы сделаете функцию «изменить имя пользователя» очень дорогой.

Я согласен с Палмси, хотя в его коде, кажется, есть небольшая ошибка:

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name)).ProviderUserKey.ToString());

должно быть

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());

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

Если вы будете в основном искать по имени пользователя, а не по идентификатору пользователя, сделайте имя пользователя кластеризованным индексом и установите некластеризованный первичный ключ.Это даст вам самый быстрый доступ при поиске имен пользователей, однако, если вы будете в основном искать UserIds, оставьте это как кластерный индекс.

Редактировать :Это также будет лучше соответствовать текущим таблицам членства ASP.Net, поскольку они также используют UserID в качестве первичного ключа.

Это устарело, но я просто хочу, чтобы люди, которые это найдут, обратили внимание на несколько вещей:

  1. База данных членства aspnet оптимизирована для доступа к записям пользователей.Поиск по кластерному индексу (оптимальный) на сервере sql используется при поиске записи с использованием пониженного имени пользователя и идентификатора приложения.Это имеет большой смысл, поскольку у нас есть только предоставленное имя пользователя, когда пользователь впервые отправляет свои учетные данные.

  2. Идентификатор пользователя guid даст больший размер индекса, чем int, но это не имеет особого значения, поскольку мы часто извлекаем только одну запись (пользователя) за раз, а с точки зрения фрагментации количество операций чтения обычно значительно перевешивает количество операций записи и редактирования. в таблицу пользователей — люди просто не обновляют эту информацию так часто.

  3. сценарий regsql, создающий таблицы членства aspnet, можно отредактировать так, чтобы вместо использования NEWID в качестве значения по умолчанию для идентификатора пользователя можно было использовать NEWSEQUENTIALID(), что обеспечивает лучшую производительность (я профилировал это).

  4. Профиль.Тот, кто создает «новый обучающий веб-сайт», не должен пытаться изобретать велосипед.На одном из веб-сайтов, на которых я работал, использовалась готовая версия таблиц членства aspnet (за исключением ужасной системы профилей), а таблица пользователей содержала почти 2 миллиона записей пользователей.Даже при таком большом количестве записей выборка все равно была быстрой, потому что, как я уже сказал для начала, индексы базы данных фокусируются на нижнем имени пользователя + идентификаторе приложения для выполнения поиска по кластерному индексу для этих записей и, вообще говоря, если sql выполняет поиск по кластерному индексу чтобы найти 1 запись, у вас не возникнет проблем даже при огромном количестве записей, при условии, что вы не добавляете столбцы в таблицы и не начинаете извлекать слишком много данных.

  5. Беспокойство по поводу руководства в этой системе, исходя из реальной производительности и опыта работы системы, для меня является преждевременной оптимизацией.Если у вас есть int для вашего идентификатора пользователя, но система выполняет неоптимальные запросы из-за вашего пользовательского дизайна индекса и т. д.система не будет хорошо масштабироваться.Ребята из Microsoft в целом хорошо поработали с базой данных членства в aspnet, и есть много более продуктивных вещей, на которых стоит сосредоточиться, чем изменение userId на int.

Я бы использовал автоматически увеличивающееся число, обычно int.

Вы хотите, чтобы размер ключа был как можно меньшим.Это сохраняет ваш индекс небольшим, а также приносит пользу любым внешним ключам.Кроме того, вы не тесно связываете структуру данных с внешними пользовательскими данными (это справедливо и для GUID aspnet).

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

Если вы собираетесь использовать LinqToSql для разработки, я бы рекомендовал использовать Int в качестве первичного ключа.У меня возникало много проблем, когда отношения строились на основе полей, отличных от Int, даже если поле nvarchar(x) имело ограничения, делающие его уникальным.

Я не уверен, является ли это известной ошибкой в ​​LinqToSql или чем-то еще, но у меня были проблемы с ней в текущем проекте, и мне пришлось поменять местами PK и FK в нескольких таблицах.

Я согласен с Майком Стоуном.Я бы также предложил использовать GUID только в том случае, если вы собираетесь отслеживать огромный объем данных.В противном случае будет достаточно простого столбца с автоматическим приращением целых чисел (Id).

Если вам действительно нужен GUID, .NET достаточно удобен, и вы можете получить его простым...

Dim guidProduct As Guid = Guid.NewGuid()

или

Guid guidProduct = Guid.NewGuid();

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

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

Я бы использовал руководство в своем коде и, как уже упоминалось, адрес электронной почты в качестве имени пользователя.Ведь оно уже уникально и запоминается для пользователя.Может быть, даже отказаться от руководства (ст.спорный).

Кто-то упомянул об использовании кластерного индекса по GUID, если он использовался в вашем коде.Я бы избегал этого, особенно если INSERT высоки;индекс будет перестраиваться каждый раз, когда вы ВСТАВЛЯЕТЕ запись.Кластерные индексы хорошо работают с идентификаторами автоматического увеличения, поскольку добавляются только новые записи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top