none
900バイトを超える主キーを持つテーブル RRS feed

  • 質問

  • OracleからSQLServerへのDBの移行を実施しております。

    Oracleのテーブルに、主キーの合計サイズが900バイトを超える
    テーブルがあります。

    SQLServerでこのテーブルを作成すると、主キーのサイズが900バイトを超えないようにとの
    エラーメッセージが表示されます。

    SQLServerで、テーブルの構成を変えずに、上記テーブルの主キー(あるいはそれに準ずるもの)を
    作成する方法はありますでしょうか?

    以上、よろしくお願いいたします。
    2013年12月5日 10:38

回答

  • こんにちは。

    「構成を変えない」という事が、アクセス方法・カラム構成の変更等も含めての事だとすると、方法は無いと思えます。

    SQL Server の最大容量仕様
    http://technet.microsoft.com/ja-jp/library/ms143432.aspx

    インデックス キーの最大サイズ
    http://technet.microsoft.com/ja-jp/library/ms191241(v=SQL.105).aspx

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 0:51
  • テーブルの構成を変えないということになると、以下のページのB案ぐらいでしょうか?

    Living with SQL's 900 Byte Index Key Length Limit
    http://blogs.msdn.com/b/bartd/archive/2011/01/06/optionsforindexedlookupsoflongvalues.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 1:13
  • trapemiyaさん

    ご回答ありがとうございます。
    英語が拙いので恐縮ですが、これは主キーの「一意制約の整合性」の部分は置いておいて、
    検索パフォーマンスを得るために、900バイトを超えない別の列にインデックスを張る。といった主旨なのでしょうか?

    2013年12月6日 2:54
  • いえ、B案は、例えば3列を合わせて一つのキーにしたいのだけれど900バイトを超えてしまうので、900バイトを超えないように2列だけでインデックスを作成し、残りの列はwhere条件に加えて検索するというものです。つまり、

    where 2列から成るインデックス = @2列から成るインデックス and もう一つの列 = @もう一つの列

    のような感じです。ご紹介したページでは、これをストアドプロシージャ化して検索で使用しています。もう一つの列の検索にはインデックスが当然使われませんが、狭い範囲のシークになるのであまり問題にはならないだろうという判断です。

    ちなみにそのページではA案を推しているようです。私も同意します。もし、そのキーを外部キーとして利用しているのであれば、サロゲートキーを追加するのがベストだと思いますが、仕様変更がおそらくきついですよね。いずれにしても900バイトの制限がありますので、それを超えないように工夫するしかないようです。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 5:14

すべての返信

  • こんにちは。

    「構成を変えない」という事が、アクセス方法・カラム構成の変更等も含めての事だとすると、方法は無いと思えます。

    SQL Server の最大容量仕様
    http://technet.microsoft.com/ja-jp/library/ms143432.aspx

    インデックス キーの最大サイズ
    http://technet.microsoft.com/ja-jp/library/ms191241(v=SQL.105).aspx

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 0:51
  • テーブルの構成を変えないということになると、以下のページのB案ぐらいでしょうか?

    Living with SQL's 900 Byte Index Key Length Limit
    http://blogs.msdn.com/b/bartd/archive/2011/01/06/optionsforindexedlookupsoflongvalues.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 1:13
  • trapemiyaさん

    ご回答ありがとうございます。
    英語が拙いので恐縮ですが、これは主キーの「一意制約の整合性」の部分は置いておいて、
    検索パフォーマンスを得るために、900バイトを超えない別の列にインデックスを張る。といった主旨なのでしょうか?

    2013年12月6日 2:54
  • いえ、B案は、例えば3列を合わせて一つのキーにしたいのだけれど900バイトを超えてしまうので、900バイトを超えないように2列だけでインデックスを作成し、残りの列はwhere条件に加えて検索するというものです。つまり、

    where 2列から成るインデックス = @2列から成るインデックス and もう一つの列 = @もう一つの列

    のような感じです。ご紹介したページでは、これをストアドプロシージャ化して検索で使用しています。もう一つの列の検索にはインデックスが当然使われませんが、狭い範囲のシークになるのであまり問題にはならないだろうという判断です。

    ちなみにそのページではA案を推しているようです。私も同意します。もし、そのキーを外部キーとして利用しているのであれば、サロゲートキーを追加するのがベストだと思いますが、仕様変更がおそらくきついですよね。いずれにしても900バイトの制限がありますので、それを超えないように工夫するしかないようです。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク でぐさん 2013年12月6日 6:46
    2013年12月6日 5:14
  • trapemiya さん
    Keiichi Oumi さん

    ご回答ありがとうございました。
    参考にさせていただきます。
    2013年12月9日 1:14