我们有现有的表:
| id | name | color | calories |
------------------------------------------
| 1 | apple | red | 20 |
| 2 | orange | orange | 10 |
| 3 | grapes | green | 5 |
| 4 | bananas | yellow | 15 |
| 5 | plum | purple | 25 |
------------------------------------------
Run Code Online (Sandbox Code Playgroud)
列id
是唯一的主键。我在编辑/更新记录时遇到了问题,当我注意更改例如第 3 行,id = 3
到id = 5
第 5 行,id = 5
到id = 3
...就像在第 3行和第 5行之间交换 id。当然有重复,但是如何解决这种情况...
但是 MySQL 从逻辑上抛出了错误。
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '5' for key 'PRIMARY'
Run Code Online (Sandbox Code Playgroud)
我知道这是一个愚蠢的场景,但我们有一个客户想要这样。他想编辑/更新每个现有记录。
Phi*_* W. 17
列 id 是唯一的和主键......就像在第 3 行和第 5 行之间交换 id。
你不应该这样做。
任何记录的主键应该创建/套/第一次创建记录和产生它应该永远不会改变,而不是对整个使用寿命该记录的,说得最多的点记录时最终被删除。
想象一下,如果银行对人们的银行账户进行重新编号,会造成怎样的混乱!
此外,虽然您在这里(还)似乎没有它们,但拥有主键的主要好处之一是其他表可以拥有引用它的外键。如果您开始更改主键值,那么您还必须更改所有相应的外键值(数据库将强制执行此操作)。
我严重怀疑任何用户都会理解这一点。
... 客户 ... 想要编辑/更新每个现有记录。
无论如何允许他们编辑数据,而不是主键。
我将假设您为此提供了某种 UI,并且他们不会直接针对数据库发出 SQL。
如果他们试图将它用作某种序列或“订单”,那么使用单独的列是可行的方法。主键,即使是自动递增的,也保证是唯一的;不保证它们是连续的或连续的。
这些应该使用中间值包装在事务中;
begin;
set @from = 3;
set @to = 5;
set @tmpid = (2000000 + @from % 147483647);
update col set id=@tmpid where id = @from;
update col set id=@from where id=@to;
update col set id=@to where id = @tmpid;
commit;
Run Code Online (Sandbox Code Playgroud)
选择高端 @tmpid 命名空间以避免冲突很重要,以免以后遇到麻烦。
归档时间: |
|
查看次数: |
1030 次 |
最近记录: |