MariaDB - Неправильное ограничение внешнего ключа? - PullRequest
0 голосов
/ 03 октября 2018

Я пытался реорганизовать базу данных, которую я использую на работе.Один на работе 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'.

Действительностранно то, что у меня нет таблицы с именем «ЕСЛИ» ... Кто-нибудь может сделать из этого голову или хвост?Это было бы очень ценно.

-- 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 голосов
/ 11 октября 2018

Хорошо, так что здесь нужно знать пару вещей, так как было несколько ошибок.Чтобы избежать проблем, необходимо проверить все элементы, о которых говорится в ошибке.

  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 и tbleckassenschnittpositionen.
  • Затем выполните операторы 2 ALTER, показанные выше для элемента 1.
  • Измените первый столбец таблицы tblBelege, чтобы он соответствовал типам столбцов, определенным для belegfID в другомтаблицы для элемента 2.
  • Затем запустите измененный оператор CREATE TABLE (с применением изменения элемента 2), чтобы создать таблицу tblBelege.

Я немного запуталсятот же FOREIGN KEY, ссылающийся на 2 разные таблицы, но если он работает для вас, тогда хорошо.(не говоря о том, что это невозможно сделать, я никогда не использовал внешний ключ таким образом) Возможно, вы имели в виду обратное, чтобы иметь внешний ключ в двух других таблицах (по 1 в каждой таблице), которые вместо этого ссылаются на tblBelege?Если это так, то вы можете добавить unsigned к определению типа для belegfID, и это сработает, и не потребуются изменения, о которых я упоминал с помощью пункта 2.

О, и послевы запускаете операторы ALTER, вы можете просмотреть структуру таблицы, выполнив:

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

..., чтобы получить определение KEY, добавленное для включения в ваши операторы CREATE TABLE.Поскольку оба они создают один и тот же ключ, вам действительно нужно выполнить только один из этих операторов, а затем добавить определение KEY в оба оператора таблицы.

...