sql >> データベース >  >> RDS >> Sqlserver

リレーショナルデータベースのカスタムフィールドのデザインパターン

    VALUEを置き換えることにより、文字列型のデータを避けます NUMBER_VALUEを使用 、DATE_VALUESTRING_VALUE 。ほとんどの場合、これらの3つのタイプで十分です。必要に応じて、後でXMLTYPEやその他の派手な列を追加できます。また、Oracleの場合は、スペースを節約するためにCHARの代わりにVARCHAR2を使用してください。

    常に正しいタイプとして値を保存するようにしてください。ネイティブデータ型は、より速く、より小さく、より使いやすく、より安全です。

    Oracleには汎用データ型システム(ANYTYPE、ANYDATA、およびANYDATASET)がありますが、これらの型は使用が難しく、ほとんどの場合回避する必要があります。

    アーキテクトは、すべてのデータに1つのフィールドを使用すると、作業が簡単になると考えることがよくあります。データモデルのきれいな画像を生成するのは簡単ですが、それ以外はすべて難しくなります。次の問題を考慮してください:

    1. タイプを知らなければ、データに対して何か面白いことをすることはできません。データを表示する場合でも、テキストを正当化するためのタイプを知っていると便利です。すべての使用例の99.9%で、3つの列のどれが関連しているかがユーザーに明らかです。
    2. 文字列型のデータに対してタイプセーフなクエリを開発するのは面倒です。たとえば、この千年紀に生まれた人々の「生年月日」を検索するとします。

      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'
      

      バグを見つけられますか?上記のクエリは、日付を正しい形式で保存したとしても危険であり、適切に修正する方法を知っている開発者はほとんどいません。 Oracleには、特定の操作順序を強制することを困難にする最適化があります。安全のために、次のようなクエリが必要になります:

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

      すべての開発者にそのようにクエリを書くように指示する必要はありません。



    1. Firebaseの概要

    2. postgresqlLIKEクエリに移動します

    3. 2つのMySQLテーブルをマージするにはどうすればよいですか?

    4. PHPメール検証リンクの最も簡単な方法