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

使用VARCHAR(3000)或TEXT有什么基本原理吗?仅仅编写VARCHAR(3000)让人感觉有些违反直觉。我已经通过Stack Overflow上的其他类似帖子,但最好获得特定于这种类型的常见消息存储的视图。


当前回答

为了澄清最佳实践:

文本格式的消息几乎总是存储为Text(它们的长度是任意的) 字符串属性应该存储为VARCHAR(目标用户名、主题等)。

我知道你有一个前端限制,这很好,直到它没有。诀窍是把DB看作是与连接到它的应用程序分开的。仅仅因为一个应用程序限制了数据,并不意味着数据在本质上是有限的。

到底是什么原因迫使这些信息不能超过3000个字符呢?如果它只是一个任意的应用程序约束(例如,对于文本框或其他东西),则在数据层使用text字段。

其他回答

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

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

如果您只使用您的字段存档 你不关心数据 检索速度 你关心速度,但你会使用操作员 '%LIKE%'在您的搜索查询中,因此索引将没有多大帮助 你 无法预测数据长度的限制

而不是短信。

为了澄清最佳实践:

文本格式的消息几乎总是存储为Text(它们的长度是任意的) 字符串属性应该存储为VARCHAR(目标用户名、主题等)。

我知道你有一个前端限制,这很好,直到它没有。诀窍是把DB看作是与连接到它的应用程序分开的。仅仅因为一个应用程序限制了数据,并不意味着数据在本质上是有限的。

到底是什么原因迫使这些信息不能超过3000个字符呢?如果它只是一个任意的应用程序约束(例如,对于文本框或其他东西),则在数据层使用text字段。

前面的答案并没有足够强调主要问题:即使是在非常简单的查询,如

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

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

来源(包含指标):https://nicj.net/mysql-text-vs-varchar-performance/ (这是指在“标准”中处理TEXT vs VARCHAR (?)MyISAM存储引擎。其他的可能不同,比如InnoDB。)

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

我认为文本存储在mysql行之外,而我认为VARCHAR存储为行的一部分。mysql的行有一个最大的行长。所以你可以使用VARCHAR限制你可以在一行中存储多少其他数据。

同样由于VARCHAR构成了行的一部分,我怀疑查看该字段的查询将比使用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

关于这个问题还有更多信息。