none
運用上行サイズがページサイズを超えないが、理論上ページサイズを超えてしまう場合の列のサイズについて RRS feed

  • 質問

  • お世話になります。

    テーブル設計についてご教授ください。

    varchar(2000)の列が5列存在するテーブルを作るとします。

    5列がすべて最大サイズ入力される可能性は極めて低いので、実運用上行サイズがページサイズを超えることはないとしても、理論上は行サイズはページサイズを超える可能性があります。

    こういった場合は、varchar(2000) -> varchar(max)として設計すべきなのでしょうか?


    2011年8月15日 7:09

回答

  • まず、SQLServer2005からは1Page8060バイト以上の定義のテーブルを作成しても警告は出なくなっていて、8060バイト以上のデータを実際に挿入した場合でもエラーにはなりません。

    あふれた分のデータはROW_OVERFLOW_DATAとして格納されます。(※見た目にはわかりませんがなんの問題もなく使用できます。)

    問題のvarchar(2000)かvarchar(max)かについてですが、varchar(max)はカラムごとに8000バイトを超える場合、LOBと同じ扱いとなり、データ行には16バイトのポインタのみ保存され、中身は別領域に保存されることとなりますが、問題のvarchar(2000)では8000バイトを超えることはないので、必ず行内保存となり、全部で8060バイトからあふれた場合は上記のような保存方法となります。

    ということで、どっちにしてもほぼ同じかと思っています。
    ※ただし、varchar(max)にした場合はsp_tableoptionを使用することで強引に行外保存にすることができます。


    • 回答としてマーク たう 2011年8月16日 2:05
    2011年8月15日 11:16

すべての返信

  • まず、SQLServer2005からは1Page8060バイト以上の定義のテーブルを作成しても警告は出なくなっていて、8060バイト以上のデータを実際に挿入した場合でもエラーにはなりません。

    あふれた分のデータはROW_OVERFLOW_DATAとして格納されます。(※見た目にはわかりませんがなんの問題もなく使用できます。)

    問題のvarchar(2000)かvarchar(max)かについてですが、varchar(max)はカラムごとに8000バイトを超える場合、LOBと同じ扱いとなり、データ行には16バイトのポインタのみ保存され、中身は別領域に保存されることとなりますが、問題のvarchar(2000)では8000バイトを超えることはないので、必ず行内保存となり、全部で8060バイトからあふれた場合は上記のような保存方法となります。

    ということで、どっちにしてもほぼ同じかと思っています。
    ※ただし、varchar(max)にした場合はsp_tableoptionを使用することで強引に行外保存にすることができます。


    • 回答としてマーク たう 2011年8月16日 2:05
    2011年8月15日 11:16
  • savurou様、ご回答ありがとうございます。

    varchar(max)は必ずポインタとして保存されているものだと勘違いしていました。

    設定するとそうなるのですね。

    そうすると、デフォルト設定であればvarchar(2000)でもvarchar(max)でもほぼ同じなんですね。

    2011年8月16日 2:09