我在MySQL InnoDB中创建了一个像这样的表:
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` enum('MANUAL','FACEBOOK') NOT NULL DEFAULT 'MANUAL',
`role` enum('COOK','HOST','ALL') NOT NULL DEFAULT 'ALL',
`about_me` varchar(1000) DEFAULT NULL,
`food_preferences` varchar(1000) DEFAULT NULL,
`cooking_experience` varchar(1000) DEFAULT NULL,
`with_friend` bit(1) DEFAULT b'0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
接下来我尝试添加一个带有这样一个语句的表(在创建表时没有添加外键,因为有问题):
CREATE TABLE `messages` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`from` bigint(20) NOT NULL,
`to` bigint(20) NOT NULL,
`content` varchar(10000) NOT NULL,
`timestamp_sent` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`timestamp_read` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
创建表后,我需要最终在引用'from'
字段的'to'
和'users'.'id'
字段上添加外键:
ALTER TABLE `messages`
ADD CONSTRAINT `messages_users_fk`
FOREIGN KEY (`from` , `to` )
REFERENCES `users` (`id` , `id` )
ON DELETE SET NULL
ON UPDATE CASCADE
, ADD INDEX `messages_users_fk_idx` (`from` ASC, `to` ASC)
我得到的错误是:
错误:错误1822:无法添加外键约束。缺少引用表'users'中约束'messages_users_fk'的索引。
但'用户'表在PRIMARY
...
'id'
索引
还尝试缩小步骤并为'from'
字段添加外键:
ALTER TABLE `messages`
ADD CONSTRAINT `messages_users_fk`
FOREIGN KEY (`from` )
REFERENCES `users` (`id` )
ON DELETE SET NULL
ON UPDATE CASCADE
, ADD INDEX `messages_users_fk_idx` (`from` ASC) ;
错误略有不同:
错误:错误1825:无法在表'消息'上添加外键约束。 FOREIGN KEY约束'cook4food / messages_users_fk'中的选项不正确。
字段的类型与其他StackOverflow线程中的问题原因一样(bigint(20) NOT NULL
)。我的表没有被分区(MySQL手册指出这是在InnoDB中具有外键约束的限制)。 'messages'
表当前不存储任何行,因此存储的数据不会以任何方式出现问题。我被困了,请帮忙。
答案 0 :(得分:15)
如果您拥有相应的权限,则可以发出以下查询:
SHOW ENGINE innodb STATUS
...它会告诉你(在其他一些信息中)错误的确切细节:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
130311 13:30:06 Error in foreign key constraint of table test/#sql-71c_6:
FOREIGN KEY (`from` , `to` )
REFERENCES `users` (`id` , `id` )
ON DELETE SET NULL
ON UPDATE CASCADE
, ADD INDEX `messages_users_fk_idx` (`from` ASC, `to` ASC):
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL.
在删除父记录时,您不能将子记录设为NULL,因为列为NOT NULL
:
`from` bigint(20) NOT NULL,
`to` bigint(20) NOT NULL,
编辑:此外,我无法看到单个复合键的用途。我想你想要两个单键。
答案 1 :(得分:0)
REFERENCES
{用户{1}} ID为(
ID为,
您正在尝试创建无效的外键(id,id)。复合索引中涉及的列(一个涉及多个列)可能不是同一列,重复。至少我从未见过。
创建两个单独的外键,一个用于FROM,另一个用于TO,每个都指向用户。
答案 2 :(得分:0)
正如我们所见,
当子列from
和to
不为空时,您无法在子记录中定义SET NULL。
因此,如果您尝试使用以下2个语句创建外键,则应在messages
表中使用外键。
1>
ALTER TABLE `messages` ADD CONSTRAINT `messages_users_from_fk` FOREIGN KEY (`from` ) REFERENCES `users` (`id` ) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX `messages_users_fk_idx` (`from` ASC) ;
和
2 - ;
ALTER TABLE `messages` ADD CONSTRAINT `messages_users_to_fk` FOREIGN KEY (`to` ) REFERENCES `users` (`id` ) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX `messages_users_fk_to_idx` (`to` ASC) ;
希望这些陈述可以帮助你。