Frage

Mein Arbeitgeber, ein kleines Unternehmen für Bürobedarf, schaltet Lieferanten und ich bin auf der Suche durch ihre elektronischen Inhalte mit einem robusten Datenbankschema zu entwickeln; unser bisheriges Schema war ziemlich einfach zusammen geworfen ohne jeden Gedanken überhaupt, und es ist ziemlich führt zu einem unerträglichen Datenmodell mit korrupten, widersprüchlichen Informationen.

Die Daten des neuen Lieferanten ist viel besser als die alte ist, aber ihre Daten ist, was ich nenne hypernormalized . Zum Beispiel hat ihre Produktkategoriestruktur 5 Stufen: Master-Abteilung, Abteilung, Klasse, Unterklasse, Produktblock. Darüber hinaus hat der Produkt Blockinhalt die lange Beschreibung, Suchbegriffe und Bildnamen für Produkte (die Idee, dass ein Produkt Block ein Produkt und alle Variationen enthält - zB ein bestimmte Stift in schwarz, blau oder rot Tinte kommen könnte, alle diese Artikel sind im wesentlichen der gleiche, so dass sie gelten Block auf einen einzelnen Produkt). In den Daten-I gegeben wurde, wird dies als die Produkte Tabelle ausgedrückt (ich sage „Tisch“, aber es ist eine flache Datei mit den Daten) einen Verweise mit dem einzigartigen ID Produkt Block.

Ich versuche, mit einem robusten Schema zu entwickeln, um die Daten aufzunehmen ich zur Verfügung gestellt habe, da ich es relativ schnell zu laden brauchen werden, und die Daten, die sie mir gegeben haben, scheinen nicht die Art entsprechen von Daten zur Verfügung stellen sie zur Demonstration auf ihrer Probe Website ( http://www.iteminfo.com ). Auf jeden Fall freue ich nicht ihre Präsentationsstruktur wieder zu verwenden, so dass es ein strittiger Punkt ist, aber ich war gerade die Seite einige Ideen zu bekommen, wie die Dinge zu strukturieren.

Was von Ich bin mir nicht sicher ist, ob ich die Daten in diesem Format behalten sollte, oder beispielsweise konsolidieren Master / Abteilung / Klasse / Unterklasse in einem einzigen „Kategorien“ Tabelle, mit einem sich selbst verweisende Beziehung und Verbindung dass ein Produkt Block (Produktblock sollten getrennt gehalten werden, da es keine „Kategorie“ als solche ist, sondern eine Gruppe von verwandten Produkten für eine bestimmte Kategorie). Derzeit verweist die Produkt-Blocktabelle die Unterklasse Tabelle, so würde dies zu „category_id“ ändern, wenn ich sie zusammen konsolidieren.

Ich werde wahrscheinlich ein E-Commerce-Schaufenster zu erschaffen der Nutzung dieser Daten mit Ruby on Rails (oder das ist mein Plan, auf jedem Fall) so versuche ich später zu vermeiden snagged bekommen oder eine aufgeblähte Anwendung mit - vielleicht ist es zu viel Gedanken ich gebe aber ich möchte lieber sicher als traurig; unsere bisherigen Daten war ein echtes Chaos und die Firma Zehn in entgangene Umsätze aufgrund inkonsistenter und ungenauen Daten Tausende von Dollar kosten. Auch werde ich von den Rails Konventionen ein wenig brechen, indem sie dafür sorgen, dass meine Datenbank robust ist und erzwingt Einschränkungen (Ich plane es auf der Anwendungsebene zu tun, auch), so dass das, was ich brauche auch zu berücksichtigen.

Wie würden Sie eine Situation wie diese bewältigen? Beachten Sie, dass ich die Daten geladen haben bereits in flachen Dateien werden, die eine Tabellenstruktur nachahmen (ich habe Dokumentation sagen, welche Spalten, welche und was Referenzen eingerichtet sind); Ich versuche zu entscheiden, ob ich sie halten, wie normalisiert, wie sie derzeit sind, oder ob ich zu konsolidieren aussehen; Ich muß wissen, wie jede Methode, um die Art und Weise beeinflussen wird ich die Seite mit Rails programmiert werden, da, wenn ich konsolidieren kann, wird es in einer einzigen Tabelle im Wesentlichen 4 „Ebene“ von Kategorien, aber das scheint auf jeden Fall besser handhabbar als getrennte Tabellen für jede Ebene, da abgesehen von Subclass (die Produktblöcken direkt verbindet) sie dies nicht tun tun alles außer die nächste Stufe der Kategorie unter ihnen zeigen. Ich bin immer ein Verlust für den „besten“ Weg, um Daten so zu handhaben. - Ich kenne den Spruch „Normalisieren bis es weh tut, dann denormalize bis es funktioniert“, aber ich habe nie wirklich hatte es zu implementieren, bis jetzt

War es hilfreich?

Lösung

Ich würde den „hypernormalized“ -Ansatz über ein denormal Datenmodell bevorzugen. Die selbstverweisenden Tabelle der Anzahl der Tabellen erwähnt könnte nach unten reduzieren und vereinfacht das Leben in gewisser Weise, aber diese Art von Beziehung im Allgemeinen kann schwierig sein, zu beschäftigen. Hierarchische Abfragen zu einem Schmerz, genau wie die Abbildung eines Objektmodells auf diese (wenn Sie sich entscheiden, diesen Weg zu gehen).

Ein paar zusätzliche Joins wird nicht verletzt und die Anwendung halten mehr wartbar. Es sei denn, die Leistung aufgrund der übermäßigen Anzahl der Joins verschlechtert, würde ich entscheiden, Dinge so lassen wie sie sind. Als zusätzlichen Bonus, wenn eine dieser Ebenen der Tabellen benötigt zusätzliche Funktionalität hinzugefügt, werden Sie nicht auf Probleme stoßen, weil man sie alle in die Selbstreferenzierung Tabelle zusammengefasst.

Andere Tipps

ich völlig anderer Meinung mit der Kritik über sich selbst verweisende Tabellenstrukturen für Eltern-Kind-Hierarchien. Die verknüpfte Listenstruktur macht UI und Business-Schicht-Programmierung einfacher und besser verwaltbar in den meisten Fällen, da verkettete Listen und Bäume sind die natürliche Art und Weise dieser Daten in Sprachen darzustellen, die die Benutzeroberfläche und Business-Schichten typischerweise in realisiert werden würden.

Die Kritik über die Schwierigkeit, auf diesen Strukturen Datenintegritätsbedingungen beibehalten ist vollkommen gültig, obwohl die einfache Lösung, die eine Verschlusstabelle zu verwenden ist, dass die härter überprüfen Einschränkungen hostet. Die Verschluss Tabelle ist leicht zu pflegen mit Trigger.

Der Nachteil ist ein wenig mehr Komplexität in der DB (Verschlusstabelle und Trigger) für viel weniger Komplexität in UI und Business-Schicht-Code.

Wenn ich richtig verstehe, wollen Sie ihre eigenen Tabellen nehmen und sie in eine Hierarchie drehen, die mit einem sich selbst verweis in einer einzigen Tabelle gehalten hat FK.

Dies ist im Allgemeinen ein flexiblerer Ansatz (zum Beispiel, wenn Sie eine fünfte Ebene hinzufügen mögen), aber SQL und relationalen Datenmodelle sind in der Regel nicht gut, wie dies mit verknüpften Listen arbeiten, auch mit neuer Syntax wie MS SQL Server CTEs. Zugegeben, CTEs es aber viel besser machen.

Es kann schwierig und kostspielig sein, die Dinge zu erzwingen, wie, dass ein Produkt immer auf der vierten Ebene der Hierarchie sein muss, etc.

Wenn Sie sich entscheiden, es auf diese Weise zu tun, dann überprüfen definitiv out Joe Celko SQL für Smarties , die ich glaube, einen Abschnitt oder zwei auf der Modellierung hat und das arbeiten mit Hierarchien in SQL oder noch besser sein Buch erhalten, die zu dem Thema ( Bäume und Hierarchien in SQL Joe Celko für Smarties ).

Normalization Datenintegrität impliziert, dh. Jede normale Form die Anzahl der Situationen reduziert, wo man Daten inkonsistent

In der Regel denormalization hat ein Ziel schneller querying, sondern führt zu einer erhöhten Raum, erhöht DML Zeit, und, last but not least, verstärkte Anstrengungen, um Daten konsistent zu machen.

Ein in der Regel Code schneller schreibt (schneller schreibt, nicht den Code schneller) und der Code ist weniger fehleranfällig, wenn die Daten normalized ist.

selbstbeziehende Tabellen fast immer viel schlimmer entpuppen abzufragen und schlechter abschneiden als normalisierte Tabellen. Tun Sie es nicht. Es kann Sie aussehen elegant zu sein, aber es ist nicht und ist eine sehr schlechte Datenbank-Design-Technik. Persönlich die Struktur, die Sie beschrieben klingt einfach gut zu mir nicht hypernormalized. Eine richtig normalisierte Datenbank (mit Fremdschlüssel-Constraints sowie Standardwerten, Trigger (wenn für komplexe Regeln erforderlich) zur Datenvalidierung constraints) ist auch weit likelier konsistente und genaue Daten zu haben. Ich bin damit einverstanden die Datenbank darüber, dass die Regeln durchzusetzen, wahrscheinlich ist dies Teil, warum die letzte Anwendung schlechte Daten hatte, weil die Regeln nicht an der richtigen Stelle durchgesetzt wurden und die Menschen konnten um sie leicht zu bekommen. Nicht, dass die Anwendung sollte nicht so gut kontrollieren (kein Punkt sogar sendet ein ungültiges Datum zum Beispiel für die datbase auf Einsatz zum Scheitern verurteilt). Da youa Redesign, würde ich mehr Zeit und Mühe in den notwendigen Einschränkungen der Gestaltung und die richtigen Datentypen wählen (nicht speichern Daten als String-Daten zum Beispiel), als bei dem Versuch, die stinknormale normalisierte Struktur aussehen zu lassen eleganter.

Ich würde es so nah wie möglich an ihrem Modell bringt (und überhaupt möglich ist, wenn, würde ich Dateien bekommen, die ihr Schema passen - nicht eine abgeflachte Version). Wenn Sie die Daten direkt in Ihr Modell bringen, was passiert, wenn Daten, die sie beginnt senden Annahmen bei der Transformation zu Ihrer internen Anwendung des Modell zu brechen?

Bessere ihre Daten zu bringen, führten Plausibilitätsprüfungen und prüfen, ob Annahmen nicht verletzt werden. Dann, wenn Sie ein anwendungsspezifisches Modell zu tun haben, wandeln sie in die für die optimale Nutzung von Ihrer Anwendung.

Sie denormalize nicht. ein gutes Schema-Design acheive Der Versuch, durch Denormalisierung ist wie der Versuch, durch Wegfahren von New York nach San Francisco zu bekommen. Es ist Ihnen nicht sagen, welcher Weg zu gehen.

In Ihrer Situation, Sie wollen herausfinden, was ein normalisiertes Schema möchte. Sie können die weitgehend auf dem Quellschema basieren, aber Sie müssen lernen, was die funktionalen Abhängigkeiten (FD) in den Daten sind. Weder das Quellschema noch die abgeflachten Dateien sind garantiert alle FDs Ihnen zeigen.

Sobald Sie wissen, was ein normalisiertes Schema aussehen würde, müssen Sie jetzt um herauszufinden, wie ein Schema zu entwerfen, die Ihren Bedürfnissen entspricht. Es dass Schema ist etwas weniger als vollständig normalisiert, so sei es. Aber für Schwierigkeiten hergestellt werden, bei der Programmierung die Transformation zwischen den Daten in den abgeflachten Dateien und die Daten in Ihrem Schema entwirft.

Sie haben gesagt, dass die früheren Schemata in Ihrem Unternehmen Millionen wegen Inkonsistenz und Ungenauigkeit kosten. Je mehr normalisiert Ihr Schema ist, desto mehr geschützt Sie interne Inkonsistenz sind. Dies läßt Sie mehr wachsam über Ungenauigkeit sein. Konsistente Daten, die durchweg falsch als irreführend, da inkonsistente Daten sein.

ist Ihr Schaufenster (oder was auch immer es ist, Sie bauen, ist nicht ganz klar auf, dass) immer Daten von diesem Anbieter gehen zu verwenden? könnten Sie jemals Lieferanten oder zusätzliche verschiedene Lieferanten ändern?

wenn ja, entwirft ein allgemeines Schema, das Ihre Bedürfnisse erfüllt, und die Herstellerdaten zuordnen. Persönlich würde ich eher leiden die (unglaublich minor) ‚Schmerz‘ eines sich selbst verweisende Kategorie (hierarchisch) Tabelle als vier halten (scheinbar halb nutzlos) Ebenen der Kategorie Varianten und dann im nächsten Jahr herausfinden, sie haben eine fünfte hinzugefügt, oder eine Produktlinie eingeführt mit nur drei ...

Für mich ist die eigentliche Frage ist: , was das Modell besser passt

Es ist wie ein Tuple und eine Liste verglichen wird.

  1. Tupeln sind eine feste Größe und sind heterogen -. Sie sind „hypernormalized“
  2. Listen sind eine arbitrarty Größe und sind homogen.

Ich benutze ein Tuple, wenn ich ein Tuple und eine Liste brauchen, wenn ich eine Liste benötigen; sie grundsätzlich Server verschiedene Zwecke.

In diesem Fall, da die Produktstruktur bereits definiert ist gut (und ich nehme nicht wahrscheinlich ändern), dann würde ich mit dem „Tuple Ansatz“ bleiben. Die wirkliche Macht / Verwendung einer List (oder Muster rekursive Tabelle) ist, wenn Sie sie brauchen erweitern zu einer beliebigen Tiefe, wie eine Stückliste oder einen Genealogie Baum.

Ich benutze beide Ansätze in einigen meiner Datenbank auf die je nach Bedarf. Allerdings gibt es auch die „versteckten Kosten“ eines rekursiven Muster, das ist, dass nicht alle ORMs (nicht sicher AR) unterstützen sie gut. Viele moderne DBs haben Unterstützung für "join Durch" (Oracle), Hierarchie-IDs (SQL Server) oder andere rekursive Muster. Ein weiterer Ansatz ist, einen Satz basierten Hierarchie zu verwenden (die auf Triggers / Wartungs allgemeinen beruht). In jedem Fall verwendet werden, wenn die ORM nicht rekursive Abfragen gut unterstützt das, dann kann es sein, die extra „Kosten“ die an die DB mit Funktionen direkt - entweder in Bezug auf manueller Abfrage / View Generation oder Managements wie Trigger. Wenn Sie nicht über eine funky ORM verwenden, oder einfach einen logischen Separator wie iBatis verwenden, dann kann dieses Problem nicht einmal anwenden.

Was die Leistung, auf neue Oracle oder SQL Server (und wahrscheinlich andere) RDBMS, sollte es sehr vergleichbar sein, so dass die meine geringste Sorge sein würde, aber die Lösungen für Ihre RDBMS und Portabilität Anliegen zur Verfügung Check-out.

Jeder, den Sie eine Hierarchie nicht zu haben, in der Datenbank eingeführt empfiehlt, eine selbst referenzierten des mit Tabelle nur die Möglichkeit, unter Berücksichtigung. Dies ist nicht der einzige Weg, um die Hierarchie in der Datenbank zu modellieren. Sie können einen anderen Ansatz verwenden, die Sie mit einfacher und schnellen Abfrage liefert, ohne rekursive Abfragen. Angenommen, Sie haben eine große Menge von Knoten (Kategorien) haben in der Hierarchie:

  

Set1 = (Node1 Knoten2 Node3 ...)

Jeder Knoten in diesem Satz kann auch eine andere von selbst eingestellt werden, das enthält anderen Knoten oder verschachtelte Sätze:

  

Node1 = (Node2 Node3 = (Knoten4 Knoten5 = (Node6) Node7))

Nun, wie wir können das Modell? Lassen Sie sich jeden Knoten hat zwei Attribute zu haben, welche die Grenzen des Knoten gesetzt enthält:

  

Node = {Id: int, Min: int, Max: int}

unsere Hierarchie zu modellieren, weisen wir nur diese Min- / Max-Werte entsprechend:

  

Node1 = {Id = 1, Min = 1, Max = 10}
  Node2 = {Id = 2, Min = 2, Max = 2}
  Node3 = {Id = 3 Min = 3, Max = 9}
  Knoten4 = {Id = 4, Min = 4, Max = 4}
  Knoten5 = {Id = 5, Min = 5, Max = 7}
  Node6 = {Id = 6, Min = 6, Max = 6}
  Node7 = {Id = 7, Min = 8, Max = 8}

Nun abfragen alle Knoten unter dem Set / Knoten5:

  

n aus. * Von Knoten als n, Knoten als s
  wo s.Id = 5 und s.Min

Die einzige ressourcenintensive Operation wäre, wenn Sie einen neuen Knoten eingefügt werden sollen, oder einen Knoten in der Hierarchie verschieben, wie viele Datensätze betroffen sein werden, aber das ist in Ordnung, da die Hierarchie selbst nicht sehr oft ändern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top