我想做一个登录系统。我希望通过电子邮件发送激活码(可点击链接)进行确认。我考虑将激活密钥存储在与用户信息分开的表中,因为这些只与未激活的用户相关。当用户注册时,包含用户信息的行将被插入到users表中,而激活密钥将被插入激活表中。单击链接后,我将从激活表中删除该记录。但是由于我没有办法在我的主机上使用innodb,这是不可靠的,因为我不能使用事务。我有两个选择。选项A:我将密钥保存在激活表中。我在用户表中存储了一个布尔值,以检查是否需要激活。如果需要激活,并且在激活表中找不到记录,则可能会重新尝试添加记录并向用户重新发送电子邮件。*更多检查(php,如果没有找到记录)*加入selects进行检查*更多插入/删除/更新
选项B:或者我可以将激活密钥存储在用户表中,这样就必须使用更多的空间,而这些空间并不总是被使用。*未使用的存储是否总是使用myisam占用空间?*建议的激活密钥长度是多少?*是否仍然需要布尔值,或者是否可以将激活密钥设置为空,以检查用户是否已被激活?
最好的解决方案是什么?为什么?速度,空间,...?
发布于 2014-02-24 06:31:35
你问题的核心似乎与激活的时刻有关。你似乎担心你会得到一个围绕激活的事务竞争条件,你将无法阻止它,因为你必须使用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
设置为0,就足以满足竞争条件:您的逻辑将不会查看您的activation_token表。
如果varchar
列包含长度为零的字符串,则它们不会占用太多空间。char
列就是这样。
https://stackoverflow.com/questions/21975185
复制相似问题