我在MySQL中有一个消息表,记录用户之间的信息。除了典型的id和消息类型(所有整数类型)之外,我需要将实际消息文本保存为VARCHAR或TEXT。我在前端设置了3000个字符的限制,这意味着消息永远不会以超过这个长度插入到数据库中。
对于选择VARCHAR(3000)或TEXT是否有理由?仅写VARCHAR(3000)感觉有些违反直觉。我已经查看了Stack Overflow上其他类似的帖子,但希望能够得到针对此类常见消息存储的具体观点。
我在MySQL中有一个消息表,记录用户之间的信息。除了典型的id和消息类型(所有整数类型)之外,我需要将实际消息文本保存为VARCHAR或TEXT。我在前端设置了3000个字符的限制,这意味着消息永远不会以超过这个长度插入到数据库中。
对于选择VARCHAR(3000)或TEXT是否有理由?仅写VARCHAR(3000)感觉有些违反直觉。我已经查看了Stack Overflow上其他类似的帖子,但希望能够得到针对此类常见消息存储的具体观点。
TEXT
和 BLOB
可能会被存储在表外,而表只有指向实际存储位置的指针。它存储的位置取决于许多因素,如数据大小、列大小、行格式和 MySQL 版本。
VARCHAR
存储在表中。当大小合理时,VARCHAR
更快,其速度取决于您的数据和硬件,您需要使用您的数据对真实情况进行基准测试。
你能预测用户输入的长度吗?
VARCHAR(X)
最大长度: 可变长度,最多65,535字节(64KB)
应用场景: 用户名、电子邮件、国家、主题、密码
TEXT
最大长度: 65,535字节(64KB)
应用场景: 消息、邮件、评论、格式化文本、HTML、代码、图像、链接
MEDIUMTEXT
最大长度: 16,777,215字节(16MB)
应用场景: 大型JSON体、中短篇小说、CSV字符串
LONGTEXT
最大长度: 4,294,967,29字节(4GB)
应用场景: 教科书、程序、多年的日志文件、哈利波特与火焰杯、科学研究记录
更多信息请参考此问题。
为了阐明最佳实践:
文本格式的消息应几乎总是以TEXT形式存储(它们最终会变得任意长)
字符串属性应该存储为VARCHAR(目标用户名、主题等)。
我知道你有前端限制,这很好,直到不好为止。 * 嘿嘿 * 诀窍是将DB视为与连接到它的应用程序分离的内容。 只是因为一个应用程序对数据设置了限制,并不意味着数据在本质上有限制。
是什么让消息本身永远不能超过3000个字符? 如果只是任意应用程序约束(比如文本框之类的),请在数据层使用TEXT
字段。
magnet:
URL一样的超大URL?它们可能比255个字符长得多。 - Roland简短回答:在实际应用中,VARCHAR(3000)(或其他任何大的限制)和TEXT没有实际性能或存储上的差异。
详细回答:
在MySQL中,VARCHAR(3000)
(或任何其他大的限制)和TEXT
基本上没有区别。前者会截断到3000个字符;后者会截断到65535个字节。(我之所以区分字节和字符是因为一个字符可能占据多个字节。)
对于VARCHAR
中较小的限制,有一些优点:
CHARACTER SET
。INDEXes
在索引列的大小方面受到限制。(767或3072个字节;这取决于版本和设置)SELECTs
创建的中间表有两种不同的处理方式——MEMORY(更快)或MyISAM(更慢)。当涉及到“大”列时,会自动选择较慢的技术。(在版本8.0中有重大变化,因此此项要点可能会发生变化。)TEXT
数据类型(与VARCHAR
相对)都直接跳转到MyISAM。也就是说,TINYTEXT
自动生成的临时表比等效的VARCHAR
更差。(但这将带我们进入第三个方向的讨论!)VARBINARY
类似于VARCHAR
;BLOB
类似于TEXT
。VARCHAR
的表可能会达到整个表定义的64KB限制;切换到TEXT
是一个简单而实用的解决方法。(例如:(42000) Row size too large, from an Oracle dump to a MySQL dump)对其他答案的反驳
原问题询问了一件事(使用哪种数据类型);被接受的答案回答了另一件事(离线存储)。那个答案现在已经过时了。
当这个线程被创建和回答的时候,InnoDB中只有两种“行格式”。不久之后,引入了另外两种格式(DYNAMIC
和COMPRESSED
)。
TEXT
和VARCHAR()
的存储位置是基于大小,而不是数据类型名称。有关大文本/ blob列的在线/离线记录存储的更新讨论,请参见此处。
免责声明:我不是MySQL专家……但这是我的理解。
我认为TEXT类型的数据存储在mysql行外,而VARCHAR类型的数据则作为行的一部分存储。MySQL行有一个最大长度限制……因此,您可以通过使用VARCHAR来限制在行中存储的其他数据量。
另外,由于VARCHAR作为行的一部分而存在,我怀疑查询该字段的速度会比使用TEXT块的查询略快。
varchar
列最多可占用9000个字节。 - Jan FabryTEXT
内联存储在表中。 - dotancohen(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id)
Varchar用于存储小型数据,例如电子邮件地址,而Text用于存储更大的数据,例如新闻文章,Blob用于存储二进制数据,例如图片。
Varchar的性能更强,因为它完全依赖内存运行。但是如果数据太大,比如varchar(4000)
,那么情况就不同了。
另一方面,Text不会固定在内存中,受到磁盘性能的影响,但您可以通过将文本数据分离到单独的表中并应用左连接查询来检索文本数据。
Blob速度较慢,只有在没有太多数据(例如10000张图像)时才使用Blob。
遵循以下提示以获得最大速度和性能:
使用varchar来存储名称、标题、电子邮件
使用Text存储大数据
将文本分开存储在不同的表中
在ID(如电话号码)上使用Left Join查询
如果要使用Blob,请应用与Text相同的提示
这将确保对数据量>10 M且大小高达10GB的表进行查询的时间不超过毫秒。
VARCHAR和TEXT之间有着巨大的区别。VARCHAR字段可以索引,而TEXT字段则不能。VARCHAR类型的字段存储在行内,而TEXT存储在离线,实际上只是存储了指向TEXT数据的指针。
如果您需要为更快的搜索、更新或删除而索引您的字段,请选择VARCHAR,无论大小如何。VARCHAR(10000000)永远不会与TEXT字段相同,因为这两种数据类型在本质上是不同的。
那么请选择TEXT。
对于这里的许多答案,我需要进行一些更正,即使现在可能已经有点晚了。
根据MySQL的文档,文本字段可以完全被索引。
链接提供 https://dev.mysql.com/doc/refman/5.6/en/column-indexes.html
总体上来说,Varchar字段比Text字段写入时间更长,但只有在有大量写请求时才会有影响。