ASP.NET 自定义成员资格提供程序用于非常大型应用程序

9
我需要为一个非常大的网站设计会员解决方案。该网站将使用ASP.NET MVC 2和MS SQL2008数据库构建。当前的会员提供程序似乎有点过度强大,功能太多了。我只想存储电子邮件/密码和基本个人资料信息,如名字、姓氏、电话号码。我只需要两个角色,管理员和用户。考虑到可能有数百万用户注册,您在这种情况下的建议是什么?StackOverflow使用了什么?我过去经常使用现有的Membership API,并扩展它来存储其他信息等。但是有一些表,比如...
aspnet_Applications
aspnet_Paths
aspnet_SchemaVersions
aspnet_WebEvent_Events
aspnet_PersonalizationAllUsers
aspnet_PersonalizationPerUser

这些都是非常冗余的,我从来没有发现它们有用处。

编辑
为了澄清@drachenstern的答案之后的一些冗余,Membership / Users表中还有其他我不需要的额外列,但这些列会增加每个select / insert语句的负载。

  1. MobilePIN
  2. PasswordQuestion / PasswordAnswer (我将基于电子邮件进行密码恢复)
  3. IsApproved (用户将始终被批准)
  4. Comment
  5. MobileAlias
  6. Username / LoweredUsername (或电子邮件/ LoweredEmail) [电子邮件即为用户名,因此只需要其中一个]

此外,我听说GUID并不那么快,而更喜欢使用整数(就像Facebook一样),这也将公开显示。

我该如何创建自己的Membership Provider,重用某些Membership API (验证、密码加密、登录cookie等),但仅使用符合我的要求的表格?

欢迎提供文章和现有实现的链接,我的谷歌搜索结果返回了一些非常基本的示例。

提前感谢
Marko


你是否已经成功解决了这个问题?还需要帮助吗? - jcolebrand
@drachenstern - 我正在实施的项目已经改期到二月份,我很可能会采纳 @Kila 的答案。 - Marko
那么也许你应该发表一条评论或将其标记为被接受的答案 ;) - jcolebrand
3个回答

13

@Marko,我完全理解标准会员系统可能包含比你需要的更多功能,但实际上这并不重要。会员系统中有一些部分是你不会使用的,就像.NET中有一些部分是你不会使用的一样。 .NET可以做很多你永远不会使用的事情,但你不会去遍历.NET并剥离那些功能,对吧?当然不会。你必须专注于对你正在尝试实现的事情至关重要的内容,并从那里开始工作。不要被分析麻痹了。你会浪费时间,白费力气,最终得不到比已经为你创建的内容更好的东西。现在微软有时确实会出错,但他们确实做对了很多事情。为了实现你的目标,你不需要接受他们所做的一切-你只需要了解对你的需求来说什么是重要的。

至于Guid和int作为主键,让我解释一些东西。主键和聚集索引之间存在着重要区别。你可以在不是主键的列上添加主键和聚集索引!这意味着,如果按名称(或其他方式)排列数据更重要,你可以自定义聚集索引以反映你需要的内容,而不影响主键。再重申一遍 - 主键和聚集索引不是同一个东西。我写了一篇关于如何给你的表添加聚集索引然后添加主键的博客文章。聚集索引将根据你需要的方式物理排序表行,而主键将强制执行你需要的完整性。请查看我的博客文章,以了解如何确切地实现它。

这里是链接 - http://iamdotnetcrazy.blogspot.com/2010/09/primary-keys-do-not-or-should-not-equal.html

这很简单,先添加聚集索引,然后再添加主键。必须按照这个顺序进行操作,否则将无法完成。当然,这是在使用Sql Server的情况下。大多数人并不知道这一点,因为SQL Server会默认在主键上创建聚集索引,但你只需要先添加聚集索引,然后再添加主键即可。使用整型作为主键,随着数据库和服务器系统的扩展,可能会变得非常棘手。我建议使用Guids,并添加聚集索引以反映您实际需要存储数据的方式。

现在,总之,我只想告诉您去创建一些伟大的东西,不要被那些对性能提升帮助不大的表面细节所困扰。生命太短暂了。还有,请记住,您的系统只能像最慢的代码一样快。所以确保查看实际上需要花费大量时间的事物,并处理它们。

另外还有一件事。您不能把您在网上看到的所有内容都当做铁板钉钉的事实。技术会随着时间的推移而变化。有时,您可能会查看某人很久以前写的一个问题的答案,该答案今天已经不再相关。另外,人们会回答问题并提供信息,而实际上没有测试他们所说的内容是否正确。为您的应用程序做最好的事情是进行压力测试。如果您正在使用ASP.Net MVC,可以在测试中执行此操作。您可以在测试中添加一个for循环,将用户添加到您的应用程序中,然后测试一下。这只是一个想法,还有其他方法。您只需要稍微努力一下,精心设计您的测试,或者至少为您的目的设计得足够好。

祝您好运!


这是一个非常好的答案,使用索引/主键也是一个非常好的想法。我需要为每个用户存储一个8位数字ID,那么我应该只是添加一个带有自动递增的额外列吗?你会对该列进行索引吗? - Marko
@Marko,那个列是你要搜索和连接的吗?如果是的话,我会对其应用索引。由于您只能在表中应用一个聚集索引,因此我会考虑将最常用于搜索/连接的列与聚集索引相匹配。请记住,聚集索引实际上会更改表数据的物理顺序。非聚集索引则不会。一开始不要太担心它。您可以使用工具进行基准测试,并逐步确定哪些索引可能最适合您,并相应地更改它们。 - Kila Morton

5
目前的会员提供程序似乎过于复杂了,功能太多。我只想存储电子邮件/密码和基本的个人资料信息,如名字、姓氏、电话号码。我只需要两个角色,管理员和用户。
那么就只使用该部分即可。它不会使用您不使用的部分,您可能会发现在未来需要使用那些其他部分。这些类已经存在于.NET框架中,因此您不需要提供任何许可证或其他东西。
数据库的大小相当小,如果像我一样将aspnetdb保持原样,则不会从其他数据库中获取任何内容。
您是否有使用第三方组件的充分理由,而不是使用已经在框架中的组件?

编辑:

在Membership/Users表中还有一些我不需要的额外列,但每个select/insert语句都会增加负载。

MobilePIN PasswordQuestion/PasswordAnswer(我将使用基于电子邮件的密码恢复) IsApproved(用户将始终被批准) Comment MobileAlias 用户名/小写用户名(或电子邮件/小写电子邮件)[电子邮件是用户名,因此只需要其中1个]

听起来你正在试图进行微优化。传递空字符串几乎没有成本(好吧,它确实存在,但您必须进行分析才能知道它的成本有多少。每个用户的成本不会太高)。我们的应用程序通常也不使用所有这些字段,但我们使用会员系统而没有可衡量的不利影响。

此外,我听说Guid并不那么快,希望使用整数(像Facebook一样),这也将公开显示。

我听说饼干怪兽喜欢饼干。但是,如果没有进行个人资料分析,你不知道这是否有害。通常人们使用GUID是因为他们希望它在任何时候都是绝对的(或者说相当绝对)独特的。每个用户仅生成一次的成本并不重要,尤其是当你已经为他们创建了一个新账户。


既然您坚定地想要从头开始创建MembershipProvider,这里提供一些参考资料:

http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.aspx

https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx

http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

http://www.amazon.com/ASP-NET-3-5-Unleashed-Stephen-Walther/dp/0672330113

Stephen Walther在他的书中详细介绍了这一点,这是一个很好的参考资料。


@Marko 我也更新了我的代码。我认为你在微观优化一些东西,而实际上你只需要使用并通过它,除非你从事创建会员控制的业务。 - jcolebrand
感谢您的更新@drachenstern,但我仍然不同意。如果可以完全删除它,为什么要有额外的有效载荷?当我们谈论查询用户列表时,即使每个用户包含<1kb的“extra”有效载荷,1000个用户的列表也意味着1mb的额外数据,对吧?此外,关于GUID与INT,可以参考这些问题https://dev59.com/h3RA5IYBdhLWcg3wyBD1和https://dev59.com/1HRC5IYBdhLWcg3wG9Xp#404057。 - Marko
@Marko,我已经在底部给了你几个链接,我认为你应该查看。它们讨论了需要考虑的事项和必须执行的继承。无论如何,我都推荐这本书。 ~ 至于<1kb的数据,我不知道你的服务器数据库磁盘有多大,但我的磁盘大小为TB级别,因此额外的兆位或兆字节的数据并不是我会错过的东西。而且当我达到一百万用户时,我已经决定了需要存储在数据库中的信息。那时候,你肯定需要重写代码。 - jcolebrand
@Marko - 我分享你对成员提供程序的痛苦,但请记住,当你编写一个新的时,你会失去所有内置的成员提供程序API功能(安全最重要)。Stack使用OpenId - 这是一个选项,如果您正在做一个新的网站,但您无法迁移现有用户。我同意@drachenstern的观点-只使用你想要的部分。考虑到您的网站的安全问题-如果它是一个简单的,非关键任务的应用程序,那么好吧-尽管编写你自己的程序。 - RPM1984

3
我的建议是你进行基准测试。添加与生产环境中相同数量的记录,并提交与生产环境中相同数量的请求,以查看其在你的环境中的性能表现。
我猜它应该没问题,你所说的开销是微不足道的。

那么你同意我认为他需要在负载下进行分析吗? ;) ... 还要考虑到这是每个用户每个页面的访问负载,因此您不仅需要生成用户登录负载,还需要使用经过身份验证的登录会话生成用户站点使用负载。而且它将不得不维护每个“用户”的cookie。 - jcolebrand
是的...我假定如果他们期望拥有数百万用户,那么这些事情需要一个良好的测试环境。 - Hector Correa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接