MySQL自增ID作为用户ID使用是否安全?

13

我正在开发一个允许用户在线创建个人资料的网站。我想知道是否将MySQL的AUTO_INCREMENT用作我的用户ID是正确的选择,同时考虑到将来可能需要在多个服务器上复制数据库?

例如,在像Twitter或Facebook这样的网站上,您会使用此方法作为userId吗?


我之前尝试过使用PHP生成userId。我使用了类似于以下代码:

function generateID() {
      $possible = "1234567890";
      $code = "";
      $characters = mt_rand(7,14);
      $i = 0;
      while ($i < $characters) { 
            $code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
            $i++;
      }
      return $code;
}

这提供了我需要的值类型,但我总是不得不从数据库中检查该ID是否尚不存在。

难道没有更好的方法吗?

5个回答

27

使用mysql自增ID作为用户ID安全吗?

如果您的安全系统可靠,基本上是安全的。但通常情况下,Web开发人员会感到不舒服,因为暴露了允许通过增加或减少数字来猜测其他ID的ID。许多人转而使用随机的多位数ID。

更为隐晦的是,数字ID也可能允许竞争对手通过跟踪递增值的增加来估计您的增长。


生成“随机的多位数ID”的最佳实践是否应该像OP建议的那样?即在服务器上生成ID,然后确保在分配之前它不存在于数据库中。 - theyuv

5

不,使用auto_increment ids并不是一个好主意,因为这些id不容易迁移。对于用户id,您需要能够备份、恢复、在数据库实例之间移动等而不必担心id冲突的id。

最好使用类似UUID的东西生成唯一的数字或字母数字字符串。


没有什么阻止你创建复合键.. 我不会点踩,但你对使用auto_increment的快速放弃有些草率。 - N.B.

2

如果您打算提前规划并可能将数据分布在多个数据库中,最好考虑使用UUID()函数来获取唯一标识符。这将使未来的数据合并更加容易。


复合主键比UUID()更好的解决方案,用于合并数据。 - N.B.
在这个问题上有两种不同的观点 - 你可以使用人工生成的键来唯一地标识某个人,或者使用一个复合主键 - 比如说,Joe Celko支持后一种方法。 - Andrew
谢谢。我以前从未使用过UUID()。根据我在互联网上看到的大多数示例,它会创建长ID,例如1E8EF774581C102CBCFEF1AB81872213,我是对的吗?如果是这样,有没有办法让它们更短?或者有人可以向我推荐一个更好地解释这个函数的网站(我认为我并不是很理解)?谢谢。 - Sthe
1
@Sthe - 复合主键可能是你的解决方案。它是一个自动递增索引,附加了另外一个或多个整数类型的列。如果你的 id 字段是自动递增的,你可以添加另一个字段叫做 server_id,然后将你的主键定义为 PRIMARY KEY(id, server_id)。每个服务器都有一个数字来标识它(比如说从1到10),然后你的自动递增就像往常一样工作,并且通过服务器ID进行区分。另一种方法是使用UUID生成更长的值。 - N.B.

0

就个人而言,我认为在某种程度上是这样的。

当使用自动增量字段复制数据库表时,我认为该字段会保留其最大值(取决于您如何复制它,我所考虑的情况是带有数据的mysqldump),因此当您添加新行时,它将被分配下一个ID。

但是,如果您要同时在多个数据库上运行此操作,并且它们没有被复制,您需要其他方式来生成ID,以避免获取具有相同ID的行(尽管我想不出会这样做的场景)。

我无法确定这是否是最佳实践,但肯定可以正常工作。


0

是的,如果您删除了一个带有ID 7的行,则自动递增的下一个值将是8而不是再次变成7。因此,所有值肯定是唯一的,并且您需要截断表以重新开始自动递增。因此,您始终可以使用自动递增字段作为用户ID。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接