我在MySQL中有一个消息表,用于在用户之间记录消息。除了典型的id和消息类型(所有整数类型),我需要将实际的消息文本保存为VARCHAR或TEXT。我设置的前端限制为3000个字符,这意味着消息永远不会插入到数据库中,而不会超过此值。
是否有理由选择VARCHAR(3000)或TEXT?有一些关于编写VARCHAR(3000)的东西,感觉有点违反直觉。我已经浏览过Stack Overflow上的其他类似帖子,但是可以很好地获取特定于此类公共消息存储的视图。
答案 0 :(得分:787)
TEXT
和BLOB
存储在表格之外,表格只有一个指向实际存储位置的指针。
VARCHAR
与表格内联存储。 VARCHAR
在大小合理时速度更快,权衡速度更快取决于您的数据和硬件,您需要根据数据对真实世界场景进行基准测试。
更新 VARCHAR
或TEXT
是否内联存储,还是取消记录取决于数据大小,列大小,row_format和MySQL版本。 不依赖于“text”vs“varchar”。
答案 1 :(得分:446)
你能预测用户输入的时间吗?
VARCHAR(X)
案例:用户名,电子邮件,国家/地区,主题,密码
TEXT
案例消息,电子邮件,评论,格式化文本,HTML,代码,图片,链接
MEDIUMTEXT
案例:大型json机构,短到中等长度的书籍,csv字符串
LONGTEXT
案例:教科书,程序,多年的日志文件,哈利波特和火焰杯,科研记录
答案 2 :(得分:215)
只是为了澄清最佳做法:
文本格式消息几乎总是存储为TEXT(它们最终会被任意长)
字符串属性应存储为VARCHAR(目标用户名,主题等)。
我知道你有一个前端限制,这是非常好的,直到它没有。 * 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
相比有一些优势。
CHARACTER SET
。INDEXes
在可索引的列数方面受到限制。 (767或3072个字节;这取决于版本和设置)SELECTs
创建的中间表以两种不同的方式处理-MEMORY(速度更快)或MyISAM(速度更快)。如果涉及“大”列,则会自动选择较慢的技术。 (8.0版将进行重大更改;因此,此项目符号可能会有所更改。)TEXT
数据类型(与VARCHAR
相对)直接跳到MyISAM。也就是说,对于生成的临时表,TINYTEXT
自动比等效的VARCHAR
更差。 (但这将讨论推向了第三方向!)VARBINARY
就像VARCHAR
; BLOB
就像TEXT
。反驳其他答案
最初的问题是一件事(使用哪种数据类型);接受的答案回答了其他问题(记录外存储)。该答案现在已过期。
启动该线程 时,InnoDB中只有两种“行格式”。此后不久,又引入了两种格式(DYNAMIC
和COMPRESSES
)。
TEXT
和VARCHAR()
的存储位置基于 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存储引擎中处理TEXT
与VARCHAR
的情况。在其他方面(例如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:
Use varchar for name, titles, emails
Use Text for large data
Separate text in different tables
Use Left Join queries on an ID such as a phone number
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字段相同,因为这两种数据类型本质上是不同的。
比选择TEXT