我应该如何将短文本字符串存储到SQL Server数据库中?

时间:2008-09-10 15:58:05

标签: sql sql-server database database-design

varchar(255),varchar(256),nvarchar(255),nvarchar(256),nvarchar(max)等?

256似乎是一个漂亮,圆形,节省空间的数字。但我看过255使用了很多。为什么呢?

varchar和nvarchar有什么区别?

8 个答案:

答案 0 :(得分:17)

在MS SQL Server(7.0及更高版本)中,varchar数据在内部用最多三个值表示:

  • 实际的字符串,从0到超过8000字节(基于页面大小,为行存储的其他列,以及其他一些因素)
  • 两个字节用于表示数据字符串的长度(产生0到8000 +之间的值)
  • 如果列可以为空,则行的空位掩码中的一位(因此最多八个可空列的空状态可以用一个字节表示)

重要的部分是双字节数据长度指示器。如果是一个字节,则只能正确记录长度为0到255的字符串;使用两个字节,您可以将长度为0的字符串记录到超过64000+的字符串(特别是2 ^ 16 -1)。但是,SQL Server页面长度为8k,这是8000+字符限制的来源。 (SQL 2005中有数据溢出的东西,但是如果你的字符串那么长,你应该使用varchar(max)。)

因此,无论您将varchar数据类型列声明为多长时间(15,127,511),您实际存储的每行都是:

  • 2个字节,表示字符串的长度
  • 实际字符串,即该字符串中的字符数

这让我想到了我的观点:许多旧系统只使用1个字节来存储字符串长度,这限制了最大长度为255个字符,这不是那么长。有2个字节,你没有这样的任意限制......所以我建议选择一个对(假设非技术导向的)用户有意义的数字。 ,我喜欢50,100,250,500甚至1000.鉴于8000+字节存储的基数,255或256与200或250一样有效,并且当时间到来时 less 效率高向最终用户解释事情。

这适用于单字节数据(即ansii,SQL _ Latin1 * _ * General_CP1,et al。)。如果您必须使用不同的字母表存储多个代码页或语言的数据,则需要使用nvarchar数据类型(我认为它的工作方式相同,两个字节用于字符数,但每个实际的数据字符需要两个存储字节)。如果nvarchar中的字符串可能超过8000或超过4000,则需要使用[n] varchar(max)数据类型。

如果你想知道为什么用额外的字节占用空间来追踪数据的时间非常重要,请查看http://www.joelonsoftware.com/articles/fog0000000319.html

菲利普

答案 1 :(得分:11)

VARCHAR(255)。它不会使用所有255个字符的存储空间,只使用您需要的存储空间。它是255而不是256因为那么你有255空间加上空终止符(或大小字节)。

“N”代表Unicode。如果您需要非ASCII字符,请使用。

答案 2 :(得分:4)

在定义char / varchar和N个变体时,还有几点需要考虑。

首先,在数据库中存储可变长度字符串会有一些开销。一个好的一般经验法则是对长度小于10个字符串的字符串使用CHAR,因为N / VARCHAR存储字符串和长度以及在N / CHAR与N中存储字符串之间的差异10下的/ VARCHAR不值得字符串长度的开销。

其次,SQL Server中的表存储在8KB页面上,因此数据行的最大大小为8060字节(其他192用于SQL的开销)。这就是为什么SQL允许最大定义的VARCHAR(8000)和NVARCHAR(4000)列。现在,您可以使用VARCHAR(MAX)和unicode版本。但是可能会有额外的开销。

如果我没弄错的话,SQL服务器会尝试将数据存储在与该行的其余部分相同的页面上,但是,如果您尝试将过多的数据放入VARCHAR(Max)列,它会对待它作为二进制文件并将其存储在另一页上。

CHAR和VARCHAR之间的另一个重要区别与页面拆分有关。鉴于SQL Server将数据存储在8KB页面中,您可以在页面上存储任意数量的数据行。如果你 UPDATE 一个VARCHAR列,其值足够大,使得该行不再适合页面,那么服务器将拆分该页面,移出一些记录。如果数据库没有可用页面且数据库设置为自动增长,则服务器将首先扩展数据库以向其分配空白页,然后将空白页分配给表,最后将单个页分成两个。

答案 3 :(得分:3)

如果您支持英语以外的语言,则需要使用nvarchar。

HTML只要包含标准的ASCII字符就可以了。我主要在支持多语言的数据库中使用nvarchar。

答案 4 :(得分:3)

因为1字节 8位所以在1字节中你可以存储多达256个不同的值,这是

0 1 2 3 4 5 ... 255

请注意,第一个数字为0,因此总共 256 数字。

所以如果你使用nvarchar(255)它将使用 1个字节来存储字符串的长度,但如果你翻过1并使用nvarchar(256)那么你就浪费了1更多字节从255开始的额外1项(因为您需要 2个字节来存储数字256 )。

这可能不是SQL服务器的实际实现,但我相信这是限制255项超过256项的典型推理。

nvarchar 用于Unicode,每个字符使用2+个字节和
varchar 适用于仅使用1个字节的普通ASCII文本

答案 5 :(得分:2)

IIRC,255是MySQL必须切换到text数据类型之前的varchar的最大大小,或者在某个时刻(实际上,我认为它现在更高)。所以保持255可能会给你带来一些兼容性。但是,在采取行动之前,你会想要查看它。

varchar vs nvarchar有点像ascii vs unicode。 varchar限制为每个字符一个字节,nvarchar可以使用两个。这就是为什么你可以有一个varchar(8000)但只有一个nvarchar(4000)

答案 6 :(得分:2)

varchar和nvarchar都自动调整内容大小,但是在声明列类型时定义的数字是最大值。

“nvarchar”中的值占用的磁盘/内存空间是“varchar”的两倍,因为unicode是双字节的,但是当您声明列类型时,您声明的是字符数,而不是字节数。

因此,在定义列类型时,应确定该列需要保留的最大字符数,并将其作为varchar(或nvarchar)大小。

一个好的经验法则是估计列需要保留的最大长度,然后再添加大约10%以上的字符支持,以避免将来意外长数据出现问题。

答案 7 :(得分:2)

varchar(255)也是SQL Server 7.0及更早版本中的最大长度。

相关问题