两列作为mysql的主键?

时间:2013-01-08 01:19:34

标签: mysql

今天我发现你可以使用两列(tsql)来获得主键。 PK必须是唯一的,但两列都不是(组合必须是唯一的)。

我觉得这很酷。至少有两个问题,我问人们在哪里大吼我说我做的(mysql)数据库错了,只有一个人说我做得很好。所以......这让我有些怀疑

这是否符合我的想法?

create table User(
   id INT primary key AUTO_INCREMENT ,  
   ipaddr  TEXT  NOT NULL , 
   email  TEXT  NOT NULL
);
create table test(
  a  INT  NOT NULL ,
  b  INT  NOT NULL ,
  dummy  INT  NOT NULL ,
  FOREIGN KEY (a) REFERENCES User(id),
  FOREIGN KEY (b) REFERENCES User(id),
  PRIMARY KEY(a,b)
);

我跑了下面所以看来我正在做我认为的事情(组合必须是唯一的。但是列中的相同值不需要是唯一的)。我应该知道什么吗?关于mysql,没有人向我提起这个问题吗?

mysql> insert into test(a,b,dummy) select 1,1,1;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test(a,b,dummy) select 1,2,2;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test(a,b,dummy) select 2,1,3;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test(a,b,dummy) select 2,2,4;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test(a,b,dummy) select 1,2,5;
ERROR 1062 (23000): Duplicate entry '1-2' for key 'PRIMARY'

8 个答案:

答案 0 :(得分:31)

你在想这个:

  • 主键(无论涉及多少列)必须是唯一的
  • 您的主键是两列a,b

因此a和b 在一起必须是唯一的。

a和b的个别价值无关。

答案 1 :(得分:4)

是的,这在SQL中是正常的,它可以工作(具有复合主键,其中多个字段一起构成唯一值)。

两个注释:

  1. 确保有必要。它经常是,然后它没关系。但有时候这表明您需要进一步规范化数据模型。

  2. 我认为你不想制作和b是来自另一个表的外键,然后将它们作为表的复合主键。如果您设置级联删除会发生什么情况,其中一个用户ID但不删除另一个用户ID?所以复合主键很好,但是你不希望来自“不相关”的外键。

答案 2 :(得分:4)

你的想法很好。我经常使用多字段主键,因为它使我的数据库设计更具逻辑性,可管理性和可读性。您可以将多字段主键视为具有唯一名称。例如:

多字段主键:

(First ,Middle, Last)

示例值:

('Michael', 'A.', 'Kline')

可能有很多人将'First'这个名字命名为'Michael'和/或'Middle'这个名字'A.'和/或'最后'名称'Kline',但就您的数据库而言,只有一个'Michael A. Kline'。

通常,多字段主键是来自其他表的其他主键的组合,并且记录内容描述与特定键值相关的内容。例如:

Table #1: Student Records (KEY: student_id)
Table #2: Course Records (KEY: course_id)
Table #3: Student Grades (KEY: student_id, course_id)

希望这有帮助。

答案 3 :(得分:2)

是的,您必须注意重复 PRIMARY_KEY ,这是一个组合键,在您的情况下不会重复。

无论如何,当您设置两个PK时,这意味着您的签名是 PK1 + PK2 ,因此您可以复制PK1或PK2,但不能同时复制它们。

希望我帮助

答案 4 :(得分:2)

还有一点需要注意: 主键在MySQL中自动编入索引。 您在主键中提及的列顺序对于提升性能至关重要here

答案 5 :(得分:1)

我相信正在发生的事情是成对的列一起是主要的。例如,您知道您不能拥有重复的主列Ex:如果col“a”是主要的,则不能有两行具有相同的a值。

在这个例子中,你有两个初选;这意味着每个col对只能有一个唯一值。 例如,如果col'a'和'b'是主要的而'c'不是: A | B | C 1,2,3的作品 1,4,5的作品 和 5,1,6的作品 9,1,10件作品

但你不能: 9,8,10 9,8,6,因为对于那个(9,8)对,你只能有一个独特的值...

这有意义还是您希望我进一步阐述?

答案 6 :(得分:0)

ALTER TABLE TableName DROP PRIMARY KEY,添加主键(column1column2); 如果您之前已设置主键,请尝试此操作。

答案 7 :(得分:0)

为了便于解释,我将仅使用一张表格。创建一个包含2个int列的表,并在它们两个上同时创建一个PK。就像在问题中一样。

create table test(
  a  INT  NOT NULL ,
  b  INT  NOT NULL ,
  PRIMARY KEY(a,b));

现在我们可以添加行,直到出现错误

insert into test values(1,1); 
Query OK, 1 row affected (0,00 sec)

insert into test values(1,2); 
Query OK, 1 row affected (0,00 sec)

insert into test values(1,1); 
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

这是合乎逻辑的,因为当执行最后一条语句时,构成PK的2列的组合值不再唯一。

允许将2的值1存储在a中,因为这不是PK。 PK是a和b列的组合值。