33

所以在我的简单学习网站中,我使用了内置的 ASP.NET 身份验证系统。

我现在添加一个用户表来保存他的 zip、DOB 等内容。我的问题是:

  1. 在新表中,键应该是用户名(字符串)还是用户 ID,即他们在asp_ tables.
  2. 如果最佳做法是使用那个丑陋的指南,有谁知道如何获得它?System.Web.HttpContext.Current.User.Identity.Name它似乎不像名称( )那样容易访问
  3. 如果您建议我既不使用(不是由 ASP.NET 身份验证提供的 guid 和 userName 字段),那么我该如何使用 ASP.NET 身份验证呢?我喜欢的一种选择是使用用户的电子邮件地址作为登录名,但是如何让 ASP.NET 身份验证系统使用电子邮件地址而不是用户名?(或者那里无事可做,只是我决定我“知道” userName 实际上是一个电子邮件地址?

请注意:

  • 我不是在问如何在 .NET 中获取 GUID,我只是指asp_ tables作为 guid 中的 userID 列。
  • 用户名在 ASP.NET 身份验证中是唯一的。
4

12 回答 12

32

您应该使用一些唯一的 ID,无论是您提到的 GUID 还是其他一些自动生成的密钥。但是,用户永远不应该看到这个数字。

这样做的一个巨大好处是您的所有代码都可以在用户 ID 上运行,但用户名并没有真正与它绑定。然后,用户可以更改他们的名字(我发现这在网站上很有用)。如果您使用电子邮件地址作为用户的登录名,这尤其有用……这对用户来说非常方便(这样他们就不必记住 20 个 ID,以防他们的常用用户 ID 很受欢迎)。

于 2008-08-07T16:26:40.910 回答
23

您应该使用用户 ID。它是 MembershipUser 的 ProviderUserKey 属性。

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
于 2008-08-07T17:55:51.387 回答
14

如果用户名是唯一的,我建议使用用户名作为表中的主键,这样做有几个很好的理由:

  1. 主键将是一个聚集索引,因此通过用户名搜索用户详细信息将非常快速。
  2. 它将阻止重复的用户名出现
  3. 您不必担心使用两种不同的信息(用户名或 guid)
  4. 由于不必查找两位信息,它将使编写代码变得更加容易。
于 2008-08-07T17:56:36.657 回答
6

我会使用用户标识。如果您想使用用户名,您将使“更改用户名”功能变得非常昂贵。

于 2008-08-07T18:25:47.660 回答
3

我同意 Palmsey 的观点,尽管他的代码似乎有一点错误:

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

应该

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
于 2009-05-06T07:58:57.877 回答
3

我会说使用用户 ID,这样用户名仍然可以在不影响主键的情况下更改。我还将用户名列设置为唯一以停止重复的用户名。

如果您主要搜索用户名而不是 UserID,则将 Username 设为聚集索引并将主键设置为非聚集索引。这将在搜索用户名时为您提供最快的访问,但是如果您主要搜索 UserId,则将其保留为聚集索引。

编辑:这也将更适合当前的 ASP.Net 成员表,因为它们也使用 UserID 作为主键。

于 2009-05-06T08:04:12.183 回答
3

这是旧的,但我只想让发现这个的人注意一些事情:

  1. aspnet 会员数据库在访问用户记录时进行了优化。当使用 loweredusername 和 applicationid 搜索记录时,使用 sql server 中的聚集索引搜索(最佳)。这很有意义,因为当用户第一次发送他们的凭据时,我们只有提供的用户名才能继续。

  2. guid userid 将提供比 int 更大的索引大小,但这并不重要,因为我们通常一次只检索 1 条记录(用户),并且就碎片而言,读取次数通常大大超过写入和编辑的次数到用户表 - 人们根本不会经常更新该信息。

  3. 可以编辑创建 aspnet 成员资格表的 regsql 脚本,这样它就可以使用 NEWSEQUENTIALID() 来提供更好的性能(我已经对此进行了分析),而不是使用 NEWID 作为用户 ID 的默认值。

  4. 轮廓。创建“新学习网站”的人不应该尝试重新发明轮子。我工作过的一个网站使用了开箱即用的 aspnet 成员表(不包括可怕的配置文件系统),用户表包含近 200 万条用户记录。即使有这么多的记录,选择仍然很快,因为正如我开始所说,数据库索引专注于降低用户名+应用程序ID来对这些记录执行聚集索引搜索,一般来说,如果 sql 正在执行聚集索引搜索要找到 1 条记录,即使有大量记录,只要您不向表中添加列并开始拉回太多数据,您也不会遇到任何问题。

  5. 担心这个系统中的引导,对我来说,基于系统的实际性能和经验,是过早的优化。如果您的用户 ID 有一个 int,但由于您的自定义索引设计等原因,系统执行次优查询,则系统将无法很好地扩展。微软的人在 aspnet 会员数据库方面做得很好,除了将 userId 更改为 int 之外,还有许多更高效的事情需要关注。

于 2012-02-02T12:01:42.437 回答
2

我会使用一个自动递增的数字,通常是一个 int。

您希望使密钥的大小尽可能小。这使您的索引保持较小,并且也有利于任何外键。此外,您没有将数据设计与外部用户数据紧密耦合(这也适用于 aspnet GUID)。

通常,GUID 不能作为良好的主键,因为它们很大,并且插入可能发生在表中的任何数据页而不是最后一个数据页。主要的例外是如果您正在运行多个复制数据库。在这种情况下,GUID 对于键非常有用,但我猜您只有一个数据库,所以这不是问题。

于 2008-08-27T08:16:04.503 回答
1

如果您打算使用 LinqToSql 进行开发,我建议您使用 Int 作为主键。当我建立非 Int 字段的关系时,我遇到了很多问题,即使 nvarchar(x) 字段具有使其成为唯一字段的约束。

我不确定这是 LinqToSql 中的一个已知错误还是什么,但我在当前项目中遇到了问题,我不得不在几个表上换掉 PK 和 FK。

于 2008-08-08T00:50:04.933 回答
0

我同意迈克·斯通的观点。如果您要跟踪大量数据,我还建议仅使用 GUID。否则,一个简单的自动递增整数 (Id) 列就足够了。

如果您确实需要 GUID,.NET 非常可爱,您可以通过一个简单的...

Dim guidProduct As Guid = Guid.NewGuid()

或者

Guid guidProduct = Guid.NewGuid();
于 2008-08-07T16:38:08.827 回答
0

我也同意迈克·斯通的观点。我的公司最近为外部客户端(而不是通过 LDAP 进行身份验证的内部用户)实施了一个新的用户表。对于外部用户,我们选择将 GUID 存储为主键,并将用户名存储为 varchar,并对用户名字段进行唯一约束。

此外,如果您要存储密码字段,我强烈建议您将密码作为加盐的哈希二进制文件存储在数据库中。这样,如果有人要破解您的数据库,他们将无法访问您客户的密码。

于 2008-08-08T01:56:00.137 回答
0

我会在我的代码中使用 guid,并且如前所述,将电子邮件地址用作用户名。毕竟,对于用户来说,它已经是独一无二且令人难忘的。甚至可能放弃 guid (v. 有争议的)。

有人提到在您的代码中使用 GUID 上的聚集索引。我会避免这种情况,尤其是在 INSERT 很高的情况下;每次插入记录时都会重建索引。聚集索引在自动增量 ID 上运行良好,因为仅附加新记录。

于 2009-05-06T08:48:33.077 回答