即使使用SET FOREIGN_KEY_CHECKS = 0,也无法创建表格(ERROR 1215);

时间:2016-01-09 18:44:29

标签: mysql foreign-keys ddl mysql-5.6 mysql-5.7

我想要做的事情我已经做了无数次但是现在无法从MySql 5.6.26升级到5.6.27(在5.7.x中也失败了)。我有一个数据库,其中包含一堆具有外键约束的表。我已导出(使用phpMyAdmin)替换表,指定以下导出选项:

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;

当表applicationproduct_x_application已存在时,将此文件输入到mysql.exe或phpMyAdmin导入函数时,表application的DROP语句成功但后续的CREATE TABLE声明失败了:

  

ERROR 1215(HY000):无法添加外键约束

但是,如果我首先删除product_x_application表,该表具有引用表product_x_application_ibfk_2的外键约束application,则CREATE TABLE语句会成功。

我已经了解了更多信息。我去了我的生产机器,它使用MySql 5.5服务器和phpMyAdmin 4.4.23 phpMyAdmin运行Linux,只导出了两个有问题的表,并能够将生成的文件导入我的MySql 5.6.27服务器。以下是两个完整导出文件(仅限结构)。首先来自有问题的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表的主键是在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表的主键。我认为问题是系统尝试重新创建product_x_application表时已经存在的application表对表的外键约束在重新创建时没有外键上所需的索引,因为尚未定义主键。

2 个答案:

答案 0 :(得分:1)

外键应引用唯一列(例如,主键)。目前,PK_Application不是一个专栏。但是,从它的名字来看,似乎你认为它是一个主键:

ALTER TABLE `application` 
ADD CONSTRAINT `application_pk` PRIMARY KEY (`PK_Application`);

答案 1 :(得分:0)

我有更多信息。我安装了更高版本的phpMyAdmin(4.5.0.2),但忘记了所有相关内容。对于咯咯笑声,我决定用那个做出口。和以前一样,我指定了ADD DROP TABLE选项(自动检查ADD CREATE TABLE,不能取消选中)。但是现在,在ADD CREATE TABLE的IF NOT EXISTS子选项旁边,它在括号中说,"(在表创建期间将生成索引的效率较低)",这当然正是我需要的(通常我不会考虑选中此选项,因为我知道此时表可能不存在)。输出是:

-- 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来运行导入。