We are designing a new database, and need to know if a nvarchar(n)
column will use any bytes to store a null value?
- If a
nvarchar(n)
column stores a null value, how many bytes are used? - How many bytes are used to store and empty string in a
nvarchar(n)
? (i.e."")
3条答案
按热度按时间shyt4zoc1#
The correct answer for how much space a NULL VARCHAR in SQL Server is, "It Depends". You'll find similar with NVARCHAR.
Note that this does not take into account ROW or PAGE Compression. This is all just for what happens in a "normal" table.
Here's a test table...
Example 1: All VARCHARS = NULL
Here are what the contents of the table look like:
Using DBCC PAGE (too long to go into here and I formatted the output for easy understanding), we get the following dump of what the row looks like.
Note that all hex values are "BIG ENDIAN". Width of Null Bitmap is (ColCnt-1)/8+1 = (12-1)/8+1 = 2
Note that NOTHING about the 10 VARCHAR columns appears in the row. It's because they're all NULL.
So one of the answers for how many bytes a NULL value is is absolutely ZERO.
Example 2: Empty Strings
If we populate the C02 column with an "Empty String", only the bitmap changes to say the column is no longer a NULL but nothing else happens... so one of the answers for how much an "Empty String" takes is Zero. In all cases, an "Empty String" occupies the same space as a NULL (and that can change as we'll soon see). Only the bitmap is changed to say column C02 no longer a NULL.
Here are the DBCC PAGE results from that. Note that ONLY the bitmap changed in valued.
Example 3: First Non-Null Variable Width Column - 5 Bytes
If we populate column C02 with an "A", it will take 5 bytes!
Here are what the content's of the table look like now...
Where do the 5 bytes come from? Two for the "Variable Width column count", two for the "1st Variable Width Column Offset" (it does NOT store the length of the column!), and 1 for the single byte entry of "A". Here are the formatted results from DBCC PAGE that show all that...
Note that the same thing that happened with adding the letter "A" is also what will happen if you add a single space (' ').
Example 4: 2 Bytes per NULL to the left of any populated VARCHAR
Let's add the letter "G" to C08.
Here are what the contents of the table looks like now:
And here are the formatted results from DBCC PAGE... get ready for a shock!
EVERY NULL VARCHAR COLUMN TO THE LEFT OF THE RIGHT-MOST POPULATED COLUMN HAS 2 BYTES ADDED TO THE ROW FOR STARTING POSITIONS THAT DON'T MATTER because the BitMap still says they're NULL.
And notice that nothing has yet shown up for columns C09 through C12. That's because there are no populated variable width columns to the right of of them.
So adding that 1 byte to C08 (the 6th VARCHAR column from the "left") caused an extra 2 bytes to appear for EVERY NULL VARCHAR column to the left of it and 2 extra bytes for itself!
My recommendation to everyone that uses a variable width "Created_By" column at the far "right" of the table is to stop doing that! :D Plan your variable width columns to appear from left to right from least sparse to most sparse. That means that your "Created_By" column should probably be the first (reading the columns left to right) of the variable width columns. :D
And, sure... you could use "SPARSE" columns but at a cost of an additional 4 bytes per entry, it might not be worth it and the MS documentation on that subject is worth a heavy study before using "SPARSE" columns.
So, the correct answers to the original and some of the follow on claims are...
In SQL Server, "It Depends"...
A NULL VARCHAR (or NVARCHAR) can take 0 or 2 bytes depending on whether or not there are any populated variable width columns to the right of it.
And "Empty Strings" work exactly the same way as NULLs concerning space used. It will also change the corresponding bit in the bitmap from "1" to "0".
jm81lzqq2#
Empty string will use 2 bytes. More details at: nchar-and-nvarchar
NULL will use 1 bit in the NULL bitmap.
7gyucuyw3#
It is a physical implementation detail, so it could be different for Oracle an for SQL Server. With SQL Server, NULLs a represented with a single bit in the null bitmap (one bit for each nullable column). An empty string, be it varchar or nvarchar, it's two bytes. Hope someone from Oracle side will complement.