具有重复值和多列主键的SQL自动增量ID?

时间:2016-08-09 14:53:17

标签: mysql sql auto-increment

CREATE TABLE Apps
(
    id int NOT NULL,
    company varChar(20) NOT NULL,
    name varChar(20) NOT NULL,
    CONSTRAINT company_app_id PRIMARY KEY (id, company)
)

-------------------------------------
| id  | company      | name         |
-------------------------------------
|  1  | Google       | Google Maps  |
|  2  | Google       | Gmail        |
|  1  | Apple        | Safari       |
|  3  | Google       | Chrome       |
|  2  | Apple        | Pages        |
-------------------------------------

在SQL中有没有办法构建上面的表,允许它自动增加特定于公司的id?因此,如果下一个条目是谷歌应用程序,它会自动将id增加到4,如果之后的条目是应用程序,它会自动将id增加到2?

由于

1 个答案:

答案 0 :(得分:3)

不,除非您的INSERT执行表锁,否则无法执行此操作。原因是INSERT必须弄清楚到目前为止您为该公司插入一行的最大值。具有该最大值的行可以是表中的任何位置。 INSERT必须搜索它,同时阻止任何其他INSERT同时运行,否则你就会遇到竞争条件。

INSERT到InnoDB表不支持此表锁定行为。 InnoDB可以进行自动增量,只允许并发INSERT,因为它跟踪每个表的一个最大值,并且它只增加,它不会向后移动或者"撤消"递增。

当使用复合主键时,MyISAM支持每个不同增量值的功能。毕竟,MyISAM已经为INSERT或其他更新执行了表锁定。在我看来,这个功能还不足以成为使用MyISAM的理由。

正如@sgeddes在上面评论的那样,无论如何,这样做的价值是值得怀疑的。当出现间隙时,您会怎么做,例如,如果删除行或是否回滚INSERT?您是否必须重新编号主键,可能会更新数千行?您是否尝试将后续行插入间隙?这将需要另一个表锁,搜索间隙并阻止其他插入。

基本上,请牢记此规则:主键不是行号。请勿将其视为一个。主键需要具有唯一值 - 但不是连续值。

重新评论:不,你不应该认为自动增加数字有任何意义,甚至不是创造的顺序。首先,auto-inc值的顺序并不总是行提交的顺序。

采取Rails告诉你的有关数据库的任何东西都是一个好主意。 Rails的设计者真的非常希望数据库开发比它简单。在过去的10年里,Rails对开发人员造成了巨大的损害。