sql >> Databasteknik >  >> RDS >> Mysql

Hur man lagrar en data vars typ kan vara numerisk, datum eller sträng i mysql

Jag har inte gjort en formell studie, men av min egen erfarenhet skulle jag gissa att mer än 80 % av databasdesignbristerna genereras från design med prestanda som det viktigaste (om inte bara) övervägandet.

Om en bra design kräver flera tabeller, skapa flera tabeller. Anta inte automatiskt att anslutningar är något som bör undvikas. De är sällan den verkliga orsaken till prestandaproblem.

Det primära övervägandet, först och främst i alla stadier av databasdesign, är dataintegritet. "Svaret kanske inte alltid är korrekt, men vi kan få det till dig väldigt snabbt" är inte ett mål någon butik bör arbeta mot. När dataintegriteten har låsts, om prestanda någonsin blir ett problem , det kan åtgärdas. Offra inte dataintegritet, särskilt för att lösa problem som kanske inte finns.

Med det i åtanke, titta på vad du behöver. Du har observationer som du behöver lagra. Dessa observationer kan variera i antal och typer av attribut och kan vara saker som värdet av en mätning, meddelande om en händelse och förändring av en status, bland annat och med möjligheten att framtida observationer läggs till.

Detta verkar passa in i ett standardmönster för "typ/undertyp", där posten "Observation" är typen och varje typ eller typ av observation är undertypen, och föreslår någon form av typindikatorfält som:

create table Observations(
   ...,
   ObservationKind  char( 1 ) check( ObservationKind in( 'M', 'E', 'S' )),
   ...
);

Men hårdkodning av en lista som denna i en kontrollbegränsning har en mycket låg underhållsnivå. Det blir en del av schemat och kan endast ändras med DDL-satser. Inget din DBA kommer att se fram emot.

Så har de typer av observationer i sin egen uppslagstabell:

ID  Name         Meaning
==  ===========  =======
M   Measurement  The value of some system metric (CPU_Usage).
E   Event        An event has been detected.
S   Status       A change in a status has been detected.

(Rädefältet kan lika gärna vara int eller smallint. Jag använder röd här för att illustrera.)

Fyll sedan i observationstabellen med en PK och de attribut som skulle vara gemensamma för alla observationer.

create table Observations(
   ID               int identity primary key,
   ObservationKind  char( 1 ) not null,
   DateEntered      date not null,
   ...,
   constraint FK_ObservationKind foreign key( ObservationKind )
      references ObservationKinds( ID ),
   constraint UQ_ObservationIDKind( ID, ObservationKind )
);

Det kan tyckas konstigt att skapa ett unikt index över kombinationen av Kind field och PK, som är unikt i sig, men håll ut med mig ett ögonblick.

Nu får varje typ eller undertyp sin egen tabell. Observera att varje typ av observation får en tabell, inte datatypen.

create table Measurements(
    ID                   int not null,
    ObservationKind      char( 1 ) check( ObservationKind = 'M' ),
    Name                 varchar( 32 ) not null, -- Such as "CPU Usage"
    Value                double not null, -- such as 55.00
    ...,  -- other attributes of Measurement observations
    constraint PK_Measurements primary key( ID, ObservationKind ),
    constraint FK_Measurements_Observations foreign key( ID, ObservationKind )
        references Observations( ID, ObservationKind )
);

De två första fälten kommer att vara desamma för de andra typerna av observationer, förutom att kontrollbegränsningen tvingar värdet till lämplig typ. De andra fälten kan skilja sig åt i antal, namn och datatyp.

Låt oss undersöka ett exempel som kan finnas i tabellen Mått:

ID    ObservationKind  Name       Value  ...
====  ===============  =========  =====
1001  M                CPU Usage  55.0   ...

För att denna tuppel ska finnas i den här tabellen måste det först finnas en matchande post i observationstabellen med ett ID-värde på 1001 och ett observationstypvärde på 'M'. Ingen annan post med ett ID-värde på 1001 kan finnas i varken observationstabellen eller tabellen Mätningar och kan inte existera alls i någon annan av de "snälla" tabellerna (händelser, status). Detta fungerar på samma sätt för alla snälla bord.

Jag skulle vidare rekommendera att skapa en vy för varje typ av observation som ger en koppling av varje typ till huvudobservationstabellen:

create view MeasurementObservations as
    select ...
    from   Observations o
    join   Measurements m
        on m.ID = o.ID;

Varje kod som enbart fungerar med mätningar skulle behöva bara träffa den här vyn istället för de underliggande tabellerna. Att använda vyer för att skapa en vägg av abstraktion mellan applikationskoden och rådata förbättrar avsevärt databasens underhållbarhet.

Nu innebär skapandet av en annan typ av observation, såsom "Error", en enkel Insert-sats i tabellen ObservationKinds:

F   Fault        A fault or error has been detected.

Naturligtvis måste du skapa en ny tabell och vy för dessa felobservationer, men att göra det kommer inte att påverka befintliga tabeller, vyer eller applikationskod (förutom, naturligtvis, att skriva den nya koden för att fungera med de nya observationerna) .



  1. Välja en processor för SQL Server 2012

  2. Är det möjligt att göra en ROLLBACK i en MySQL-utlösare?

  3. 2 sätt att returnera rader som endast innehåller alfanumeriska tecken i PostgreSQL

  4. IDLE timeout-parameter i Oracle