Mysql:复合主键中的autoincrement字段,用于其他字段的每个唯一组合

use*_*355 5 mysql mysql-workbench

我有一个带有复合主键的Mysql表.
我需要主键的一个字段分别为其他两个字段的每个唯一对自动增量.
例如:

Book_Name | Author_Name | 第一
册第1页 作者1 | 1
Book1 | 作者1 | 2
Book1 | 作者1 | 3
Book2 | 作者2 | 1
Book2 | 作者2 | 2
Book2 | 作者2 | 3
Book3 | 作者3 | 1
Book3 | 作者3 | 2
Book3 | 作者3 | 3


有谁知道如何在Mysql Workbench中完成这项工作?

Mic*_*bot 8

只有(书籍,作者,章节)才能成为主键,并且章节只能在一种情况下为每个独特的(书籍,作者)组合自动增加:

存储引擎必须是MyISAM.

MyISAM像这样定义的表将完全按照您的预期运行,从"1"开始为每个唯一(a,b)的列"c":

CREATE TABLE `aa_test` (
  `a` varchar(48) NOT NULL,
  `b` varchar(48) NOT NULL,
  `c` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`a`,`b`,`c`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

但是,不要这样做.

至少有以下原因:

首先,您不应该使用MyISAM.它是一种非常古老的技术恐龙,它不是交易性的,并且它不像InnoDB腐败和崩溃恢复那样强大.您应该使用InnoDB,而MyISAM中的这种遗留行为并不是以不同方式做到这一点的理由.

其次,这并不适合使用自动增量.实际上,自动增量应仅用于作为代理值所需但在现实世界中没有实际意义的值.

第三,你的桌子似乎没有精心设计,甚至可能不是第二范式.

基于这种结构,两件事之一必须是真的:

一本书的每一章都可以有一个不同的作者,这打破了尝试自动增加(书籍,作者)......或者(更可能)每一行都存在作者属性的全部内容(书籍,章节)是多余的.

可以说,这个表中唯一的候选键是(书,章),如果作者不依赖于书和章,则该表不在2NF中.

此外,您不应该在每行中存储书籍的名称.任何给定的数据应该只出现在关系数据库的单个表中的单个行中的单个列中,其他每个都通过键引用它(例如,"book_id"在这里引用单个"id" "book"表,其中包含本书"标题"的列.

那么,我的答案是建议你不要试图解决正确的问题,并且应该考虑重新设计你的结构,以便作者是一本书中的书的属性,每本书只有一行,然后你就有了这个表(书,章),您的应用程序可以手动填充这些章节号.

或者,如果您坚持自动生成这些值,则可以使用BEFORE INSERT触发器计算插入时的适当值,包含如下逻辑:

IF IFNULL(NEW.Chapter,0) = 0 THEN  
  SET NEW.Chapter = (SELECT COUNT(1) FROM this_table_name x
                      WHERE x.Book_Name = NEW.Book_Name
                        AND x.Author_Name = NEW.Author_Name) + 1;
END IF;
Run Code Online (Sandbox Code Playgroud)

具有此逻辑的触发器可用于任何存储引擎.

IFNULL()是必需的,因为当列不可为空时,MySQL在触发触发器之前历史上将null强制为0,即使此行为不正确.