Ich habe eine interessante Diskussion mit einem anderen Datenbankdesigner über Normalisierung. In diesem Beispiel haben wir eine GameTitles-Tabelle und jeder Datensatz muss das Jahr enthalten, in dem das Spiel veröffentlicht wurde. Er sagt, dass 2NF vorschreibt, dass alles normalisiert werden muss. Um konform zu sein, sollte das Jahresfeld in eine ReleaseYears-Tabelle mit einem eigenen Primärschlüssel aufgeteilt werden, auf den die GameTitles-Tabelle verweist. Ich sage, es sollte als Feld auf dem GameTitles-Tisch selbst bleiben.
Mein Argument dafür ist, dass ein Jahr nur ein nicht-primitiver numerischer Wert ist, der von Natur aus statisch ist (dh 2011 wird immer 2011 sein). Aus diesem Grund dient es als eigene Kennung und muss nicht referenziert werden, da es das ist, was es ist. Dies führt auch zu einer zusätzlichen Wartung, da Sie der Tabelle jetzt ein neues Jahr hinzufügen müssen, um darauf zu verweisen. Wenn Sie die Tabelle mit einem großen Bereich von Jahren vorab ausfüllen, verfügen Sie über zusätzliche Datensätze, auf die möglicherweise überhaupt keine Verweise vorhanden sind. Dies erhöht auch die Datenbankgröße, da Sie jetzt über eine zusätzliche Tabelle, einen zusätzlichen Datensatzaufwand und den zusätzlichen Primärschlüssel für das Jahr selbst verfügen. Wenn Sie das Jahr als Feld in der GameTitles-Tabelle behalten, entfallen all diese zusätzlichen Wartungs- und Verwaltungskosten.
Gedanken dazu?
edit: Soll dies auf StackOverflow posten. Kann jemand abstimmen, um dies zu löschen oder um es zur Aufmerksamkeit zu melden?
quelle
Antworten:
Der andere Datenbankdesigner ist einfach falsch, aber auch Ihre Argumentation ist falsch. Angenommen, Sie beginnen mit dieser Tabelle, die einen einzelnen Kandidatenschlüssel "game_title" enthält.
Sie bewerten, ob es in 2NF ist, indem Sie sich diese Fragen stellen.
F: Zuallererst ist es in 1NF?
A: Ja, das ist es.
F: Was sind die Hauptattribute (Attribute, die Teil eines Kandidatenschlüssels sind)?
A: "game_title" ist das einzige Hauptattribut.
F: Was sind die Nicht-Prim-Attribute?
A: "year_first_released" ist der einzige.
F: Ist "year_first_released" funktional abhängig von "game_title" oder nur von einem Teil davon?
A: Der einzige Kandidatenschlüssel "game_title" ist eine einzelne Spalte. es hat nicht einmal Teile. "Year_first_released" ist also funktional abhängig von "game_title".
Voilà. Sie haben 2NF gefunden.
Sie können einige der formalen Begriffe durchgehen, indem Sie zuerst fragen, ob es sich um 1NF handelt, und dann diese Frage beantworten.
F: Gibt es zusammengesetzte Kandidatenschlüssel?
A: Nein.
Voilà. Sie haben wieder 2NF gefunden.
Per Definition muss eine Tabelle mindestens einen Kandidatenschlüssel mit mehr als einer Spalte haben, damit sie gegen 2NF verstößt.
Hier sind Ihre Gründe, die Meinung Ihres Freundes abzulehnen.
Keiner dieser Gründe hat etwas damit zu tun, ob sich eine Tabelle in 2NF befindet.
Beim Entwerfen einer Datenbank ist es nicht falsch, Wartungsprobleme, Datenbankgröße, nicht referenzierte Zeilen, Bereichsbeschränkungen usw. zu berücksichtigen. Es ist einfach falsch, diese Dinge als Normalisierung zu bezeichnen.
Oh, und diese zweispaltige Tabelle, die ich oben bereitgestellt habe - es ist in 5NF.
quelle
Das Erstellen einer separaten Tabelle für ein Attribut hat nichts mit Normalisierung zu tun. 2NF, 3NF, BCNF, 4NF, 5NF befassen sich alle mit der Beseitigung von Nicht-Schlüssel-Abhängigkeiten. Wenn Sie ein einzelnes Attribut in einer neuen Tabelle entfernen und durch ein Fremdschlüsselattribut ersetzen, werden die Abhängigkeiten in der Tabelle logischerweise genauso sein wie zuvor. Die überarbeitete Version der Tabelle wird also nicht mehr oder weniger normalisiert war vorher.
quelle
Aus meiner Sicht ist eine separate Jahrestabelle nur dann sinnvoll, wenn das "Erscheinungsjahr" kein Kalenderjahr ist, sondern zB ein Geschäftsjahr, das mehrere Kalenderjahre umfassen kann (zB von Oktober bis Oktober).
Diese Tabelle würde dann die Definition (reales Start- und Enddatum) des Geschäftsjahres enthalten
quelle
Aus http://en.wikipedia.org/wiki/Second_normal_form :
Sie haben nicht angegeben, ob das Jahr Teil des Kandidatenschlüssels ist oder nicht, aber ich bin nicht sicher, ob es von Bedeutung ist, da 2NF in beiden Fällen in Bezug auf das Jahr zufrieden wäre.
Aus praktischen Gründen ist es eine schlechte Idee, das Jahr aus all Ihren Gründen zu trennen.
quelle
Ich mag das Argument gegen die separate Tabelle nicht, weil sie so groß ist oder nicht verwendete Zeilen enthält. Selbst wenn Sie 1000 Jahre in diese Tabelle eingeben, ist die Größe vernachlässigbar.
Trotzdem glaube ich nicht, dass der Tisch überhaupt gebraucht wird. Was nützt es, eine separate Tabelle für das Jahr zu haben? Diese Daten befinden sich bereits in der Haupttabelle und Sie sparen absolut nichts, indem Sie eine zweite Tabelle erstellen.
Das Argument kann für eine Kalendertabelle unterschiedlich sein, wobei jede Zeile einen Tag darstellt und andere Attribute haben kann (Wochentag, UTC-Offset, ob es sich um einen Feiertag handelt usw.).
Aber das ganze Jahr allein? Nein, ich sehe überhaupt keinen Nutzen ... Und wie andere darauf hingewiesen haben, fragen Sie sie, warum sie denken, dass dies normaler ist? Oder was gewinnen sie? Wenn Sie versuchen, Fragen wie zu schreiben
Anstatt von
Dann würde ich versuchen, Sie davon zu überzeugen, dass Letzteres für die Leistung (unter der Annahme, dass dt indiziert ist) und die Speicherung viel besser ist. Wenn die Einfachheit der Codierung von größter Bedeutung ist, würde ich sagen, dass eine dauerhaft berechnete Spalte besser ist als eine andere Tabelle.
quelle
Ich stimme der Antwort von Catcall vollkommen zu, außer in einem Punkt: "Jahr" ist vielleicht nicht immer ein primitiver Wert, aber ich denke, das ist eher ein Geschäftslogik-Konzept als ein Datenbank-Design-Konzept.
Nehmen wir an, dass die Jahre bei gleichem Design nur die Jahre sein sollten, für die die Freigabe zulässig ist. Auf diese Weise haben Sie es nicht mit primitiven numerischen Werten zu tun, sondern mit einer Teilmenge davon, und da eine solche Teilmenge keine primitive Implementierung hat, müssen Sie Ihre eigene (eine separate Tabelle?) Erstellen und darauf verweisen (mit einem FK). Auf diese Weise sprechen wir immer noch von Jahren, aber wir müssen sie auf eine andere Weise verwalten, weil sie konzeptionell ihre Bedeutung geändert haben. Sie sind zwar immer noch "Erscheinungsjahr", aber konzeptionell anders, was sie für jemanden mit Domänenkenntnissen bedeuten.
Für diesen speziellen Fall sage ich noch einmal, dass Catcalls Antwort richtig ist, wollte aber nur darauf hinweisen. (Entschuldigung, ich habe noch nicht genug Repräsentanten, um einen Kommentar abzugeben.)
quelle