当我们存储长度小于10的字符串时,varchar(10)和varchar(1000)之间有区别吗?

8
我了解charvarchar的区别,但我不确定 varchar 最大长度的确切含义。
当我们存储长度小于10的string时,varchar(10)varchar(100)有什么区别吗?
我认为这两种情况使用相同的空间并且具有相同的性能。如果是这样的话,我们为什么需要varchar的最大限制呢?
只使用"varchar"而不是"varchar(xxx)"是否足够?
(添加)我正在使用MySQL 5.0.67

可能取决于您使用的产品。请为特定的RDBMS产品添加标签。 - Damien_The_Unbeliever
我正在使用MySQL,但是paxdiablo的答案已经足够了。无论如何,我已经添加了MySQL标签。 - firia2000
3个回答

7
这完全取决于所使用的数据库引擎。SQL本身并不规定如何物理存储数据,只有逻辑上如何查看。例如,您的DBMS可能为最大大小在行中分配空间,并额外分配一些字节来存储长度。在这种情况下,varchar(10)varchar(1000)之间会有很大的区别,因为每行将浪费相当多的空间。或者,它可能为varchar数据使用缓冲池,并仅在行中存储长度和缓冲池“起始地址”。在这种情况下,每个单独的行都将为varchar列存储相同大小的信息,而不管其大小,但从该列提取实际数据需要添加步骤(跟随缓冲池链接)。
使用 varchar 的原因正是它被命名为 varchar 的原因。它允许您存储可变大小的数据元素。通常情况下,char(10) 给您十个字符,无论什么情况下都会用空格填充。您可以在提取它时去掉尾随空格,但如果您想要保留带有尾随空格的数据"hello ",这样做效果可能不那么好。
一个不错的DBMS引擎可能会根据 varchar 列的最大大小做出权衡。对于较短的列,它可以直接将其存储在行内,并使用额外的字节来消耗大小。
更长的 varchar 列可以“外包”到单独的缓冲池中,以确保保持行读取的效率(至少在您需要大型 varchar 列之前)。
您需要做的是针对您特定的DBMS重新提问问题,以获得更具针对性的答案。
或者,说实话,你可以设计你的数据库只存储最大尺寸。如果你知道它是10,那么varchar(1000)就是浪费。如果将来需要扩大列,则在那个时候进行扩展,而不是现在(参见YAGNI)。
对于MySQL,您需要查看在线文档的第14章存储引擎
它涵盖了MySQL使用的各种存储引擎(如InnoDB和MyISAM),如果深入研究,您可以看到信息是如何物理存储的。
例如,在MyISAM中,表中存在可变长度数据(包括varchar)通常意味着动态表。这遵循了我上面提到的缓冲池概念的大致类似方案,具有变量大小列浪费更少空间的优点,但行可能会成为碎片。
另一种存储格式(不考虑压缩格式,因为它只用于只读表)是静态格式,其中数据存储在单个物理行中。

您可以在这里找到有关InnoDB物理结构的信息。根据您使用的Antelope或Barracuda文件格式,您最终会得到“所有信息都是物理行”或“缓冲池”情况,类似于MyISAM动态和静态之间的区别。


1
在SQL Server中,限制不影响数据在磁盘上的存储方式。然而,它确实提供了一个免费的约束条件。如果你作为数据库设计者只想存储最多10个字符,那么你就可以防止别人存储一篇小说。
引用块:

对于SQL Server来说,仅使用"varchar"是否足够呢?在大多数情况下,肯定不是你想要的。如果你不指定限制,通常会得到一个varchar(1)(肯定是有史以来最无意义的数据类型)。偶尔,它可能是一个varchar(30)


0
在Oracle中,Varchar的大小取决于其使用情况,只要达到设置的限制点即可。这意味着,确实,包含2个字符的varchar(10)和varchar(100)使用相同的空间(对于char来说不同,它总是使用完整分配的空间)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接