sql >> Database teknologi >  >> RDS >> Sqlserver

Designmønster til brugerdefinerede felter i relationel database

Undgå strengt indtastede data ved at erstatte VALUE med NUMBER_VALUE , DATE_VALUE , STRING_VALUE . Disse tre typer er gode nok det meste af tiden. Du kan tilføje XMLTYPE og andre smarte kolonner senere, hvis de er nødvendige. Og for Oracle skal du bruge VARCHAR2 i stedet for CHAR for at spare plads.

Forsøg altid at gemme værdier som den korrekte type. Indbyggede datatyper er hurtigere, mindre, nemmere at bruge og sikrere.

Oracle har et generisk datatypesystem (ANYTYPE, ANYDATA og ANYDATASET), men disse typer er svære at bruge og bør undgås i de fleste tilfælde.

Arkitekter tror ofte, at det bliver lettere at bruge et enkelt felt til alle data. Det gør det nemmere at generere smukke billeder af datamodellen, men det gør alt andet vanskeligere. Overvej disse problemer:

  1. Du kan ikke gøre noget interessant med data uden at kende typen. Selv for at vise data er det nyttigt at kende typen til at begrunde teksten. I 99,9 % af alluse tilfælde vil det være tydeligt for brugeren, hvilken af ​​de 3 kolonner der er relevant.
  2. Det er smertefuldt at udvikle typesikre forespørgsler mod strengt indtastede data. Lad os f.eks. sige, at du vil finde "fødselsdato" for personer født i dette årtusinde:

    select *
    from ReportFieldValue
    join ReportField
        on ReportFieldValue.ReportFieldid = ReportField.id
    where ReportField.name = 'Date of Birth'
        and to_date(value, 'YYYY-MM-DD') > date '2000-01-01'
    

    Kan du få øje på fejlen? Ovenstående forespørgsel er farlig, selvom du har gemt datoen i det korrekte format, og meget få udviklere ved, hvordan de rettes korrekt. Oracle har optimeringer, der gør det svært at fremtvinge en bestemt rækkefølge af operationer. Du skal bruge en forespørgsel som denne for at være sikker:

    select *
    from
    (
        select ReportFieldValue.*, ReportField.*
            --ROWNUM ensures type safe by preventing view merging and predicate pushing.
            ,rownum
        from ReportFieldValue
        join ReportField
            on ReportFieldValue.ReportFieldid = ReportField.id
        where ReportField.name = 'Date of Birth'
    )
    where to_date(value, 'YYYY-MM-DD') > date '2000-01-01';
    

    Du ønsker ikke at skulle bede alle udviklere om at skrive deres forespørgsler på den måde.



  1. Hvordan kontrollerer man, om markøren returnerer nogen poster i oracle?

  2. Indstilling af MySQL root-brugeradgangskoden på OS X

  3. syntaks for enkelt række MERGE / upsert i SQL Server

  4. Sådan opdeles en kommasepareret værdi i kolonner