如何为列[innodb specific]选择优化的数据类型?

时间:2010-07-20 03:09:51

标签: mysql database database-design innodb

我正在学习数据库数据类型的用法。

例如:

  • 哪个更适合电子邮件? varchar [100],char [100]或tinyint(开玩笑)
  • 哪个用户名更好?我应该使用int,bigint还是varchar? 说明。我的一些朋友说,如果我们使用int,bigint或其他数字数据类型,它会更好(facebook会这样做)。像u = 123400023指的是用户123400023,而不是user = thenameoftheuser。由于数字需要较少的时间来获取。
  • 哪个电话号码更好?帖子(如博客或公告)?或者也许是日期(我使用日期时间)?也许有些人做了想分享的研究。
  • 产品价格(我使用小数(11,2),不知道你们的人)?
  • 或者您想到的任何其他内容,例如“我使用串行数据类型进行blablabla”。

为什么我特意提到innodb?

  

除非您使用InnoDB表   类型(见第11章,“高级   MySQL,“更多信息”,CHAR   列比访问更快   VARCHAR。

Inno db有一些我不知道的差异。 我是从here读到的。

3 个答案:

答案 0 :(得分:15)

摘要:

(只是我的意见)

  1. 用于电子邮件地址 - VARCHAR(255)
  2. 代表用户名 - VARCHAR(100)VARCHAR(255)
  3. for id_username - 使用INT(除非您计划在系统中使用超过20亿用户)
  4. 电话号码 - INTVARCHARCHAR(取决于您是否要存储格式)
  5. 帖子 - TEXT
  6. 日期 - DATEDATETIME(绝对包括帖子或电子邮件等内容的时间)
  7. money - DECIMAL(11,2)
  8. misc - 见下文
  9. 至于使用InnoDB,因为VARCHAR应该更快,我不会担心这一点,或一般的速度。使用InnoDB是因为您需要执行事务和/或您希望使用外键约束(FK)来保证数据完整性。此外,InnoDB使用行级锁定,而MyISAM仅使用表级锁定。因此,InnoDB可以比MyISAM更好地处理更高级别的并发性。使用MyISAM来使用全文索引,并减少开销。

    更重要的是速度比引擎类型:将索引放在需要快速搜索的列上。始终将索引放在ID / PK列上,例如我提到的id_username。

    更多详情:

    以下是关于MySQL数据类型和数据库设计的一系列问题(警告,比您要求的更多):

    关于何时使用InnoDB引擎的几个问题:

    我只使用tinyint几乎所有内容(严重)。

    编辑 - 如何存储“帖子:”

    下面是一些更详细的链接,但这里是简短版本。对于存储“帖子”,您需要一个长文本字符串的空间。 CHAR最大长度为255,因此这不是一个选项,当然CHAR会浪费未使用的字符而不是VARCHAR,这是可变长度CHAR

    在MySQL 5.0.3之前,VARCHAR最大长度为255,因此您将留下TEXT。但是,在较新版本的MySQL中,您可以使用VARCHARTEXT。选择取决于偏好,但有一些差异。 VARCHARTEXT最大长度现在都是65,535,但您可以在VARCHAR设置自己的最大值。假设您认为您的帖子最多只需要2000,您可以设置VARCHAR(2000)。如果您每次都遇到限制,您可以ALTER稍后再提出并将其提交到VARCHAR(3000)。另一方面,TEXT实际上将其数据存储在BLOB(1)中。我听说VARCHARTEXT之间可能存在性能差异,但我没有看到任何证据,因此您可能希望了解更多信息,但您可以随时更改该细节在将来。

    更重要的是,使用全文索引而不是LIKE搜索此“发布”列会快得多(2)。但是,您必须使用MyISAM引擎才能使用全文索引,因为InnoDB不支持。在MySQL数据库中,每个表都可以有异构的引擎组合,因此您只需要使用MyISAM使您的“帖子”表成为可能。但是,如果你绝对需要“帖子”来使用InnoDB(用于交易),那么设置一个触发器来更新你的“帖子”表的MyISAM副本,并使用MyISAM副本进行所有全文搜索。

    请参阅底部以获取一些有用的引用。

      

    (3)“VARCHAR列中的值为   变长字符串。长度   可以指定为0到0之间的值   在MySQL 5.0.3之前255,并且0到   5.0.3及更高版本中的65,535。

         

    在MySQL 5.0.3之前,如果需要数据   尾随空格不是的类型   删除,考虑使用BLOB或TEXT   类型。

         

    存储CHAR值时,它们是   右边有空格的   指定长度。当CHAR值是   检索,尾随空格   除去。

         

    在MySQL 5.0.3之前,尾随空格   从它们中移除值   存储在VARCHAR列中;这个   意味着空间也不存在   从检索到的值。“

    最后,这里有一篇关于VARCHAR与TEXT的优缺点的文章。它还谈到了性能问题:

答案 1 :(得分:3)

有多个角度可以解决您的问题。

从设计POV中,最好选择表达您想要最佳建模数量的数据类型。也就是说,正确地获取数据域和数据大小,以便非法数据首先不能存储在数据库中。但这不是MySQL首先强大的地方,特别是没有默认的sql_mode(http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html)。如果它适合您,请尝试TRADITIONAL sql_mode,它是许多可能标志的简写。

从性能POV来看,问题完全不同。例如,关于电子邮件正文的存储,您可能需要阅读http://www.mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb/,然后再考虑一下。

删除冗余和拥有快捷键可能是一个巨大的胜利。例如,在我看过的项目中,日志表一直存储http用户代理信息。通过简单地用查找表中的用户代理字符串的数字id替换日志表中的每个用户代理字符串,数据集大小显着(大于60%)减少。通过进一步解析用户代理然后存储一堆ID(操作系统,浏览器类型,版本索引),数据集大小减少到原始大小的1%。

最后,有许多规则可以帮助您发现架构设计中的错误。

例如,名称中包含id并且不是无符号整数类型的任何内容都可能是错误(特别是在innodb的上下文中)。

例如,任何名称中有价格或成本且未签名的东西都是欺诈的潜在来源(欺诈者会创建负价格的文章,然后购买)。

例如,任何适用于货币数据且未使用适当大小的DECIMAL数据类型的东西可能都是错误的数学(DECIMAL正在进行BCD,十进制纸数学具有正确的精度和舍入,DOUBLE和FLOAT不会)

答案 2 :(得分:1)

SQLyog具有计算最佳数据类型功能,该功能有助于根据插入表中的记录查找最佳数据类型。 它使用

  

SELECT * FROM table_name` PROCEDURE ANALYZE(1,10);

查询以找出最佳数据类型