sql >> Database teknologi >  >> RDS >> Mysql

Sådan gemmer du data, hvis type kan være numerisk, dato eller streng i mysql

Jeg har ikke lavet en formel undersøgelse, men ud fra min egen erfaring vil jeg gætte på, at mere end 80 % af databasedesignfejlene kommer fra design med ydeevne som den vigtigste (hvis ikke kun) overvejelse.

Hvis et godt design kræver flere tabeller, skal du oprette flere tabeller. Antag ikke automatisk, at joinforbindelser er noget, der skal undgås. De er sjældent den sande årsag til ydeevneproblemer.

Den primære overvejelse, først og fremmest i alle faser af databasedesign, er dataintegritet. "Svaret er måske ikke altid korrekt, men vi kan få det til dig meget hurtigt" er ikke et mål, som enhver butik bør arbejde hen imod. Når dataintegriteten er blevet låst, hvis ydeevne nogensinde bliver et problem , kan det løses. Giv ikke ofre dataintegritet, især for at løse problemer, der måske ikke eksisterer.

Med det i tankerne, se på, hvad du har brug for. Du har observationer, du skal gemme. Disse observationer kan variere i antal og typer af attributter og kan være ting som værdien af ​​en måling, meddelelse om en hændelse og ændring af en status, blandt andet og med mulighed for, at fremtidige observationer tilføjes.

Dette ser ud til at passe ind i et standard "type/undertype"-mønster, hvor "Observation"-indgangen er typen, og hver type eller type observation er undertypen, og foreslår en form for typeindikatorfelt såsom:

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

Men hårdkodning af en liste som denne i en kontrolbegrænsning har et meget lavt vedligeholdelsesniveau. Det bliver en del af skemaet og kan kun ændres med DDL-sætninger. Ikke noget din DBA kommer til at se frem til.

Så har den slags observationer i deres egen opslagstabel:

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ør-feltet kunne lige så godt være int eller smallint. Jeg bruger char her til illustration.)

Udfyld derefter observationstabellen med en PK og de attributter, der ville være fælles for alle 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 virke mærkeligt at lave et unikt indeks over kombinationen af ​​Kind field og PK, som er unik i sig selv, men bær over med mig et øjeblik.

Nu får hver type eller undertype sin egen tabel. Bemærk, at hver type observation får en tabel, ikke 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 første to felter vil være de samme for de andre typer observationer, bortset fra at kontrolbegrænsningen vil tvinge værdien til den passende type. De øvrige felter kan variere i antal, navn og datatype.

Lad os undersøge et eksempel på tuple, der kan eksistere i tabellen Målinger:

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

For at denne tuple kan eksistere i denne tabel, skal der først findes en matchende post i observationstabellen med en ID-værdi på 1001 og en observationstypeværdi på 'M'. Ingen anden post med en ID-værdi på 1001 kan eksistere i hverken Observationstabellen eller Målingstabellen og kan slet ikke eksistere i nogen anden af ​​de "venlige" tabeller (Begivenheder, Status). Dette fungerer på samme måde for alle slags borde.

Jeg vil endvidere anbefale at oprette en visning for hver type observation, som vil give en sammenføjning af hver art med hovedobservationstabellen:

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

Enhver kode, der udelukkende fungerer med målinger, skal kun ramme denne visning i stedet for de underliggende tabeller. Brug af visninger til at skabe en mur af abstraktion mellem applikationskoden og de rå data forbedrer i høj grad databasens vedligeholdelse.

Nu involverer oprettelsen af ​​en anden form for observation, såsom "Fejl", en simpel Insert-sætning til ObservationKinds-tabellen:

F   Fault        A fault or error has been detected.

Selvfølgelig skal du oprette en ny tabel og visning for disse fejlobservationer, men at gøre det vil ikke have nogen indflydelse på eksisterende tabeller, visninger eller applikationskode (undtagen selvfølgelig at skrive den nye kode for at arbejde med de nye observationer) .



  1. Forstå deadlocks i MySQL og PostgreSQL

  2. Skråstreg i MySQL-tabeller, men ved hjælp af PDO og parameteriserede forespørgsler. Hvad så?

  3. Proceduren forventer parameter, som ikke blev leveret

  4. MySQL Job kunne ikke starte