Sql-und-Xml - Home

Sql-Tutorial

Erste Normalform: Attribute sollen atomar sein, wiederholende Gruppen sind auszulagern

Die erste Normalform (NF1) ist durch zwei Forderungen charakterisiert:
  1. Attribute müssen atomar sein. Das meint: Einem Attribut dürfen nicht mehrere Werte aus dem definierten Gültigkeitsbereich zugeordnet sein.
  2. Wiederholende Gruppen, also mehrwertige Relationen, sind in eine eigene Tabelle auszulagern und zu verknüpfen.
Beispiele:
  • Trennen von Nachname, Vorname, eventuell Namenszusatz (... van der ...) in ein eigenes Feld, also Vergrößerung der Zahl der Spalten. Wird beim Namenszusatz auf eine eigene Spalte verzichtet, so kann es später zu inkonsistenten Einträgen kommen. Einmal wird der Vorname um den Namenszusatz ergänzt {Schmidt, Sybille van der}, andere Varianten sind {van der Schmidt, Sybille} oder {Schmidt van der, Sybille}. In sämtlichen Fällen können bei Suchabfragen nach 'Schmidt' oder 'Sybille' Zeilen ignoriert werden, so daß der Datensatz nicht gefunden und ein zweites Mal eingetragen wird.
  • Schauspieler zu einem Film, an einem Projekt beteiligte Mitarbeiter, Etagen in einem Haus, Zimmer einer Etage: Eine handschriftliche Aufzeichnung würde die beteiligten Personen / Etagen / Zimmer der Reihe nach aufführen, sie damit alle in eine Zelle schreiben. Die Lösung, mehrere Spalten für mehrere Teilnehmer usw. anzufügen, ist ungeeignet, da entweder zu viele Zellen leer bleiben oder zu wenige Spalten vorhanden sind. Also wird eine Detailtabelle (Mitwirkende, Projektbeteiligte, Etagen, Zimmer) erstellt, die in einer n:1 - Beziehung zur Grundtabelle (Filme, Projekte, Häuser, Etagen) steht. Die Gruppe dieser gleichartig strukturierten Detail-Informationen wird in diese Detail-Tabelle ausgelagert.

Zuordnung von Werttypen / Datentypen zu Attributen

Um eine zusätzliche Konsistenz der atomaren Einträge zu erzwingen, werden den Attributen (= Spalten) Datentypen zugeordnet. Damit kann das DBMS bei allen Einfügungs- und Aktualisierungsoperationen überprüfen, ob die Eingabedaten dem geforderten Datentyp entsprechen und die Ausführung der Operation gegebenenfalls untersagen.

Standard-Datentypen

  • binary(Länge): Binärdaten fester Länge. Dieser kann mit analogen Datentypen verwendet werden, um Bilder, Videos, Word- oder PDF-Dokumente abzuspeichern.
  • Boolean bzw. bit: Boolsche Wahr / Falsch bzw. Ja / Nein - Werte. Dieser Werttyp eignet sich zur Darstellung von zwei einander ausschließenden Werten und kann als Checkbox zum Anhaken oder Pulldown-Liste (Ja/Nein) dargestellt werden.
  • char(Länge): Zeichenfolge (1-Byte-Zeichen) mit fester Länge (char(5) = fünf Zeichen). Dies erlaubt nur Zeichen aus dem Ascii bzw. den ISO-Codierungen, so daß maximal 256 verschiedene Zeichen gespeichert werden können.
  • datetime: Datums- und Zeitfelder. Beide Informationen werden gemeinsam gespeichert. Wurde nur das Datum angegeben, so wird als Zeit '00:00:00' genommen, bei einer reinen Zeitangabe wird meist als Bezugsdatum der 01.01.1900 verwendet. Jedes DBMS kennt Funktionen, mit welchen aus einem datetime-Feld nur der Datums- oder nur der Zeitanteil herausgezogen werden kann. Ebenso gibt es in jedem DBMS Funktionen für Datumsoperationen, mit welchen Datumsangaben addiert oder Datums-Differenzen ausgegeben werden können.
  • decimal[(p[, s])], Synonym numeric: Dezimal-Datentyp für numerische Datentypen mit einer fest vorgegebenen Genauigkeit und fest definierten Anzahl von Dezimalstellen. p legt die Zahl aller Stellen vor und nach dem Dezimalpunkt fest und kann üblicherweise zwischen 1 und knapp 40 liegen. s fixiert die Nachkommastellen und liegt zwischen 0 und p. s = 0 bedeutet, daß der Datentyp nur Ganzzahlen akzeptiert. decimal(15,5) deklariert einen Datentyp mit fünf Nachkomma- und maximal 10 Vorkomma-Stellen.
  • float bzw. real: Ungefähre Zahlendatentypen, die für numerische Gleitkomma-Daten genutzt werden können. Intern werden diese in der wissenschaftlichen Darstellung 5.79E2 dargestellt, also als 5.79 * 10^2 = 579. Diese Datentypen sind ungefähr, da nicht alle Werte im zulässigen Zahlbereich genau dargestellt werden. float ist in der Regel doppelt so genau wie real und benötigt 8 statt 4 Byte.
  • image: Binary-Daten variabler Länge, meist mit einer maximalen Länge in der Größenordnung 2^31
  • int bzw. Integer: Ganzzahl mit negativen oder positiven Werten. Im Regelfall mit 4 Byte implementiert, damit kann ein Wertebereich von +/- 2^31, also -2.147.483.648 bis +2.147.483.648 abgedeckt werden. Ist eine Spalte als Primärschlüssel definiert, so hat sie diesen Datentyp, eine Spalte mit einer Fremdschlüsseleinschränkung muß dementsprechend ebenfalls vom Typ Integer sein.
  • money: Währungsdatentyp. Währungen werden mit hinreichend vielen Nachkomma-Stellen gespeichert
  • nchar(Länge): Unicode-Zeichenfolge mit fester Länge, benötigt zwei Byte pro Zeichen.
  • ntext: Unicode-Zeichenfolge variabler Länge, in der Regel bis zu 2^30 Zeichen.
  • nvarchar(Länge): Unicode-Zeichenfolge variabler Länge, beim Ms-Sqlserver beschränkt auf 4000 Zeichen.
  • text: Nicht-Unicode-Zeichenfolge variabler Länge, in der Regel bis zu 2^31 Zeichen.
  • varbinary(Länge): Binary-Daten variabler Länge zwischen 0 und dem durch 'Länge' festgelegten Wert. Beim Ms-SqlServer existiert eine zusätzliche Obergrenze von 8000 Zeichen.
  • varchar(Länge): Zeichenfolge (1-Byte-Zeichen) mit variabler Länge, maximal der durch 'Länge' festgelegte Wert.

Spezielle Datentypen

  • timestamp: Ein datenbankweit eindeutiger Ausdruck, der bei jeder Änderung der Daten automatisch hochgezählt wird. Wird einer Tabelle eine Spalte vom Typ timestamp hinzugefügt, so kann diese zur Versionskennung der Zeile verwendet werden. Beim Lesen der Daten wird dieser Wert mitgesandt, beim Schreiben geht der timestamp-Wert zusammen mit dem Primärschlüssel in die Where-Bedingung ein. Hat ein anderer Nutzer in der Zwischenzeit diese Zeile geändert, so scheitert die Aktualisierung.
  • uniqueidentifier: Ein global eindeutiger Bezeichner (GUID, Global unique Identifier). Auto-Werte sind nur innerhalb der Tabelle eindeutig. Werden global eindeutige Werte benötigt, so können GUID's genutzt und in uniqueidentifier-Spalten abgelegt werden. Die Verwendung als Primärschlüssel ist jedoch nicht zu empfehlen, da die Indizes, welche den Primärschlüssel nutzen, dann sehr groß werden.
  • int Identity(1, 1), eine Identitätsspalte: Dies definiert eine Spalte vom Typ Integer, die zusätzlich einen Identitätswert erhält, eine Zahl, die vom DBMS automatisch hochgezählt und deren Eindeutigkeit damit garantiert ist. Solche Spalten sind gute Kandidaten für Primärschlüssel. Die erste Zahl legt den Startwert fest, die zweite Zahl deklariert die Schrittweite. Werden Datensätze eingefügt, so wird üblicherweise für eine Identitätsspalte kein Wert angegeben. MsAccess läßt es zu, daß ein Wert angegeben wird, sofern dieser bislang noch nicht verwendet wurde. Beim Ms-Sqlserver muß zuvor die Spalte mit SET IDENTITY_INSERT <Tabellenname> ON für solche Aktionen zugelassen und anschließend mit 'OFF' wieder deaktiviert werden.

    Veränderte Schrittweiten lassen sich bsp. dann verwenden, falls später Zeilen eingefügt werden, bei welchen bereits an der Id deutlich werden soll, daß es sich um besondere Objekte handelt. So legt eine Anweisung 'int Identity(2, 2)' fest, daß nur die Zahlen 2, 4, 6, ... für das automatische Einfügen vom Benutzer verwendet werden können. Vom System eingefügte Zeilen mögen ungerade Zahlen erhalten. Ein späterer Test modulo 2 unterscheidet beide Typen.

Hinweise zum Gebrauch der Datentypen

  • Verwenden Sie als Primärschlüssel den Integer-Datentyp, meist kombiniert mit einer automatischen Erhöhung. Vermeiden Sie Zeichendaten als Primärschlüssel. Zum einen werden Integer mit einer festen Größe abgespeichert. Zum anderen genügt ein Bit-für-Bit-Vergleich, da keine Groß-Klein-Schreibung berücksichtigt werden muß. Damit ist der Vergleich zwischen zwei Integer-Zellen auf jeden Fall schneller als zwischen zwei Text-Zellen. Schließlich wird der Primärschlüssel bei anderen Indizes verwendet. Lange Textfelder blähen diese Indizes unnötig auf. Der Aufwand für eine zusätzliche Spalte dürfte immere gering im Vergleich zu solchen Seiteneffekten sein. Die Eindeutigkeit einer Spalte (etwa Telefonnummern) läßt sich auch mit einer UNIQUE-Einschränkung in Kombination mit NOT NULL erzwingen.
  • Für Telefonnummern sind in der Regel char- oder varchar-Datentypen notwendig. Würden stattdessen Integer-Werte genutzt, so würden führende Nullen entfernt werden. Telefonnummern oder isoliert abgelegte Hausnummern sollten ohne Leerzeichen abgespeichert und die bei der Suche vom Nutzer eingegebenen Leerzeichen entfernt werden. Ansonsten könnten Werte nicht gefunden werden.
  • Bei der Verwendung von Unicode-Datentypen (nchar, nvarchar, ntext) anstelle der gewöhnlichen Text-Datentypen (char, varchar, text) ist zu beachten, daß diese zwar korrekt gespeichert werden, die Anzeige jedoch fehlerhaft sein kann. Denn wird zur Anzeige nicht ein passender Unicode-Font genutzt, so werden Unicode-Zeichen oberhalb Ascii nur als leere Quadrate dargestellt. Hier ist bsp. im Ms-Access-Formular als Font 'MS Arial Unicode' zu verwenden. Im deutschen bzw. europäischen Sprachraum bzw. für eine nur in dieser Region verwendeten Datenbank kann es genügen, nur Ascii-Texte zuzulassen. Für internationale Namen, Produktbeschreibungen in verschiedenen Sprachen oder wissenschaftliche Texte, bei welchen Sonderzeichen aus verschiedenen ISO-Codepages benötigt werden, sollten sofort Unicode-Datentypen verwendet werden.
  • Ein Nachteil von Unicode beim Einsatz auf dem Ms-SqlServer ist zu beachten: Dort beträgt die maximale Datengröße pro Zeile etwa 8000 Byte. Man kann folglich Ascii-Texte bis zu 8000 oder Unicode-Text bis 4000 Zeichen ablegen. Sollte sich eine Tabelle dieser Grenze annähern, so kann man nach dem Muster der 1:1 - Beziehung Texte mit nvarchar-Datentyp auch in eine Nebentabelle auslagern.
  • Die Verwendung der binary large object (BLOB) Datentypen text-, ntext- und image-Daten bedeutet, daß in der Zeile nur ein Zeiger gespeichert und der eigentliche Inhalt ausgelagert wird. Damit sind zwar einerseits hinreichend große Daten verwaltbar, jedoch können diese Daten nicht in einer üblichen Where-Klausel genutzt werden. Auf text/ntext läßt sich allerdings der LIKE-Operator anwenden. Beim Ms-SqlServer ist es möglich, diese BLOB-Datentypen in einer eigenen Dateigruppe abzulegen, so daß die Dateigruppe für die Hauptdaten hiervon unabhängig ist.
  • Allgemein wird davon abgeraten, Bilder, Videos und ähnliches in Datenbank-Spalten abzulegen. Denn die eigentlichen Stärken eines DBMS wie Vergleiche, Filterung und Sortierung können bei BLOB-Daten ohnehin kaum verwendet werden. Diese blähen jedoch die Datenbank unnötig auf und erschweren damit Sicherungen. Da BLOB-Daten normalerweise nur sehr selten geändert werden, ist es sinnvoller, diese im Dateisystem abzulegen und lediglich relative Pfadangaben sowie das Datum der letzten Aktualisierung in der Datenbank zu speichern.

© 2003-2016 Jürgen Auer, Berlin.