【发布时间】:2015-12-24 08:26:42
【问题描述】:
在 InnoDB MySQL 存储引擎中,存储过程用于生成 tbaaa000000 形式的主键值。
密钥生成
因此,主键的格式为:
对于固定长度,例如 l,第一个 two 字符表示 table_name,接下来的 m 是字母,其余 (l-2-m) 是数字(只有数字)。
存储过程已被编码为使用动态 SQL 手动增加最右边的 m+n 块字符。这是通过查找表中存在的最大 ID(比如 tbaaa999999 )并将其递增(到 tbaab000000)来完成的。通过动态 SQL,我的意思是它已被用于在运行时通过在查询中合并变量来动态构建 SQL 语句。
表单提交
假设我们正在尝试为表Table1 生成这个主键。另外,我们还有另一个表(比如Table2),它引用了Table1 的主键(Table2 在Table1 上有一个外键)。
现在,使用 PHP 脚本将表单提交到服务器,该脚本将表单数据插入 Table1 和 Table2。但是,主键 ID 是在执行 Table1 的查询期间使用存储过程生成的,但是即使对于 Table2 的插入查询,该 ID 也是同时需要的,这在 PHP 脚本中是未知的。
另外,可能有多个客户端试图访问该页面,因此 PHP 脚本会为所有用户运行,因此生成的存储过程可能会为多个用户生成相同的主键 ID。
我的问题:
- 由于请求的并发性,我如何管理
Table1中唯一 ID 的生成和插入? - 如何在 PHP 脚本中获取生成的 Table1 的主键以插入到
Table2?
SO 鼓励我将我尝试过的内容包括在内,因此我将自己的努力包括在内。但是,我不希望限制答案的范围,所以请在阅读我的试用版之前尝试考虑一种方法。
我想到的方法:
我们可以从 PHP 脚本中调用一个过程,该过程将插入数据作为参数并生成主键 ID Table1 并将数据插入到两个表中。但是,这会失败,因为整个过程仍然可以为并发请求生成相同的 ID。
我还在 PHP 脚本末尾探索了一个 try-catch 方法,该方法将调用一个函数来生成 ID 并将其返回给 PHP 脚本。然后,这将尝试插入Table1,如果相同的 ID 已经存在(可能是由于另一个用户的并发另一个插入处理),这将失败并抛出一个duplicate key exception 并再次尝试生成,从而提供唯一性。但是,我不确定这种方法,因为这可能效率低下并且可能导致性能问题。
【问题讨论】:
标签: php mysql database concurrency primary-key