web-dev-qa-db-ja.com

日付を月と年のキーペア値でグループ化して格納するためのベストプラクティス

年月の組み合わせでグループ化して計算したデータを保持する必要のあるサービスを1つ作成しています。データを計算して新しいテーブルに配置する方法を知っています。しかし、月と年の値を格納するためにどのような種類のデータを使用すればよいか混乱しています。これが私が考えたことです。

  1. 2つのInteger列は1年に1つ、もう1つは月に対応します(理解しやすく、操作が強力です(このテーブルを使用する人は誰でも範囲と順序を簡単に使用できます)。
  2. 日付フィールドを使用し、月全体で常に1つの日付を格納します。 (それがどのように機能し、どのようにWHERE句を作成するかをユーザーに説明するのは難しい)
  3. 1つのvarchar(7)列と2012-02,2013-01のような文字列を入れます。私にとってこれは理解しやすいですが、操作するのは難しいです。

どっちがいい?または他の解決策があります。パフォーマンスに応じて、どちらの方法が適切なソリューションになるかを誰かが提案できますか?ほとんどのクエリは、ソリューションと私の新しいテーブルが約200万から500万のレコードを持つデータ範囲を使用するためです。

6
adopilot

月の最初の日付フィールドとCHECK制約を使用して、それが1日目に留まるようにします。

これにより、ネイティブの日付/時刻形式で保持されます(これはオプション3に関する観察です)

オプション1では、必要なストレージは少なくなりますが、比較が複雑になります。 500万行はそれほど多くありません。使用するストレージは少なくなりますが、コードとクエリが複雑になります

9
gbn

データの必要性に応じて、1つ(または複数)のオプションを選択する必要があると思います取得

500万件のレコードの場合、スペースは主な関心事ではありません。各オプションについて、ここにretrievalの長所と短所があります。

(1)2つの整数列:これは、異なる年の月を比較する必要がある場合に使用する優れたアプローチです。年と月を別々に索引付けすると、月ごとの抽出と年ごとのソートがはるかに速くなります。オプション1は、これがデータを使用する重要または頻繁なモードである場合に最適です。一方、このモードでは、年月以外の範囲を抽出するのはひどいです。たとえば、年をまたぐ範囲には適していません。 WHERE句は、日付範囲が暦年の境界を超える場合に理想的になるよりも複雑になる可能性があります。 (2011年11月から2012年2月まで考えてください。)

(2)日付フィールド:あなたとgbnはどちらも、このフォーマットの良い点を識別しています。年代順に並べ替えたり、月の範囲を抽出したりするのにも適しています。たまたま最もコンパクトな表現です(たった3バイト)。さまざまな年の月のように比較することはまったく得策ではなく、画面やレポートに表示することも考えられません。

(3)char(7)YYYY-MM Field:本当にスペースが気になる場合(そしてあなたは気にしないでくださいあなたのケースでは)charの代わりにvarcharを使用できます。これは、すべてのアイテムが既知の長さになるためです。 YYYY-MMの使用は、範囲の並べ替えとフィルタリングに適しています。スペースについては(2)ほど良くありませんが、WHERE句の表示と単純さのためには優れています-何年にもわたって月などを抽出する必要がない限り。


必要な抽出の性質に関しては、(1)と(2)/(3)の間に違いがあることに気づいたかもしれません。 1か月/年と月の範囲の抽出の両方を行う必要がある場合、これらのオプションはどれも完璧ではありません。その場合は、(1)と(2)または(3)の組み合わせを使用することを検討することをお勧めします。ストレージよりも表示/使用の容易さを重視するため、(3)を選択します。スペース。組み合わせを使用する場合は、どちらか一方を計算カラムにして、効率的な検索のためにインデックスを付けます。

2
Joel Brown

2つの日付値(開始日と終了日)を持つ期間としてモデル化を検討します。クローズドオープン表現を使用します(「オープン」は、実際には終了日が期間内に発生しないことを示します)。

たとえば、現在の月(2012年3月)は、行を使用してモデル化されます。

(start_date, end date) VALUES ('2012-03-01T00:00:00', '2012-04-01T00:00:00')
1
onedaywhen

テーブルに完全な日付もあり、集約にのみ減少したものを使用する場合は、日付から正規化された理想的に分散された値(「1970年1月からの月数」など)を作成する関数を作成し、集計プロセスをスピードアップするその関数の結果。

0
Simon Richter