我在MySQL中有一个消息表,该表记录了用户之间的消息。除了典型的ID和消息类型(所有整数类型)之外,我需要将实际消息文本另存为VARCHAR或TEXT。我将前端限制设置为3000个字符,这意味着消息插入数据库的时间绝不会超过此时间。
是否有使用VARCHAR(3000)或TEXT的理由?只是编写VARCHAR(3000)有点不合常理。我曾经在Stack Overflow上浏览过其他类似的文章,但是最好获得特定于这种常见消息存储类型的视图。
我在MySQL中有一个消息表,该表记录了用户之间的消息。除了典型的ID和消息类型(所有整数类型)之外,我需要将实际消息文本另存为VARCHAR或TEXT。我将前端限制设置为3000个字符,这意味着消息插入数据库的时间绝不会超过此时间。
是否有使用VARCHAR(3000)或TEXT的理由?只是编写VARCHAR(3000)有点不合常理。我曾经在Stack Overflow上浏览过其他类似的文章,但是最好获得特定于这种常见消息存储类型的视图。
Answers:
TEXT
并且BLOB
可以通过将该表存储在表之外,而该表仅具有指向实际存储位置的指针。它的存储位置取决于许多因素,例如数据大小,列大小,row_format和MySQL版本。
VARCHAR
与表内联存储。VARCHAR
如果大小合理,则速度更快,折衷的速度会更快,这取决于您的数据和硬件,因此您希望使用数据对实际场景进行基准测试。
varchar
和blob
/ text
上的小型文本项之间应该没有性能差异吗?那么,仅将每种类型都设置为varchar
一个text
类型并让DB管理内联与溢出是否明智?
您能预测用户输入多长时间吗?
VARCHAR(X)
案例:用户名,电子邮件,国家/地区,主题,密码
文本
案例:消息,电子邮件,评论,格式化文本,html,代码,图像,链接
中文字
案例:大型JSON正文,中短长度的书籍,CSV字符串
长文本
案例:教科书,程序,日志文件的年限,哈利·波特与火焰杯,科学研究记录
只是为了阐明最佳做法:
文本格式的消息几乎应始终存储为TEXT(它们最终会任意长)
字符串属性应存储为VARCHAR(目标用户名,主题等)。
我知道您有一个前端限制,这很好,直到没有限制为止。*咧嘴*诀窍是将数据库与连接到数据库的应用程序分开考虑。仅仅因为一个应用程序对数据进行了限制,并不意味着数据本身就受到限制。
消息本身是什么使它们不能超过3000个字符?如果这只是一个任意的应用程序约束(例如,对于文本框之类的东西),请TEXT
在数据层使用字段。
免责声明:我不是MySQL专家...但这是我对问题的理解。
我认为TEXT存储在mysql行之外,而我认为VARCHAR存储为该行的一部分。mysql行有一个最大行长度。因此,您可以使用VARCHAR限制一行中可以存储多少其他数据。
同样由于VARCHAR构成了行的一部分,我怀疑查看该字段的查询会比使用TEXT块的查询稍快。
varchar
列最多可占用9000个字节。
TEXT
也会在表中存储内联。
简短的回答: 没有实用性,性能或存储差异。
长答案:
VARCHAR(3000)
(或任何其他大限制)和之间(在MySQL中)基本上没有区别TEXT
。前者将截断3000个字符 ; 后者将截断为65535 字节。(我区分字节和字符,因为一个字符可以占用多个字节。)
对于较小的限制VARCHAR
,与相比有一些优势TEXT
。
CHARACTER SET
。INDEXes
在可索引的列数方面受到限制。(767或3072 字节;这取决于版本和设置)SELECTs
系统创建的中间表以两种不同的方式处理-MEMORY(更快)或MyISAM(更快)。如果涉及“大”列,则会自动选择较慢的技术。(8.0版中将进行重大更改;因此,此项目符号可能会有所更改。)TEXT
数据类型(与相对VARCHAR
)直接跳到MyISAM。也就是说,TINYTEXT
对于生成的临时表,它自动比等效表更糟VARCHAR
。(但这将讨论引向了第三方向!)VARBINARY
就像VARCHAR
; BLOB
就像TEXT
。反驳其他答案
最初的问题是一件事(使用哪种数据类型)。接受的答案回答了其他问题(记录外存储)。该答案现在已过期。
当启动并回答该线程时,InnoDB中只有两种“行格式”。此后不久,又引入了两种格式(DYNAMIC
和COMPRESSED
)。
对于存储位置TEXT
和VARCHAR()
基于大小,而不是数据类型的名称。有关大型text / blob列的开/关记录存储的最新讨论,请参见this。
前面的答案在主要问题上的坚持不够:即使在非常简单的查询中,例如
(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id)
可能需要一个临时表,如果VARCHAR
涉及到一个CHAR
字段,它将转换为临时表中的一个字段。因此,如果您在表中说有一个VARCHAR(65000)
字段500 000行,则仅此列将使用6.5 * 5 * 10 ^ 9字节。这样的临时表无法在内存中处理,而是被写入磁盘。可以预期的影响是灾难性的。
来源(带有指标):https : //nicj.net/mysql-text-vs-varchar-performance/
(这是指“标准”(?)MyISAM存储引擎中TEXT
vs 的处理VARCHAR
。在其他方面可能有所不同,例如InnoDB。)
VARCHAR和TEXT之间存在巨大差异。虽然可以为VARCHAR字段建立索引,但不能为TEXT字段建立索引。VARCHAR类型字段是内联存储的,而TEXT是脱机存储的,实际上只有TEXT数据的指针存储在记录中。
如果必须索引字段以进行快速搜索,更新或删除,而不是使用VARCHAR(无论大小如何)。VARCHAR(10000000)永远不会与TEXT字段相同,因为这两种数据类型本质上是不同的。
而不是去TEXT。
Varchar用于小数据,例如电子邮件地址,而Text用于大数据,例如新闻文章,Blob用于二进制数据,例如图像。
Varchar的性能更强大,因为它完全依靠内存运行,但是varchar(4000)
,例如,如果数据太大,则情况并非如此。
另一方面,文本不会保留在内存中,并且会受到磁盘性能的影响,但是您可以通过在单独的表中分离文本数据并应用左联接查询来检索文本数据来避免这种情况。
Blob的速度要慢得多,因此仅当您没有太多数据(例如10000张图像,将花费10000条记录)时才使用它。
请遵循以下提示以实现最大速度和性能:
使用varchar作为名称,标题,电子邮件
使用文本处理大数据
在不同表格中分开文字
在ID(例如电话号码)上使用左联接查询
如果您要使用Blob,请应用与“文字”中相同的提示
这将使表在数据大于10 M且保证最大大小为10GB的表上花费毫秒的时间。