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

SQL autoincrement id with duplicate values and multiple column primary keys?

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 中有没有一种方法可以构建上面的 table 允许它自动增加特定于公司的 ID?因此,如果下一个条目是 Google 应用程序,它会将 id 自动递增到 4,如果之后的条目是 Apply 应用程序,它会自动将 id 递增到 2?

谢谢

不,除非您的 INSERT 执行 table-lock,否则无法执行此操作。原因是 INSERT 必须计算出您要为其插入行的相应公司到目前为止的最大值是多少。具有该最大值的行可以在 table 中的任何位置。并且 INSERT 必须搜索它,同时阻止 运行 中的任何其他 INSERT 同时进行,否则就会出现竞争条件。

INSERT 到 InnoDB table 不支持这种 table 锁定行为。 InnoDB 可以执行允许并发 INSERT 的自动增量,仅因为它跟踪每个 table 的一个最大值并且它只增量,它不会向后移动或 "undo" 增量。

MyISAM 在使用复合主键时支持按不同值递增的功能。毕竟,MyISAM 已经为 INSERT 或其他更新做了一个 table-lock。在我看来,这个特性不足以成为使用 MyISAM 的理由。

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

基本上,请牢记这条规则:主键不是行号。不要将其视为行号。主键必须具有唯一值,但不能是连续值。


回复你的评论:不,你不应该认为自动递增数字有任何意义,甚至是创建顺序。一方面,auto-inc 值的顺序并不总是提交行的顺序。

最好对 Rails 告诉您的有关数据库的任何内容持保留态度。 Rails 的设计者真的非常希望数据库开发比现在更简单。 Rails 在过去 10 年中对开发人员造成了巨大的伤害。