我应该为我的MySQL数据库使用MyISAM或InnoDB表吗?

时间:2011-09-20 22:55:59

标签: mysql database database-design innodb myisam

我的数据库中有以下两个表(索引是完整,因为它将基于我使用的引擎):

表1:

CREATE TABLE `primary_images` (
  `imgId` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
  `imgTitle` varchar(255) DEFAULT NULL,
  `view` varchar(45) DEFAULT NULL,
  `secondary` enum('true','false') NOT NULL DEFAULT 'false',
  `imgURL` varchar(255) DEFAULT NULL,
  `imgWidth` smallint(6) DEFAULT NULL,
  `imgHeight` smallint(6) DEFAULT NULL,
  `imgDate` datetime DEFAULT NULL,
  `imgClass` enum('jeans','t-shirts','shoes','dress_shirts') DEFAULT NULL,
  `imgFamily` enum('boss','lacoste','tr') DEFAULT NULL,
  `imgGender` enum('mens','womens') NOT NULL DEFAULT 'mens',
  PRIMARY KEY (`imgId`),
  UNIQUE KEY `imgDate` (`imgDate`)
)

表2:

CREATE TABLE `secondary_images` (
  `imgId` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
  `primaryId` smallint(6) unsigned DEFAULT NULL,
  `view` varchar(45) DEFAULT NULL,
  `imgURL` varchar(255) DEFAULT NULL,
  `imgWidth` smallint(6) DEFAULT NULL,
  `imgHeight` smallint(6) DEFAULT NULL,
  `imgDate` datetime DEFAULT NULL,
  PRIMARY KEY (`imgId`),
  UNIQUE KEY `imgDate` (`imgDate`)
)

表1将用于创建一个缩略图库,其中包含指向图像较大版本的链接。 imgClassimgFamilyimgGender会优化显示的缩略图。

表2包含与表1中的相关的图像。因此,使用primaryId将表1中的单个图像与表2中的一个或多个图像相关联。这是我在考虑使用InnoDB的外键功能,但我也熟悉MyISAM中索引的功能。

如果不对剩余字段进行过多研究,imgDate将用于对结果进行排序。

最后,但并非最不重要的是,我应该提到这个数据库是 READ ONLY 。所有数据都将由我输入。有人告诉我,如果一个数据库是只读的,它应该是MyISAM,但我希望你可以了解一下在我的情况下会做什么。

4 个答案:

答案 0 :(得分:22)

默认情况下始终使用InnoDB。

在MySQL 5.1之后,你应该使用InnoDB。在MySQL 5.1中,您应该enable the InnoDB plugin。在MySQL 5.5中,InnoDB插件默认启用,所以只需使用它。

多年前的建议是MyISAM在许多情况下都更快。但如果您使用当前版本的MySQL,则不再适用。

可能存在一些奇怪的极端情况,其中MyISAM对某些工作负载(例如表扫描或仅大量INSERT工作)执行得稍微好一点,但默认选择应该是InnoDB,除非你能证明

InnoDB的优点除了通常提到的对事务和外键的支持外还包括:

  • InnoDB比MyISAM更能抵抗表损坏。
  • 行级锁定。在MyISAM中,读者会阻止作者,反之亦然。
  • 支持数据和索引的大缓冲池。 MyISAM密钥缓冲区仅用于索引。
  • MyISAM停滞不前;所有未来的发展都将在InnoDB。

另请参阅我对MyISAM versus InnoDB

的回答

答案 1 :(得分:4)

MyISAM不会让你进行mysql级别检查。例如,如果您想将两个表上的imgId更新为单个事务:

START TRANSACTION;
UPDATE primary_images SET imgId=2 WHERE imgId=1;
UPDATE secondary_images SET imgId=2 WHERE imgId=1;
COMMIT;

另一个缺点是完整性检查,使用InnoDB可以做一些错误检查,以避免字段UNIQUE KEY imgDateimgDate)中的重复值。相信我,这真的来了,并且不那么容易出错。在我看来,MyISAM是为了玩游戏,而一些更严肃的工作应该依赖于InnoDB。

希望有所帮助

答案 2 :(得分:2)

需要考虑的一些事项:

  1. 您需要交易支持吗?
  2. 你会使用外键吗?
  3. 桌子上会写很多吗?
  4. 如果回答任何这些问题是“是”,那么你一定要使用InnoDB。 否则,您应该回答以下问题:

    1. 你的桌子有多大?
    2. 它们包含多少行?
    3. 数据库引擎的负载是多少?
    4. 您希望运行哪种查询?
    5. 除非您的表非常大并且您希望数据库负载很大,否则任何一个都可以正常工作。

      我更喜欢MyISAM,因为它适用于各种数据大小和负载。

答案 3 :(得分:-1)

我想补充一些人们可能会从中受益的东西: 我刚刚创建了一个InnoDB表(将所有内容保留为默认值,但将排序规则更改为Unicode除外),并使用大约300,000条记录(行)填充它。

SELECT COUNT(id) FROM table之类的查询会挂起,直到发出错误消息,而不是返回结果;

我已将数据克隆到新的MyISAM表中 -

,同样的查询以及其他大型SELECT查询会快速返回,一切正常。