因此,在此应用中,我们有user id
,这很简单auto-increment primary key
。由于我们不希望在客户端公开此内容,因此我们将使用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查询。那么有更好的方法吗?
答案 0 :(得分:1)
因为我们不想在客户端公开这个
只是不要。
在设计良好的数据库中,用户永远不需要查看主键值。实际上,用户甚至不需要知道主键是否存在。
根据您的问题,您似乎实际上用代理ID替换了正常的自动增量ID列(如果没有跳到最后一段)。
尝试使用另一个唯一的代理ID创建一个列,并在前端使用它。并且您可以保留正常的主要ID用于关系等。'
请记住主键的基本必须规则之一:
整数序列也具有易于使用和实现的优点。它们还取决于序列化方法的具体实现,具有可快速导出的优点,因为大多数数据库仅将序列号存储在固定位置。意味着代替max(id)+1
数据库已经存储并快速自动递增。
所以我们正在进行插入然后获取last_insert_id然后使用 对于user_id`,它会添加一个额外的数据库查询。
last_insert_id
当您执行插入查询时,它实际上不是查询,而是数据库连接中保存的变量。
如果您的代理人ID已经有第二列,请忽略以上所有内容:
所以我们正在进行插入然后获取last_insert_id然后使用 对于user_id`,它添加了一个额外的数据库查询。有没有 更好的方法吗?
不,你只能通过查询来检索那个uniqid。
$res = mysql_query('SELECT LAST_INSERT_ID()');
$row = mysql_fetch_array($res);
$lastsurrogateid = $row['surrogate_id'];
其他任何事情都使得它变得更加复杂。
答案 1 :(得分:1)
在实际答案之前的一些事情:使用InnoDB作为默认存储引擎的MySQL的最新版本 - 你总是想要一个整数pk (或着名的auto_increment)。原因主要是表现。有关更多信息,您可以研究InnoDB如何使用PK聚类记录以及它为何如此重要。除此之外,让我们考虑创建一个独特的代理键的选项。
您自己使用PHP和从MySQL获得的信息(last_insert_id()
)自行计算,然后重新更新数据库。
优点:即使是新手程序员也很容易理解,产生短代理键。
缺点:对于并发访问非常糟糕,您可能会发生冲突,并且您永远不想使用PHP来计算数据库所需的唯一索引。 你不想要那个选项
为您的查询提供uniqid()
,创建一个AFTER INSERT
触发器,将uniqid()
与auto_increment连接。
优点:易于理解,产生短代理键。
缺点:要求您创建触发器,实现直接从代码中看不到的魔法,这肯定会混淆某个时候继承项目的开发人员 - 以及经验我会打赌坏事会发生
使用通用唯一标识符或UUID(也称为GUID)。只需提供surrogate_key = UUID()
的查询,MySQL完成其余的工作。
优点:永远独一无二,无需魔法,易于理解。
缺点:无,除非占据36个字符的事实困扰你。
您需要选项3。