使用 myisam 将激活密钥存储在分隔表中
Posted
技术标签:
【中文标题】使用 myisam 将激活密钥存储在分隔表中【英文标题】:Store activation key in separated table using myisam 【发布时间】:2014-03-25 08:57:31 【问题描述】:我想做一个登录系统。我想通过电子邮件发送激活码(可点击的链接)来确认。我考虑将激活密钥与用户信息存储在单独的表中,因为这些仅与未激活的用户相关。当用户注册时,将在用户表中插入包含用户信息的行,并在激活表中插入激活密钥。单击链接后,我会从激活表中删除记录。 但是由于我无法在我的主机上使用 innodb,所以这不是防错的,因为我不能使用事务。我有两个选择。 选项 A: 我将密钥保存在激活表中。 我在用户表中存储了一个布尔值来检查是否需要激活。如果需要激活并且在激活表中找不到记录,则可以重新尝试添加记录并重新向用户发送电子邮件。 * 更多检查(php,以防找不到记录) * 加入选择检查 * 更多的插入/删除/更新
选项 B: 或者我可以将激活密钥存储在用户表中,而不得不使用更多空间,而这并不总是使用。 *未使用的存储是否总是使用 myisam 占用空间? *激活密钥的推荐长度是多少? *是否仍然需要布尔值,或者我可以将激活密钥设置为 NULL 以检查用户是否已被激活?
什么是最好的解决方案,为什么?速度、空间……?
【问题讨论】:
【参考方案1】:您问题的核心似乎与激活的时刻有关。您似乎担心您会在激活时遇到事务性竞争条件,并且您将无法阻止它,因为您必须使用 MyISAM 而不是 InnoDB。
这似乎不是一个关键问题。如果新用户尝试使用相同的正确令牌多次激活,或者如果她尝试同时使用不正确的令牌作为正确令牌进行激活,则不会造成任何损害。
什么是关键的成功因素?为活动用户执行正常的身份验证操作(登录)。如果您的查询必须为每个登录的用户加入一个单独的激活令牌表,那么这不会为您提供理想的性能。查询也不包含这样的子句:
AND user.activation_token IS NOT NULL
您可能希望使用布尔列值(一个短整数)来指示用户表中的“激活待定”。如果该列在正常登录期间出现,您可以调用额外的、不经常使用的逻辑来激活。例如,如果您需要能够加速此操作:
SELECT hashed_password, activation_pending
FROM user
WHERE username = ?
您可以在(username, hashed_password, activation_pending)
上创建一个复合索引并使该操作非常高效。那么当你成功完成挂起激活(相对不频繁的操作)后,就可以进行这两个操作了。
UPDATE user
SET activation_pending = 0
WHERE user = ?;
DELETE
FROM activation_token
WHERE user = ?;
一旦 activation_pending
设置为零,这对于竞争条件就足够了:您的逻辑不会查看您的 activation_token 表。
varchar
列如果包含零长度字符串,则不会占用太多空间。 char
列。
【讨论】:
非常感谢!这很有道理!以上是关于使用 myisam 将激活密钥存储在分隔表中的主要内容,如果未能解决你的问题,请参考以下文章