sql >> Databasteknik >  >> RDS >> Mysql

Mysql:Lagra array av data i en enda kolumn

För det första vill du verkligen inte göra det. En kolumn i en RDBMS är avsedd att vara atomär, eftersom den innehåller en och endast en del av information. Att försöka lagra mer än en bit data i en kolumn är ett brott mot den första normala formen.

Om du absolut måste göra det, måste du konvertera data till ett formulär som kan lagras som en enda datapost, vanligtvis en sträng. Du kan använda PHPs serialize()-mekanism, XML-tolkning (om data råkar vara ett dokumentträd), json_encode(), etc.

Men hur efterfrågar man sådan data effektivt? Svaret är att du inte kan.

Dessutom, om någon annan tar över ditt projekt vid ett senare tillfälle kommer du verkligen att irritera dem, eftersom serialiserade data i en databas är hemska att arbeta med. Jag vet eftersom jag har ärvt sådana projekt.

Nämnde jag att du verkligen inte vill göra det? Du måste tänka om din design så att den lättare kan lagras i termer av atomrader. Använd en annan tabell för dessa data, till exempel, och använd främmande nycklar för att relatera den till masterposten. De kallas relationsdatabaser av en anledning.

UPPDATERA :Jag har blivit tillfrågad om krav på datalagring, som om en enskild rad skulle vara billigare när det gäller lagring. Svaret är, i typiska fall är det inte det, och i de fall där svaret är ja är priset du betalar för det inte värt att betala.

Om du använder en tabell med 2 kolumner (1 kolumn för den främmande nyckeln för posten som provet tillhör, en för ett enda sampel) kommer varje kolumn att kräva i värsta fall 16 byte (8 byte för en longint-nyckelkolumn, 8 byte för ett flyttaltal med dubbel precision). För 100 poster är det 1600 byte (ignorerar db overhead).

För en serialiserad sträng lagrar du i bästa fall 1 byte per tecken i strängen. Du kan inte veta hur lång strängen kommer att vara, men om vi antar att 100 sampel med alla lagrade data av någon konstruerad slump alla faller mellan 10000,00 och 99999,99 och att det bara alltid finns två siffror efter decimalkomma, då tittar på 8 byte per prov. I det här fallet är allt du har sparat kostnaden för de främmande nycklarna, så mängden lagring som krävs kommer ut på 800 byte.

Det är naturligtvis baserat på många antaganden, som att teckenkodningen alltid är 1 byte per tecken, att strängarna som utgör samplen aldrig är längre än 8 tecken, etc.

Men det finns förstås också omkostnader för vilken mekanism du än använder för att serialisera data. Den absolut enklaste metoden, CSV, innebär att man lägger till ett kommatecken mellan varje prov. Det lägger till n-1 byte till den lagrade strängen. Så exemplet ovan skulle nu vara 899 byte, och det är med det enklaste kodningsschemat. JSON, XML, även PHP-serialiseringar lägger alla till fler overheadtecken än så här, och du kommer snart att ha strängar som är mycket längre än 1600 byte. Och allt detta är med antagandet om 1 byte teckenkodning.

Om du behöver indexera proverna kommer datakraven att växa ännu mer oproportionerligt mot strängar, eftersom ett strängindex är mycket dyrare när det gäller lagring än ett flyttalskolumnindex skulle vara.

Och naturligtvis om dina prover börjar lägga till fler siffror, går datalagringen upp ytterligare. 39281.3392810 kommer inte att kunna lagras i 8 byte som en sträng, inte ens i bästa fall.

Och om data serialiseras kan databasen inte manipulera. Du kan inte sortera proverna, göra någon form av matematisk operation på dem, databasen vet inte ens att de är siffror!

För att vara ärlig är dock lagring löjligt billig nuförtiden, du kan köpa flera TB-enheter för små summor. Är lagring verkligen så kritisk? Om du inte har hundratals miljoner poster så tvivlar jag på att det är det.

Du kanske vill kolla in en bok som heter SQL Antipatterns



  1. Sammanfoga bord på flera servrar

  2. Frågar DAU/MAU över tid (dagligen)

  3. Fel vid lagring av @Lob med hibernate java mysql

  4. Unicode-normalisering i Postgres