我在MySQL中有一个消息表,记录用户之间的消息。除了典型的id和消息类型(所有整数类型)之外,我需要将实际的消息文本保存为VARCHAR或text。我设置了3000个字符的前端限制,这意味着消息永远不会被插入到db中,超过这个长度。

使用VARCHAR(3000)或TEXT有什么基本原理吗?仅仅编写VARCHAR(3000)让人感觉有些违反直觉。我已经通过Stack Overflow上的其他类似帖子,但最好获得特定于这种类型的常见消息存储的视图。


当前回答

TEXT和BLOB可以存储在表外,表只有一个指向实际存储位置的指针。它存储在哪里取决于很多东西,比如数据大小、列大小、row_format和MySQL版本。 VARCHAR与表内联存储。当大小合理时,VARCHAR会更快,这取决于您的数据和硬件,您希望使用您的数据对真实场景进行基准测试。

其他回答

TEXT和BLOB可以存储在表外,表只有一个指向实际存储位置的指针。它存储在哪里取决于很多东西,比如数据大小、列大小、row_format和MySQL版本。 VARCHAR与表内联存储。当大小合理时,VARCHAR会更快,这取决于您的数据和硬件,您希望使用您的数据对真实场景进行基准测试。

Varchar适用于电子邮件地址这样的小数据,而Text适用于新闻文章这样的大数据,Blob适用于图像这样的二进制数据。

Varchar的性能更强大,因为它完全从内存中运行,但如果数据太大,例如Varchar(4000),情况就不一样了。

另一方面,文本不固定在内存中,并且受到磁盘性能的影响,但是可以通过将文本数据分离到单独的表中并应用左连接查询来检索文本数据来避免这种情况。

Blob要慢得多,所以只有当你没有很多数据时才使用它,比如10000张图片,这将花费10000条记录。

遵循以下技巧获得最大的速度和性能:

使用varchar记录姓名,头衔,电子邮件 大数据使用文本 在不同的表格中分离文本 对一个ID(比如电话号码)使用左连接查询 如果你要使用Blob,应用与文本相同的技巧

这将使数据> 10m和最大10GB的表上的查询花费毫秒。

简单的回答是:没有实用性、性能或存储方面的差异。

长一点的回答:

(在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列的记录内/记录外存储的最新讨论,请参见此。

前面的答案并没有足够强调主要问题:即使是在非常简单的查询,如

(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。)

免责声明:我不是MySQL专家…但这是我对问题的理解。

我认为文本存储在mysql行之外,而我认为VARCHAR存储为行的一部分。mysql的行有一个最大的行长。所以你可以使用VARCHAR限制你可以在一行中存储多少其他数据。

同样由于VARCHAR构成了行的一部分,我怀疑查看该字段的查询将比使用TEXT块的查询略快。