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

Modello di progettazione per campi personalizzati nel database relazionale

Evita i dati di tipo stringa sostituendo VALUE con NUMBER_VALUE , DATE_VALUE , STRING_VALUE . Questi tre tipi sono abbastanza buoni per la maggior parte del tempo. Puoi aggiungere XMLTYPE e altre colonne fantasiose in seguito, se necessario. E per Oracle, usa VARCHAR2 invece di CHAR per risparmiare spazio.

Cerca sempre di memorizzare i valori come il tipo corretto. I tipi di dati nativi sono più veloci, più piccoli, più facili da usare e più sicuri.

Oracle ha un sistema di tipi di dati generici (ANYTYPE, ANYDATA e ANYDATASET), ma questi tipi sono difficili da usare e dovrebbero essere evitati nella maggior parte dei casi.

Gli architetti spesso pensano che l'utilizzo di un unico campo per tutti i dati semplifichi le cose. Semplifica la generazione di belle immagini del modello di dati, ma rende tutto il resto più difficile. Considera questi problemi:

  1. Non puoi fare nulla di interessante con i dati senza conoscerne il tipo. Anche per visualizzare i dati è utile conoscere il tipo per giustificare il testo. Nel 99,9% dei casi di utilizzo sarà ovvio per l'utente quale delle 3 colonne è rilevante.
  2. Lo sviluppo di query type-safe su dati tipizzati in modo stringato è doloroso. Ad esempio, supponiamo che tu voglia trovare "Data di nascita" per le persone nate in questo millennio:

    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'
    

    Riesci a individuare il bug? La query di cui sopra è pericolosa, anche se hai archiviato la data nel formato corretto e pochissimi sviluppatori sanno come risolverla correttamente. Oracle dispone di ottimizzazioni che rendono difficile forzare un ordine specifico di operazioni. Avrai bisogno di una query come questa per essere sicuro:

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

    Non devi dire a tutti gli sviluppatori di scrivere le loro query in questo modo.