Почему при создании таблицы происходит сбой, когда все innodb, а не когда одна таблица - MyIsam? - PullRequest
0 голосов
/ 28 июня 2011

Я нахожу innodb довольно раздражающим, когда пытаюсь спроектировать структуру БД, по крайней мере, по сравнению с MyIsam, которая, кажется, имеет меньшие ограничения

Скажите, если я хочу создать простую библиотечную систему. И у меня есть четыре стола.

1, таблица book_item, в которой записаны имя книги, имя автора, время публикации и основная информация о книгах

2, таблица book, представляющая конкретный реальный объект предмета книги. Таким образом, объект book_item может относиться ко многим объектам книги.

3, таблица tag, представляющая тег книги. Как наука, литература, архитектура и т. Д.

4, таблица tag_book_item_relation, которая связывает теги с book_items.

Итак, отношения такие, как показано ниже.

1, у нас есть элемент книги до книга это отношение один ко многим отношение

2, book_item to tag - это отношение многие ко многим .

Обратите внимание, двигатель для таблицы все innodb Если я попытаюсь создать таблицы, произойдет сбой:

Error:
Executing SQL script in server
ERROR: Error 1005: Can't create table 'yet_another_test.book' (errno: 121)

Однако, если я изменю двигатель с book или tag_book_item_relation на MyISAM , все будет хорошо.

Итак, мне интересно, что идет не так, если я использую двигатель innodb для таблицы book и tag_book_item_relation

Сценарий sql находится здесь (прямое проектирование в MySQL Workbench):

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book_item` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`tag_book_item_relation` (
  `book_item_id` INT NOT NULL ,
  `tag_id` INT NOT NULL ,
  PRIMARY KEY (`book_item_id`, `tag_id`) ,
  INDEX `fk_tag` (`tag_id` ASC) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  CONSTRAINT `fk_tag`
    FOREIGN KEY (`tag_id` )
    REFERENCES `yet_another_test`.`tag` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `yet_another_test`.`book` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `book_item_id` INT NOT NULL ,
  PRIMARY KEY (`id`, `book_item_id`) ,
  INDEX `fk_book_item` (`book_item_id` ASC) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  CONSTRAINT `fk_book_item`
    FOREIGN KEY (`book_item_id` )
    REFERENCES `yet_another_test`.`book_item` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

Ответы [ 4 ]

2 голосов
/ 28 июня 2011

Кажется, есть проблема с "CREATE TABLE book", что ограничение внешнего ключа fk_book_item имеет то же имя, что и ограничение в tag_book_item_relation.Попробуйте использовать другое имя для ограничения в book, и CREATE TABLE должен работать нормально.

Это не проблема в MyISAM, поскольку они не имеют понятия внешних ключей и поэтому ограничения FK игнорируются.

Надеюсь, это поможет!

1 голос
/ 28 июня 2011

Создайте свои таблицы без ограничений Foreign Key. Хотя те же операторы работают с движком MyISAM, ограничения там игнорируются - поэтому вы не получаете ошибок. Если вам действительно нужны эти ограничения, то создайте их правильно. Однако я обычно стараюсь избегать ограничений FK и реализовывать ограничения на уровне приложений.

Одна проблема, которую я сразу заметил, - это символы ваших ограничений, которые должны быть уникальными на уровне БД, и у вас есть fk_book_item как на tag_book_item_relation таблице, так и на book таблице

1 голос
/ 28 июня 2011

В этом сообщении об ошибке говорится, что где-то есть дубликат ключа. Это может быть вызвано конфликтом имен в ограничении внешнего ключа; Вы не можете использовать одно и то же имя внешнего ключа в разных таблицах. (Я не знаю, какие еще таблицы могут быть в вашей базе данных.)

Часто ошибка вызвана таблицей, уже существующей во внутреннем словаре InnoDB, даже если файл .frm пропал. Если это так, то проще всего сделать дамп данных sql, удалить базу данных, воссоздать ее, а затем загрузить данные из дампа.

1 голос
/ 28 июня 2011

ОШИБКА 121 говорит: «Создание таблицы завершилось неудачно, поскольку ограничение внешнего ключа не было правильно сформировано. Если сообщение об ошибке ссылается на ошибку –1, создание таблицы, вероятно, не удалось, поскольку таблица содержит имя столбца, которое соответствует имени внутренней таблицы InnoDB . "

Ссылка

Имя индекса и имя ограничения могут совпадать, измените при попытке создать таблицу.

...