如何正确创build复合主键 – MYSQL

这是我正在与一个激烈的设置过分简化。 table_1table_2都有自动递增代理主键作为ID。 info是一个包含关于table_1table_2信息的表。

 table_1 (id, field) table_2 (id, field, field) info ( ???, field) 

我试图决定是否应该使信息的主键是来自table_1table_2的ID的组合。 如果我要这样做,哪个最有意义?
(在这个例子中,我将ID 11209与ID 437结合)

INT(9) 11209437 (我能想象为什么这是不好的)
VARCHAR (10) 11209-437
DECIMAL (10,4) 11209.437

或者是其他东西?

将这个作为MYSQL MYISAM DB的主键就可以吗?

我会使用复合(多列)键。

 CREATE TABLE INFO ( t1ID INT, t2ID INT, PRIMARY KEY (t1ID, t2ID) ) 

这样,你可以将t1ID和t2ID作为外键指向它们各自的表。

我不会让“info”表的主键是来自其他表的两个值的组合。

其他人可以更好地说明原因,但是有一个真正由两部分信息组成的专栏感觉不对。 如果由于某种原因想要从第二个表中sortingID呢? 如果要计算来自两个表中的某个值的次数,该怎么办?

我会永远保持这两个不同的列。 你可以在mysql中使用两列主要键… PRIMARY KEY(id_a,id_b)…但我更喜欢使用两列唯一索引,并有一个自动增加主键字段。

语法是CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)例如:

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

上面的例子将工作,如果你正在写它,而你正在创build表例如::

 CREATE TABLE person ( P_Id int , ............, ............, CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName) ); 

要将此约束添加到现有表中,您需要遵循以下语法

 ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName) 

复合主键是你想要创build与事实表多对多关系的地方。 例如,您可能有一个假期租赁套餐,其中包含一些物业。 另一方面,该物业也可以作为多个租赁套餐的一部分,无论是单独还是与其他物业一起使用。 在这种情况下,您需要通过财产/包裹事实表来确定财产和租赁包裹之间的关系。 属性和包之间的关联将是唯一的,您将只能使用包含属性表和/或package_id的包表来使用property_id。 每个关系都是唯一的,一个auto_increment键是多余的,因为它不会在任何其他表中使用。 因此定义组合键是答案。

除个人devise偏好之外,还有一些情况下需要使用复合主键。 表可能有两个或更多的字段提供一个独特的组合,而不一定通过外键。

举个例子,美国每个州都有一套独特的国会地区。 虽然许多国家可能单独拥有CD-5,但在50个州中,任何一个都不会有一个以上的CD-5,反之亦然。 因此,为马萨诸塞州CD-5创build自动编号字段将是多余的。

如果数据库驱动一个dynamic网页,编写代码来查询两个字段的组合可能比提取/重新提交一个自动编号的密钥简单得多。

所以,虽然我没有回答原来的问题,但我当然非常感谢亚当的直接答复。

 CREATE TABLE `mom`.`sec_subsection` ( `idsec_sub` INT(11) NOT NULL , `idSubSections` INT(11) NOT NULL , PRIMARY KEY (`idsec_sub`, `idSubSections`) ); 

@AlexCuse我想添加这个评论给你的答案,但放弃了多次失败的尝试在评论中添加新行。

也就是说,t1ID在table_1中是唯一的,但是它在INFO表中也不是唯一的。

例如:

Table_1有:
Id字段
1 A
2 B

表2有:
Id字段
1 X
2 Y

INFO然后可以有:
t1ID t2ID字段
1 1个
1 2数据
每个2 1个
2 2排

所以在INFO表中唯一标识一行你需要t1ID和t2ID

假设你现在已经创build了一个表,你可以使用这个查询来创build复合主键

 alter table employee add primary key(emp_id,emp_name);