Ich speichere verschiedene Benutzerdetails in meiner MySQL-Datenbank. Ursprünglich wurde es in verschiedenen Tabellen eingerichtet, was bedeutet, dass Daten mit UserIds verknüpft sind und über manchmal komplizierte Aufrufe ausgegeben werden, um die Daten nach Bedarf anzuzeigen und zu bearbeiten. Beim Einrichten eines neuen Systems ist es fast sinnvoll, alle diese Tabellen in einer großen Tabelle mit verwandten Inhalten zu kombinieren.
- Wird dies eine Hilfe oder ein Hindernis sein?
- Überlegungen zur Geschwindigkeit beim Aufrufen, Aktualisieren oder Suchen / Bearbeiten?
Hier ist ein Beispiel für einige meiner Tabellenstrukturen:
- Benutzer - Benutzer-ID, Benutzername, E-Mail, verschlüsseltes Passwort, Registrierungsdatum, IP
- user_details - Cookie-Daten, Name, Adresse, Kontaktdaten, Zugehörigkeit, demografische Daten
- user_activity - Beiträge, zuletzt online, letzte Anzeige
- user_settings - Einstellungen für die Profilanzeige
- user_interests - Werbung für zielgerichtete Variablen
- user_levels - Zugriffsrechte
- user_stats - Treffer, Tallies
Bearbeiten: Ich habe bisher alle Antworten positiv bewertet, sie haben alle Elemente, die im Wesentlichen meine Frage beantworten.
Die meisten Tabellen haben eine 1: 1-Beziehung, was der Hauptgrund für die Denormalisierung war.
Wird es Probleme geben, wenn sich die Tabelle über mehr als 100 Spalten erstreckt, wenn ein großer Teil dieser Zellen wahrscheinlich leer bleibt?
quelle
Antworten:
Mehrere Tabellen helfen auf folgende Weise / in folgenden Fällen:
(a) Wenn verschiedene Personen Anwendungen mit unterschiedlichen Tabellen entwickeln, ist es sinnvoll, diese aufzuteilen.
(b) Wenn Sie verschiedenen Personen für verschiedene Teile der Datenerfassung unterschiedliche Befugnisse erteilen möchten, ist es möglicherweise bequemer, sie aufzuteilen. (Natürlich können Sie auch Ansichten definieren und entsprechende Berechtigungen erteilen.)
(c) Um Daten an verschiedene Orte zu verschieben, insbesondere während der Entwicklung, kann es sinnvoll sein, Tabellen zu verwenden, die zu kleineren Dateigrößen führen.
(d) Ein geringerer Platzbedarf kann Komfort bieten, wenn Sie Anwendungen für die spezifische Datenerfassung einer einzelnen Entität entwickeln.
(e) Es ist eine Möglichkeit: Was Sie als Einzelwertdaten dachten, kann sich in Zukunft als wirklich mehrere Werte herausstellen. zB ist das Kreditlimit ab sofort ein einzelnes Wertefeld. Aber morgen können Sie entscheiden, die Werte als (Datum von, Datum bis, Kreditwert) zu ändern. Geteilte Tabellen könnten jetzt nützlich sein.
Ich würde für mehrere Tabellen stimmen - mit entsprechend aufgeteilten Daten.
Viel Glück.
quelle
Das Kombinieren der Tabellen wird als Denormalisieren bezeichnet.
Es kann (oder auch nicht) hilfreich sein, einige Abfragen (die viele
JOIN
s machen) schneller auszuführen, auf Kosten der Erstellung einer Wartungshölle.MySQL
ist in der Lage, nurJOIN
Methode zu verwenden, nämlichNESTED LOOPS
.Dies bedeutet, dass für jeden Datensatz in der
MySQL
Treibertabelle ein übereinstimmender Datensatz in der Treibertabelle in einer Schleife gefunden wird.Das Auffinden eines Datensatzes ist ein ziemlich kostspieliger Vorgang, der Dutzende Male so lange dauern kann wie das reine Scannen von Datensätzen.
Wenn Sie alle Ihre Datensätze in eine Tabelle verschieben, können Sie diesen Vorgang vermeiden. Die Tabelle selbst wird jedoch größer und der Tabellenscan dauert länger.
Wenn Sie viele Datensätze in anderen Tabellen haben, kann eine Erhöhung des Tabellenscans die Vorteile der nacheinander gescannten Datensätze übergewichten.
Die Wartungshölle hingegen ist garantiert.
quelle
Sind alle 1: 1-Beziehungen? Ich meine, wenn ein Benutzer beispielsweise verschiedenen Benutzerebenen angehören könnte oder wenn die Benutzerinteressen als mehrere Datensätze in der Benutzerinteressentabelle dargestellt werden, würde das Zusammenführen dieser Tabellen sofort nicht in Frage kommen.
In Bezug auf frühere Antworten zur Normalisierung muss gesagt werden, dass die Regeln für die Datenbanknormalisierung die Leistung völlig außer Acht gelassen haben und sich nur mit einem ordentlichen Datenbankdesign befassen. Das ist oft das, was Sie erreichen möchten, aber es gibt Zeiten, in denen es sinnvoll ist, aktiv zu denormalisieren, um Leistung zu erzielen.
Alles in allem würde ich sagen, dass die Frage darauf hinausläuft, wie viele Felder in den Tabellen vorhanden sind und wie oft auf sie zugegriffen wird. Wenn Benutzeraktivitäten oft nicht sehr interessant sind, kann es aus Leistungs- und Wartungsgründen nur lästig sein, sie immer auf demselben Datensatz zu haben . Wenn auf einige Daten, wie z. B. Einstellungen, sehr häufig zugegriffen wird, aber einfach zu viele Felder enthalten, ist es möglicherweise auch nicht bequem, die Tabellen zusammenzuführen. Wenn Sie nur an der Leistungssteigerung interessiert sind, können Sie andere Ansätze in Betracht ziehen, z. B. die Einstellungen getrennt zu halten, sie jedoch in einer eigenen Sitzungsvariablen zu speichern, damit Sie die Datenbank nicht sehr oft nach ihnen abfragen müssen.
quelle
3NF
Normalisierung nicht erfüllen , also profitieren Sie von einer zweiten Tabelle, um das zu beheben, aber das scheint nicht das zu sein, worauf sich OP für die anderen Tabellen bezieht.)Haben alle diese Tabellen eine
1-to-1
Beziehung? Hat beispielsweise jede Benutzerzeile nur eine entsprechende Zeile inuser_stats
oderuser_levels
? In diesem Fall ist es möglicherweise sinnvoll, sie in einer Tabelle zu kombinieren. Wenn die Beziehung nicht besteht1 to 1
, wäre es wahrscheinlich nicht sinnvoll, sie zu kombinieren (zu denormalisieren).Wenn Sie sie in separaten Tabellen gegenüber einer Tabelle haben, hat dies wahrscheinlich nur geringe Auswirkungen auf die Leistung, es sei denn, Sie haben Hunderttausende oder Millionen von Benutzerdatensätzen. Der einzige wirkliche Vorteil besteht darin, dass Sie Ihre Abfragen vereinfachen, indem Sie sie kombinieren.
ETA:
Wenn Sie Bedenken haben, zu viele Spalten zu haben , überlegen Sie, welche Elemente Sie normalerweise zusammen verwenden, und kombinieren Sie diese. Lassen Sie den Rest in einer separaten Tabelle (oder bei Bedarf in mehreren separaten Tabellen).
Wenn Sie sich die Art und Weise ansehen, wie Sie die Daten verwenden, werden Sie wahrscheinlich feststellen, dass etwa 80% Ihrer Abfragen 20% dieser Daten verwenden, während die restlichen 80% der Daten nur gelegentlich verwendet werden. Kombinieren Sie die häufig verwendeten 20% in einer Tabelle und lassen Sie die 80%, die Sie nicht oft verwenden, in separaten Tabellen, und Sie haben wahrscheinlich einen guten Kompromiss.
quelle
Das Erstellen einer massiven Tabelle widerspricht den Prinzipien relationaler Datenbanken. Ich würde nicht alle zu einem Tisch zusammenfassen. Sie werden mehrere Instanzen wiederholter Daten erhalten. Wenn Ihr Benutzer beispielsweise drei Interessen hat, haben Sie drei Zeilen mit denselben Benutzerdaten, um nur die drei verschiedenen Interessen zu speichern. Entscheiden Sie sich auf jeden Fall für den Ansatz mit mehreren "normalisierten" Tabellen. Auf dieser Wiki-Seite finden Sie Informationen zur Datenbanknormalisierung.
Bearbeiten: Ich habe meine Antwort aktualisiert, da Sie Ihre Frage aktualisiert haben ... Ich stimme meiner ursprünglichen Antwort jetzt noch mehr zu, da ...
Wenn zum Beispiel ein Benutzer keine Interessen hatte, wenn Sie normalisieren, haben Sie einfach keine Zeile in der Interessentabelle für diesen Benutzer. Wenn Sie alles in einer massiven Tabelle haben, haben Sie Spalten (und anscheinend viele davon), die nur NULL-Werte enthalten.
Ich habe für eine Telefoniefirma gearbeitet, in der es unzählige Tabellen gab. Das Abrufen von Daten kann viele Verknüpfungen erfordern. Wenn die Leistung beim Lesen aus diesen Tabellen kritisch war, wurden Verfahren erstellt, die eine flache Tabelle (dh eine denormalisierte Tabelle) generieren konnten, für die keine Verknüpfungen, Berechnungen usw. erforderlich waren, auf die Berichte verweisen konnten. Diese wurden dann in Verbindung mit einem SQL Server-Agenten verwendet, um den Job in bestimmten Intervallen auszuführen (dh eine wöchentliche Ansicht einiger Statistiken würde einmal pro Woche usw. ausgeführt).
quelle
Warum nicht den gleichen Ansatz verwenden? Wordpress verwendet eine Benutzertabelle mit grundlegenden Benutzerinformationen, die jeder hat, und fügt dann eine "user_meta" -Tabelle hinzu, die im Grunde ein beliebiges Schlüssel-Wert-Paar sein kann, das der Benutzer-ID zugeordnet ist. Wenn Sie also alle Metainformationen für den Benutzer finden müssen, können Sie diese einfach zu Ihrer Abfrage hinzufügen. Sie müssten auch nicht immer die zusätzliche Abfrage hinzufügen, wenn sie nicht zum Beispiel für die Anmeldung benötigt wird. Der Vorteil dieses Ansatzes lässt Ihre Tabelle auch offen, um Ihren Benutzern neue Funktionen hinzuzufügen, z. B. das Speichern ihres Twitter-Handles oder jedes einzelne Interesse. Sie müssen sich auch nicht mit einem Labyrinth zugeordneter IDs befassen, da Sie eine Tabelle haben, die alle Metadaten regelt, und Sie beschränken sie auf nur eine Zuordnung anstelle von 50.
Wordpress tut dies speziell, um das Hinzufügen von Funktionen über Plugins zu ermöglichen, sodass Ihr Projekt skalierbarer wird und keine vollständige Datenbanküberholung erforderlich ist, wenn Sie eine neue Funktion hinzufügen müssen.
quelle
wp_usermeta
Tabelle wächst geometrisch. Jeder Benutzer fügt derwp_usermeta
Tabelle X Zeilen hinzu , eine Zeile für jede Metainformation, die wir für diesen Benutzer behalten möchten. Wenn Sie 8 benutzerdefinierte Felder für jeden Benutzer behalten, bedeutet dies, dass wp_usermetausers * 8
Zeilen lang ist. Dies scheint Leistungsprobleme zu verursachen, aber ich bin nicht sicher, ob das das Problem ist oder nicht ...get_users()
) geladen hat, nur um die Paginierung zu berechnen. Nachdem wir den Code korrigiert hatten, umSELECT COUNT(…)
stattdessen eine Abfrage für die Paginierung zu verwenden, stieg die Ladezeit der Seite von 28 Sekunden auf etwa 400 ms. Ich frage mich immer noch, wie die Leistung im Vergleich zu verknüpften Tabellen oder einer einzelnen flachen Tabelle ist. Ich hatte Probleme, Leistungsmetriken im Web zu finden.Ich denke, dies ist eine dieser Situationen, in denen es darauf ankommt. Mehrere Tische zu haben ist sauberer und wahrscheinlich theoretisch besser. Wenn Sie jedoch 6-7 Tabellen verbinden müssen, um Informationen zu einem einzelnen Benutzer zu erhalten, können Sie diesen Ansatz überdenken.
quelle
Ich würde sagen, es hängt davon ab, was die anderen Tabellen wirklich bedeuten. Enthält ein user_details mehr als 1 weitere / users und so weiter? Welcher Normalisierungsgrad für Ihre Anforderungen am besten geeignet ist, hängt von Ihren Anforderungen ab.
Wenn Sie eine Tabelle mit einem guten Index haben, wäre dies wahrscheinlich schneller. Aber auf der anderen Seite wahrscheinlich schwieriger zu pflegen.
Für mich sieht es so aus, als könnten Sie User_Details überspringen, da es sich wahrscheinlich um eine 1: 1-Beziehung zu Users handelt. Aber der Rest sind wahrscheinlich viele Zeilen pro Benutzer?
quelle