MariaDB-外键约束不正确?

时间:2018-10-02 22:34:47

标签: mariadb mysql-workbench

我试图重新设计我在工作中使用的数据库。工作中的一个是MS Access。在家里,是MariaDB。为了方便起见,我使用MySQL Workbench。

将完整的SQL转储发送到服务器时,出现有关某些外键格式不正确的错误。我想这是一个小错误,但仍然找不到。

我的InnoDB状态告诉我:

最新外键错误

2018-10-03 00:18:29 409c7450 Error in foreign key constraint of table `mydb`.`IF`:

   FOREIGN KEY (`belegid`)
   REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION,
 CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
   FOREIGN KEY (`belegid`)
   REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION)
ENGINE = InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Create  table '`mydb`.`IF`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near '
   FOREIGN KEY (`belegid`)
   REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION,
 CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
   FOREIGN KEY (`belegid`)
   REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION)
ENGINE = InnoDB'.

真正奇怪的是我没有任何名为“ IF”的表... 谁能为我做这个的头或尾?非常感谢。

-- Table `mydb`.`tblBelegPositionen`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblBelegPositionen` ;

SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblBelegPositionen` (
  `belegposid` INT NOT NULL AUTO_INCREMENT,
  `belegposBetrag` DOUBLE NOT NULL,
  `zahlartfID` INT NOT NULL,
  `belegfID` INT NOT NULL,
  PRIMARY KEY (`belegposid`))
ENGINE = InnoDB;

SHOW WARNINGS;

-- Table `mydb`.`tblECKassenschnittPositionen`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblECKassenschnittPositionen` ;

SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblECKassenschnittPositionen` (
  `ecposid` INT NOT NULL AUTO_INCREMENT,
  `belegfID` INT NOT NULL,
  `ecposBetrag` DOUBLE NOT NULL,
  `kassenschnittfID` INT NOT NULL,
  PRIMARY KEY (`ecposid`))
ENGINE = InnoDB;

SHOW WARNINGS;

-- Table `mydb`.`tblBelege`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblBelege` ;

SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblBelege` (
  `belegid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `belegKassierer` INT NOT NULL,
  `belegDatum` DATETIME NOT NULL,
  `kassefID` INT NOT NULL,
  `belegSchicht` INT NULL,
  `gvfID` INT NOT NULL,
  `belegJahr` YEAR NULL,
  `belegDruckErfolgt` TINYINT(1) NULL,
  `belegDruckDatum` DATETIME NULL,
  `belegPeriodenfremdeBuchung` TINYINT(1) NULL,
  PRIMARY KEY (`belegid`, `gvfID`, `kassefID`),
  CONSTRAINT `fk_tblBelege_tblBelegPositionen10`
    FOREIGN KEY (`belegid`)
    REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
    FOREIGN KEY (`belegid`)
    REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

SHOW WARNINGS;

1 个答案:

答案 0 :(得分:0)

好的,这里有几件事情要知道,因为有一些错误。您必须检查错误中提到的所有项目,以确保正确性,以避免麻烦。

  1. 错误消息的cannot find an index in the referenced table部分意味着必须在另一个表中为REFERENCES子句中指定的列/字段建立索引。
  2. 然后,FOREIGN KEY子句中指定的列的列类型定义也必须与REFERENCES子句中指定的列的列类型匹配,因此即使第一项更正了部分内容。问题,仍然存在与消息的另一部分相关的错误:...or column types in the table and the referenced table do not match

因此,要修复项目1,请运行以下2个查询:

ALTER TABLE `tblbelegpositionen` ADD INDEX(`belegfID`);
ALTER TABLE `tbleckassenschnittpositionen` ADD INDEX(`belegfID`);

然后修复项目2,我不得不更改表tblBelege的第一列 从这里:

`belegid` INT UNSIGNED NOT NULL AUTO_INCREMENT,

对此:

`belegid` INT NOT NULL,

...使得它们与其他表中定义的belegfID列具有相同的类型。经过这两项更改后,我能够成功运行您的CREATE TABLE `tblBelege`语句。

所以,回顾一下:

  • 运行tblbelegpositionen的create table语句,然后 tbleckassenschnittpositionen
  • 然后对项目1运行上面显示的2条ALTER语句。
  • 修改表tblBelege的第一列,以匹配项目2的其他表中为belegfID定义的列类型。
  • 然后运行修改后的CREATE TABLE语句(应用了第2项更改)来创建tblBelege表。

我对引用2个不同表的同一个FOREIGN KEY感到有些困惑,但是如果它对您有用,那就好了。 (并不是说不能做到这一点,我从来没有那样使用过外键)也许您是相反的意思,在其他两个引用tblBelege的表(每个表中有一个)中有一个外键吗?如果是这样,则可以将unsigned添加到belegfID的类型定义中,它将起作用,并且不需要需要我在项目2中提到的更改。

哦,在运行ALTER语句之后,可以通过运行以下命令查看表结构:

SHOW CREATE TABLE `tblbelegpositionen`;
SHOW CREATE TABLE `tbleckassenschnittpositionen`;

...以获取添加到CREATE TABLE语句中的KEY定义。由于它们都创建相同的键,因此您实际上只需要运行这些语句之一,然后将KEY定义添加到两个表语句中即可。

相关问题