Должен ли я использовать имя пользователя или идентификатор пользователя для ссылки на аутентифицированных пользователей в ASP.NET - PullRequest
27 голосов
/ 07 августа 2008

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

Я добавляю таблицу пользователя для сохранения таких вещей, как его zip, DOB и т. Д. Мой вопрос:

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

Обратите внимание:

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

Ответы [ 12 ]

31 голосов
/ 07 августа 2008

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

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

23 голосов
/ 07 августа 2008

Вы должны использовать идентификатор пользователя. Это свойство ProviderUserKey для MembershipUser.

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
12 голосов
/ 07 августа 2008

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

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

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

3 голосов
/ 02 февраля 2012

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

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

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

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

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

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

3 голосов
/ 06 мая 2009

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

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

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

3 голосов
/ 06 мая 2009

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

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

должно быть

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
2 голосов
/ 27 августа 2008

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

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

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

1 голос
/ 08 августа 2008

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

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

0 голосов
/ 06 мая 2009

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

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

...