För allt som alltid är inställd för varje användare bör du ha en tendens att behålla det i Users
tabell, enligt vanlig normalisering. När det gäller valfri konfiguration brukar jag gilla följande tabellstruktur:
TABLE Users:
id INT AI
name VARCHAR
...
TABLE User_Settings
user_id INT PK,FK
name VARCHAR PK
type BOOL
value_int INT NULL
value_str VARCHAR NULL
Där User_Settings.type
anger om heltals- eller strängfältet ska refereras.
dvs:
INSERT INTO Users (id, name) VALUES (1, 'Sammitch');
INSERT INTO User_Settings (user_id, name, type, value_int) VALUES (1, 'level', 1, 75);
INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'en');
Och för INSERT/UPDATE-frågan:
INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'fr')
ON DUPLICATE KEY UPDATE value_str='fr';
Dessutom, som de flesta andra säger, är det inte en särskilt bra idé att serialisera och lagra inställningarna eftersom:
- Du kan inte hämta ett enda värde med en fråga, du måste hämta hela den serialiserade strängen, avserialisera den och kassera onödiga data.
- Det är lätt att korruptera och svårt att återhämta sig från.
- Det är jobbigt att skriva en obearbetad fråga för, dvs. att globalt fixa en viss inställning.
- Du lagrar vad som i huvudsak är tabelldata i ett enda tabellfält.
Sept 2016 Retrospektiv redigering:
Under den mellanliggande tiden har jag haft några argument med folk om hur man bäst lagrar valfria inställningar, såväl som den allmänna tabellstrukturen definierad ovan.
Även om den tabellstrukturen inte är direkt dålig , det är inte precis bra antingen. Det är att försöka göra det bästa av en dålig situation. Serialisering av valfria inställningar kan fungera så länge du kan ta emot dessa inställningar:
- Alla laddas på en gång, inget plockning eller val.
- Är inte indexerbar, sökbar eller lätt att ändra en masse .
Då kan du överväga att lägga till ett fält som optional_settings
i Users
tabell som innehåller en serialiserad [t.ex.:JSON] form av inställningarna. Du avväger visserligen ovanstående, men det är ett mer okomplicerat tillvägagångssätt och du kan lagra mer komplexa inställningar.
Dessutom, om du använder en LOB-typ som TEXT
för lagring lagras data inte nödvändigtvis "i raden" åtminstone i MySQL.
Hur som helst, det är upp till dig för att avgöra vad din applikations krav och begränsningar är, och göra det bästa valet baserat på den informationen.