• Aucun résultat trouvé

Reducing Storage for Null Columns

Dans le document Transact-SQL Recipes (Page 184-187)

SQL Server 2008 introduces sparse columns, a storage optimization improvement that enables zero-byte storage ofNULLvalues. Consequently, this allows a large number of sparse columns to be defined for a table (as of this writing, 30,000 sparse columns are allowed). This improvement is ideal for database designs and applications requiring a high number of infrequently populated columns or for tables having sets of columns related only with a subset of the data stored in the table.

To define a sparse column, you need only add theSPARSEstorage attribute after the column definition within aCREATEorALTER TABLEcommand, as the following query demonstrates:

CREATE TABLE dbo.WebsiteProduct

(WebsiteProductID int NOT NULL PRIMARY KEY IDENTITY(1,1), ProductNM varchar(255) NOT NULL,

PublisherNM varchar(255) SPARSE NULL, ArtistNM varchar(150) SPARSE NULL, ISBNNBR varchar(30) SPARSE NULL, DiscsNBR int SPARSE NULL,

MusicLabelNM varchar(255) SPARSE NULL)

The previous table takes a somewhat denormalized approach to creating columns that apply only to specific product types. For example, thePublisherNMandISBNNBRcolumns apply to a book product, whereasDiscsNBR,ArtistNM, andMusicLabelNMwill more often apply to a music product.

When a product row is stored, the sparse columns that do not apply to it willnot incur a storage cost for eachNULLvalue.

Continuing the demonstration, I’ll insert two new rows into the table (one representing a book

Sparse columns can be queried using a couple of methods. The following is an example of using a standard method of querying:

SELECT ProductNM, PublisherNM,ISBNNBR FROM dbo.WebsiteProduct

WHERE ISBNNBR IS NOT NULL This returns

ProductNM PublisherNM ISBNNBR

SQL Server 2008 Transact-SQL Recipes Apress 1590599802

The second method is to use a column set. A column set allows you to logically group all sparse columns defined for the table. Thisxmldata type calculated column allows forSELECTs and data modification and is defined by designatingCOLUMN_SET FOR ALL_SPARSE_COLUMNSafter the column definition. You can only have one column set for a single table, and you also can’t add one to a table that already has sparse columns defined in it. In this next example, I’ll re-create the previous table with a column set included:

DROP TABLE dbo.WebsiteProduct CREATE TABLE dbo.WebsiteProduct

(WebsiteProductID int NOT NULL PRIMARY KEY IDENTITY(1,1), ProductNM varchar(255) NOT NULL,

INSERT dbo.WebsiteProduct

Now that the column set is defined, I can reference it instead of the individual sparse columns:

SELECT ProductNM, ProductAttributeCS FROM dbo.WebsiteProduct

WHERE ProductNM IS NOT NULL This returns

ProductNM ProductAttributeCS

SQL Server 2008 Transact-SQL Recipes <PublisherNM>Apress</PublisherNM><ISBNNBR>

1590599802</ISBNNBR>

Etiquette <ArtistNM>Casiotone for the Painfully Alone

</ArtistNM><DiscsNBR>1</DiscsNBR>< MusicLabelNM>

Tomlab</ MusicLabelNM>

As you can see from the previous results, each row shows untyped XML data that displays ele-ments for each non-NULLcolumn value.

I can use both anINSERTandUPDATEto modify the values across all sparse columns. The follow-ing query demonstrates addfollow-ing a new row:

INSERT dbo.WebsiteProduct

Any sparse columns not referenced in my DML operation will be set to aNULLvalue. Once a column set is defined for a table, performing aSELECT *query no longer returns each individual sparse column, as the following query demonstrates (only non-sparse columns and then the column set):

SELECT *

FROM dbo.WebsiteProduct

WebsiteProductID ProductNM ProductAttributeCS

1 SQL Server 2008 Transact-SQL Recipes <PublisherNM>Apress

</PublisherNM><ISBNNBR>

3 Roots & Echoes <ArtistNM>The Coral</ArtistNM>

<DiscsNBR>1</DiscsNBR>

<MusicLabelNM>Deltasonic

</MusicLabelNNM>

You still, however, have the option of explicitly naming each sparse column you wish to see, rather than viewing the entire sparse column:

SELECT ProductNM, ArtistNM FROM dbo.WebsiteProduct WHERE ArtistNM IS NOT NULL

This returns

ProductNM ArtistNM

Etiquette Casiotone for the Painfully Alone Roots & Echoes The Coral

How It Works

The sparse column storage attribute allows you to store up to 30,000 infrequently populated columns on a single table. As demonstrated in this recipe, defining a column asSPARSEis as simple as adding the name within the column definition:

CREATE TABLE dbo.WebsiteProduct ...

ArtistNM varchar(150) SPARSE NULL, ...

Most data types are allowed for a sparse column, with the exception of theimage,ntext,text, timestamp,geometry,geography, or user-defined data types.

Caution

Sparse columns also addmorerequired space for non-null values than for regular non-sparse, non-null columns.

This recipe also demonstrated the use of a column set, which was defined within the column definition during theCREATE TABLE(but can also be added usingALTER TABLEif no other column set or sparse columns exist):

CREATE TABLE dbo.WebsiteProduct ...

ProductAttributeCS xml COLUMN_SET FOR ALL_SPARSE_COLUMNS)

The column set becomes particularly useful when a table has thousands of sparse tables, as it allows you to avoid directly referencing each sparse column name in your query. The column set allows querying and DML operations. When performing anINSERTorUPDATE, all unreferenced sparse columns are set toNULLand have zero-byte storage.

Dans le document Transact-SQL Recipes (Page 184-187)