Home > Artikel > Ausgabe 11/2014 > Adressen konsolidieren

Adressen konsolidieren

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Der geradezu prototypische Anwendungsfall für eine Datenbank ist sicherlich die Speicherung von Kontakten. Ob Nordwind-, unsere Südwinddatenbank oder die hier oft verwendete Stammdatentabelle: im Zentrum stehen Adressdatensätze. Auf den ersten Blick gibt es dabei keinen Erklärungsnotstand, denn so ein Kontaktdatensatz scheint eine einfache Angelegenheit zu sein. Bei genauerem Hinsehen tauchen aber doch Fragen auf, die dieser Beitrag thematisiert.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1411_Adressen.mdb.

Für die Beispieldatenbank zu diesem Beitrag wurde die Stammdatentabelle aufgebohrt und mit zusätzlichen Feldern und Daten versehen. Neben Namen und Anschrift kommen Telefonnummern und E-Mail-Adressen hinzu, so dass sie sich wie in Bild 1 gestaltet. In diese Tabelle könnten Sie bereits etwa Ihre Outlook-Kontakte importieren.

Aufbau der Adressentabelle

Bild 1: Aufbau der Adressentabelle

Man findet Adresstabellen in dieser Form recht häufig in Datenbanken. Dabei ist der Aufbau keineswegs optimal, obwohl es sich bereits um eine normalisiertere Form handelt, denn Anreden, Orte und Länder sind bereits mit Lookup-Tabellen verknüpft (siehe Bild 2).

Lookup-Tabellen der Adressentabelle

Bild 2: Lookup-Tabellen der Adressentabelle

Diese Felder verhindern auch einen einfachen Import aus anderen Datenquellen. Damit etwa im Feld IDOrt der Bezug zur Tabelle tblOrte gespeichert werden kann, muss diese erst mit Orten gefüllt worden sein. Natürlich könnte man diese Felder auch als Text anlegen, was in Hinsicht auf den Speicherbedarf jedoch suboptimal ist. Beim Import aus anderen Datenquellen kommt es in der Regel jedoch zu so einer Tabelle, die in der Beispieldatenbank als tblAdressenImport zu finden ist (Bild 3).

Aufbau der Importtabelle

Bild 3: Aufbau der Importtabelle

Normalisieren des Imports

Im Folgenden wird Schritt für Schritt aufgezeigt, wie die Importtabelle in eine normalisierte Form überführt wird.

Legen Sie also zunächst die Lookup-Tabellen rechts in Bild 2 an, wobei für das Feld ID ein Autowert als Primärschlüssel zu verwenden ist und für das andere Feld – Anrede, Ort, Land – das Textformat. Jetzt kann die Tabelle tblOrte mit Daten gefüllt werden, wofür eine Anfügeabfrage zum Einsatz kommt:

INSERT INTO tblOrte (Ort)

SELECT DISTINCT Ort

FROM tblAdressenImport;

Nur die Orte der Ausgangstabelle werden hier in die Orte-Tabelle gespeichert, wobei Doppelungen infolge der DISTINCT-Klausel ausbleiben. Analog die Anfügeabfragen für die Länder und Anreden:

INSERT INTO tblLaender (Land)

SELECT DISTINCT Land

FROM tblAdressenImport;

INSERT INTO tblAnreden (Anrede)

SELECT DISTINCT Anrede

FROM tblAdressenImport;

Sehen Sie sich die Inhalte der Tabellen an. Hier wird schon deutlich, worin der Vorteil der Normalisierung liegt. Waren in der Importtabelle noch 11.444 Felder mit Länderbezeichnungen gefüllt, sind es in der Ländertabelle nur noch 16 Einträge, auf die per ID verwiesen werden muss. Und da der Long-Wert von IDLand weniger Bytes benötigt, als ein Bezeichnungs-String, wird die Speicherersparnis offensichtlich.

Diese Rechnung zeigt allerdings, dass nicht in jedem Fall eine solche Normalisierung nützlich ist. Nehmen Sie etwa das Feld Nation der Importtabelle. Auch hier könnte man eine Lookup-Tabelle tblNationen anlegen, die dann lediglich die zwei Einträge "D" und "CH" für Deutschland und Schweiz enthielte.

Ein Verweis auf die ID dieser Einträge kostet 4 Bytes und ist damit größer, als die ein beziehungsweise zwei Bytes der Strings. Eine Lookup-Tabelle wäre hier nutzlos und machte Abfragen auf die Tabellen nur komplizierter – es sei denn, Sie wollten die Lookup-Tabelle für die Auswahl in einem Kombinationsfeld verwenden.

Umgekehrt macht die Auslagerung in eine Lookup-Tabelle nur dann Sinn, wenn sich die Datenmenge dadurch reduzieren lässt. Würde man Postleitzahlen auslagern, wäre der Nutzen sehr gering, weil es eben so viele unterschiedliche Postleitzahlen gibt, dass man sie auch gleich in der Originaltabelle belassen kann.

Wenden wir uns dem Überführen der Daten aus der Importtabelle in die tblAdressen zu. Auch dafür eignet sich eine Anfügeabfrage, die verkürzt so daher kommt:

INSERT INTO tblAdressen ( Nachname, Vorname, Strasse, ...)

SELECT Nachname, Vorname, Strasse, ...

FROM tblAdressenImport;

Transferiert werden alle Daten mit Ausnahme der Felder für Anrede, Ort und Land, denn diese existieren in der Zieltabelle nicht als Textfelder. Sie enthält ja stattdessen Verweise auf die IDs der entsprechenden Lookup-Tabellen.

Wie kommen diese Lookup-Verweise nun aber in die Tabelle tblAdressen? Das ist nicht ganz so einfach. Dazu braucht es drei Ausgangstabellen, die miteinander verknüpft eine Aktualisierungsabfrage bilden, wie in Bild 4.

Aktualisierungsabfrage zum Füllen der Ort-Verweise

Bild 4: Aktualisierungsabfrage zum Füllen der Ort-Verweise

Die Importtabelle vergleicht über eine Beziehung das Ort-Feld mit den Inhalten der tblOrte. Die so ermittelte ID des Ortes wird dann benutzt, um das Feld IDOrt der Tabelle tblAdressen zu aktualisieren.

Auf ähnliche Weise verfahren Sie mit dem Aktualisieren der Felder für Anrede und Land.

Sie habe damit die neue Tabelle tblAdressen vollständig befüllt und können die Ausgangstabelle wieder löschen. Um ihre Daten anzuzeigen, bedienen Sie sich einer Auswahlabfrage, die den gleichen Aufbau hat, wie die Beziehungen in Bild 2.

Flexibilisieren des Adressenaufbaus

Eingangs war davon die Rede, dass der Aufbau der tblAdressen samt Lookup-Tabellen nicht wirklich optimal ist. So findet man für Telefonnummern und E-Mail-Adressen jeweils zwei Felder in ihr, was im einen Fall zu viel, im anderen Fall zu wenig sein kann. Ist zu einem Kontakt keine Telefonnummer bekannt – ein Umstand, der gerade in den Outlook-Kontakten nicht selten ist –, so bleiben die beiden Felder leer. Ebenso kann ein Kontakt aber auch mehr als zwei Telefonnummern aufweisen, etwa Privat-, Geschäfts- und Mobilnummer. Dann ist guter Rat teuer. Dasselbe gilt für E-Mail-Adressen.

Natürlich könnte man nun etwa die Zahl der Telefonnummernfelder in der Tabelle heraufsetzen, was jedoch zu weitgehend leeren Zellen führte wird und die Speicherverschwendung vorantriebe.

Für diesen Fall ist es daher günstiger, die Telefonnummern und E-Mail-Adressen in gesonderte Tabellen auszulagern und über die ID eines Adressdatensatzes zu verknüpfen.

Dabei entsteht allerdings keine Lookup-Tabelle, sondern eine n:m-Detailtabelle, die über eine Verknüpfungstabelle an die Adresse gekoppelt wird.

Legen Sie eine Tabelle tblTelefonnummern an, die den gleichen Aufbau hat, wie die zuvor beschriebenen Lookup-Tabellen und befüllen Sie sie auch analog.

Die Anfügeabfrage ist aber zweimal durchzuführen: je einmal für das Feld Telefon1 und das Feld Telefon2:

INSERT INTO tblTelefonnummern (Telefon)

SELECT Telefon1 FROM tblAdressen;

INSERT INTO tblTelefonnummern (Telefon)

SELECT Telefon2 FROM tblAdressen;

Die Daten aus den beiden Telefonfeldern werden hier also in einem Feld Telefon zusammengefasst und somit konsolidiert. Im Ergebnis kann diese Tabelle dann mehr Datensätze enthalten, als die Adressentabelle selbst. Verfahren Sie mit den E-Mail-Adressen entsprechend.

Da nun zu jedem Adressdatensatz mehrere Telefonnummern existieren können, ist das Einfügen einer n:m-Zwischentabelle unumgänglich. In Bild 5 lautet diese tblAdressenTelefon.

Das komplette Beziehungsmodell der Adressdatenbank, normalisiert und komsolidiert

Bild 5: Das komplette Beziehungsmodell der Adressdatenbank, normalisiert und komsolidiert

Sie verknüpft eine oder mehrere Telefonnummern aus tblTelefonnummern mit einem Datensatz aus tblAdressen, wobei jeweils nur die verweisenden IDs der Datensätze gespeichert werden.

Auf den Autowert-Primärschlüssel ID der Verknüpfungstabelle könnte man auch verzichten, es ist aber grundsätzlich ratsam, jedem Datensatz einer Tabelle einen eindeutigen Schlüssel zu spendieren. Spätestens bei Migration der Datenbank auf einen SQL-Server wird so ein Schlüssel notwendig.

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!