Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Padrão de design para campos personalizados no banco de dados relacional


Evite dados de tipo string substituindo VALUE com NUMBER_VALUE , DATE_VALUE , STRING_VALUE . Esses três tipos são bons o suficiente na maioria das vezes. Você pode adicionar XMLTYPE e outras colunas sofisticadas posteriormente, se necessário. E para Oracle, use VARCHAR2 em vez de CHAR para economizar espaço.

Sempre tente armazenar valores como o tipo correto. Os tipos de dados nativos são mais rápidos, menores, mais fáceis de usar e mais seguros.

A Oracle tem um sistema de tipo de dados genérico (ANYTYPE, ANYDATA e ANYDATASET), mas esses tipos são difíceis de usar e devem ser evitados na maioria dos casos.

Os arquitetos geralmente pensam que usar um único campo para todos os dados facilita as coisas. Facilita a geração de imagens bonitas do modelo de dados, mas torna todo o resto mais difícil. Considere estas questões:
  1. Você não pode fazer nada interessante com dados sem conhecer o tipo. Mesmo para exibir dados é útil conhecer o tipo para justificar o texto. Em 99,9% de todos os casos de uso, será óbvio para o usuário qual das 3 colunas é relevante.

  2. O desenvolvimento de consultas de tipo seguro contra dados de tipo string é doloroso. Por exemplo, digamos que você queira encontrar "Data de nascimento" para pessoas nascidas neste milênio:
    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'
    

    Você consegue identificar o bug? A consulta acima é perigosa, mesmo se você armazenou a data no formato correto e muito poucos desenvolvedores sabem como corrigi-la adequadamente. O Oracle possui otimizações que dificultam a força de uma ordem específica de operações. Você precisará de uma consulta como esta para ser seguro:
    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';
    

    Você não quer ter que dizer a cada desenvolvedor para escrever suas consultas dessa maneira.