sql >> Database >  >> RDS >> Mysql

Hoe gegevens op te slaan waarvan het type numeriek, datum of tekenreeks kan zijn in mysql

Ik heb geen formeel onderzoek gedaan, maar uit eigen ervaring vermoed ik dat meer dan 80% van de ontwerpfouten in databases worden gegenereerd door ontwerpen met prestaties als de belangrijkste (zo niet alleen) overweging.

Als een goed ontwerp meerdere tabellen vereist, maak dan meerdere tabellen. Ga er niet automatisch van uit dat joins vermeden moeten worden. Ze zijn zelden de echte oorzaak van prestatieproblemen.

De belangrijkste overweging, in de eerste plaats in alle stadia van databaseontwerp, is gegevensintegriteit. "Het antwoord is misschien niet altijd juist, maar we kunnen het heel snel bij je krijgen" is geen doel waar elke winkel naar toe zou moeten werken. Zodra de gegevensintegriteit is vergrendeld, als prestatie ooit een probleem wordt , kan worden aangepakt. Geef geen gegevensintegriteit op, vooral niet om problemen op te lossen die er misschien niet zijn.

Kijk met dat in gedachten naar wat je nodig hebt. Je hebt waarnemingen die je moet opslaan. Deze waarnemingen kunnen variëren in het aantal en type attributen en kunnen zaken zijn als de waarde van een meting, de melding van een gebeurtenis en de verandering van een status, onder andere en met de mogelijkheid dat toekomstige waarnemingen worden toegevoegd.

Dit lijkt te passen in een standaard "type/subtype"-patroon, waarbij het item "Observatie" het type is en elk type of soort waarneming het subtype, en suggereert een vorm van type-indicatorveld zoals:

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

Maar het hardcoderen van een lijst als deze in een controlebeperking heeft een zeer laag onderhoudbaarheidsniveau. Het wordt onderdeel van het schema en kan alleen worden gewijzigd met DDL-instructies. Niet iets waar uw DBA naar uitkijkt.

Dus hebben de soorten waarnemingen in hun eigen opzoektabel:

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.

(Het veld char kan net zo goed int of smallint zijn. Ik gebruik hier char ter illustratie.)

Vul vervolgens de tabel Observaties in met een PK en de kenmerken die voor alle waarnemingen gelden.

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 )
);

Het lijkt misschien vreemd om een ​​unieke index te maken op de combinatie van Kind-veld en de PK, die op zichzelf uniek is, maar heb even geduld.

Nu krijgt elke soort of subtype zijn eigen tabel. Merk op dat elk soort observatie een tabel krijgt, niet het gegevenstype.

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 eerste twee velden zijn hetzelfde voor de andere soorten waarnemingen, behalve dat de controlebeperking de waarde naar de juiste soort dwingt. De overige velden kunnen verschillen in aantal, naam en gegevenstype.

Laten we eens kijken naar een voorbeeld van een tuple die in de tabel Metingen kan voorkomen:

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

Om deze tuple in deze tabel te laten bestaan, moet er eerst een overeenkomend item in de tabel Observaties bestaan ​​met een ID-waarde van 1001 en een soort observatiewaarde van 'M'. Geen enkel ander item met een ID-waarde van 1001 kan voorkomen in de Observations-tabel of de Measurements-tabel en kan helemaal niet voorkomen in een van de andere "soort" tabellen (Gebeurtenissen, Status). Dit werkt op dezelfde manier voor alle soort tabellen.

Ik zou verder aanbevelen om voor elk type observatie een weergave te maken die een verbinding van elke soort met de hoofdobservatietabel zal opleveren:

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

Elke code die alleen met metingen werkt, hoeft alleen deze weergave te raken in plaats van de onderliggende tabellen. Door weergaven te gebruiken om een ​​muur van abstractie te creëren tussen de applicatiecode en de onbewerkte gegevens, wordt de onderhoudbaarheid van de database aanzienlijk verbeterd.

Het creëren van een ander soort observatie, zoals "Error", houdt een eenvoudige Insert-instructie in bij de ObservationKinds-tabel:

F   Fault        A fault or error has been detected.

Natuurlijk moet u een nieuwe tabel en weergave maken voor deze foutwaarnemingen, maar dit heeft geen invloed op bestaande tabellen, weergaven of applicatiecode (behalve natuurlijk om de nieuwe code te schrijven om met de nieuwe waarnemingen te werken) .



  1. MySQL 8 instellen vanuit Binary Tarball

  2. PostgreSQL-streamingreplicatie versus logische replicatie

  3. bijwerken en comprimeren van sqlite-database in Android

  4. MySQL-gegevens naar JSON via PHP