我正在使用Oracle
创建ID使用max(id)+1和使用sequance.nexval,使用何时以及何时使用有什么区别?
喜欢:
insert into student (id,name) values (select max(id)+1 from student, 'abc');
Run Code Online (Sandbox Code Playgroud)
和
insert into student (id,name) values (SQ_STUDENT.nextval, 'abc');
Run Code Online (Sandbox Code Playgroud)
SQ_STUDENT.nextval 有时给出重复记录的错误...
请帮我解决这个疑问
Ale*_*ole 34
使用该select max(id) + 1方法,同时插入两个会话将从表中看到相同的当前最大ID,并且两者都插入相同的新ID值.安全使用它的唯一方法是在启动事务之前锁定表,这很麻烦并且序列化事务.(正如Stijn指出的那样,如果删除最高记录,则可以重复使用值).基本上,永远不要使用这种方法.(可能偶尔有一个令人信服的理由这样做,但我不确定我曾经见过一个).
该序列保证两个会话将获得不同的值,并且不需要序列化.它性能更好,更安全,更容易编码,更易于维护.
使用序列可以获得重复错误的唯一方法是,如果表中已存在ID高于序列值的记录,或者某些内容仍在插入记录而不使用序列.因此,如果您有一个手动输入ID的现有表,例如1到10,并且您创建了一个默认开始值为1的序列,则使用该序列的第一个插入将尝试插入ID为1 - 已经存在.在尝试了10次之后,序列会给你11次,这将起作用.如果你然后使用max-ID方法进行下一次使用12的插入,但序列仍然是11,并且下次你打电话时也会给你12 nextval.
序列和表格无关.如果将手动生成的ID值插入表中,则序列不会自动更新,因此这两种方法不会混合.(除此之外,相同的序列可用于为多个表生成ID,如文档中所述).
如果您要从手动方法更改为序列方法,则需要确保使用高于表中所有现有ID的start-with值创建序列,并且执行插入操作的所有内容都使用序列只在将来.
Jus*_*ave 10
如果您打算拥有多个用户,则使用序列可以正常工作.使用a max不.
如果您执行a max(id) + 1并允许多个用户,则同时运行的多个会话将定期查看相同的内容max,从而生成相同的新密钥.假设您已正确配置了约束,那么将产生您必须处理的错误.INSERT如果其他会话在您的会话重试之前阻塞了您,那么您可以通过重试可能会一次又一次地失败来处理它,但这对于每个INSERT操作来说都是很多额外的代码.
它还将序列化您的代码.如果我在会话中插入一个新行并在我记得提交之前去吃午餐(或者我的客户端应用程序在我提交之前崩溃),那么在我回来并提交或者提交之前,将禁止每个其他用户插入新行DBA终止我的会话,强制重启.
| 归档时间: |
|
| 查看次数: |
17049 次 |
| 最近记录: |