简体   繁体   中英

Space used by nulls in database

If a column is null, does that affect the space used by the column? Is the space used fixed by the column definition? Does this vary from database to database. (I am mainly interestred in SQL Server 2000.)

Clarification: The question relates not to what happens when the column is 'nullable' (This costs another bit as Kritsen & gbn pointed out). The question is, is there any saving when the column is actually null (in some particular row).

...

Cadaeic provided the answer for SQL Server which seems to be no savings in SQL Server until version 2008, whereas according to Quassnoi you can get savings in Oracle if the null columns are at the end. Thanks for the answers, they were all helpful.

Storing a NULL in a column does not specifically cost or save space. For fixed-length data, the entire space is still reserved.

On the other hand, variable-length data requires only the length of the data plus overhead to store the actual length. For example, a VARCHAR(n) will use 2 bytes of data to indicate that actual length, so the storage space required is always n+2.

Additionally, it should be mentioned that if SET ANSI_PADDING ON, a char(n) with a NULL value will behave as a VARCHAR(n).

No matter what, you will not recognize space "savings" from storing NULLs when using SQL Server 2000 or SQL Server 2005. SQL Server 2008 introduces the concept of a sparse column, which can yield savings for columns that are primarily NULL.

SQL Server has a Bit to indicate NULL. There is no such bit used if the column is defined as NOT NULL

VARCHAR uses variable length to store data (and thus has overhead of indicating how long the actual data is), whereas CHAR is fixed width.

So on that basis a CHAR(1) NOT NULL is "shorter" than a VARCHAR(1) NOT NULL as VARCHAR needs a length indicator, and CHAR will always use just one byte.

EDIT: Note that having a BIT field that allows NULL requires two bits to store it! I often see BIT fields where this has not been considered, don't need to store NULL but have not been set to NOT NULL so are wasting a bit unintentionally

In Oracle , it depends on type of the column and its position in the row.

If the NULL columns are last in the row, then they don't take any space at all. Oracle prepends the total row size to each row, everything that doesn't fit is considered NULL .

If there is some non- NULL data after a NULL column, then the NULL is stored as a single byte of 0xFF (that is, NULL type).

Empty VARCHAR2 is equivalent to NULL . If you test the type of a literal NULL returned from SELECT list, it will give you a VARCHAR2(0) .

It's stored in a bitmap, not as a column value.

Example: a nullable varchar column called middle name

  • row 1, "bob" is stored as an offset, 3 bytes for bob, 2 bytes for length of "bob"
  • row 2, NULL row is not stored as a value like "bob", but in the row header

Unless you have a very small table, say a single column char(1), then it's more efficient

Link 1 Link 2

In Oracle 11G, I also had a same situation. You can not free up (check dba_segments) space which occupied by existing rows by setting a column NULL regardless of its position, in the middle or in the end.

UPDATE AUCORE_QA.SYSTEM_AUDIT_LOGS SET KEY=NULL;
SELECT OWNER, TABLESPACE_NAME , SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024 MB
FROM DBA_SEGMENTS 
WHERE OWNER LIKE 'AUCORE_QA' AND SEGMENT_TYPE='TABLE' AND SEGMENT_NAME like '%AUDIT_LOG%'
ORDER BY BYTES DESC;

However, I made the column 'Nullable' and was able to see the save savings for subsequent inserted rows.

ALTER TABLE SYSTEM_AUDIT_LOGS MODIFY KEY NULL;

The number of bytes used by the row is smaller if you are using varchar or nvarchar datatypes. This is why you can create a table (but shouldn't) that has more potential bytes than can actually be stored in a record.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM