即使使用 SET FOREIGN_KEY_CHECKS=0 也无法创建 table(错误 1215);
Can't create table (ERROR 1215) even with SET FOREIGN_KEY_CHECKS=0;
我尝试做的事情我已经做了无数次,但现在从 MySql 5.6.26 升级到 5.6.27 失败了(在 5.7.x 中也失败了)。我有一个数据库,其中有一堆 table 具有外键约束。我已经导出(使用 phpMyAdmin)替换 tables 指定以下导出选项:
Disable foreign key checks
Add DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER statement
Add CREATE TABLE statement
生成的导出文件部分包含:
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
. . .
. . .
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
. . .
. . .
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
当 mysql.exe 或 phpMyAdmin 导入函数输入此文件时 tables application
和 product_x_application
已经存在,[=49 的 DROP 语句=] application
成功但随后的 CREATE TABLE 语句失败:
ERROR 1215 (HY000): Cannot add foreign key constraint
但是,如果我首先删除 product_x_application
table,它有一个引用 table application
的外键约束 product_x_application_ibfk_2
,那么CREATE TABLE 语句成功。
此后我了解了更多信息。我去了我的生产机器,它是 运行 Linux,带有 MySql 5.5 服务器和 phpMyAdmin 4.4.23 phpMyAdmin,并且只导出了两个 tables有问题并且能够将生成的文件导入我的 MySql 5.6.27 服务器。这是两个 complete 导出文件(仅结构)。首先来自有问题的 5.6.27 服务器:
-- phpMyAdmin SQL Dump
-- version 4.4.15
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 07:01 AM
-- Server version: 5.6.26-log
-- PHP Version: 5.6.12
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `application`
--
ALTER TABLE `application`
ADD PRIMARY KEY (`PK_Application`);
--
-- Indexes for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD PRIMARY KEY (`PK_Product_X_Application`),
ADD KEY `Product_PKID` (`Product_PKID`),
ADD KEY `FK_Application` (`FK_Application`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `application`
--
ALTER TABLE `application`
MODIFY `PK_Application` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `product_x_application`
--
ALTER TABLE `product_x_application`
MODIFY `PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
请注意,application
table 的主键是在 ALTER TABLE 语句中定义的。这是从 5.5 服务器导出的文件:
-- phpMyAdmin SQL Dump
-- version 3.5.8.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 05:09 AM
-- Server version: 5.5.42-37.1-log
-- PHP Version: 5.4.23
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL AUTO_INCREMENT,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL,
PRIMARY KEY (`PK_Application`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL,
PRIMARY KEY (`PK_Product_X_Application`),
KEY `Product_PKID` (`Product_PKID`),
KEY `FK_Application` (`FK_Application`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1633 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
此处 application
table 的主键在定义 table 时立即定义。我认为问题在于 product_x_application
table,当系统试图重新创建 application
table 时,它已经存在,具有对 table 重新创建时外键上没有所需的索引,因为尚未定义主键。
外键应引用唯一列(例如,主键)。 PK_Application
,目前没有这样的专栏。但是,从它的名字来看,您似乎打算将其作为主键:
ALTER TABLE `application`
ADD CONSTRAINT `application_pk` PRIMARY KEY (`PK_Application`);
我有更多信息。我安装了更高版本的 phpMyAdmin (4.5.0.2),但完全忘记了。为了咯咯笑,我决定用那个做出口。和以前一样,我将 ADD DROP TABLE 指定为选项(ADD CREATE TABLE 会自动选中,无法取消选中)。但是现在,在 ADD CREATE TABLE 的 IF NOT EXISTS sub-option 旁边,它在括号中说,“(效率较低,因为在 table 创建期间将生成索引)”,这当然是正是我需要的(通常我不会考虑检查这个选项,因为我知道 table 此时不可能存在)。输出是:
-- phpMyAdmin SQL Dump
-- version 4.5.0.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 07:54 AM
-- Server version: 5.6.26-log
-- PHP Version: 5.6.12
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE IF NOT EXISTS `application` (
`PK_Application` int(11) NOT NULL AUTO_INCREMENT,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL,
PRIMARY KEY (`PK_Application`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE IF NOT EXISTS `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL,
PRIMARY KEY (`PK_Product_X_Application`),
KEY `Product_PKID` (`Product_PKID`),
KEY `FK_Application` (`FK_Application`)
) ENGINE=InnoDB AUTO_INCREMENT=1633 DEFAULT CHARSET=latin1;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
所以问题一直是 phpMyadmin 4.4.15 版本而不是 MySql 版本。显然,我一直在定期升级 phpMyAdmin 版本,我可以推断我从来没有机会 运行 导入有问题的(至少对我而言)phpMyAdmin 版本 4.4.15 直到现在。
我尝试做的事情我已经做了无数次,但现在从 MySql 5.6.26 升级到 5.6.27 失败了(在 5.7.x 中也失败了)。我有一个数据库,其中有一堆 table 具有外键约束。我已经导出(使用 phpMyAdmin)替换 tables 指定以下导出选项:
Disable foreign key checks
Add DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER statement
Add CREATE TABLE statement
生成的导出文件部分包含:
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
. . .
. . .
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
. . .
. . .
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
当 mysql.exe 或 phpMyAdmin 导入函数输入此文件时 tables application
和 product_x_application
已经存在,[=49 的 DROP 语句=] application
成功但随后的 CREATE TABLE 语句失败:
ERROR 1215 (HY000): Cannot add foreign key constraint
但是,如果我首先删除 product_x_application
table,它有一个引用 table application
的外键约束 product_x_application_ibfk_2
,那么CREATE TABLE 语句成功。
此后我了解了更多信息。我去了我的生产机器,它是 运行 Linux,带有 MySql 5.5 服务器和 phpMyAdmin 4.4.23 phpMyAdmin,并且只导出了两个 tables有问题并且能够将生成的文件导入我的 MySql 5.6.27 服务器。这是两个 complete 导出文件(仅结构)。首先来自有问题的 5.6.27 服务器:
-- phpMyAdmin SQL Dump
-- version 4.4.15
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 07:01 AM
-- Server version: 5.6.26-log
-- PHP Version: 5.6.12
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `application`
--
ALTER TABLE `application`
ADD PRIMARY KEY (`PK_Application`);
--
-- Indexes for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD PRIMARY KEY (`PK_Product_X_Application`),
ADD KEY `Product_PKID` (`Product_PKID`),
ADD KEY `FK_Application` (`FK_Application`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `application`
--
ALTER TABLE `application`
MODIFY `PK_Application` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `product_x_application`
--
ALTER TABLE `product_x_application`
MODIFY `PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
请注意,application
table 的主键是在 ALTER TABLE 语句中定义的。这是从 5.5 服务器导出的文件:
-- phpMyAdmin SQL Dump
-- version 3.5.8.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 05:09 AM
-- Server version: 5.5.42-37.1-log
-- PHP Version: 5.4.23
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE `application` (
`PK_Application` int(11) NOT NULL AUTO_INCREMENT,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL,
PRIMARY KEY (`PK_Application`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL,
PRIMARY KEY (`PK_Product_X_Application`),
KEY `Product_PKID` (`Product_PKID`),
KEY `FK_Application` (`FK_Application`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1633 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
此处 application
table 的主键在定义 table 时立即定义。我认为问题在于 product_x_application
table,当系统试图重新创建 application
table 时,它已经存在,具有对 table 重新创建时外键上没有所需的索引,因为尚未定义主键。
外键应引用唯一列(例如,主键)。 PK_Application
,目前没有这样的专栏。但是,从它的名字来看,您似乎打算将其作为主键:
ALTER TABLE `application`
ADD CONSTRAINT `application_pk` PRIMARY KEY (`PK_Application`);
我有更多信息。我安装了更高版本的 phpMyAdmin (4.5.0.2),但完全忘记了。为了咯咯笑,我决定用那个做出口。和以前一样,我将 ADD DROP TABLE 指定为选项(ADD CREATE TABLE 会自动选中,无法取消选中)。但是现在,在 ADD CREATE TABLE 的 IF NOT EXISTS sub-option 旁边,它在括号中说,“(效率较低,因为在 table 创建期间将生成索引)”,这当然是正是我需要的(通常我不会考虑检查这个选项,因为我知道 table 此时不可能存在)。输出是:
-- phpMyAdmin SQL Dump
-- version 4.5.0.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 10, 2016 at 07:54 AM
-- Server version: 5.6.26-log
-- PHP Version: 5.6.12
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Database: `spmorell_sami`
--
-- --------------------------------------------------------
--
-- Table structure for table `application`
--
DROP TABLE IF EXISTS `application`;
CREATE TABLE IF NOT EXISTS `application` (
`PK_Application` int(11) NOT NULL AUTO_INCREMENT,
`FK_Parent` int(11) DEFAULT NULL,
`ApplicationLevel` tinyint(4) NOT NULL,
`Description` varchar(35) NOT NULL,
`Sequence` tinyint(4) NOT NULL,
PRIMARY KEY (`PK_Application`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `product_x_application`
--
DROP TABLE IF EXISTS `product_x_application`;
CREATE TABLE IF NOT EXISTS `product_x_application` (
`PK_Product_X_Application` int(11) NOT NULL AUTO_INCREMENT,
`Product_PKID` varchar(36) NOT NULL,
`FK_Application` int(11) NOT NULL,
PRIMARY KEY (`PK_Product_X_Application`),
KEY `Product_PKID` (`Product_PKID`),
KEY `FK_Application` (`FK_Application`)
) ENGINE=InnoDB AUTO_INCREMENT=1633 DEFAULT CHARSET=latin1;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_x_application`
--
ALTER TABLE `product_x_application`
ADD CONSTRAINT `product_x_application_ibfk_1` FOREIGN KEY (`Product_PKID`) REFERENCES `product` (`Product_PKID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `product_x_application_ibfk_2` FOREIGN KEY (`FK_Application`) REFERENCES `application` (`PK_Application`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
所以问题一直是 phpMyadmin 4.4.15 版本而不是 MySql 版本。显然,我一直在定期升级 phpMyAdmin 版本,我可以推断我从来没有机会 运行 导入有问题的(至少对我而言)phpMyAdmin 版本 4.4.15 直到现在。