web-dev-qa-db-ja.com

Sybaseの不思議な「タイムスタンプ」データ型とは何ですか?

最近、Sybaseデータベースで「timestamp」タイプの列を使用するテーブルを見つけました。このような不思議なタイムスタンプデータ型を使用してテーブルを作成すると、

create table dropme (
    foo timestamp,  
    roo int null
)
insert into dropme (roo) values(123)
insert into dropme (roo) values(122)
insert into dropme (roo) values(121)
select * from dropme
go

'select * fromdropme'から次のようになります。

 foo                  roo
 -------------------- -----------
   0x000100000e1ce4ea         123
   0x000100000e1ce4ed         122
   0x000100000e1ce509         121

0x000100000e1ce4eaは、私にはタイムスタンプがあまりありません。また、「sp_helptimestamp」からのこの出力が表示されます。

 Type_name Storage_type Length Prec Scale Nulls Default_name Rule_name Access_Rule_name Identity
 --------- ------------ ------ ---- ----- ----- ------------ --------- ---------------- ----------
 timestamp varbinary         8 NULL  NULL     1 NULL         NULL      NULL                   NULL

私の質問は次のとおりです

  1. タイムスタンプとは一体何ですか?
  2. 時間や日付に関係はありますか?
  3. 日時に変換できますか?
  4. 時間でも日付でもない場合、何に使用しますか?
16
Eric Johnson

一体タイムスタンプとは何ですか?

タイムスタンプデータ型は次のように定義されます

varbinary(8) null

時間や日付とはまったく関係がありますか?

いいえ。名前はあまり選ばれていません。

日時に変換できますか?

番号。

時刻でも日付でもない場合、何に使用しますか?

タイムスタンプ列のある行が挿入または更新されるたびに、タイムスタンプ列が自動的に更新されます。実際には2種類のタイムスタンプがあることに注意してください。 TIMESTAMPおよびCURRENT TIMESTAMP。違いはCURRENT TIMESTAMPは挿入時にのみ設定されます。

Sybase documentation はそこで停止し、なぜf * Rainbow!* kがデータ型タイムスタンプを使用するのか疑問に思いました。幸いなことに、私はいくつかの otherdiscussions を見つけ、楽観的同時実行制御を実装するときに使用されると推測しました。

同時実行制御は、複数のトランザクションを同時に/ほぼ同時に実行し、それでも正しいデータを生成できるようにする方法です。 楽観的同時実行制御は、複数のトランザクションが互いに干渉することなく完了することができると想定する同時実行制御方式です。つまり、ロックは必要ありません。ウィキペディアでは、次のアルゴリズムについて説明しています。

  1. トランザクションの開始時に日付/時刻のマーキングを記録します
  2. データの読み取り/更新
  3. 別のトランザクションがデータを変更したかどうかを確認します
  4. コミットまたはロールバック

Sybaseのタイムスタンプデータ型は、日付/時刻を使用する代わりに、このアルゴリズムのステップ1と3で使用できます。しかし、日時データ型を使用する手間を大幅に節約できるとは思えません。パフォーマンスが向上する可能性があります。

16
Eric Johnson

最近、誰かがTIMESTAMPSYBASE IQデータ型をDATEに変換できるかどうかを尋ねてきました。このデータタイプは暗闇のため、私は常に避けています。 SYBASEドキュメント を数時間読んでテストを行った後、私の結論は次のとおりです。

タイムスタンプ:

  • BINARYとして保存される12桁の数字です(これは環境によって異なる場合があります)
  • 1970年1月1日からのマイクロ秒単位の値を表します
  • Sybaseはそれらを変換するための直接関数を含みません
  • レコードが挿入されるたびに自動的に安定化されます

以下は、TIMESTAMPをDATEに変換するためのSQL文です。

SELECT timestamp as TS, CONVERT(decimal, timestamp) as TS_IN_MS,
   CONVERT(date, dateadd(SS, CONVERT(int, SUBSTRING(CONVERT(varchar,                     
      CONVERT(decimal, timestamp)), 1, 9)), '1/1/1970'), 123)  as TS_AS_DATE  
   FROM TheTable

変換は、次のようなオンラインエポックコンバーターを使用して証明できます。

SYBASE ASEの場合、TIMESTAMPタイプは有効な NIX-Epoch

8
ArBR

(これは別の質問として投稿された回答です 不思議なSybase ASEの「タイムスタンプ」データ型の質問への回答 ここに追加する担当者のいないユーザーによるものです。私はコミュニティWikiとしてコピーしました。クレジットを請求したくないが、ここにあるはずです)

Q#1への回答:「タイムスタンプとは一体何ですか?」

•SybaseASEデータベースのタイムスタンプは、そのデータベースの内部メモリ内テーブル「dbtable」に一元的に保持されます。このテーブルは、データベースがオンラインになったときに作成されます。 @@ dbtsを選択すると、現在のDBタイムスタンプをクエリできます。このvarbinary(8)の「データベース」タイムスタンプ値はプラットフォームに依存します。つまり、ビッグエンディアンとスモールエンディアンの影響を受けることに注意してください。

•各ユーザーテーブルには、特定の行のINSERT/UPDATEの「データベース」タイムスタンプ値を保持するためのタイムスタンプ列が1つある場合があります。 TSQL DMLコマンドが正常に完了すると、すべての「テーブル」タイムスタンプ列の値が(ID列と同様に)ASEによって自動的に維持されます。ただし、「データベース」タイムスタンプとは異なり、「テーブル」のタイムスタンプ値は、O/Sプラットフォームのエンディアンに関係なく常にビッグエンディアンのバイト順で保持されるため、プラットフォームに依存しません(詳細については、以下の詳細情報を参照してください)。


Q#2への回答:「時間や日付とはまったく関係がありますか?」

いいえ、「データベース」タイムスタンプとページ「ローカル」タイムスタンプの値は、実際の日時を反映していません。


Q#3への回答:「日時に変換できますか?」

いいえ、ページの「データベース」タイムスタンプまたは「ローカル」タイムスタンプを日付/時刻値に変換することはできません。


Q#4への回答:「時間でも日付でもない場合、何に使用しますか?」

•影響を受けるページの「ローカル」タイムスタンプ(ページヘッダー内)がその時点の「データベース」タイムスタンプと同期されている間に、データベース内のページが変更または作成されるたびに、「データベース」タイムスタンプが1ずつ増加します。

•現時点での「データベース」タイムスタンプと比較すると、データベースページの「ローカル」タイムスタンプは、そのページの最後の更新または最初の作成の相対的な経過時間を反映しています。したがって、ASEは、データベース内のすべてのページに対する更新/作成の時系列順を通知できます。

•アプリケーションは、ID列と同様の方法で「テーブル」タイムスタンプ列を利用して、行のキー値に関係なく、最近または最も最近挿入/更新された行を見つけることができます。


詳細情報、警告、および警告:-

(1)「データベース」と「ローカル」のタイムスタンプは3つの部分に格納され、OSプラットフォームのエンディアンに依存します。例えば0xHHHH 0000 LLLLLLLL

  • 2バイトの上位-0xHHHH
  • 2バイトフィラー-0x0000
  • 4バイトの下位-0xLLLLLLLL

(2)ユーザーの「テーブル」タイムスタンプも3つの部分に格納されますが、常にビッグエンディアンの向きになります。例えば0x0000 HHHH LLLLLLLL

  • 2バイトのフィラー-0x0000
  • 2バイトの上位-0xHHHH
  • 下位4バイト-0xLLLLLLLL

(3)データベースのタイムスタンプは、特定のデータベースのメモリ内システムテーブルdbtableに保持されます(データベースがオンラインになったときに作成されます)。

  • 注1-「テーブル」のタイムスタンプ列の値は、タイムスタンプ列が定義されているデータベーステーブルのデータページやインデックスページの他の列値と同じように保持されます。
  • 注2-現在のデータベースの「データベース」タイムスタンプをSELECT @@ dbtsでクエリすると、16進表現が返されることに注意してください。これは、OSプラットフォームのエンディアンの影響を受けます。
  • 注3-対照的に、DBCC dbtable(推奨されません)で 'データベース'タイムスタンプをクエリすると、ビッグエンディアンの16進表記が返されるため、プラットフォームに依存しません。
  • 警告-特定のデータベースの「データベース」タイムスタンプが最大制限(0xFFFF、0xFFFFFFFF)に近づき、データベース内の挿入/更新操作の頻度によっては、このポイントに到達するまでに10年以上かかる場合があります。警告をスローし、それ以上の挿入/更新は不可能になります-唯一のオプションは、BCP(およびsp_showtextを介したストアドプロシージャ)を使用してすべてのオブジェクトからデータをエクスポートし、データベースを削除して、再度作成します(新しいニアザ 'データベース'タイムスタンプ)およびデータ(およびストアドプロシージャ)をインポートします。

FYI-上記の回答、ヒント、およびヒントは、私がSybaseで働いていて、現在は製品ASEを所有するSAPで働いているため、本物で正確です。

2
Tim B

アプリケーションにデータをフェッチするとします。何かをした後、(低レベルで!)取得するまでこのレコードが変更されていることを確認したいですか?

この場合、[〜#〜]タイムスタンプ[〜#〜]列が必要です。まず、その列を保存する必要があります。データを更新する直前に、各値を比較して確認する必要があります。

そのため、このデータ型が存在します。

1
Burçin