MySQL FK到非唯一字段不起作用

MySQL FK到非唯一字段不起作用,mysql,foreign-keys,mysql-error-1005,Mysql,Foreign Keys,Mysql Error 1005,在MySQL手册中,我读到“然而,系统并没有强制要求引用的列是唯一的或声明为非空的。”。因此,我尝试创建两个表: CREATE TABLE album( id INT, title VARCHAR(20)) DEFAULT CHARSET=utf8; CREATE TABLE track2( album int, dsk INTEGER, posn INTEGER, song VARCHAR(255), FO

在MySQL手册中,我读到“然而,系统并没有强制要求引用的列是唯一的或声明为非空的。”。因此,我尝试创建两个表:

CREATE TABLE album(
    id INT, 
    title VARCHAR(20)) DEFAULT CHARSET=utf8;
CREATE TABLE track2(   
    album int,   
    dsk INTEGER,   
    posn INTEGER,   
    song VARCHAR(255),   
    FOREIGN KEY (album) REFERENCES album(id) ) default charset=utf8;
并且有错误:错误1005(HY000):无法创建表“b.track2”(错误号:150)


为什么我不能使用MySQL提供并在其手册中描述的与SQL标准不同的功能?

之所以发生这种情况,是因为您没有在
相册
表中将
id
设置为
主键

使用


更新1 请阅读


更新2 我相信,你的引擎是MyISAM。根据,您的声明对InnoDB有效,对MyISAM无效


此外,MySQL和InnoDB要求对引用的列进行索引以提高性能。但是,系统不强制要求引用的列是唯一的或声明为非空。对于诸如UPDATE或DELETE CASCADE之类的操作,没有很好地定义对非唯一键或包含空值的键的外键引用的处理。建议您使用只引用唯一键而非空键的外键。

发生这种情况是因为您没有在
相册
表中将
id
设置为
主键

使用


更新1 请阅读


更新2 我相信,你的引擎是MyISAM。根据,您的声明对InnoDB有效,对MyISAM无效


此外,MySQL和InnoDB要求对引用的列进行索引以提高性能。但是,系统不强制要求引用的列是唯一的或声明为非空。对于诸如UPDATE或DELETE CASCADE之类的操作,没有很好地定义对非唯一键或包含空值的键的外键引用的处理。建议您使用仅引用唯一键而非空键的外键。

我了解如何操作:

create table album2 (id int, title varchar(20), key (id));
create table track2 (
     track_id int primary key, 
     album_id int not null, 
     title varchar(100), 
     foreign key (album_id) references album2 (id)
);

mysql> show create table album2;
+--------+-----------------------------
| Table  | Create Table
+--------+-----------------------------
| album2 | CREATE TABLE `album2` (
  `id` int(11) DEFAULT NULL,
  `title` varchar(20) DEFAULT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------------

mysql> show create table track2;
+--------+-----------------------------------------------------------------------
| Table  | Create Table
+--------+-----------------------------------------------------------------------
| track2 | CREATE TABLE `track2` (
  `track_id` int(11) NOT NULL,
  `album_id` int(11) NOT NULL,
  `title` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`track_id`),
  KEY `album_id` (`album_id`),
  CONSTRAINT `track2_ibfk_1` FOREIGN KEY (`album_id`) REFERENCES `album2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------------------------------------------------------

我所需要的就是在album2中创建非唯一的键。

我知道怎么做:

create table album2 (id int, title varchar(20), key (id));
create table track2 (
     track_id int primary key, 
     album_id int not null, 
     title varchar(100), 
     foreign key (album_id) references album2 (id)
);

mysql> show create table album2;
+--------+-----------------------------
| Table  | Create Table
+--------+-----------------------------
| album2 | CREATE TABLE `album2` (
  `id` int(11) DEFAULT NULL,
  `title` varchar(20) DEFAULT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------------

mysql> show create table track2;
+--------+-----------------------------------------------------------------------
| Table  | Create Table
+--------+-----------------------------------------------------------------------
| track2 | CREATE TABLE `track2` (
  `track_id` int(11) NOT NULL,
  `album_id` int(11) NOT NULL,
  `title` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`track_id`),
  KEY `album_id` (`album_id`),
  CONSTRAINT `track2_ibfk_1` FOREIGN KEY (`album_id`) REFERENCES `album2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------------------------------------------------------

我只需要在album2中创建非唯一的键。

您使用的是什么引擎?InnoDB还是MyISAM?@GuyFawkes:注意你的语言。在这方面,没有人愿意回答……我只是说了我自己,没有说你或其他人的坏话。无论如何,谢谢你的回答。@GuyFawkes:你在用MyISAM。。。是吗?我已经回答过你了。是InnoDB,你用的是什么引擎?InnoDB还是MyISAM?@GuyFawkes:注意你的语言。在这方面,没有人愿意回答……我只是说了我自己,没有说你或其他人的坏话。无论如何,谢谢你的回答。@GuyFawkes:你在用MyISAM。。。是吗?我已经回答过你了。它是InnoDB.PK是唯一的字段。我知道我可以为其他表中的唯一字段创建FK。但我不想将id设置为PK:MySQL手册中说我可以创建FK到非唯一字段。PK是唯一字段。我知道我可以为其他表中的唯一字段创建FK。但我不想将id设置为PK:在MySQL手册中说我可以创建FK到非唯一字段。