微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – varchar(255)或varchar(256)?

在设计表时我应该使用varchar(255)还是varchar(256)?我听说一个字节用于列的长度,或用于存储元数据.

此时此刻是否重要?

我在互联网上看到了一些帖子,但它们适用于Oracle和MySQL.

我们有Microsoft sql Server 2016企业版,它如何应用于这种环境?

现在说,例如,如果我告诉我的客户保持例如,文本描述为255个字符而不是256个,那有什么区别?我读到的内容“最大长度为255个字符,DBMS可以选择使用单个字节来指示字段中的数据长度.如果限制为256或更大,则需要两个字节.”这是真的?

解决方法

适当地调整每一列的大小.不要为每列使用“标准”大小.如果您只需要30个字符,为什么要创建一个可以处理255的列?我很高兴你不提倡为你的字符串列使用varchar(max).

如果您需要索引列,或者您使用列作为主键并且它具有外键引用,那么这是特别谨慎的建议. sql Server使用其查询优化器中每列的大小来了解查询处理的估计内存需求.使用超大列可能会对性能产生不利影响.

超大列的索引可能导致生成错误

CREATE TABLE dbo.WideIndex
(
    col1 varchar(255) NOT NULL,col2 varchar(255) NOT NULL,col3 varchar(600) NOT NULL    
);

CREATE INDEX IX_WideIndex_01
ON dbo.WideIndex (col1,col2,col3);

上面创建索引的尝试导致此警告:

Warning! The maximum key length is 900 bytes. The index ‘IX_WideIndex_01’ has maximum length of 1110 bytes. For some combination of large values,the insert/update operation will fail.

900字节是聚簇索引(以及sql Server 2012及更早版本上的非聚簇索引)的最大密钥大小. 1700字节是较新版本的sql Server上非聚簇索引的最大密钥大小.如果设计具有通用宽度的列,例如(255),则可能会比预期更频繁地遇到此警告.

如果您对存储内部感兴趣,可以使用以下微小测试来更好地了解sql Server如何存储未压缩的行存储数据.

首先,我们将创建一个表,我们可以存储各种大小的列:

IF OBJECT_ID(N'dbo.varchartest',N'U') IS NOT NULL
DROP TABLE dbo.varchartest;
GO

CREATE TABLE dbo.varchartest
(
    varchar30 varchar(30) NOT NULL,varchar255 varchar(255) NOT NULL,varchar256 varchar(256) NOT NULL
);

现在我们将插入一行:

INSERT INTO dbo.varchartest (varchar30,varchar255,varchar256)
VALUES (REPLICATE('1',30),REPLICATE('2',255),REPLICATE('3',256));

查询使用未记录且不受支持函数sys.fn_RowDumpCracker和sys.fn_PhyslocCracker来显示有关该表的一些有趣详细信息:

SELECT rdc.*,plc.*
FROM dbo.varchartest vct
CROSS APPLY  sys.fn_RowDumpCracker(%%rowdump%%) rdc
CROSS APPLY sys.fn_physlocCracker(%%physloc%%) plc

输出看起来类似于:

╔═════════════════════╦════════════╦═════════╦══════════╦══════════════════════════╦══════════╦═════════════╦═════════════╦═════════╦═════════╦═════════╗
║ partition_id        ║ colName    ║ IsInrow ║ Issparse ║ IsRecordPrefixCompressed ║ IsSymbol ║ PrefixBytes ║ InRowLength ║ file_id ║ page_id ║ slot_id ║
╠═════════════════════╬════════════╬═════════╬══════════╬══════════════════════════╬══════════╬═════════════╬═════════════╬═════════╬═════════╬═════════╣
║ 1729382263096344576 ║ varchar30  ║ 1       ║ 0        ║ 0                        ║ 0        ║ 0           ║ 30          ║ 1       ║ 1912    ║ 0       ║
║ 1729382263096344576 ║ varchar255 ║ 1       ║ 0        ║ 0                        ║ 0        ║ 0           ║ 255         ║ 1       ║ 1912    ║ 0       ║
║ 1729382263096344576 ║ varchar256 ║ 1       ║ 0        ║ 0                        ║ 0        ║ 0           ║ 256         ║ 1       ║ 1912    ║ 0       ║
╚═════════════════════╩════════════╩═════════╩══════════╩══════════════════════════╩══════════╩═════════════╩═════════════╩═════════╩═════════╩═════════╝

如您所见,显示每个值的InRowLength,以及每行的物理存储位置 – “file_id”,“page_id”和“slot_id”.

如果我们从上面的查询结果中获取file_id和page_id值并使用它们运行DBCC PAGE,我们可以看到实际的物理页面内容

DBCC TRACEON (3604); --send display to the client
DBCC PAGE (tempdb,1,1912,3); --database,file_id,page_id,3 to show page contents
DBCC TRACEOFF (3604);--reset display back to the error log

我的机器的结果是:

PAGE: (1:1912)


BUFFER:


BUF @0x00000000FF5B2E80

bpage = 0x0000000024130000          bhash = 0x0000000000000000          bpageno = (1:1912)
bdbid = 2                           breferences = 0                     bcputicks = 0
bsampleCount = 0                    bUse1 = 32497                       bstat = 0x10b
blog = 0x212121cc                   bnext = 0x0000000000000000          

PAGE HEADER:


Page @0x0000000024130000

m_pageId = (1:1912)                 m_headerVersion = 1                 m_type = 1
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8000
m_objId (AllocUnitId.idobj) = 98834 m_indexId (AllocUnitId.idind) = 7936
Metadata: AllocUnitId = 2233785421652951040                              
Metadata: PartitionId = 1945555045333008384                              Metadata: IndexId = 0
Metadata: ObjectId = 34099162       m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 4                         m_slotCnt = 1                       m_freeCnt = 7538
m_freeData = 652                    m_reservedCnt = 0                   m_lsn = (35:210971:362)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = 0                      DB Frag ID = 1                      

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = NOT ALLOCATED          PFS (1:1) = 0x41 ALLOCATED  50_PCT_FULL
DIFF (1:6) = NOT CHANGED            ML (1:7) = NOT MIN_LOGGED           

Slot 0 Offset 0x60 Length 556

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 556                   
Memory Dump @0x000000005145A060

0000000000000000:   30000400 03000003 002d002c 012c0231 31313131  0........-.,.,.11111
0000000000000014:   31313131 31313131 31313131 31313131 31313131  11111111111111111111
0000000000000028:   31313131 31323232 32323232 32323232 32323232  11111222222222222222
000000000000003C:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
0000000000000050:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
0000000000000064:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
0000000000000078:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
000000000000008C:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
00000000000000A0:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
00000000000000B4:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
00000000000000C8:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
00000000000000DC:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
00000000000000F0:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
0000000000000104:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
0000000000000118:   32323232 32323232 32323232 32323232 32323232  22222222222222222222
000000000000012C:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
0000000000000140:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
0000000000000154:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
0000000000000168:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
000000000000017C:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
0000000000000190:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
00000000000001A4:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
00000000000001B8:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
00000000000001CC:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
00000000000001E0:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
00000000000001F4:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
0000000000000208:   33333333 33333333 33333333 33333333 33333333  33333333333333333333
000000000000021C:   33333333 33333333 33333333 33333333           3333333333333333

Slot 0 Column 1 Offset 0xf Length 30 Length (physical) 30

varchar30 = 111111111111111111111111111111                               

Slot 0 Column 2 Offset 0x2d Length 255 Length (physical) 255

varchar255 = 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222                               

Slot 0 Column 3 Offset 0x12c Length 256 Length (physical) 256

varchar256 = 3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
3333333333333333333333333333333333333333333                              

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐