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?
由于
答案 0 :(得分:3)
不,除非您的INSERT执行表锁,否则无法执行此操作。原因是INSERT必须弄清楚到目前为止您为该公司插入一行的最大值。具有该最大值的行可以是表中的任何位置。 INSERT必须搜索它,同时阻止任何其他INSERT同时运行,否则你就会遇到竞争条件。
INSERT到InnoDB表不支持此表锁定行为。 InnoDB可以进行自动增量,只允许并发INSERT,因为它跟踪每个表的一个最大值,并且它只增加,它不会向后移动或者"撤消"递增。
当使用复合主键时,MyISAM支持每个不同增量值的功能。毕竟,MyISAM已经为INSERT或其他更新执行了表锁定。在我看来,这个功能还不足以成为使用MyISAM的理由。
正如@sgeddes在上面评论的那样,无论如何,这样做的价值是值得怀疑的。当出现间隙时,您会怎么做,例如,如果删除行或是否回滚INSERT?您是否必须重新编号主键,可能会更新数千行?您是否尝试将后续行插入间隙?这将需要另一个表锁,搜索间隙并阻止其他插入。
基本上,请牢记此规则:主键不是行号。请勿将其视为一个。主键需要具有唯一值 - 但不是连续值。
重新评论:不,你不应该认为自动增加数字有任何意义,甚至不是创造的顺序。首先,auto-inc值的顺序并不总是行提交的顺序。
采取Rails告诉你的有关数据库的任何东西都是一个好主意。 Rails的设计者真的非常希望数据库开发比它简单。在过去的10年里,Rails对开发人员造成了巨大的损害。