2012-12-06 11 views
9

Ich habe eine 4 Arten von Benutzern und hat jeweils spezifische Daten, sondern sie auch commun Daten, wie username, password ..Relationale Datenbank-Design mehrerer Benutzertypen

Mein erster Gedanke ist eine Haupt users Tabelle zu erstellen, geben Sie user_type Spalte. Dann bei der Abfrage von Benutzerdaten kann ich zuerst ihre user_type auswählen und dann je nach output eine andere Abfrage ausführen, um "user type" spezifische Daten zu erfassen. Ich mag das nicht, da ich wünschte, ich könnte alle benutzerbezogenen Daten mit einer Abfrage erfassen und idealerweise Fremdschlüssel verwenden.

zweite Idee ist nicht eine user_type Spalte in der Tabelle users haben und stattdessen Fremdschlüssel verwenden, die von einer bestimmten Benutzer-Typ-Tabelle mit einer Zeilentabelle der Haupt users verweisen. Ich mag das ein bisschen besser, obwohl ich denke, dass ich N Abfragen ausführen muss, wobei N die Anzahl der Benutzertypen jedes Mal ist, wenn ich Benutzerdaten greifen muss.

Gibt es noch andere Optionen? Was wäre die gute Praxis in einem solchen Fall?

Vielen Dank

+0

Wenn ich Sie zu verstehen, müssen Sie nur eine JOIN-Klausel in der SQL-Anweisung verwenden. So etwas wie SELECT * FROM Benutzer U LEFT JOIN user_details D ON U.id = D.user_id WHERE U.id = ' –

+0

kann ein Benutzer sein, mehr als eine Art zu einer Zeit? –

+0

@Catcall nicht in diesem ein Benutzerszenario nur eine Art haben kann, obwohl ich neugierig bin, was die Möglichkeiten sind in jedem Fall – silkAdmin

Antwort

14

Ihr Fall sieht aus wie eine Instanz der Klasse/Unterklasse.

Es gibt zwei klassische Möglichkeiten, SQL-Tabellen für Unterklassen zu entwickeln. Jeder hat Vor- und Nachteile.

Ein Weg heißt "Single Table Inheritance". In diesem Design gibt es nur eine Tabelle für alle Arten von Benutzern. Wenn eine bestimmte Spalte nicht zu einer bestimmten Zeile gehört, bleibt der Schnittpunkt NULL. Eine Spalte kann hinzugefügt werden, um den Benutzertyp anzugeben.

Ein anderer Weg heißt "Class Table Inheritance". Das ist ähnlich wie die Antwort, die Nanego gab, mit ein paar kleinen Änderungen. Es gibt eine Tabelle für Benutzer mit allen gemeinsamen Daten und einem ID-Feld. Für jede Unterklasse gibt es eine Tabelle mit Daten, die zu dieser Unterklasse gehören. Das ID-Feld wird oft als Kopie des ID-Feldes in der entsprechenden Zeile in der Benutzertabelle eingerichtet.Auf diese Weise kann der Unterklassenschlüssel doppelte Aufgaben erfüllen und sowohl als Primärschlüssel als auch als Fremdschlüssel fungieren, der auf die Benutzertabelle verweist. Diese letzte Technik wird als "Gemeinsamer Primärschlüssel" bezeichnet. Es erfordert ein wenig Programmierung beim Einfügen, aber es ist es wert. Es erzwingt die Eins-zu-Eins-Beziehung und beschleunigt die notwendigen Joins.

Sie können alle drei dieser Entwürfe als Tags in SO oder als Artikel aus, die im Internet nachschlagen.

+2

Danke, dass du diese Begriffe fallen gelassen hast, sie gegoogelt hast und schon viel gelernt hast – silkAdmin

0

Mein Weg, es zu tun gewesen wäre, mit den gemeinsamen Bereichen, und eine Tabelle für jede Art von Benutzer mit einem Fremdschlüssel „person_id“ eine Tabelle „Person“ zu erstellen.

In Ihrer Anfrage müssen Sie nur zwei Tabellen mit dem foreign_key verbinden, um alle Daten für einen Benutzertyp zu erhalten.

Wie viele Benutzer haben Sie?

+0

jetzt 4, aber ich möchte, dass flexibel halten .. Die zweite Lösung, die ich erwähnt ist eigentlich, was Sie vorschlagen . – silkAdmin

2

Obwohl der Plattenspeicher effizienter genutzt wird, besteht das Problem bei der Aufsplittung in separate Tabellen darin, dass Sie bedingte Joins benötigen - die Verbindung mit der benutzerspezifischen Tabelle basierend auf dem user_type. Es ist ein Schmerz, als SQL zu programmieren, und wer kümmert sich heutzutage um Speicherplatz?

Die bessere Option ist, eine Benutzer-Tabelle mit genügend Spalten zu haben, um Informationen über beliebigen Benutzertyp zu speichern, wohl wissend, dass einige Spalten für einige Benutzertypen nicht verwendet werden. Die "Ineffizienz", unbenutzte Spalten zu haben, wird mehr als ausgeglichen in der Ausführungsgeschwindigkeit und der Einfachheit der Abfrage.

Es ist auch leicht erweiterbar, falls Sie einen anderen Benutzertyp bekommen - es ist viel einfacher, Spalten hinzuzufügen als Tabellen hinzuzufügen, und wenn Sie mehr Benutzertypen hinzufügen, würde die Anforderung für neue Spalten abnehmen (dort nur aren ' t, dass viele verschiedene Dinge über einen Benutzer müssen Sie speichern)

+2

Ich hasse es, dies zu verbessern, da es sich einfach schlampig anfühlt, aber es ist wirklich die Wahrheit. –

+0

Ich bin damit einverstanden tun, würde den Code viel sauberer machen schließt sich zu vermeiden, aber ich würde gerne Tabellen haben, die die PHP-Klassen entsprechen, Es wäre nur eleganter fühlen – silkAdmin

+1

i ist auch ein Nachteil dieses sehen, dass die Tabelle lose Integrität als i msgstr "" "" "" "" "" "" "" "" "" "" "" "" "muss alle Felder, die NULL - Werte zur Folge haben können, zu Fehlern im Backend - Code führen – silkAdmin