2010-12-01 7 views
13

Ich habe eine Webanwendung, an der ich gerade arbeite, die eine MySQL-Datenbank für das Backend verwendet, und ich muss wissen, was für meine Situation besser ist, bevor ich weitermache.Sollte ich flache Tabellen oder eine normalisierte Datenbank verwenden?

Einfach gesagt, in dieser Anwendung werden Benutzer in der Lage sein, ihre eigenen Formulare mit beliebigen Zahlenfeldern zu konstruieren (sie entscheiden), und jetzt habe ich alles in ein paar Tabellen durch Fremdschlüssel verknüpft. Ein Freund von mir schlägt vor, die Dinge so "einfach/schnell" zu halten, dass ich das Formular jedes Benutzers in eine flache Tabelle umwandeln soll, so dass die Abfrage von Daten von ihnen schnell bleibt (im Falle eines großen Wachstums).

Soll ich die Datenbank normalisieren mit allem in relationalen Tabellen mit Fremdschlüsseln (Indizes, etc.) gepoolten oder sollte ich flache Tabellen für jedes neue Formular erstellen, das ein Benutzer erstellt?

Offensichtlich sind einige Vorteile der Erstellung von flachen Tabellen Datentrennung (Sicherheit) und Abfragegeschwindigkeiten würden reduziert werden. Aber ernsthaft, wie viel Gewinn würde ich daraus ziehen? Ich will wirklich nicht 10000 Tische haben und die ganze Zeit fallen lassen, verändern und hinzufügen, aber wenn es besser wird als ich es tun werde ... brauche ich nur etwas Input.

Vielen Dank

+5

Normalisieren, bis es weh tut. :) – shamazing

+0

Keine wirkliche Antwort ... aber Sie können immer Wikipedia als Anleitung verwenden. Hier ist das Datenbankschema von Wikipedia: http://commons.wikimedia.org/wiki/File:Mediawiki-database-schema.png – Dragontamer5788

+4

@shamazing dann denormalize bis es funktioniert. 80)) – Keng

Antwort

21

Faustregel. Es ist einfacher, von Normalisierung zu Denormalisierung zu wechseln als umgekehrt.

Beginnen Sie mit einem vernünftigen Niveau der Datenbanknormalisierung (mit vernünftigen ich meine lesbar, wartbar und effizient, aber nicht vorzeitig optimiert), dann, wenn Sie Leistungsprobleme wie Sie wachsen, haben Sie die Möglichkeit, in Möglichkeiten, in denen Denormalisierung kann die Leistung erhöhen.

+0

Zufällig las ich http://stackoverflow.com/questions/4301089/when-to-denormalize-a-database-design – Sathya

+0

Bob Palmer, ausgezeichnete Antwort. –

+0

Danke, Bob. Du hast einen sehr guten Punkt gemacht. Sehr geschätzt. –

2

Das Ändern des Schemas zur Laufzeit ist selten eine gute Idee. Was Sie berücksichtigen möchten, ist das Modell EAV (Entity-Attribut-Value).

Wikipedia hat some very good info über die Vor- und Nachteile sowie Implementierungsdetails. EAV ist zu vermeiden, wenn möglich, aber für Situationen wie Ihres mit einer unbekannten Anzahl von Spalten für jedes Formular, EAV ist in Betracht zu ziehen.

+0

Ich hatte noch nie von EAV gehört, aber es scheint ähnlich zu der oben vorgeschlagenen Lösung zu sein, die eine Tabelle mit Schlüssel/Wert-Paaren verwendet. Ist meine vorgeschlagene Lösung ähnlich wie die von Ihnen vorgeschlagene EAV-Lösung? Ich bin nur neugierig, weil ich mehr über EAV-Modellierung erfahren möchte. –

+1

@Matt: Ja, das ist genau richtig. In Ihrem Fall ist E = form_id, A = Schlüssel, V = Wert. Es gibt modifizierte Versionen, in denen Sie zusätzliche Wertespalten für verschiedene Datentypen haben, so dass Sie effizienter mit Indizes und Aggregationen usw. werden können, aber dies erhöht auch die Komplexität von Abfragen. – RedFilter

+0

danke für die Info! –

1

Halten Sie Ihre Daten normalisiert. Das System sollte schnell bleiben, vorausgesetzt, Sie haben eine korrekte Indexierung.

Wenn Sie wirklich schnell gehen wollen, dann wechseln Sie das Schema zu einer der Schlüsselwertdatenbanken wie bigDB/couchDB usw. Das ist total denormalisiert und sehr, sehr schnell.

3

... in dieser Anmeldung Benutzer in der Lage sein werden, ihre eigenen Formulare mit einer beliebigen Anzahl Felder ...

Huch zu bauen! Dann wie könnten Sie möglicherweise irgendeine Art von Normalisierung tun, wenn die Benutzer, in essense, die Datenbank Entscheidungen für Sie treffen.

Ich denke, Sie müssen es entweder Schritt für Schritt verwalten oder lassen Sie Ihre Freak-Flagge fliegen und einfach kaufen Hardware, um mit der Prügel zu halten, die Sie bekommen werden, wenn die Benutzer wirklich anfangen, sich darauf einzulassen ... Sehen Sie sich an, was passiert, wenn Benutzer beginnen, neue Formulare und Ansichten in SharePoint zu erstellen ... CRIKY !! Sprechen Sie über Umfang schleichen !!

+1

Definieren Sie klar, welche Felder/Eingaben sie erstellen können. Begrenzen Sie die Anzahl der Anpassungen, die sie vornehmen können. Der Umfang ist für das Projekt definiert und sollte nicht geändert werden, es sei denn, ich mache es. Danke für deinen Beitrag. –

+1

@Steve B. Sie könnten eine Palette von universellen Feldern betrachten, die sie hinzufügen können und die normalisiert sind. Zum Beispiel: Mitarbeiter-ID, die zur emp_table geht, damit die Leute das Rad nicht neu erstellen. – Keng

+0

Ich habe eine Liste von 15 oder so Eingaben, die ein Benutzer möglicherweise auf einem Formular verwenden könnte, dies kann wachsen, aber es ist fast alles, was sie benötigen würde, sie werden in einer statischen Tabelle gespeichert und durch ID mit Benutzerformularen verknüpft . –

1

Die Art, wie ich damit umgehen würde, ist eine normalisierte, erweiterbare „Property“ Tabelle zu verwenden, wie unten:

Table: FormProperty 
id: pk 
form_id: fk(Form) 
key: varchar(128) 
value: varchar(2048) 

oben The ist nur ein Beispiel, aber ich habe dieses Muster in vielen Fällen verwendet und es tendiert dazu, ziemlich gut zu funktionieren. Das einzige echte "Gotcha" ist, dass Sie den Wert als String/Varchar serialisieren müssen und ihn dann zu dem Deserialisieren müssen, was er auch sein muss. Es gibt also eine kleine zusätzliche Verantwortung für den Client.

+0

Um beispielsweise ein Anmeldeformular zu erstellen, könnten Sie: Werte in FormProperty (form_id, key, value) einfügen (1, 'email', ''); Einfügen in Werte von FormProperty (form_id, key, value) (1, 'password', ' passwort '); –

+0

Als Alternative zu dem json/xml im obigen Beispiel könnten Sie eine zusätzliche Tabelle für die Feldeigenschaften erstellen und diese über Fremdschlüssel verknüpfen. –

5

Halten Sie Ihre Daten normalisiert. Wenn Sie richtig indizieren, werden Sie für eine sehr lange Zeit nicht auf Leistungsprobleme stoßen.

In Bezug auf Sicherheit: Der flache Ansatz erfordert, dass Sie viele create/drop table, alter table etc Anweisungen schreiben, dh viel mehr Code und eine Menge weiterer Fehlerpunkte.

Der einzige Grund, flache Dateien zu haben, wäre, wenn sich Ihre Benutzer direkt mit der Datenbank verbinden könnten (Sie könnten immer noch für die Sicherheit auf Zeilenebene gehen). Aber in diesem Fall sind die Neuimplementierung Sie wirklich eine Variante von phpMyAdmin

+0

+1 sehr gute Antwort.Martin was tun, wenn nach dieser sehr langen Zeit Performance-Probleme auftreten? Ich habe noch nie mit so viel Daten/Datenverkehr gearbeitet, also bin ich mir nicht sicher, was der nächste Schritt ist. –

+0

a) Indizes sind * sehr * schnell - suchen Werte in 100 Millionen. Ringtabelle im Allgemeinen kein Problem, solange die relevanten Spalten indiziert sind. Es gibt also wirklich viel Spielraum, bevor Sie Leistungsprobleme haben. b) Sie können * Tabellen nach Bereichen partitionieren, z. B. eine Partition pro 1000 Benutzer-IDs erstellen. Ihre Abfragen wirken sich hauptsächlich auf eine einzelne Benutzer-ID und somit auf eine einzelne Partition aus - daher sollte diese fast linear skaliert werden. – Martin

0

Normalized == schnellen Suche, einfacher Indizes zu halten, langsame Insert-Transaktionen (auf mehreren Zeilen)

Denormalisierte == schnelle Einsätze, ususally diese verwendet wird, wenn es viele Einfügungen gibt (Data Warehouses, die chronologische Daten sammeln und aufzeichnen)

Verwandte Themen