web-dev-qa-db-ja.com

SQL Serverの12の小数桁

現在、DB2からSQL Serverに移行しています。 DB2はTIMESTAMP(6-12)をサポートしていますが、DATETIME2は最大7桁までしかサポートしていません。 TIMESTAMP(12)として表される多くのキーがあるので、これらをSQL Serverに移行する最良の方法は何でしょうか

varchar(32)またはchar(32)として保存する必要があると考えていました。これにより、12の小数桁すべてを格納できます。

昇順/降順の順序は、datetime2としてvarchar/charでも同じように機能すると思います。

アプリケーションのすべてのSQLは、datetime2/timestamp値がSQLの文字列として表されるのと同じままであると想定しています。

ただし、前後にキャストしない限り、SQL Serverで時間関数を使用すると問題が発生します(おそらくうまく機能しません)。

より良い提案はありますか?

2
Kelvin Wayne

文字ベースの列に日付/時刻データを格納することは、非常に悪い考えです。そして、いいえ、datetime2/timestampの値は、SQL Serverでは文字列としてされていません。トピックについては Aaron Bertrandの優れた悪癖ブログシリーズ を参照してください。

DB2のtimestampデータ型1 です:

年、月、日、時、分、秒、マイクロ秒で日付と時刻を表す7つの部分からなる値。0001-01-01-00.00.00.000000000から9999-12-31-24.00.00.000000000の範囲で、ナノ秒の精度。タイムスタンプはタイムゾーン情報も保持できます

これは、SQL Serverのdatetime2(7)データ型とほぼ完全に同じです。2

時間部分:0から7桁、精度は100ns。デフォルトの精度は7桁です。

非常に正確な 粒子加速器の物理学 を測定しているのでない限り、1 nsを超える精度は必要ありません。

どのタイムソースを使用していますか?

質問で、これらの高精度のタイムスタンプ値をキーとして使用していることを説明しました。これらの値をSQL Serverのnumeric(32,12)列に格納することの妥当性を調査します。

これは、そのタイプのキー列を持つサンプルテーブルです。

_IF OBJECT_ID(N'dbo.TimeTesT', N'U') IS NOT NULL
DROP TABLE dbo.TimeTest;
CREATE TABLE dbo.TimeTest
(
    ItemKey numeric(32,12) NOT NULL
        CONSTRAINT PK_TimeTest
        PRIMARY KEY CLUSTERED
) ON [PRIMARY]
WITH (DATA_COMPRESSION = PAGE);
_

ここでは、非常に大きく正確な値を列に挿入します。

_INSERT INTO dbo.TimeTest (ItemKey)
VALUES (99999999999999999999.123456789012);
_

それはどのように見えるか:

_SELECT *
FROM dbo.TimeTest;
_
+ ----------------------------------- + 
 | ItemKey | 
 + ----------------------------------- + 
 | 99999999999999999999.123456789012 | 
 + ----------------------------------- +

DB2 timestamp(12)の値をSQL Serverに正常にインポートするには、適切な大きさと精度の数値としてエクスポートする必要があります。それが可能であれば、データが失われることはなく、SQL Serverがキー列で使用されるデータを適切に検証できるようになります。数値列はロケールや照合順序に依存しないため、並べ替えにも非常に効率的です。

varchar(45)を使用すると、_this is a very long, non-numeric key_のようにキーを作成できます。これは明らかに悪い考えです。

3
Max Vernon

タイムスタンプを2つの列に分割します。数百ナノ秒に格納されるdatetime2(7)列と、残りをキャプチャするint *列です。

 + ---------------------------------- + --------- -------------------- + ------- + 
 | DB2タイムスタンプ(12)| SQL Serverのdatetime2(7)| int | 
 + ---------------------------------- + ------- ---------------------- + ------- + 
 | 2017-04-08 14.43.52.456017331416 | 2017-04-08 14:43:52.4560173 | 31416 | 
 + ---------------------------------- + ------- ---------------------- + ------- + 

DB2レベルの精度のキーが必要な場合は、両方の列で複合キーを使用してください。

小数点以下7桁を超える精度が必要ない場合は、残りの列をそのままにしておくことができます。結局、タイムスタンプにマイクロ秒を追加しても、小数点以下6桁を超える桁は変更されません。そのため、datetime2列でSQL Serverの日付/時刻関数を引き続き使用できます。それを超えて、あなたはあなた自身にあります。

SQL Serverに移行するので、新しいデータや新しいビジネス要件がdatetime2が処理できる精度を超えず、レガシーシステムからのデータにのみ対応することを望んでいます。古いデータがアーカイブされると、残りの列とそれを使用するカスタム関数の必要性は時間とともに減少するはずです。

* DATEADD/DATEDIFF機能を100ナノ秒未満の増分/期間/ TimeSpansでレプリケートするカスタム関数の作成を開始する場合は、残りの列を0〜99999に保つための制約を追加します。

1