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

Zac*_*son 13 sql database sql-server database-design

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

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

varchar和nvarchar有什么区别?

Phi*_*ley 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一样高,而且当需要向最终用户解释时,效率较低.

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

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

菲利普


Jas*_*hen 11

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

"N"代表Unicode.如果您需要非ASCII字符,请使用.


Jos*_*sef 5

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

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

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

如果我没记错的话,SQL Server 会尝试将数据与行的其余部分存储在同一页上,但是,如果您尝试将过多数据放入 VARCHAR(Max) 列中,它会将其视为二进制并将其存储在另一个页面上。

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