2011-06-28 55 views
0

我發現innodb很煩人,當我試圖設計一個數據庫結構,至少與MyIsam相比,似乎有更少的限制爲什麼表格創建失敗時,一切都innodb,但不是當一個表是MyIsam?

說,如果我想創建一個簡單的圖書館系統。 而我有四張桌子。

1,表book_item,其中記錄了BOOK_NAME,作者,出版時間和有關書籍

2,表book這些基本信息,它代表了書項目的具體實物。因此,book_item對象可以與許多書對象相關聯。

3,表tag,其代表書籤。像科學,文學,建築等。

4,表tag_book_item_relation,它將標籤與book_items關聯。

所以,關係如下。

1,我們有一個書項目一個一對多關係

2,book_item標籤許多一對多關係。

注意這裏,發動機爲表都InnoDB的 如果我嘗試創建表,它將會失敗:

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

但是,如果我改變的booktag_book_item_relation發動機的MyISAM,一切都會好起來的。

所以,我想知道是怎麼回事錯的,如果我用發動機InnoDB的爲表booktag_book_item_relation

SQL腳本是在這裏(在MySQL工作臺正向工程):

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; 
+0

主鍵已經是唯一的,所以不需要在'tag'和'book_item'中添加唯一索引。 –

+2

咦? InnoDB真棒,MyISAM是魔鬼。爲什麼一個不理解事務概念的數據庫引擎甚至被支持,更不用說默認情況下MySQL使用的數據庫引擎了。充其量,非交易型數據庫就是一種玩具。 – aroth

+0

我同意InnoDb更好地執行 – xiaohan2012

回答

1

創建沒有Foreign Key限制的表格。儘管MyISAM引擎使用了相同的語句,但這些約束在這裏被忽略 - 這就是爲什麼你沒有得到錯誤。如果你真的需要這些約束,那麼就正確地創建它們。但是,我通常傾向於避免FK約束,並在應用程序級別實施約束。

一個問題我當場馬上是這必須是在數據庫級別唯一的你的約束符號,你同時擁有對tag_book_item_relation表和bookfk_book_item

+0

非常感謝,我明白了! – xiaohan2012

+1

建議不要使用FK是最值得懷疑的問題http://stackoverflow.com/questions/15616578/foreign-keys-when-cascades-arent-needed –

+0

我有點偏執狂 - 我喜歡明確地做所有事情 - 當我刪除'orders'記錄,我不希望我的'訂單行'被刪除,除非我明確刪除它們。是的,我可能會在數據庫中得到孤兒記錄,但通常這就是我想要的。我認爲這是一個喜好的問題。 –

1

ERROR 121表示「表創建失敗是因爲外鍵約束沒有正確形成,如果錯誤信息引用了錯誤-1,表創建可能失敗,因爲表包含一個與InnoDB內部表名相匹配的列名。」

Link

索引名和約束名稱可以相同,改變試圖創建表。

+0

感謝您分享鏈接! – xiaohan2012

1

此錯誤消息是說,有一個重複關鍵的地方。它可能是由外鍵約束中的名稱衝突引起的;您不能在不同的表中使用相同的外鍵名稱。 (我不知道你的數據庫中可能有其他的表格。)

通常,錯誤是由InnoDB內部字典中已經存在的表引起的,即使.frm文件不存在。如果是這樣的話,那麼最簡單的做法是執行數據的SQL轉儲,刪除數據庫,重新創建數據庫,然後從轉儲中加載數據。

2

看起來有一個問題,「CREATE TABLE book」外鍵約束fk_book_item具有與tag_book_item_relation中的約束相同的名稱。嘗試在book中使用另一個約束名稱,並且CREATE TABLE應該可以正常工作。

這在MyISAM中不是問題,因爲它們沒有外鍵的概念,所以忽略FK約束。

希望這會有所幫助!

相關問題