sql >> Database >  >> RDS >> Mysql

Mysql:een reeks gegevens opslaan in een enkele kolom

Ten eerste, dat wil je echt niet doen. Een kolom in een RDBMS is bedoeld als atomair, in die zin dat het één en slechts één stuk informatie bevat. Als u meer dan één stuk gegevens in een kolom probeert op te slaan, is dit een schending van de eerste normaalvorm.

Als u het absoluut moet doen, moet u de gegevens converteren naar een formulier dat kan worden opgeslagen als een enkel gegevensitem, meestal een tekenreeks. Je zou PHP's serialize()-mechanisme, XML-parsing (als de gegevens toevallig een documentstructuur zijn), json_encode(), enz. kunnen gebruiken.

Maar hoe bevraag je dergelijke gegevens effectief? Het antwoord is dat je het niet kunt.

En als iemand anders je project op een later tijdstip overneemt, ga je ze echt irriteren, omdat geserialiseerde gegevens in een database verschrikkelijk zijn om mee te werken. Ik weet het omdat ik zulke projecten heb geërfd.

Had ik al gezegd dat je dat echt niet wilt? U moet uw ontwerp heroverwegen, zodat het gemakkelijker kan worden opgeslagen in termen van atomaire rijen. Gebruik bijvoorbeeld een andere tabel voor deze gegevens en gebruik refererende sleutels om deze te relateren aan het stamrecord. Ze worden niet voor niets relationele databases genoemd.

UPDATE :Mij is gevraagd naar de vereisten voor gegevensopslag, bijvoorbeeld of een enkele rij goedkoper zou zijn in termen van opslag. Het antwoord is, in typische gevallen is dat niet het geval, en in gevallen waar het antwoord ja is, is de prijs die u ervoor betaalt het niet waard om te betalen.

Als u een afhankelijke tabel met 2 kolommen gebruikt (1 kolom voor de refererende sleutel van het record waartoe het monster behoort, één voor een enkel monster), dan vereist elke kolom in het slechtste geval 16 bytes (8 bytes voor een longint-sleutelkolom, 8 bytes voor een getal met dubbele precisie met drijvende komma). Voor 100 records is dat 1600 bytes (db overhead negerend).

Voor een geserialiseerde string sla je in het beste geval 1 byte per karakter op in de string. Je kunt niet weten hoe lang de string zal zijn, maar als we uitgaan van 100 samples met alle opgeslagen gegevens door een verzonnen toeval die allemaal tussen 10000,00 en 99999,99 vallen, waarbij er altijd maar 2 cijfers achter de komma staan, dan heb je' opnieuw kijken naar 8 bytes per monster. In dit geval heb je alleen de overhead van de externe sleutels bespaard, dus de benodigde hoeveelheid opslagruimte komt uit op 800 bytes.

Dat is natuurlijk gebaseerd op veel aannames, zoals de karaktercodering altijd 1 byte per karakter, de strings waaruit de samples bestaan ​​nooit langer dan 8 karakters, enz.

Maar er is natuurlijk ook de overhead van het mechanisme dat u gebruikt om de gegevens te serialiseren. De absoluut eenvoudigste methode, CSV, betekent het toevoegen van een komma tussen elk monster. Dat voegt n-1 bytes toe aan de opgeslagen string. Dus het bovenstaande voorbeeld zou nu 899 bytes zijn, en dat is met het eenvoudigste coderingsschema. JSON, XML en zelfs PHP-serialisaties voegen allemaal meer overhead-tekens toe dan dit, en je zult al snel strings hebben die veel langer zijn dan 1600 bytes. En dit alles is met de aanname van 1 byte karaktercodering.

Als u de voorbeelden moet indexeren, zullen de gegevensvereisten nog onevenredig toenemen ten opzichte van tekenreeksen, omdat een tekenreeksindex veel duurder is in termen van opslag dan een drijvende-kommakolomindex zou zijn.

En natuurlijk, als uw monsters meer cijfers gaan toevoegen, gaat de gegevensopslag verder omhoog. 39281.3392810 kan niet worden opgeslagen in 8 bytes als een string, zelfs in het beste geval.

En als de gegevens geserialiseerd zijn, kan de database niet manipuleren. Je kunt de monsters niet sorteren, er geen wiskundige bewerkingen op uitvoeren, de database weet niet eens dat het getallen zijn!

Om eerlijk te zijn, opslag is tegenwoordig belachelijk goedkoop, je kunt meerdere TB-schijven kopen voor kleine bedragen. Is opslag echt zo belangrijk? Tenzij je honderden miljoenen records hebt, betwijfel ik of dat zo is.

Misschien wil je een boek lezen met de naam SQL Antipatterns



  1. Hoe kan ik de stringwaarde van het datatype van Oracle bepalen aan de hand van de code?

  2. Hoe het root-wachtwoord in MySQL 8.0.11 opnieuw in te stellen?

  3. Efficiënte methode om groepstitel eenmaal weer te geven — PHP/MySQL/jQuery

  4. SQL Server cumulatieve som per groep