我在MySQL中有一个消息表,记录用户之间的消息。除了典型的id和消息类型(所有整数类型)之外,我需要将实际的消息文本保存为VARCHAR或text。我设置了3000个字符的前端限制,这意味着消息永远不会被插入到db中,超过这个长度。
使用VARCHAR(3000)或TEXT有什么基本原理吗?仅仅编写VARCHAR(3000)让人感觉有些违反直觉。我已经通过Stack Overflow上的其他类似帖子,但最好获得特定于这种类型的常见消息存储的视图。
我在MySQL中有一个消息表,记录用户之间的消息。除了典型的id和消息类型(所有整数类型)之外,我需要将实际的消息文本保存为VARCHAR或text。我设置了3000个字符的前端限制,这意味着消息永远不会被插入到db中,超过这个长度。
使用VARCHAR(3000)或TEXT有什么基本原理吗?仅仅编写VARCHAR(3000)让人感觉有些违反直觉。我已经通过Stack Overflow上的其他类似帖子,但最好获得特定于这种类型的常见消息存储的视图。
当前回答
简单的回答是:没有实用性、性能或存储方面的差异。
长一点的回答:
(在MySQL中)VARCHAR(3000)(或任何其他较大的限制)和TEXT之间基本上没有区别。前者将在3000个字符处截断;后者将截断到65535字节。(我在字节和字符之间做了区分,因为一个字符可以包含多个字节。)
对于VARCHAR中较小的限制,有一些优于TEXT的优点。
"smaller" means 191, 255, 512, 767, or 3072, etc, depending on version, context, and CHARACTER SET. INDEXes are limited in how big a column can be indexed. (767 or 3072 bytes; this is version and settings dependent) Intermediate tables created by complex SELECTs are handled in two different ways -- MEMORY (faster) or MyISAM (slower). When 'large' columns are involved, the slower technique is automatically picked. (Significant changes coming in version 8.0; so this bullet item is subject to change.) Related to the previous item, all TEXT datatypes (as opposed to VARCHAR) jump straight to MyISAM. That is, TINYTEXT is automatically worse for generated temp tables than the equivalent VARCHAR. (But this takes the discussion in a third direction!) VARBINARY is like VARCHAR; BLOB is like TEXT. A table with several 'large' VARCHARs could hit a limit of 64KB for the whole table definition; switching to TEXT is a simple and practical fix. (Example: (42000) Row size too large, from an Oracle dump to a MySQL dump )
反驳其他答案
最初的问题只问了一件事(使用哪种数据类型);接受的答案回答了其他问题(非记录存储)。这个答案现在已经过时了。
当这个线程启动并应答时,InnoDB中只有两种“行格式”。不久之后,又引入了两种格式(DYNAMIC和COMPRESSED)。
TEXT和VARCHAR()的存储位置基于大小,而不是数据类型的名称。有关大型文本/blob列的记录内/记录外存储的最新讨论,请参见此。
其他回答
免责声明:我不是MySQL专家…但这是我对问题的理解。
我认为文本存储在mysql行之外,而我认为VARCHAR存储为行的一部分。mysql的行有一个最大的行长。所以你可以使用VARCHAR限制你可以在一行中存储多少其他数据。
同样由于VARCHAR构成了行的一部分,我怀疑查看该字段的查询将比使用TEXT块的查询略快。
前面的答案并没有足够强调主要问题:即使是在非常简单的查询,如
(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id)
可能需要一个临时表,如果涉及到VARCHAR字段,则将其转换为临时表中的CHAR字段。因此,如果你的表中有500000行VARCHAR(65000)字段,这一列将使用6.5*5*10^9字节。这样的临时表不能在内存中处理,而是被写入磁盘。其影响预计将是灾难性的。
来源(包含指标):https://nicj.net/mysql-text-vs-varchar-performance/ (这是指在“标准”中处理TEXT vs VARCHAR (?)MyISAM存储引擎。其他的可能不同,比如InnoDB。)
VARCHAR和TEXT之间有一个巨大的差异。虽然VARCHAR字段可以被索引,但TEXT字段不能。VARCHAR类型字段内联存储,而TEXT则脱机存储,只有指向TEXT数据的指针实际存储在记录中。
如果你必须索引你的字段,以便更快的搜索,更新或删除,而不是使用VARCHAR,无论有多大。VARCHAR(10000000)永远不会与TEXT字段相同,因为这两种数据类型在本质上是不同的。
如果您只使用您的字段存档 你不关心数据 检索速度 你关心速度,但你会使用操作员 '%LIKE%'在您的搜索查询中,因此索引将没有多大帮助 你 无法预测数据长度的限制
而不是短信。
你能预测用户输入的时长吗?
VARCHAR(X) Max Length: variable, up to 65,535 bytes (64KB) Case: user name, email, country, subject, password TEXT Max Length: 65,535 bytes (64KB) Case: messages, emails, comments, formatted text, html, code, images, links MEDIUMTEXT Max Length: 16,777,215 bytes (16MB) Case: large json bodies, short to medium length books, csv strings LONGTEXT Max Length: 4,294,967,29 bytes (4GB) Case: textbooks, programs, years of logs files, harry potter and the goblet of fire, scientific research logging
关于这个问题还有更多信息。
只是对这里这么多答案的更正,即使现在有点晚了。
MySQL可以根据它们的文档对文本字段进行完全索引。
提供的链接 https://dev.mysql.com/doc/refman/5.6/en/column-indexes.html
总的来说,写Varchar字段比写Text字段要长,但只有当你有大量的写请求时才会有影响