我在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列的记录内/记录外存储的最新讨论,请参见此。
其他回答
TEXT和BLOB可以存储在表外,表只有一个指向实际存储位置的指针。它存储在哪里取决于很多东西,比如数据大小、列大小、row_format和MySQL版本。 VARCHAR与表内联存储。当大小合理时,VARCHAR会更快,这取决于您的数据和硬件,您希望使用您的数据对真实场景进行基准测试。
免责声明:我不是MySQL专家…但这是我对问题的理解。
我认为文本存储在mysql行之外,而我认为VARCHAR存储为行的一部分。mysql的行有一个最大的行长。所以你可以使用VARCHAR限制你可以在一行中存储多少其他数据。
同样由于VARCHAR构成了行的一部分,我怀疑查看该字段的查询将比使用TEXT块的查询略快。
为了澄清最佳实践:
文本格式的消息几乎总是存储为Text(它们的长度是任意的) 字符串属性应该存储为VARCHAR(目标用户名、主题等)。
我知道你有一个前端限制,这很好,直到它没有。诀窍是把DB看作是与连接到它的应用程序分开的。仅仅因为一个应用程序限制了数据,并不意味着数据在本质上是有限的。
到底是什么原因迫使这些信息不能超过3000个字符呢?如果它只是一个任意的应用程序约束(例如,对于文本框或其他东西),则在数据层使用text字段。
你能预测用户输入的时长吗?
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中)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列的记录内/记录外存储的最新讨论,请参见此。