Beliebig viele Tabellenspalten beim SQL Server 2008: Sparse Columns

Ich hoffe, jeder Leser dieses Blogs hat beim Datenbank-Design gut aufgepasst, dann wissen sie oder er ja, dass man keine unendlich breiten Tabellen erzeugen soll. Aber gut, mal unter uns und nicht weitersagen: manchmal geht es eben nicht anders, aber dann auf eigenes Risiko! Mitunter wird der SQL Server nur als so eine Art »Excel auf dem Server« missbraucht, und seit Excel 2007 jetzt auch 16.384 Spalten speichern kann (statt vorher nur 256) ist natürlich die Frage: kann der SQL Server das auch? Nun, bis zur Version 2008 kann er das nicht, da beherrscht er »nur« 1024 Spalten. Jetzt kann er diese Grenze sprengen, aber nur, wenn die zusätzlichen Spalten nur spärlich (»sparse«) gefüllt sind!


Aber zurück zum Design! Es ist wirklich eine Lücke im relationalen Modell: Ich entwerfe für Backwaren eine Produkttabelle, in der will ich etwa für Berliner (oder wenn man mich als Berliner fragt: Pfannkuchen) die Füllung abspeichern; Pflaumenmus, Eierlikör, etc. Für Croissants passt das dann auch noch, aber bei Brötchen und Brot ist diese Spalte natürlich immer leer, also NULL! Andersherum ist es mit dem Belag: bei Brötchen mag da noch manchmal Sesam, Mohn oder Kürbiskern drin stehen, aber die Mehrzahl der Produkte ist natürlich überhaupt nicht belegt, also bleibt die Belag-Spalte NULL.

Gängige Lösungen für dieses Design-Problem wären etwa eine Zusatz-Tabelle mit den Spalten Produktnummer – Attribut (Inhalt z.B. »Belag«) – Wert (Inhalt z.B. »Sonnenblumenkerne«). Diese Tabelle ist aber relational etwas schwer auszuwerten, außer mit dem PIVOT-Operator. Man könnte auch eine Spalte mit dem unten beschriebenen XML-Datentyp anhängen, aber leider ist ein großes XML-Schema nicht besonders effektiv, wenn es fast immer leer ist. Im SQL Server 2008 kann man nun solche spärlich gefüllten Spalten von Anfang an als SPARSE bezeichnen, dann nehmen sie, wenn sie leer bleiben, keinen Platz weg. Und so kann man dann auch viele tausend zusätzliche Spalten anhängen!

CREATE TABLE dbo.Produkte(
   ProduktID                              int                          PRIMARY KEY IDENTITY
, Produktnummer                        char(12)                  NOT NULL
, Produktbezeichnung              nvarchar(255)          NOT NULL
, Belag                                    nvarchar(30)            SPARSE NULL
, Füllung                                  nvarchar(30)            SPARSE NULL
, Fettanteil                            numeric(3,1)            SPARSE NULL
/* hier noch viele hundert SPARSE-Spalten */)

Schreibe einen Kommentar