复合键 - 一个是外键,另一个是自动递增

时间:2013-07-17 17:24:10

标签: mysql composite

我在MySQL中创建表时遇到问题。基本上,我需要一个使用“client_id”和“problem_id”的复合键。在表“clients”中,“client_id”是主键,所以我想保持这种关系,“problem_id”需要自动递增。

CREATE TABLE problems (
client_id BIGINT(10) NOT NULL REFERENCES clients(client_id),
problem_id INT NOT NULL AUTO_INCREMENT,
status CHAR(1) NOT NULL,
description VARCHAR(100) NOT NULL,
start_date VARCHAR(10) NOT NULL,
end_date VARCHAR(10),
PRIMARY KEY (client_id, problem_id)
);

MySQL不接受这一点,但对我来说似乎合乎逻辑。我怎样才能实现这样的表格?

3 个答案:

答案 0 :(得分:3)

两个问题:

  • InnoDB要求auto_increment列是主键中的第一列。

  • InnoDB不支持列级REFERENCES语法,它只支持表级FOREIGN KEY约束语法。

这应该有效:

CREATE TABLE problems (
 client_id BIGINT(10) NOT NULL,
 problem_id INT NOT NULL AUTO_INCREMENT,
 status CHAR(1) NOT NULL,
 description VARCHAR(100) NOT NULL,
 start_date VARCHAR(10) NOT NULL,
 end_date VARCHAR(10),
 PRIMARY KEY (problem_id, client_id),
 FOREIGN KEY (client_id) REFERENCES clients(client_id)
);

但是,这意味着您的聚簇索引(主键)将有利于查找 by problem_id,但不是client_id的查找。

答案 1 :(得分:1)

根据AUTO INCREMENT docs,如果您使用的是MyISAM或BDB引擎,则只能在复合键中使用自动增量列:

  
    

对于MyISAM和BDB表,您可以在多列索引的辅助列上指定AUTO_INCREMENT。

  

如果您正在使用InnoDB,则可能不允许这样做。我建议只使用problem_id作为主键 - 它本身就是唯一的,我认为将它与client_id结合起来并没有任何好处。

答案 2 :(得分:0)

我怀疑你必须使problem_id成为主(集群)密钥,并在client_id上创建另一个索引。 MySQL包含对主键的引用,作为其他索引的一部分。

CREATE TABLE problem (
    problem_id INT NOT NULL AUTO_INCREMENT,
    client_id BIGINT(10) NOT NULL REFERENCES clients(client_id),
    status CHAR(1) NOT NULL,
    description VARCHAR(100) NOT NULL,
    start_date DATE NOT NULL,
    end_date DATE,
    PRIMARY KEY (problem_id)
    INDEX problem_ndx1 (client_id)
);