sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Servers maximala radstorlek kontra Varchar(Max) storlek

I Microsoft SQL Server lagras data (som inkluderar index) på en eller flera 8k (8192 byte) "sidor". Det finns olika typer av sidor som kan användas för att hantera olika situationer (t.ex. Data, LOB, Index, AllocationMap, etc) . Varje sida har en rubrik som är metadata om den sidan och vad den innehåller.

De flesta data lagras i själva raden, och en eller flera av dessa rader lagras i sin tur på en sida för "in-row data". På grund av det utrymme som radhuvudet tar, är den största en rad kan vara (för "in-rad"-data) 8060 byte.

Men inte all data lagras i raden. För vissa datatyper kan data faktiskt lagras på en "LOB-data"-sida medan en pekare finns kvar i "in-row"-data:

  • Äldre/föråldrade LOB-typer som ingen längre borde använda (TEXT , NTEXT och IMAGE ), som standard, lagrar alltid deras data på LOB-sidor och använd alltid en 16-byte-pekare till den LOB-sidan.

  • De nyare LOB-typerna (VARCHAR(MAX) , NVARCHAR(MAX) , VARBINARY(MAX) och XML ), som standard, försöker passa data direkt i raden om det passar. Annars kommer den att lagra data på LOB-sidor och använda en pekare på 24 - 72 byte (beroende på storleken på LOB-data).

Så här kan du lagra upp till 78 GB + 4 byte (kan inte glömma INT Primär nyckel;-) i en enda rad:den maximala radstorleken kommer att vara mellan 940 byte ((39 * 24) + 4) och 2812 byte ((39 * 72) + 4). Men återigen, det är bara det maximala intervallet; om data i var och en av de 39 VARCHAR(MAX) fält är bara 10 byte, då kommer all data att lagras i rad och radstorleken blir 394 byte ((39 * 10) + 4).

Med tanke på att du har så många fält med variabel längd (oavsett om de är MAX eller inte), är det enda sättet att uppskatta storleken på framtida rader att ha en bra uppfattning om vilken data du kommer att lagra i den här tabellen. Även om en tabell med alla, eller till och med de flesta, MAX datatyper antyder att ingen riktigt har någon aning om vad som kommer att lagras i den här tabellen.

Längs dessa linjer bör det påpekas att detta är en fruktansvärt modellerad tabell/hemsk användning av MAX datatypfält, och bör omfaktoreras.

För mer information om hur datasidor är strukturerade, se mitt svar på följande DBA.StackExchange-fråga:

SUMMAN av DATALENGTHs matchar inte tabellstorleken från sys.allocation_units



  1. PATINDEX()-ersättning i MYSQL

  2. Hur man uppdaterar datagrid i WPF

  3. Hur läser man en CLOB-kolumn i Oracle med OleDb?

  4. Fullständig MariaDB-kryptering i vila och under transport för maximalt dataskydd - del två