MySQL中VarChar(255)和VarChar(65536)的处理方式不同。

14

有人知道使用VarChar(255)和VarChar(65536)之间的区别吗?

以下是我现在所知道的:

  • VarChar(255) 只使用一个字节的大小。
  • VarChar(65536) 将使用两个字节的大小。
  • VarChar(65536) 只存在于MySQL 5.0.3之后。
  • MySQL在255和65536之间使用不同的处理方式(虽然不知道差异)。

我不确定是否有任何性能差异。

假设我想要创建一个包含多种类型行的表格。使用枚举类型'data_type1'和'data_type2'

'data_type1' varchar 的长度永远不会超过255个字符。 'data_type2' varchar 的长度大多数情况下会超过255个字符。

哪种解决方案的表格更好呢?

id (int) - autoincrement
type (enum : data_type1, data_type2)
msg (varchar(255))
data (TEXT)

当type等于data_type2时,是否只使用"data"列?

或者

id (int) - autoincrement
type (enum : data_type1, data_type2)
msg (varchar(65536))

无论什么类型,都可以使用“msg”列?

实际上,在两种解决方案中都需要type列以进行处理。

编辑:

当type == data_type2时,存储的数据实际上永远不会超过10000个字符

编辑2:

我不想在msg和data列中进行搜索

这是有关存储性能的简单问题,与索引或搜索性能无关...


我真的无法理解你在问什么。 - Lightness Races in Orbit
我想,简而言之,我的问题是:对于存储大小不同的两种数据类型,表1和表2哪个更好? - TheSquad
从语义上讲,版本2。 - Lightness Races in Orbit
是啊,我猜应该是这样,所以我写了它,但如果方案1获取数据更快,那谁会在意语义呢 ;) - TheSquad
我同意!而且,这可能并不是问题所在。无论如何,它都不会成为你的瓶颈。如果你真的很在意,就对其进行性能分析。否则,只需编写代码并继续处理更重要的事情。 - Lightness Races in Orbit
2个回答

35

你提到的一些内容是正确的,我将解释VARCHAR是如何工作的。

如果您指定VARCHAR(60),那意味着它最多可以容纳60个字符。如果它包含较少的字符,比如50个字符-那么MySQL使用50个字节来存储数据,而不是60个字节。

对于CHAR(60)则恰好相反——它保留了60个字节,无论要保存的字符串长度是多少。

现在,VARCHAR是如何工作的呢?如果您将其指定为VARCHAR(255),那么该列将保留1个字节+字符串字节数。 那1个字节表示字符串的长度。1个字节=您可以存储0-255个值(2的8次方=256)。

至于超过255的VARCHAR,则需要以某种方式存储使用的字节数。由于1个字节只能存储多达256个不同的值(0-255),所以需要使用两个字节。2的16次方=65536,这意味着您可以存储任何大小的字符串,然后它会增加2个字节来指示字符串的长度。

因此,简而言之-性能差异在于如果您有VARCHAR(65536)并且使用了200个字节来存储文本,则会浪费VARCHAR(65536)将使用的那1个额外字节。 有人可能会想:“哦,但只是1个字节,谁关心那个呢。”其实很多人都关心-想象一下在一个有5000万条记录的表中有几个VARCHAR列。假设您有3个varchar列,每个都浪费了额外的1个字节-那就是3个字节×5000万≈144兆字节的浪费空间。有趣的是,这不仅是浪费空间。它还会导致处理开销和在读取内容时使用额外的RAM。

了解这些信息可能会帮助您自己决定什么是最好的选择。

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html 如果您之前没有查看过此文档,它会解释每种数据类型是如何存储以及需要多少空间。


如果我正在获取data_type1,将一个TEXT字段设置为NULL会不会减慢速度?并且获取varchar(65536)或TEXT是否一样快? - TheSquad
这里的差异微不足道,你谈论的是在找到行之后检索性能,但你完全忘记了要找到想要检索的行。就规模而言,你正在错误的领域进行优化。你到底在做什么?听起来有点像你偶然发现的强类型EAV数据模型,你能否澄清一下,以便我可以指引你正确的方向? - Michael J.V.
我实际上担心的是这个表将被频繁查询!行生命周期非常简单,即插入-选择-删除(实际上是一个队列)。现在我们每小时面临每个操作300K(300k插入,300k选择,300k删除)。我希望在添加和删除以及当然选择方面获得最佳性能(但实际上我并不担心选择)。 - TheSquad
你使用的是哪种数据库引擎?如果是InnoDB,那么如果你的DELETE和SELECT基于主键查找(WHERE id = 123),那么InnoDB将非常快,并且varchar / text数据类型在这里不会有任何影响。如果是MyISAM,则插入将像一级方程式赛车一样快,但其他部分可能会崩溃,而基于主键的SELECT将比基于InnoDB的SELECT慢得多。 - Michael J.V.
它是带有主键查找的InnoDB引擎。所以我猜我是在担心无谓的事情...等我完成后再看吧 ;) 谢谢 - TheSquad
相对于三个varchar列的数据约28 GB,144 MB相对较小。 - Jimmy T.

-1

在我看来,与其他字符串类型相比,最好使用VARCHAR,因为TEXT有大小限制,而CHAR会在磁盘上保留空间。VARCHAR仅使用您输入的字符所需的空间。


6
抱歉,那不是真的,你得到了错误的信息。CHAR确实会“保留”空间,TEXT不会,这类似于VARCHAR的工作原理。 - Michael J.V.
那么这意味着,如果我使用字段类型TEXT并存储一个值为300个字符的值,TEXT会适应这个大小吗?还是说,我会浪费一些空间? - carloscarcamo
旧帖子,但看到这个就想评论一下。varchartext之间唯一的区别是可以存储的数据量最大值。varchar(max) - 可变宽度字符字符串 - 最大尺寸1,073,741,824个字符text - 可变宽度字符字符串 - 2GB文本数据 - hmiedema9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接