MySQL:大型VARCHAR与TEXT?

时间:2010-01-07 20:40:33

标签: mysql text messages varchar

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

是否有理由选择VARCHAR(3000)或TEXT?有一些关于编写VARCHAR(3000)的东西,感觉有点违反直觉。我已经浏览过Stack Overflow上的其他类似帖子,但是可以很好地获取特定于此类公共消息存储的视图。

8 个答案:

答案 0 :(得分:787)

  • TEXTBLOB存储在表格之外,表格只有一个指向实际存储位置的指针。

  • VARCHAR与表格内联存储。 VARCHAR在大小合理时速度更快,权衡速度更快取决于您的数据和硬件,您需要根据数据对真实世界场景进行基准测试。

更新 VARCHARTEXT是否内联存储,还是取消记录取决于数据大小,列大小,row_format和MySQL版本。 依赖于“text”vs“varchar”。

答案 1 :(得分:446)

你能预测用户输入的时间吗?

  

VARCHAR(X)

     
    

案例:用户名,电子邮件,国家/地区,主题,密码

  
     
     

TEXT

     
    

案例消息,电子邮件,评论,格式化文本,HTML,代码,图片,链接

  
     
     

MEDIUMTEXT

     
    

案例:大型json机构,短到中等长度的书籍,csv字符串

  
     
     

LONGTEXT

     
    

案例:教科书,程序,多年的日志文件,哈利波特和火焰杯,科研记录

  

答案 2 :(得分:215)

只是为了澄清最佳做法:

  1. 文本格式消息几乎总是存储为TEXT(它们最终会被任意长)

  2. 字符串属性应存储为VARCHAR(目标用户名,主题等)。

  3. 我知道你有一个前端限制,这是非常好的,直到它没有。 * grin *诀窍是将DB视为与连接它的应用程序分开。仅仅因为一个应用程序限制了数据,并不意味着数据本质上受限制。

    消息本身是什么让他们永远不会超过3000个字符?如果它只是一个任意的应用程序约束(例如,对于文本框或其他东西),请在数据层使用TEXT字段。

答案 3 :(得分:32)

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

我认为TEXT存储在mysql行之外,而我认为VARCHAR存储为行的一部分。 mysql行有一个最大行长度。因此,您可以使用VARCHAR限制可以在一行中存储的其他数据量。

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

答案 4 :(得分:21)

简短的答案:没有实用性,性能或存储方面的差异。

长答案:

VARCHAR(3000)(或任何其他大限制)和TEXT之间基本上没有区别(在MySQL中)。前者将截断为3000个字符;后者将截断为65535个字节。 (我区分了 bytes characters ,因为一个字符可以占用多个字节。)

对于VARCHAR中较小的限制,与TEXT相比有一些优势。

  • “较小”表示191、255、512、767或3072等,具体取决于版本,上下文和CHARACTER SET
  • INDEXes在可索引的列数方面受到限制。 (767或3072个字节;这取决于版本和设置)
  • 由复杂SELECTs创建的中间表以两种不同的方式处理-MEMORY(速度更快)或MyISAM(速度更快)。如果涉及“大”列,则会自动选择较慢的技术。 (8.0版将进行重大更改;因此,此项目符号可能会有所更改。)
  • 与上一项有关,所有TEXT数据类型(与VARCHAR相对)直接跳到MyISAM。也就是说,对于生成的临时表,TINYTEXT自动比等效的VARCHAR更差。 (但这将讨论推向了第三方向!)
  • VARBINARY就像VARCHARBLOB就像TEXT

反驳其他答案

最初的问题是一件事(使用哪种数据类型);接受的答案回答了其他问题(记录外存储)。该答案现在已过期。

启动该线程 时,InnoDB中只有两种“行格式”。此后不久,又引入了两种格式(DYNAMICCOMPRESSES)。

TEXTVARCHAR()的存储位置基于 size ,而不是基于数据类型名称。有关大型文本/ blob列的开/关记录存储的更新讨论,请参见this

答案 5 :(得分:5)

前面的答案在主要问题上的坚持不够充分:即使是在非常简单的查询中,例如

(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) 

可能需要一个临时表,如果涉及到VARCHAR字段,它将转换为临时表中的CHAR字段。因此,如果表中有50万行带有VARCHAR(65000)字段,则仅此列将使用 6.5 * 5 * 10 ^ 9 字节。这样的临时表无法在内存中处理,而是被写入磁盘。可以预期的影响是灾难性的。

来源(带有指标):https://nicj.net/mysql-text-vs-varchar-performance/ (这指的是在“标准”(?)MyISAM存储引擎中处理TEXTVARCHAR的情况。在其他方面(例如InnoDB)可能有所不同。)

答案 6 :(得分:0)

Varchar is for small data like email addresses, while Text is for much bigger data like news articles, Blob for binary data such as images.

The performance of Varchar is more powerful because it runs completely from memory, but this will not be the case if data is too big like varchar(4000) for example.

Text, on the other hand, does not stick to memory and is affected by disk performance, but you can avoid that by separating text data in a separate table and apply a left join query to retrieve text data.

Blob is much slower so use it only if you don't have much data like 10000 images which will cost 10000 records.

Follow these tips for maximum speed and performance:

  1. Use varchar for name, titles, emails

  2. Use Text for large data

  3. Separate text in different tables

  4. Use Left Join queries on an ID such as a phone number

  5. If you are going to use Blob apply the same tips as in Text

This will make queries cost milliseconds on tables with data >10 M and size up to 10GB guaranteed.

答案 7 :(得分:-1)

VARCHAR和TEXT之间存在巨大差异。虽然可以为VARCHAR字段建立索引,但不能为TEXT字段建立索引。 VARCHAR类型字段是内联存储的,而TEXT是脱机存储的,实际上只有TEXT数据的指针存储在记录中。

如果必须索引字段以进行更快的搜索,更新或删除,而不是使用VARCHAR,无论大小如何。 VARCHAR(10000000)永远不会与TEXT字段相同,因为这两种数据类型本质上是不同的。

  • 如果您仅将字段用于归档
  • 您不在乎数据 检索速度
  • 您关心速度,但是您将使用运算符 搜索查询中的“%LIKE%”,因此建立索引不会有太大帮助
  • 你 无法预测数据长度的限制

比选择TEXT