MySQL DB忽略了外键约束

时间:2017-11-13 20:38:17

标签: mysql foreign-keys

我有一个非常奇怪(又可怕)的问题:我的mySQL数据库通常忽略外键约束!

我的所有表格都是InnoDB,我正在用liquibase创建它们:

<addForeignKeyConstraint baseColumnNames="user_account_id"
    baseTableName="account_transaction"
    constraintName="fk_account_transaction_user_account_id"
    referencedColumnNames="id"
    referencedTableName="user_account"/>

外键创建正常。在HeidiSQL中,我看到他们是这样的: heidiSQL DB Management

我还检查了FOREIGN_KEY_CHECKS并将其设置为1(SET FOREIGN_KEY_CHECKS=1;

我的所有ID列的数据类型都为BIGINT(如果重要的话,请注意dunno)。

还值得一提:以下声明

  SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = DATABASE();

返回一堆约束,但没有外键约束......当我在本地mySQL DB上执行相同的语句时,它返回所有约束INCLUDING外键约束。我无法弄清楚它们之间的区别但是......

非常感谢任何帮助:)

@Update: 所以MyISAM和InnoDB的暗示就是诀窍。我之前做过调查。但是,出于某种原因,我的表是InnoDB,但我的数据库是MyISAM。我将对此进行进一步调查:) enter image description here

1 个答案:

答案 0 :(得分:1)

Bill Karwin在评论中指出,如果表格不是InnoDB,则FOREIGN KEY约束忽略

演示:

CREATE TABLE foo_p
( id BIGINT UNSIGNED PRIMARY KEY
) ENGINE=MYISAM
;  

CREATE TABLE foo_c
( id   BIGINT UNSIGNED PRIMARY KEY
, p_id BIGINT UNSIGNED
) ENGINE=MYISAM
;

添加外键约束:

ALTER TABLE foo_c 
  ADD CONSTRAINT fk_foo_c_foo_p
  FOREIGN KEY (id) REFERENCES foo_p (id)
  ON DELETE NO ACTION ON UPDATE NO ACTION
;  

MySQL创建索引但不创建外键。

将存储引擎更改为InnoDB不会创建外键:

ALTER TABLE foo_p ENGINE=INNODB ;

ALTER TABLE foo_c ENGINE=INNODB ;

使用SHOW CREATE TABLE foo_c查看表格定义:

CREATE TABLE `foo_c` (
  `id` BIGINT(20) UNSIGNED NOT NULL,
  `p_id` BIGINT(20) UNSIGNED DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_foo_c_foo_p` (`id`)
) ENGINE=INNODB

有一个索引(从MyISAM定义转换而来)但没有外键。

添加外键:

ALTER TABLE foo_c 
  DROP KEY fk_foo_c_foo_p  
, ADD CONSTRAINT fk_foo_c_foo_p
  FOREIGN KEY (p_id) REFERENCES foo_p (id)
  ON DELETE NO ACTION ON UPDATE NO ACTION
;

SHOW CREATE TABLE显示FOREIGN KEY约束,以及自动创建的索引:

CREATE TABLE `foo_c` (
  `id` BIGINT(20) UNSIGNED NOT NULL,
  `p_id` BIGINT(20) UNSIGNED DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_foo_c_foo_p` (`p_id`),
  CONSTRAINT `fk_foo_c_foo_p` FOREIGN KEY (`p_id`) REFERENCES `foo_p` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=INNODB