Lösung Normalisierung Kaufmann
Transcription
Lösung Normalisierung Kaufmann
SQL 2013-05-28 Es soll eine Datenbank für einen Laden erstellt werden. Dabei werden Kunden erfasst, Artikel gespeichert und ein Kunde soll Bestellungen durchführen können. Man kann dabei auf zwei Varianten vorgehen. Variante 1 wird angewendet, wenn man sich nicht sicher ist. 1. Variante: Testdaten in eine Testtabelle schreiben +-----+------+--------------+--------+---------+------+------+-------+ | KdNr| Name | Adresse | BestNr | Datum | Ware | Preis| Menge | |--------------------------------------------------------------------| 100 | Meier | Daheim 4a | 1000 | 1.1.2013 | 1206 | 1 | 5 | | 1000 | 1.1.2013 | 1307 | 2 | 3 | | 100 | Meier | Daheim 4a |--------------------------------------------------------------------| 100 | Meier | Daheim 4a | 1001 | 7.1.2013 | 4711 | 4 | 13 | | 1001 | 7.1.2013 | 1206 | 1 | 5 | | 100 | Meier | Daheim 4a |--------------------------------------------------------------------| 101 | Huber | Nirvana 7b | 1002 | 7.1.2013 | 1206 | 1 | 5 | +--------------------------------------------------------------------+ Hier wird ersichtlich, dass einige Daten (farbig markiert) redundant existieren (Daten des Kunden Meier scheinen öfter auf, dass die Bestellung 1000 am 1.1.2013 aufgenommen wurde, sowie dass der Artikel 1206 1 Euro kostet). Warum ist die redundante Speicherung problematisch? +-----+------+--------------+--------+---------+-------+------+-------+ | KdNr| Name | Adresse | BestNr | Datum | Ware | Preis| Menge | |--------------------------------------------------------------------| 100 | Meier | Daheim 4a | 1000 | 1.1.2013 | 1206 | 1 | 5 | | 100 | Meier | Daheim 4a | 1000 | 1.1.2013 | 1307 | 2 | 3 | |--------------------------------------------------------------------| 100 | Meier | Daheim 4a | 1001 | 7.1.2013 | 4711 | 4 | 13 | | 100 | Meier | Daheim 4a | 1001 | 7.1.2013 | 1206 | 1 | 5 | |--------------------------------------------------------------------| 101 | Huber | Nirvana 7b | 1002 | 7.1.2013 | 1206 | 1 | 5 | |--------------------------------------------------------------------| 100 | Mayer | Daheim 4a | 1003 | 9.1.2013 | 1206 | 1 | 3 | +--------------------------------------------------------------------+ Hier wurde eine neue Bestellung des Kunden 100 eingegeben, allerdings ist ein Fehler passiert: Mayer statt Meier. Die Folge ist, dass zwei unterschiedliche Kunden mit der gleichen Nummer existieren. Welcher ist der richtige? Ähnliches kann passieren, wenn Daten aktualisiert werden. Angenommen, Artikel 1206 wird teurer, so müssen alle Einträge aktualisiert werden. Passiert hier wieder ein Fehler, gibt es zwei unterschiedliche Artikel gleicher Nummer. +-----+------+--------------+--------+---------+-------+------+-------+ | KdNr| Name | Adresse | BestNr | Datum | Ware | Preis| Menge | |--------------------------------------------------------------------| 5 | | 100 | Meier | Daheim 4a | 1000 | 1.1.2013 | 1206 | 1 | 100 | Meier | Daheim 4a | 1000 | 1.1.2013 | 1307 | 2 | 3 | |--------------------------------------------------------------------| 100 | Meier | Daheim 4a | 1001 | 7.1.2013 | 4711 | 4 | 13 | | 100 | Meier | Daheim 4a | 1001 | 7.1.2013 | 1206 | 1 | 5 | |--------------------------------------------------------------------| 101 | Huber | Nirvana 7b | 1002 | 7.1.2013 | 1206 | 2 | 5 | +--------------------------------------------------------------------+ Als Konsequenz dieser Problematik werden redundante Daten in eigene Tabellen ausgegliedert. Diesen Schritt kann man auch durchführen, wenn man bereits etwas Gefühl dafür hat, was wohin gehört. Im Prinzip gehören Objekte, die gewisse Eigenschaften aufweisen (Artikel haben Preise, Bezeichnungen; Personen haben Namen, Adressen) in eigene Tabellen. 2. Variante: eigene Tabellen Tab. Kunde (kid = PS) ----------------------------KdNr | name | adresse --------------------100 | Meier | Daheim 4a --------------------101 | Huber | Nirvana 7b ----------------------- Tab. Artikel (PS = aid) -------------------------------aid | bezeichnung | preis -------------------------------1206 | Maus | 12 -------------------------------1307 | Tastatur | 30 -------------------------------4711 | Pheromon | 100 Tab. bestellungen ---------------------------------bestellnr | Datum | Menge ---------------------------------1000 | 1.1.2013 | 5 ---------------------------------1001 | 7.1.2013 | 3 Allerdings weiß man jetzt nicht mehr, welcher Artikel auf welcher Bestellung von welchem Kunden ist. Würde man wieder in der Tabelle bestellungen diese Information dazu eintragen, hätte man wieder das Problem der Redundanz. Hier ist 1 SQL 2013-05-28 das Wissen über Beziehungen wichtig. Zwischen welchen Objekten existieren Beziehungen? Um welche handelt es sich? • Zwischen Kunde – Bestellung liegt eine 1:N-Beziehung vor (1 Kunde kann mehrere – n – Bestellungen aufgeben, 1 Bestellung ist nur 1 Kunden zugeordnet). • Zwischen Artikel – Bestellung liegt eine M:N-Beziehung vor (1 Artikel kann auf mehreren – n – Bestellungen vorkommen, auf einer Bestellung können mehrere – m –Artikel sein). • eine Beziehung zwischen Kunden – Artikel braucht nicht hergestellt zu werden, da diese ja über den Umweg Kunden – Bestellungen – Artikel hergestellt werden kann Bei 1:N-Beziehungen wird in der Tabelle, die das N aufweist, ein Fremdschlüssel (Verweis) auf die Bezugstabelle eingetragen, bei M:N-Beziehungen wird eine Zwischentabelle angelegt, die die beiden Primärschlüssel der Bezugstabellen bekommt. Somit existieren im Endeffekt folgende Tabellen: Tab. Kunde (KdNr = PS) ----------------------------KdNr | name | adresse --------------------100 | Meier | Daheim 4a --------------------101 | Huber | Nirvana 7b ----------------------- Tab. Artikel (PS = aid) -------------------------------aid | bezeichnung | preis -------------------------------1206 | Maus | 12 -------------------------------1307 | Tastatur | 30 -------------------------------4711 | Pheromon | 100 Tab. bestell_kopf (PS = bestnr) -------------------------bestnr | datum | kunde(F) ----------------------------1000 | 1.1.2013 | 100 ----------------------------1001 | 7.1.2013 | 100 Tab. bestell_positionen (PS = artikel + bestnr) ----------------------artikel(F)| menge | bestnr (F) -------------------------1206 | 5 | 1000 -------------------------1307 | 3 | 1000 -------------------------4711 | 13 | 1001 -------------------------1206 | 1 | 1001 Jetzt geht es noch um die Kontrolle der sogenannten Normalformen • die 1. Normalform (1. NF) besagt, dass kein Attribut (Eigenschaft) eine Liste von Werten beinhalten darf, sondern immer nur atomare Werte. Eine Liste, und somit verboten, wäre folgendes Tab. blumen blid | name | farbe -------------------------1 | tulpe | rot, gelb, weiss -------------------------------------2 | nelke | rot, blau ------------------------------------- Trotzdem haben einige Datenbankhersteller (auch PostgreSQL) entsprechende Datentypen vorgesehen, weil sie einfach praktisch sind, und oft einfacher handzuhaben sind als normalisierte Daten. Ein Nachteil ergibt sich daraus, dass solche Datentypen nicht immer portierbar sind. In unserem Beispiel ist die 1.NF in allen Tabellen gewährleistet. • die 2. Normalform (2. NF) besagt, dass alle weiteren Eigenschaften, die keine Schlüssel sind, nur vom gesamten Primärschlüssel abhängig sein dürfen, und nicht von einem Teil des Schlüssels. Daher tritt diese Normalform nur bei Tabellen mit mehrteiligem Primärschlüssel auf (hier die Tabelle bestell_positionen). In dieser Tabelle ist eine weitere Nicht-Schlüssel-Spalte vorhanden (menge), aber diese Eigenschaft gehört sowohl zum Artikel als auch zur Bestellung gleichzeitig, weil sie besagt, welcher Artikel auf welcher Bestellung in welcher Menge vorhanden ist. Nicht 2 SQL 2013-05-28 erfüllt wäre die 2.NF in folgendem Beispiel (wenn der Preis in die Tabelle bestell_positionen aufgenommen werden würde) Tab. bestell_positionen (PS = artikel + bestnr) -------------------------artikel(F) | menge | bestnr (F) | preis ----------------------------------------1206 | 5 | 1000 | 1 ----------------------------------------1307 | 3 | 1000 | 1.5 ----------------------------------------4711 | 13 | 1001 | 12 ----------------------------------------1206 | 1 | 1001 | 1 Der Preis würde ausschließlich etwas mit dem Artikel zu tun haben, und nicht mit der Bestellung, daher hängt der Preis nur von einem Teil des Schlüssels ab. Die Problematik ist ersichtlich, da hier wieder Werte redundant vorhanden sind (artikel – preis). • die 3. Normalform (3. NF) besagt, dass keine Eigenschaften untereinander abhängig sein dürfen, sonder immer nur vom Schlüssel. Ein Beispiel: Tab. bestell_kopf (PS = bestnr) bestNr | Datum | KdNr | Adresse -------------------------------------1000 | 1.1.2013 | 100 | Daheim 4a -------------------------------------1001 | 7.1.2013 | 100 | Daheim 4a Adresse hängt nur vom Kunden ab, aber nicht vom Primärschlüssel (bestnr), daher ist die 3. NF verletzt. Auffällig sind hier wieder die Redundanzen (Adresse). Aufgabe: erweitere das Schema so, dass die Artikel noch einer Warengruppe zugeordnet werden (zum Beispiel wird Zucker der Gruppe Lebensmittel) und ein Mehrwertsteuersatz (Normalsteuersatz von 20%, reduzierter Satz von 10% oder Sondersteuersatz bei Wein-Abhofverkauf von 12%) vordefiniert ist. Die Mehrwertsteuer gilt für Artikel und nicht für Warengruppen. Tab. Kunde (KdNr = PS) ----------------------------KdNr | name | adresse --------------------100 | Meier | Daheim 4a --------------------101 | Huber | Nirvana 7b ----------------------- Tab. bestell_kopf (PS = bestnr) -------------------------bestnr | datum | kunde(F) ----------------------------1000 | 1.1.2013 | 100 ----------------------------1001 | 7.1.2013 | 100 Tab. Artikel (PS = aid) -------------------------------aid | bezeichnung | preis -------------------------------1206 | Maus | 12 -------------------------------1307 | Tastatur | 30 -------------------------------4711 | Pheromon | 100 Tab. bestell_positionen (PS = artikel + bestnr) ----------------------artikel(F)| menge | bestnr (F) -------------------------1206 | 5 | 1000 -------------------------1307 | 3 | 1000 -------------------------4711 | 13 | 1001 -------------------------1206 | 1 | 1001 3