为什么将varchar(n)中的n指定为具体数字?

时间:2010-10-16 14:37:35

标签: sql-server database database-design memory-management storage

我对此进行了红读,无法清楚地理解......

(为了缩短这个问题)

DECLARE @temp VARCHAR(4001); 
--update: 4001 is for example only to avoid varchar(MAX) discussions
-- I am aware about 8000 
SET @temp = 'a';  

SQL Server为@temp保留了4001个字节(其余4000个来自@temp的4001个字节)在@temp被释放之前不能用于任何其他目的吗?

<击>

如果没有那么(更新:抱歉,这是修辞问题,我相信这并没有改变我的问题意识):

  • 为什么SQL Server需要知道varchar值的最大大小?
  • 为什么不能将大于4001字节的字符串(重新)分配给@temp?
    更新:如果没有为@temp
  • 预先分配或保留4001个字节
  • SQL Server如何使用此大小?

关于包含一个varchar(4001)列的表的相同问题。
我应该如何在varchar(4001)中命名4001以避免与varchar(max)的歧义? 即避免参与“最大”字。

例如,

[1]暗示它是列大小:

  

varchar数据类型是可变长度数据类型。值小于列的大小 ... [1]

本可以理解这个大小是保留的,该列具有固定大小(在所有行上),与存储在那里的较短值无关。 正确吗?如果不正确那么 使用[1]中的术语,varchar(4001)列的大小是多少?

更新
我希望(通过指定4001)避免将此主题从行内值存储(例如,SQL Server varchar(max),文本等类型)转移到此处未特别提及的其他主题。

问题不是关于如何在varchar(n)中使用n,而是如何使用它(由SQL Server)。

我欢迎其他DBMS专家,因为它应该是DBМS不可知的问题,尽管在SQL Server 2000(或2005+没有varchar(MAX))的上下文中指定了具体的数字。

UPDATE2
根据[2],在SQL Server中存储表数据的长度前缀的大小总是2。 为什么不使用varchar()让SQL Server以实际大小工作呢? 除了我(故意)基于变量的问题 此外,put数字实际上会截断存储/数据:

DECLARE @temp VARCHAR(2); 
SET @temp = 'aaaaaa';
select @temp
 -- result is: aa

[1]
msdn“使用char和varchar数据”
http://msdn.microsoft.com/en-us/library/ms175055.aspx
[2]
估计堆的大小
http://msdn.microsoft.com/en-us/library/ms189124.aspx

2 个答案:

答案 0 :(得分:2)

  

如何使用varchar(n)中的n?

它依赖于实现。

SQLite中,n完全被忽略。

PostgreSQL中,varchar(n)基本上等同于TEXT,约束为CHECK (LENGTH(TheColumn) <= n)。指定最大大小没有性能优势。

MySQL中,n确定长度前缀的大小,因此VARCHAR(255)使用1个字节来存储长度,VARCHAR(65535)使用2个字节。

对于MS SQL Server,请参阅问题[Why not use] varchar(max) everywhere?

答案 1 :(得分:1)

为什么要分配tinyint或整数?如果一个给定列的数据有15个离散值,那么很明显就是tinyint。

同样适用于varchar:它告诉SQL Server此列中预期的值/长度。 SQL Server会在数据被截断时抛出错误。

您可以为NULL / NOT NULL或外键或CHECK约束等应用相同的参数:它们都是为了保持数据正确。请参阅“Declarative referential integrity”。

例如,我想要禁止有人试图在我的100字节名称纯文本列中存储500k的XMl,因为它们可以。如果某人确实成功了,那么预计最多100个字节的其他客户会怎么想?

这对于存储效率也很重要。可以为c#对象声明“String”,你可以实例化,使用,丢弃并保留在内存中(大部分),因为它的寿命很短。坚持十亿行“字符串”是不必要的开销。

有人可能会进一步询问为什么要使用varchar? Why not use nvarchar everywhere?同样,我确实有一个存储货币代码的表,接近十亿行。 nchar(3)vs char(3)花费额外的3GB存储空间(+索引+行长度变化)。

摘要:这是对数据的限制。