检查用户是不是激活了他/她的帐户的最有效方法?

Posted

技术标签:

【中文标题】检查用户是不是激活了他/她的帐户的最有效方法?【英文标题】:Most efficient way of checking if a user as activated his/her account?检查用户是否激活了他/她的帐户的最有效方法? 【发布时间】:2011-03-24 19:16:17 【问题描述】:

我希望我的用户在能够登录之前激活他们的帐户。注册后他们会收到一封包含激活链接的电子邮件,如下所示:

http://www.blabla.com/activate.php?email=blabla@blabla.com&token=Aisd23uNMAu53932asdDasd82AS

当然,每当有人登录时,我都必须检查该用户是否激活了他/她的帐户。我可以想到 2 种方法来解决这个问题,要么在我的“用户”表中有一个额外的列,当用户像这样激活时,它被设置为空:

-----------------------------------------------
| id | username | password | activation_token |
-----------------------------------------------
| 1  | user1    | blabla   |                  |
-----------------------------------------------
| 2  | user1    | blabla   | asd232DA34qADJs2 |
-----------------------------------------------

然后,每当用户登录时,我都会提取activation_token 以及用户信息。或者我可以有一个单独的表,其中仅包含激活令牌,然后在每次用户登录时加入“用户”表:

--------------------------------------
| id | account_id | activation_token |
--------------------------------------
| 1  | 37         | dsad2428491dka98 |
--------------------------------------
| 2  | 2          | asd232DA34qADJs2 |
--------------------------------------

那么哪一个最有效?感谢您的宝贵时间。

编辑:感谢所有精彩的回复

【问题讨论】:

我想说,随便挑一个就行了。标准化版本会更容易实现。 规范化表将为您节省一些数据库空间,但代价是更复杂的 SQL 查询。这两种解决方案都有效,所以只需选择一个。 正如其他人所说,因为在大多数情况下,对于任何帐户,此激活只会发生一次,因此速度可以忽略不计。 如果您使用第二种变体,您可以为验证类型添加另一列,并将其用于需要用户验证的各种类型的操作(初始激活、密码更改等) .). 我使用第二个,一旦用户激活他们的帐户并节省空间,我就可以删除激活密钥。 【参考方案1】:

就个人而言,我会做两者的结合......

-------------------------------------
| id | username | password | status |
-------------------------------------
| 1  | user1    | blabla   | 1      |
-------------------------------------
| 2  | user1    | blabla   | 0      |
-------------------------------------

其中状态是TINYINT(1) 字段,对于停用的用户为 0,对于已激活的用户为 1。这样,您可以非常快速地了解用户的“状态”......

然后,将令牌存储在另一个表中(就像您已经拥有的一样)...这样,您无需在未激活帐户时加入或检查字符串列...

【讨论】:

【参考方案2】:

使用第一个选项 - 将 isactivated 列添加到 USERS 表。

不需要单独的表 - 这是一对一的关系。

【讨论】:

【参考方案3】:

将令牌存储在用户表中而不是单独的表中意味着您不必在每次查询期间加入它们,这会稍微快一些。

此外,您不会存储用户 ID 并为该令牌表创建新 ID,这将节省数据存储空间。

【讨论】:

【参考方案4】:

我会有一个整数字段,Activated,默认为 0。当有人尝试进行身份验证时,您将只查找已激活的帐户。就像您描述的那样,我将身份验证令牌存储在单独的表中。

【讨论】:

【参考方案5】:

如果关系是 1-1(例如,激活表每个帐户 id 有 1 行),那么执行完全规范化的 2 表方法就有点过头了。

这两种方法都不会有大问题,但单表更容易。

如果您使用 2-table 方法,您应该在用户表中存储“激活”是/否标志,因此您无需加入第二个表以进行用户登录。

【讨论】:

【参考方案6】:

如果激活令牌仅用于验证“单击此处激活您的帐户”链接并且不再使用,那么在存储 char(32)(或其他任何内容)的用户表中浪费空间是没有意义的) 字段用于一次性使用。将激活令牌放在单独的表格中,当用户单击激活时,您的帐户激活脚本可以参考该表格。激活完成后,您可以从该单独的表中删除令牌的记录。

在用户表中放置一个“is_activated”布尔/位字段,您的登录脚本可以在登录过程中检查该字段(如果该字段为 null/false,则输出“嘿,您尚未激活”错误)。

当然,现在磁盘空间很便宜。即使是每个拥有 32char 激活令牌的一百万用户也只会“浪费”32meg 的空间。一个 TB 驱动器的价格不到 100 美元,占磁盘的 0.00305%,成本基本上是 0.00 美元(0.305 美分)。

【讨论】:

但是我还不如将激活令牌存储在用户表中?如果我已经计划存储“is_activated”布尔/位字段,那么我已经在使用额外的列“已保存” 表中的列数通常不是问题。这是列占用的空间量。 mysql 中的单个位字段至少占用 1 个字节的空间(1-7 位字段 = 1 个字节,8-15 个位字段 = 2 个字节,等等),而固定 char(32) 需要 32 个字节。因此,为代码创建一个单独的表将为每条记录节省 31 个字节,并且仅在激活过程处于活动状态时才占用空间。【参考方案7】:

我认为没有必要将激活令牌存储在 DB 中。像 md5('users@email' . 'secret') 这样的东西可以正常工作。至于用户状态,我同意其他人的观点,在用户表中使用单独的专用“状态”列。另一个优点是该列也可以存储其他统计信息(例如“禁止”;)

【讨论】:

【参考方案8】:

在我看来,与其将激活码存储在 users 表中,不如保留一个默认情况下将其设置为关闭的标志。当用户点击任何激活链接时,更新表格并设置标志。

在登录之前检查标志是否打开。 如果标志关闭,则用户没有点击激活链接。然后你可以给用户一个错误信息。

如果flag为on,则用户可以成功登录。

【讨论】:

以上是关于检查用户是不是激活了他/她的帐户的最有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

使用电子邮件地址检查 PayPal 帐户是不是存在?

Meteor 模板:检查用户是不是登录的最简单方法是啥?

检查表中是不是存在行的最有效方法是啥?

检查对象是不是为值类型的最有效方法

在 perl 中检查 $string 是不是以 $needle 开头的最有效方法

检查数组是不是包含Java中的值的最有效方法? [复制]