我想做一个登录系统。我想通过电子邮件发送激活码(可点击链接)进行确认。我考虑将激活 key 与用户信息存储在单独的表中,因为这些仅与未激活的用户相关。当用户注册时,包含用户信息的行将被插入到用户表中,并且激活 key 将被插入到激活表中。单击链接后,我将从激活表中删除该记录。 但由于我无法在我的主机上使用 innodb,所以这不是防错的,因为我无法使用事务。我有两个选择。 选项A: 我将 key 保存在激活表中。 我在用户表中存储一个 bool 值来检查是否需要激活。如果需要激活并且激活表中没有找到记录,则可以重新尝试添加记录并向用户重新发送电子邮件。 * 更多检查(php,以防没有找到记录) * 加入select进行检查 * 更多插入/删除/更新
选项B: 或者我可以将激活 key 存储在用户表中,但必须使用更多空间,而这并不总是被使用。 *使用myisam时未使用的存储是否总是占用空间? *激活 key 的建议长度是多少? *是否仍然需要 bool 值,或者我可以将激活 key 设置为 NULL 以检查用户是否已激活?
最好的解决方案是什么?为什么?速度、空间……?
最佳答案
你的问题的核心似乎与激活的时刻有关。您似乎担心在激活时会遇到事务竞争条件,并且无法阻止它,因为您必须使用 MyISAM 而不是 InnoDB。
这似乎不是一个关键问题。如果新用户尝试使用相同的正确 token 多次激活,或者尝试同时使用错误的 token 和正确的 token 激活,则不会造成任何损害。
什么是成功的关键因素?事件用户的正常身份验证操作(登录)的性能。如果您的查询必须为每个登录用户连接到单独的激活 token 表,那么这不会为您提供理想的性能。也不包含这样的子句的查询:
AND user.activation_token IS NOT NULL
您可能需要使用 bool 列值(短整数)来指示用户表中的“激活待处理”。如果该列在正常登录期间显示为 true,则您可以调用额外的、不常用的激活逻辑。例如,如果您需要能够加速此操作:
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
列可以。
关于mysql - 使用 myisam 将激活 key 存储在单独的表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21975185/