为自动递增字段创建唯一的用户散列


creating unique user hash for autoincrement field

所以在这个应用程序中,我们有一个简单的auto-increment primary keyuser id。因为我们不想在客户端公开它,所以我们将使用simple hash (encryption不重要,只有obfuscation)。

所以当一个用户被添加到表中时,我们执行uniqid(). user_id。这将保证user hash是足够的random并且总是unique

我的问题是,在插入记录时,我们不知道此时的用户id(不能假设是max(user_id) + 1),因为可能会提交插入。所以我们正在做一个插入,然后得到last_insert_id then using that for the user_id ',这增加了一个额外的db查询。那么有没有更好的办法呢?

在实际答案之前,有几件事:在最新版本的MySQL中,使用InnoDB作为默认存储引擎-您总是需要一个整数pk(或著名的auto_increment)。原因主要是性能。要了解更多信息,您可以研究InnoDB集群如何使用PK进行记录以及为什么它如此重要。解决了这个问题后,让我们考虑创建唯一代理键的选项。

选项1

你自己计算,使用PHP和你从MySQL (last_insert_id())获得的信息,然后你更新数据库回来。

优点:即使是新手程序员也容易理解,生成简短的代理键。

Cons:对于并发访问来说非常糟糕,您可能会遇到冲突,并且您永远不想使用PHP来计算数据库所需的唯一索引。你不需要这个选项

选项2

为您的查询提供uniqid(),创建一个AFTER INSERT触发器,将uniqid()与auto_increment连接起来。

优点:易于理解,生成简短的代理键。

Cons:要求您创建触发器,实现代码中不直接可见的魔法,这肯定会使继承项目的开发人员在某些时候感到困惑-从经验来看,我敢打赌会发生不好的事情

选项3

使用通用唯一标识符或uuid(也称为GUIDs)。只需提供surrogate_key = UUID()查询,MySQL就会完成其余的工作。

优点:总是独特的,不需要魔法,容易理解。

Cons: none,除非它占用了36个字符。

选择3

因为我们不想在客户端公开这个

不。

在设计良好的数据库中,用户永远不需要看到主键值。实际上,用户甚至不需要知道主键的存在。

从你的问题来看,似乎你实际上用代理ID替换了正常的自动增量ID列(如果不跳到最后一段)。

尝试用另一个唯一代理ID创建一个列,并在您的前端使用它。你可以保留正常的主id用于关系等。

请记住主键的基本规则之一:

  • 主键必须紧凑,包含尽可能少的属性。

整数序列还具有易于使用和实现的优点。根据序列化方法的具体实现,它们还具有快速派生的优点,因为大多数数据库只是将序列号存储在固定位置。这意味着db已经存储了max(id)+1,并且可以快速自动递增。

我们先执行插入操作,然后获取last_insert_id,然后使用对于theuser_id ',它增加了一个额外的数据库查询。

last_insert_id实际上不是一个查询,而是在您执行插入查询时在数据库连接中保存的变量。

如果您已经为代理ID设置了第二列,则忽略以上所有内容:

我们先执行插入操作,然后获取last_insert_id,然后使用对于theuser_id ',它添加了一个额外的数据库查询。所以有没有有更好的方法吗?

不,你只能通过查询来获取那个唯一id。

$res = mysql_query('SELECT LAST_INSERT_ID()');
$row = mysql_fetch_array($res);
$lastsurrogateid = $row['surrogate_id'];