0

我正在尝试设计一个带有主键的简单用户表userid,然后是另一个userid用作该表的外键的users表。我在这里有正确的想法吗?

CREATE TABLE `users` (
    `userid` INT(6) NOT NULL,
    `username` VARCHAR(50) NOT NULL,
    `password` VARCHAR(50) NOT NULL,
    `date_join` DATE NOT NULL,       <- should I just make this CURDATE instead?
    `user_handle` VARCHAR(50) NOT NULL,
    `date_modified` DATE NOT NULL,
    PRIMARY KEY (`userid`)
)

1)如何使用户名自动递增?

2)如何将密码存储为 MD5 哈希?另外,我已经阅读了各种强烈推荐 brcrypt 的编码器,想法?

3) 如何将默认值设置user_handle为电子邮件的第一部分在@符号之前?这样john@smith.com会产生一个用户句柄john

4) 在设计用户数据库时我应该采取什么额外的安全措施?

5) 与用户关联的其他表中的外键是否需要指向用户的外键userid

非常感谢大家,我希望这不是太多问题!

4

2 回答 2

3
  1. 如何使用户 ID 自动递增?

    指定列AUTO_INCREMENT上的属性userid

    CREATE TABLE `users` (
        `userid` INT(6) NOT NULL AUTO_INCREMENT,
        -- etc.
    
  2. 如何将密码存储为 MD5 哈希?另外,我已经阅读了各种强烈推荐 brcrypt 的编码器,想法?

    推荐 bcrypt 而不是 MD5 用于散列密码的主要原因是 bcrypt 是为此目的而设计的,而 MD5 旨在验证消息的完整性:因此 bcrypt 故意慢,而 MD5 故意快。这意味着与 MD5 相比,攻击者需要做更多的工作来暴力破解 bcrypt 哈希。

    由于这两个函数都产生固定大小的二进制输出(在 MD5 的情况下为 16 字节,在 bcrypt 的情况下为 56 字节),一个合理的列类型是BINARYBINARY(16)对于 MD5 和BINARY(56)bcrypt。

    在任何一种情况下,你都应该确保你的哈希值加盐。Salt是一个随机字符串,在计算(最终)哈希之前与用户密码连接:使用的salt与用户记录一起存储在数据库中,但对于每个用户来说都是不同的。如果您的数据库遭到破坏,这可以击败彩虹表攻击以恢复用户的密码。

    执行这些操作所涉及的实际代码将取决于您开发应用程序所使用的语言、库和/或框架。

  3. 如何将默认值设置为符号user_handle之前的电子邮件的第一部分?@这样john@smith.com会产生一个用户句柄john

    这样的逻辑可能最适合您的应用程序代码,但也可以使用 MySQL 的函数在 SQLINSERT语句中完成:SUBSTRING_INDEX()

    INSERT INTO users VALUES (
      -- [ deletia ]
      SUBSTRING_INDEX('john@smith.com', '@', 1),
      -- [ deletia ]
    );
    
  4. 在设计用户数据库时我应该采取哪些额外的安全措施?

    我强烈建议您阅读这篇出色的文章,以全面了解相关安全概念。

  5. 与用户关联的其他表中的外键是否需要指向用户的外键userid

    是的。外键的存在是因为它被用于该目的;如果您希望在 MySQL 中强制执行外键约束(即确保引用的记录存在于外部表中),您将需要对本地表和外部表使用 InnoDB 存储引擎;此外,索引必须存在于密钥的本地和外部副本上。然后使用如下子句在引用表中定义约束:

    FOREIGN KEY (userid) REFERENCES users (userid)
    
于 2012-08-27T01:12:12.257 回答
2
  1. 假设您有能力修改您的CREATE TABLE陈述,您可以这样做:

    CREATE TABLE `users` (
        `userid` INT(6) NOT NULL AUTO_INCREMENT,
        ...
    )
    
  2. 通常,您在数据库之上运行的服务器将自己生成密码哈希(在注册和登录时),然后将哈希作为字符串传递给数据库。所以从数据库的角度来看,你的模式很适合这个。或者几乎没问题,具体取决于密码哈希的最终长度。

  3. 同样,这通常是您在服务器代码(甚至在 JavaScript 中)而不是在数据库本身中处理的事情。一个简单的字符串split()substring()将完成这项工作。如果您真的想在数据库中执行此操作,您可以使用触发器来检测插入事件并设置所需的默认值。

  4. 是的。 给你的密码加盐

  5. 是的,您的其他表将有一个引用userid“用户”中的字段的键。就像是:

    CONSTRAINT `FK3FD7C193F39FADA` FOREIGN KEY (`owner_id`) REFERENCES `users` (`userid`)
    
于 2012-08-27T01:01:13.823 回答