Ich frage mich, wie eine Benutzereinstellung am besten dargestellt werden kann, die entweder einen Wert aus einer Gruppe (wie "Hoch", "Mittel" oder "Niedrig") oder eine Liste von IDs aus einer anderen (oder derselben!) Tabelle (Viele zu Viele Beziehung).
Ich würde gerne wissen, was häufig verwendet wird und welche Nachteile / Vorteile jede Lösung hat (in Bezug auf Leistung, Integrität und Nachhaltigkeit).
Bis zu einem gewissen Grad hängt jede Lösung in hohem Maße davon ab, was Sie genau tun und welches RDBMS Sie verwenden. Im Allgemeinen ist es jedoch eine schlechte Idee, ein Textfeld zum Speichern einer durch Kommas getrennten Liste von Ganzzahlen zu verwenden.
Die Ausgangspunktlösung ist immer eine ID-basierte Referenz. Dies ist ein guter Anfang, da es den richtigen relationalen Regeln folgt und es Ihnen ermöglicht, Dinge wie mehrere Werte zu handhaben, indem Sie diese in neue Beziehungen aufteilen. In der Tat würde ich sagen, es ist immer am besten, hier zu beginnen.
Alternativen funktionieren jedoch in einigen Fällen und mit einigen RDBMS gut. ENUM-Felder (oder alternativ Textdomänen mit einem Häkchen, um sie innerhalb einiger Werte zu halten) sind hilfreich, wenn Sie niemals Optionen löschen müssen. Wenn Sie dies tun, müssen Sie festlegen, was Sie dagegen tun möchten, bevor Sie sie löschen. Zweitens können Array-Typen auch in bestimmten Fällen nützlich sein (und sie brechen nicht unbedingt 1NF, wenn das Array als Ganzes ein atomarer Wert einer Domäne ist, beispielsweise wenn wir eine IPv4-Adresse als Array von 4 8-Bit-Ganzzahlen darstellen ). Array-basierte Ansätze hängen stark von Ihrer Arbeit und der Unterstützung auf DB-Ebene ab. Bei PostgreSQL würde ich jedoch ein Array auswählen, bei dem es auf Kardinalität ankommt (dh ein Array ist ein Tupel anstelle einer Menge) und bei dem die Semantik vollständig in sich geschlossen ist .
Um es auf den Punkt zu bringen: Es gibt keine gemeinsame Lösung, sie hängt stark von den eigenen Bedürfnissen ab. Die zweite Lösung, die ich angesprochen habe, sieht jedoch besser und skalierbarer aus als die erstere. Verstehe ich gut
Antoine Pinsard
2
Sie haben uns nicht viel gegeben, um hier zu arbeiten. Worum geht es in der "anderen Tabelle"? Nehmen wir an, es ist vorerst eine benutzerdefinierte Priorität.
Um einen Fremdschlüssel für mehrere Typen festlegen zu können, müssen Sie die Tabellenvererbung verwenden . Es wird eine Mastertabelle geben, und beide Typen "erben" von ihr unter Verwendung desselben Primärschlüsselfelds.
Es gibt einige Arten der Tabellenvererbung. Single Table Inheritance verwendet Nullen, ist jedoch weitaus einfacher. Die Vererbung in der Klassentabelle ist normalisiert, aber eher schmerzhaft.
PRIORITY
id
type {generic, custom}
PRIORITY_GENERIC
id pk fk PRIORITY
name
PRIORITY_CUSTOM
id pk fk PRIORITY
name
created_at timestamp
USER
id pk
name
priority_id fk PRIORITY
insertinto priority values(1,'Generic'),(2,'Generic'),(3,'Generic'),(4,'Custom');insertinto priority_generic values(1,'Low'),(2,'Medium'),(3,'High');insertinto priority_custom values(4,'Crazy Super High',current_timestamp);insertintouservalues(1,'neil',3);insertintouservalues(2,'chris',4);
Es tut mir leid, wenn ich mich nicht klar ausgedrückt habe, aber ich denke nicht, dass die in der anderen Tabelle gespeicherten Daten von Bedeutung sind. Dies können Benutzer, Produkte oder Bananen sein. Wichtig ist, dass der benutzerdefinierte Wert eine LISTE der Zeilen aus der anderen Tabelle ist, wenn ich keinen "generischen" oder vordefinierten Wert im Feld habe. Also im Grunde eine durch Kommas getrennte Liste von IDs. Ich werde meine Frage umschreiben, sie ist möglicherweise nicht gut ausgedrückt.
Antoine Pinsard
OK. Mein Schema sollte immer noch für Sie funktionieren. Sie möchten keine CSV-Liste in einer Spalte speichern.
Neil McGuigan
Eigentlich kann ich nicht sehen, wie die Tabellenvererbung das Problem löst. Ich habe meine Frage bearbeitet. Vielleicht wird es Missverständnisse beseitigen?
Antoine Pinsard
Kann diese Benutzereinstellung also auf eine beliebige Tabelle in Ihrer Datenbank verweisen?
Neil McGuigan
Nein, es zeigt auf eine bestimmte bekannte Tabelle. Meine Frage ist ziemlich allgemein, es ist nicht für ein bestimmtes Projekt. Wenn es für Sie jedoch klarer ist, nehmen Sie einfach an, dass es auf die Benutzertabelle verweist (was sinnvoll ist, wenn der Benutzer beispielsweise "Jedem", "Freunden", "Niemand" oder einer bestimmten Gruppe von Benutzern Zugriff auf seine Profilseite gewähren möchte ).
Antoine Pinsard
-1
Die "XOR-gepaarte Spalten" -Lösung
Diese Lösung besteht aus zwei Spalten, die zusammenarbeiten:
Ein nullbares Zeichen, das die Spalte "ENUM" variiert und den Wert "Hoch", "Mittel" oder "Niedrig" haben kann.
Eine virtuelle Spalte, die tatsächlich durch eine dritte Tabelle dargestellt wird, die die Beziehung zwischen der Benutzertabelle und der Fremdtabelle herstellt. Genau wie bei einer klassischen Viele-zu-Viele-Beziehung.
Wenn ersteres "Hoch", "Mittel" oder "Niedrig" wert ist, würde die Anwendung nur diesen Wert annehmen und letzteres würde einfach ignoriert. Wenn es dagegen NULL ist, wird die M2M-Beziehung verwendet.
Sie haben uns nicht viel gegeben, um hier zu arbeiten. Worum geht es in der "anderen Tabelle"? Nehmen wir an, es ist vorerst eine benutzerdefinierte Priorität.
Um einen Fremdschlüssel für mehrere Typen festlegen zu können, müssen Sie die Tabellenvererbung verwenden . Es wird eine Mastertabelle geben, und beide Typen "erben" von ihr unter Verwendung desselben Primärschlüsselfelds.
Es gibt einige Arten der Tabellenvererbung. Single Table Inheritance verwendet Nullen, ist jedoch weitaus einfacher. Die Vererbung in der Klassentabelle ist normalisiert, aber eher schmerzhaft.
quelle
Die "XOR-gepaarte Spalten" -Lösung
Diese Lösung besteht aus zwei Spalten, die zusammenarbeiten:
Wenn ersteres "Hoch", "Mittel" oder "Niedrig" wert ist, würde die Anwendung nur diesen Wert annehmen und letzteres würde einfach ignoriert. Wenn es dagegen NULL ist, wird die M2M-Beziehung verwendet.
quelle