mysql - 使用 myisam 将激活 key 存储在单独的表中

标签 mysql transactions myisam activation

我想做一个登录系统。我想通过电子邮件发送激活码(可点击链接)进行确认。我考虑将激活 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/

相关文章:

mysql - 使用 MySQL 事件到 "deactivate"帐户

php - Codeigniter mysql 查询 AND_OR

java - 如何将 @EnableTransactionManagement 与 StaticMethodMatcherPointcutAdvisor 结合使用

mysql - MyISAM不是InnoDB的替代品吗?

MySQL全文检索外键包含的数据

mysql - 迁移php4/mysql4到php5/mysql5 : switch to InnoDB?

mysql - 访问具有多个名称的一张表

mysql - 尝试查看表时 MySQL 命令行客户端出现 1064 错误,但在 MySQL Workbench 中工作正常

mysql - MongoDB 4.0 : e-commerce Apps

java - JTA事务意外回滚,嵌套异常为javax.transaction.RollbackException