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);
嘗試在上面創建索引會導致此警告:
警告!最大密鑰長度為 900 字節。索引“IX_WideIndex_01”的最大長度為 1110 字節。對於較大值的某些組合,插入/更新操作將失敗。
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
我機器的結果是:
頁:(1:1912) 緩衝: BUF @0x00000000FF5B2E80 bpage = 0x0000000024130000 bhash = 0x0000000000000000 bpageno = (1:1912) bdbid = 2 breferences = 0 bcputicks = 0 bsampleCount = 0 bUse1 = 32497 bstat = 0x10b 部落格 = 0x212121cc bnext = 0x0000000000000000 頁眉: 頁面@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 元數據:AllocUnitId = 2233785421652951040 元數據:PartitionId = 1945555045333008384 元數據:IndexId = 0 元數據: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 數據庫碎片 ID = 1 分配狀態 GAM (1:2) = 已分配 SGAM (1:3) = 未分配 PFS (1:1) = 0x41 已分配 50_PCT_FULL DIFF (1:6) = 未更改 ML (1:7) = 未更改 MIN_LOGGED 插槽 0 偏移量 0x60 長度 556 記錄類型 = PRIMARY_RECORD 記錄屬性 = NULL_BITMAP VARIABLE_COLUMNS 記錄大小 = 556 記憶體轉儲@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 插槽 0 列 1 偏移量 0xf 長度 30 長度(物理) 30 varchar30 = 11111111111111111111111111111 插槽 0 列 2 偏移量 0x2d 長度 255 長度(物理) 255 varchar255 = 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 222222222222222222222222222222222222222222 插槽 0 列 3 偏移量 0x12c 長度 256 長度(物理) 256 varchar256 = 333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 3333333333333333333333333333333333333333333