2010-07-20 26 views
15

我正在学习数据库数据类型的用法。如何选择列[innodb特定]的优化数据类型?

例如:

  • 哪一个电子邮件更好? VARCHAR [100],的char [100]或tinyint(开玩笑)
  • 哪个用户名更好?我应该使用int,bigint还是varchar? 解释。我的一些朋友说,如果我们使用int,bigint或其他数字数据类型,它会更好(Facebook做它)。就像u = 123400023引用用户123400023,而不是用户=用户名称。由于数字花费的时间更短。
  • 哪个更适合电话号码?帖子(如在博客或通告)?或者也许日期(我使用datetime)?也许有些人已经做了想要分享的研究。
  • 产品价格(我使用十进制(11,2),不知道你们)?
  • 或其他任何你的想法一样,“我用的串行数据类型blablabla。”

为什么我提的InnoDB具体?

除非你使用的是InnoDB表 类型(参见第11章, “高级 的MySQL,” 了解更多信息),CHAR 列更快地比 VARCHAR访问。

的Inno DB有一些diffrence,我不知道。 我从here读到。

+0

感谢colithium。我不知道如何处理链接哈哈。 – 2010-07-20 03:21:11

+0

添加了mysql标签。 – 2010-07-20 04:33:42

回答

15

小结:

(只是我的意见)

  1. 对于电子邮件地址 - VARCHAR(255)
  2. 用户名 - VARCHAR(100)VARCHAR(255)
  3. 为id_username - 使用INT(除非你计划在系统中有超过20亿用户)
  4. 电话号码 - TEXT
  5. 日期 - - INTVARCHAR也许CHAR
  6. 职位(如果你想存储格式取决于)DATEDATETIME(肯定包括时代喜欢的事情的帖子或电子邮件)
  7. 钱 - DECIMAL(11,2)
  8. 杂项 - 见下文

至于使用的是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数据库中,每个表可以有不同的引擎组合,因此您只需使“My Posts”表使用MyISAM即可。但是,如果您绝对需要使用InnoDB(针对交易)的“帖子”,请设置一个触发器来更新“posts”表的MyISAM副本,并使用MyISAM副本来处理所有全文搜索。

查看底部的一些有用的引号。

(3)“在VARCHAR列中的值是 可变长度字符串。可以将指定长度为 的值设置为MySQL 5.0.3之前的0至 255,0.0.3及更高版本中的0至 65,535。

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

当存储CHAR值时,它们是 右侧填充空格到 指定的长度。当检索到CHAR值为 时,尾随空格是 已删除。

在MySQL 5.0.3之前,将尾部空格 从 存储到VARCHAR列的值中删除;这 意味着空间也从检索到的值缺席 “

最后,这里是关于VARCHAR的与TEXT利弊一个伟大的职位也说,以性能问题:。

+0

这个帖子怎么样? 1 for =“thelongpost”? ,2 =“the2ndlongpost”:)。 – 2010-07-20 04:18:06

+1

对不起Adam,我想我已经包含了另一个链接来回答你的问题。好吧,请看我的编辑存储“帖子”。 – JohnB 2010-07-20 14:45:15

+0

拍摄,我忘了提及比InnoDB不支持全文索引。你必须使用MyISAM。请重新阅读我的部分。 – JohnB 2010-07-20 16:32:33

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 User-Agent信息。通过简单地将日志表中的每个用户代理字符串替换为查找表中的用户代理字符串的数字标识,数据集大小显着降低(超过60%)。通过进一步解析用户代理,然后存储一堆ID(操作系统,浏览器类型,版本索引),数据集大小减少到原始大小的1%。

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

例如,名称中有id并且不是无符号整数类型的任何东西都可能是一个错误(特别是在innodb环境中)。例如,任何名称中含有价格或成本且未签名的东西都是潜在的欺诈来源(欺诈者用负价创建文章并购买该文章)。

例如,任何对货币数据有效并且没有使用适当大小的DECIMAL数据类型的人可能会犯数学错误(DECIMAL正在做BCD,具有正确精度和舍入的小数纸张数学运算,DOUBLE和FLOAT不会)。

1

SQLyog的具有计算最优化的数据类型功能,这有助于基于插入表中的记录找出最佳的数据类型。 它使用

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

查询,找出最佳的数据类型为固定