日付を整数(数値)として格納することの利点


11

質問1

日付が整数(実際の数値(8,0))として格納されているシステムを使用していますが、他のシステムもこのスレッドにciscoなどのintとして日付を格納していることに気付きました。例

20120101  -- 01 Jan 2012

数値日付システムを維持し、SQL日時を使用しないことの利点はありますか?

質問2

現在、2つの日付の間の顧客を見つけるために、数値の日付をループ処理しています。startおよびenddateが2か月にわたる場合、60だけではなく数千のレコードを取得します。例:

create table #temp1(day int,capacity int) /* just a temp table */

declare @start int 
declare @end int

set @start=20111201
set @end = 20120131

while (@start <= @end) 
Begin
    insert into #temp1  /* I am storing things in #temp table so data looks pretty */
    exec usp_GetDailyCap @date1= @start

    set @start = @start + 1;    
end

select * from #temp1

これにより、60ではなく8931レコードが取得されます。上記のロジックを改善して、有効な日付のみを取得する方法はありますか?IsDateとサブクエリを試してみましたが、効率的に機能しませんでした。


SQL Server 2008以降を実行している場合、実際には日付型のデータのみを使用できます。これは少し小さく、時間を含める必要はありませんが、SQLのほとんどすべての日時関数が引き続き機能します。
DForck42

2
私はこのアプローチの欠点だけを見て、何の利点もない
a_horse_with_no_name

回答:


11

最初の質問に答えるために、DATETIMESQL Server内のデータ型を使用することをお勧めします。必ずしもパフォーマンス上の理由からではなく、RDBMS固有の機能を活用するため。たとえば、あなただけの基本的な日付の計算を行うためのロジックの多くを再発明する必要が(と思うだろうDATEDIFF()DATEADD()DATEPART()および他の多くの機能。彼らは明らかに合わせて調整されDATETIMEたデータ型とで動作するように簡単です)。

2番目の質問については、最初の質問(および私の答え)がに向けられている正確な問題に直面しています。 あなたは20111201と20120131を日付として見ていて、あなたの脳はそれが60日の違いであるべきだとあなたに言っています。さて、あなたはデルタに基づいてループしています...それは:

20120131 - 20111201 = 8930 (インクルーシブループでは8931になります)

つまり、WHILEループは8931回実行されています。これは整数値であり、ループが20111231から20120101に直接ジャンプしないために発生します。

整数は、年と月の上限(つまり、質問2の問題)を考慮に入れません。


まあそれはまさに私の質問です。数値の日付の場合、ループは30日または29日だけでなく、数千にも及ぶ可能性があります。ただし、私はプロのシステムで作業していることを覚えておいてください。そして、シスコでさえ、それを使用しているようです。
Jackofall 2012年

4
パフォーマンスと機能性に加えて、整合性もあります。日付として整数を使用する20121301と、dbは日付として、20120230さらに20129999は日付としても使用できます。
ypercubeᵀᴹ

@Jackofallシスコには、背後にRDBMSのプラットフォームがありません。彼らは彼ら自身の論理を書いた。なぜ整数だけを使わないのか。基本的に、これは低レベルソフトウェアにとっておそらく最も簡単な方法です。しかし、ここではリンゴとオレンジについて話しています。
トーマス・ストリンガー

3
@Jackofall:日付を整数として格納する(およびギャップがある)と、日付/時刻スタンプを整数として格納する、またはVB / Excelのように日付を整数として格納することの間には大きな違いがあります。
ypercubeᵀᴹ

4
多くの(ほとんどではないにしても)専門的に設計されたデータベースには、不適切な手法が使用されています。私は多くのCOTS製品を使用してきましたが、データベースの観点からよく設計された製品は見ていません。
HLGEM 2012年

6
  1. Ralph Kimballは、日付を整数として保存することをお勧めします。彼はオンラインの記事と本の両方をたくさん書いています。
  2. 次のように、カレンダーテーブルを使用して、日付に連続番号を発行できます。

    日付番号

    20120229 1234

    20120301 1235

カレンダーテーブルを生成する必要がありますが、それは非常に簡単な作業です。


1
私はあなたが数値として格納された日付と日付のテーブルに参加し、「@startdateと@EndDateの間ここで、[日付]を」使用して打つはずの数値、日付をフィルタリングすることにより、クエリをフィルタする場合を見てみたいと思います
DForck42

1
@ DForck42提案しているケースは必要ありません。「where [dateAsInt] between 20120229 and 20120329」は「where [date] between '20120229' and '20120329'」とまったく同じ行を返します
AK

3
そして、彼の推論は何でしたか?
HLGEM 2012年

5

潜在的なデータ型とそのサイズ/制限:

  • Decimal(8,0):5バイト
  • 日付:3バイト、0001-01-01から9999-12-31
  • Int:4バイト

数値データ型の長所:

  • 彼らはきれいに見えますか?

数値データ型の短所:

  • 日付操作を処理するためのカスタムコードが必要
  • 正しい日付を管理するにはカスタムコードが必要です(つまり、20120230を許可しない[2012年2月30日])
  • 日付データ型と比較すると、データフットプリントが大きくなります。

正直なところ、日付データ型IMHOを使用する方がベターです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.