2013-09-04 3 views
5

Ich habe eine Tabelle von Benutzer, wo 1 Spalte Benutzer "Rollen" speichert. Wir können mehrere Rollen bestimmten Benutzer zuweisen.Wie speichert man mehrere Werte in einer einzelnen Spalte, wo weniger Speicher benötigt wird?

Dann möchte ich Rollen-IDs in der Spalte "Rollen" speichern.

Aber wie kann ich mehrere Werte in einer einzigen Spalte speichern, um Speicher auf einfache Weise zu speichern? Beispielsweise ist das Speichern mit einem durch Kommas begrenzten Feld nicht einfach und verwendet Speicher.

Irgendwelche Ideen?

+1

was Speicher nicht speichern gemein zu dir? –

+0

Speicher von MySQL zu speichern bedeutet in der Größe und einfach zu bedienen – harsh4u

+1

Es wird nicht einfacher zu bedienen, und es wird kein Speicher gespeichert. Verwenden Sie einfach mehrere Spalten. –

Antwort

0

Man könnte so etwas wie diese

INSERT INTO table (id, roles) VALUES ('', '2,3,4'); 

Dann tun, um es FIND_IN_SET

+4

Das verbessert die Performance überhaupt nicht, die DB muss immer noch die gesamte Tabelle scannen, um Übereinstimmungen zu finden. – DCoder

+0

op wollte einzelne Spalte/gleiche Tabelle, so ist dies eine gute Antwort IMO. Op könnte besser sein ohne zusätzliche Komplexität von Multi-Tabelle .. wer weiß :) – akostadinov

+2

@akostadinov Dies ist ein klassisches [XY Problem] (http://meta.stackexchange.com/q/66377/226333). Während der Benutzer nach etwas fragt, ist das in diesem Fall definitiv nicht das, was sie wollen. Eine Lösung mit mehreren Tabellen wird in Zukunft sauberer, schneller und viel einfacher zu warten sein. –

10

Wenn ein Benutzer mehrere Rollen verwendet zu finden haben kann, ist es wahrscheinlich besser ist, einen user_role Tisch zu haben, die diese Informationen speichert. Es ist normalisiert und wird viel einfacher abzufragen sein.

Eine Tabelle wie:

user_id | role 
--------+----------------- 
     1 | Admin 
     2 | User 
     2 | Admin 
     3 | User 
     3 | Author 

Erlauben Sie für alle Benutzer mit einer bestimmten Rolle zu fragen, wie SELECT user_id, user.name FROM user_role JOIN user WHERE role='Admin' anstatt Zeichenfolge zu verwenden Parsen Details aus einer Spalte zu erhalten.

Unter anderem wird dies schneller, da Sie die Spalten richtig indizieren können und marginal mehr Platz benötigen als jede Lösung, die mehrere Werte in eine einzelne Spalte bringt - was im Gegensatz zu dem steht, für welches relationale Datenbanken entwickelt wurden.

Der Grund, warum dies nicht gespeichert werden sollte, ist, dass es ineffizient ist, weil DCoder auf dem comment to this answer steht. Um zu überprüfen, ob ein Benutzer eine Rolle hat, muss jede Zeile der Benutzertabelle gescannt werden, und dann muss die Spalte "Rollen" mit dem Zeichenfolgenabgleich gescannt werden - unabhängig davon, wie diese Aktion ausgeführt wird, muss der RMDBS dies tun Führen Sie Zeichenfolgenoperationen aus, um den Inhalt zu analysieren. Dies sind sehr teure Operationen und überhaupt kein gutes Datenbankdesign.

Wenn Sie Notwendigkeit eine einzelne Spalte zu haben, würde ich empfehlen, dass Sie nicht mehr ein technisches Problem, sondern ein Mensch-Management einer. Das Hinzufügen zusätzlicher Tabellen zu einer bestehenden Datenbank, die sich in der Entwicklung befindet, sollte nicht schwierig sein. Wenn dies nicht etwas ist, zu dem Sie berechtigt sind, erklären Sie, warum die zusätzliche Tabelle für die richtige Person benötigt wird - weil munging mehrere Werte in einer einzigen Spalte ist ein schlechter, schlechter Idee.

+0

Ok .. aber muss in einer einzelnen Spalte gespeichert werden, wie ich in meiner Frage beschreiben – harsh4u

+0

@ harsh4u Es gibt keinen technischen Grund, dass dies eine einzige Spalte sein muss, so habe ich einige weitere Details hinzugefügt. –

1

Aus Ihrer Frage, was ich habe,

Angenommen, Sie haben zu Tisch. einer ist "Mahlzeit" Tisch und ein anderer ist "Combo_Meal" -Tabelle. Jetzt denke ich, dass Sie mehrere meal_id in einer combo_meal_id speichern möchten, ohne Koma [,] zu trennen. Und du hast gesagt, dass es deine DB zu mehr Standard macht.

Wenn ich nicht falsch von Ihrer Frage, dann lesen Sie bitte sorgfältig meinen Vorschlag unten. Es kann dir helfen.

Zuerst denke, ist Ihr Konzept richtig. Definitiv wird es dir mehr Standard DB geben.

Dazu müssen Sie eine weitere Tabelle erstellen [Beispieltabelle: combo_meal_relation], um auf diese beiden Tabellendaten zu verweisen. Kann ein sichtbares Beispiel sein wird es löschen.

meal table 

+------+--------+-----------+---------+ 
| id | name | serving | price | 
+------+--------+-----------+---------+ 
| 1 | soup1 | 2 person | 12.50 | 
+------+--------+-----------+---------+ 
| 2 | soup2 | 2 person | 15.50 | 
+------+--------+-----------+---------+ 
| 3 | soup3 | 2 person | 23.00 | 
+------+--------+-----------+---------+ 
| 4 | drink1 | 2 person | 4.50 | 
+------+--------+-----------+---------+ 
| 5 | drink2 | 2 person | 3.50 | 
+------+--------+-----------+---------+ 
| 6 | drink3 | 2 person | 5.50 | 
+------+--------+-----------+---------+ 
| 7 | frui1 | 2 person | 3.00 | 
+------+--------+-----------+---------+ 
| 8 | fruit2 | 2 person | 3.50 | 
+------+--------+-----------+---------+ 
| 9 | fruit3 | 2 person | 4.50 | 
+------+--------+-----------+---------+ 

combo_meal table 

+------+--------------+-----------+ 
| id | combo_name | serving | 
+------+--------------+-----------+ 
| 1 | combo1  | 2 person | 
+------+--------------+-----------+ 
| 2 | combo2  | 2 person | 
+------+--------------+-----------+ 
| 4 | combo3  | 2 person | 
+------+--------------+-----------+ 

combo_meal_relation 

+------+--------------+-----------+ 
| id | combo_meal_id| meal_id | 
+------+--------------+-----------+ 
| 1 |  1  |  1 | 
+------+--------------+-----------+ 
| 2 |  1  |  2 | 
+------+--------------+-----------+ 
| 3 |  1  |  3 | 
+------+--------------+-----------+ 
| 4 |  2  |  4 | 
+------+--------------+-----------+ 
| 5 |  2  |  2 | 
+------+--------------+-----------+ 
| 6 |  2  |  7 | 
+------+--------------+-----------+ 

Wenn Sie in Tabelle suchen, wird es schneller Ergebnis erzeugen.

Suchbegriff:

SELECT m.* 
FROM combo_meal cm 
JOIN meal m 
ON  m.id = cm.meal_id 
WHERE cm.combo_id = 1 

Hoffentlich verstehen Sie :)

2

Sie können auch bitweise Logik mit MySQL verwenden. role_id muss in BASE 2 (0, 1, 2, 4, 8, 16, 32 ...) sein

role_id | label 
--------+----------------- 
     1 | Admin 
     2 | User 
     4 | Author 

user_id | name | role 
--------+----------------- 
     1 | John | 1 
     2 | Steve | 3 
     3 | Jack | 6 

bitweise Logik können Sie alle Benutzerrollen wählen

SELECT * FROM users WHERE role & 1 
-- returns all Admin users 

SELECT * FROM users WHERE role & 5 
-- returns all users who are admin or Author because 5 = 1 + 4 

SELECT * FROM users WHERE role & 6 
-- returns all users who are User or Author because 6 = 2 + 4 
Verwandte Themen