none
楽観的同時実行制御と"timestamp型"の非推奨に関して RRS feed

  • 質問

  • お世話になります。

    タイムスタンプ列を利用した楽観的同時実行制御を前提としたデータベースの新規設計をしており、
    楽観的同時実行制御に使用する[タイムスタンプ列]のデータ型を検討しています。

    オンラインブックの「SQL Server 2014 データベース エンジンの非推奨機能」に下記のような表があります。

    非推奨機能:timestamp データ型の rowversion 構文
    代替:rowversion データ型の構文

    寿命の長い設計を重視したいため非推奨の機能は使用したくありません。

    そこで"rowversion"を使おうとSQLServer2014のテーブルデザインで[タイムスタンプ列]のデータ型に"rowversion"を選択しようと思いましたが表示されません。
    ("timestamp"は表示されています。)

    ただ試しに下記のスクリプトを実行したところ正常終了しましたが”ts列”は"timestamp"と表示されています。
    CREATE TABLE [dbo].[Table_1]([ID] [nchar](10) NULL, [ts] [rowversion] NULL) ON [PRIMARY]

    SQL2014での"timestamp"は実は"rowversion"で前述の代替と理解して良いのでしょう?

    "timestamp"が継続的に使用できればトリガ等を作成しなくて済むので使用したいのですが、
    単純に[タイムスタンプ列]を"int型"等にしてトリガ等でインクリメントしていた方が無難でしょうか?

    アドバイスをお願いいたします。



    2016年5月18日 5:59

回答

  • 以下辺りが参考になりそうですね。

    Microsoft recommends using Rowversion over timestamp , but i can not find “rowversion” data type inside my sql server 2008 R2 [closed]
    http://dba.stackexchange.com/questions/86523/microsoft-recommends-using-rowversion-over-timestamp-but-i-can-not-find-rowve

    簡単に要約すると、SQL Serverにrowversionというデータ型は存在しない。GUIではtimestampを使う必要がある。DDLではrowversionを使うことができるが、内部的にはtimestamp型になっている。

    こういう状況が長く続いており、話題になることもあるようですが、これという答えはないようですね。
    ちなみにSQL Server 2005には既に非推薦の記述があります。
    timestamp = rowversion ということを認識した上で、GUI(SQL Server Mangement Studio)では前者を、DDLでは後者を使うというのが、最善のような気がします。

    >単純に[タイムスタンプ列]を"int型"等にしてトリガ等でインクリメントしていた方が無難でしょうか?

    個人的には前述したように、timestamp、またはrowversionを使うのが確実ですし、楽だと思います。
    もしtimstampという文字を一つも使いたくないのであれば、GUIでテーブルを作らず、全てDDLを使い、その中でrowversionのみを使えば良いと思います。ただ、SQL Server 2014で試してみましたが、そうやって作っても、GUIで開くとtimestamp型として表示されますし、そこからそのテーブルを作成するスクリプトを生成しても、その中ではtimestamp型が使われます。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    • 編集済み trapemiya 2016年5月18日 7:30 追記
    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月18日 7:25
  • rowversionには次の記述があります。

    timestamp は rowversion データ型のシノニムであり、データ型のシノニムの動作が適用されます。

    Transact-SQL timestamp データ型は、ISO 標準で定義されている timestamp データ型とは異なります。

    つまりSQL Serverではrowversionというデータ型が存在し、timestampはデータ型のように見えますがシノニム(いわゆるエイリアス)で実体はrowversionとなっています。

    なぜこのようなことになっているかというとISO標準には別の目的のtimestamp型が存在するから、かと。ですので、非推奨とされているのはtimestampエイリアスのことで、なるべく正しいデータ型rowversionで記述してほしいという意味です。

    # trapemiyaさんも指摘されていますが、SQL Server Management Studioはこの指針をあまり意識していないようで引き続きtimestamp型という表現を使用していますね。

    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月18日 7:53
  • Hoshinaです
    こんにちは

    Microsoft社の技術で終始するのであれば、timestampを使用することで直接的なデメリットはないと思います。(非推奨の文言は別にして)

    このフォーラムの範囲外ですが、私の知っていることを簡単に書いてみます。参考まで。

    もし、構築したデータベースを将来Javaで利用する可能性があるようでしたら、以下の考慮が必要かも。
    Javaからデータベースを操作する仕様にJPAというものがあります。
    JPAには楽観的排他制御の仕組みが仕様として規定されています。
    その際、利用できるフィールドの型がJavaの型として限定されています。
    timestamp型はJavaの型ではbyte[](バイト配列)となり、楽観的排他制御として利用できません。
    そんな将来まで心配であるなら、何らかの数値型を選択しておくのもありかもしれません。

    timestamp型を.NETで操作する場合、そのデータ型(.NETのデータ型)はSQL Serverのバージョンで異なったような記憶があります。
    これはあやふやな情報ですみませんが、ご確認を。

    それでは

    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月19日 0:20

すべての返信

  • 以下辺りが参考になりそうですね。

    Microsoft recommends using Rowversion over timestamp , but i can not find “rowversion” data type inside my sql server 2008 R2 [closed]
    http://dba.stackexchange.com/questions/86523/microsoft-recommends-using-rowversion-over-timestamp-but-i-can-not-find-rowve

    簡単に要約すると、SQL Serverにrowversionというデータ型は存在しない。GUIではtimestampを使う必要がある。DDLではrowversionを使うことができるが、内部的にはtimestamp型になっている。

    こういう状況が長く続いており、話題になることもあるようですが、これという答えはないようですね。
    ちなみにSQL Server 2005には既に非推薦の記述があります。
    timestamp = rowversion ということを認識した上で、GUI(SQL Server Mangement Studio)では前者を、DDLでは後者を使うというのが、最善のような気がします。

    >単純に[タイムスタンプ列]を"int型"等にしてトリガ等でインクリメントしていた方が無難でしょうか?

    個人的には前述したように、timestamp、またはrowversionを使うのが確実ですし、楽だと思います。
    もしtimstampという文字を一つも使いたくないのであれば、GUIでテーブルを作らず、全てDDLを使い、その中でrowversionのみを使えば良いと思います。ただ、SQL Server 2014で試してみましたが、そうやって作っても、GUIで開くとtimestamp型として表示されますし、そこからそのテーブルを作成するスクリプトを生成しても、その中ではtimestamp型が使われます。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


    • 編集済み trapemiya 2016年5月18日 7:30 追記
    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月18日 7:25
  • rowversionには次の記述があります。

    timestamp は rowversion データ型のシノニムであり、データ型のシノニムの動作が適用されます。

    Transact-SQL timestamp データ型は、ISO 標準で定義されている timestamp データ型とは異なります。

    つまりSQL Serverではrowversionというデータ型が存在し、timestampはデータ型のように見えますがシノニム(いわゆるエイリアス)で実体はrowversionとなっています。

    なぜこのようなことになっているかというとISO標準には別の目的のtimestamp型が存在するから、かと。ですので、非推奨とされているのはtimestampエイリアスのことで、なるべく正しいデータ型rowversionで記述してほしいという意味です。

    # trapemiyaさんも指摘されていますが、SQL Server Management Studioはこの指針をあまり意識していないようで引き続きtimestamp型という表現を使用していますね。

    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月18日 7:53
  • Hoshinaです
    こんにちは

    Microsoft社の技術で終始するのであれば、timestampを使用することで直接的なデメリットはないと思います。(非推奨の文言は別にして)

    このフォーラムの範囲外ですが、私の知っていることを簡単に書いてみます。参考まで。

    もし、構築したデータベースを将来Javaで利用する可能性があるようでしたら、以下の考慮が必要かも。
    Javaからデータベースを操作する仕様にJPAというものがあります。
    JPAには楽観的排他制御の仕組みが仕様として規定されています。
    その際、利用できるフィールドの型がJavaの型として限定されています。
    timestamp型はJavaの型ではbyte[](バイト配列)となり、楽観的排他制御として利用できません。
    そんな将来まで心配であるなら、何らかの数値型を選択しておくのもありかもしれません。

    timestamp型を.NETで操作する場合、そのデータ型(.NETのデータ型)はSQL Serverのバージョンで異なったような記憶があります。
    これはあやふやな情報ですみませんが、ご確認を。

    それでは

    • 回答としてマーク Watanabe NS 2016年5月28日 7:42
    2016年5月19日 0:20
  • 業務が専任でないため回答が遅くなってすみません。

    経緯まで含めた詳しい説明をありがとうございます。

    表現(構文)に対して"非推奨"ということだけで、
    "timestamp型"を使用すること自体は問題ないということだったのですね。

    私としては"timestamp型"を継続的に利用して良いかを心配しておりましたので安心しました。

    GUI上で"timestamp"と表示される件に関しても問題ないです。

    将来的にも、.NETからの接続のみですので型表現に関しても許容範囲です。

    みなさんご回答ありがとうございました。

    2016年5月28日 7:41