トップ回答者
IDが飛ぶ件について

質問
-
SQL Server 2012 Express
Windows 10 Pro
の環境において、IISで動くASP.NETアプリの構築を行い、マスタ設定で主キー列(Identity)でseedを1にしていたのですが
急にIDが100ずつ飛ぶようになって原因を調べたところ、下記の情報を拝見しました。http://kikki.hatenablog.com/entry/2015/11/23/180637
サービスの起動時パラメータに-T272を追加し、サービスの再起動をしても、PCの再起動をしても改善されませんでした。
他にも考慮すべき箇所があるかどうかご教示願えますでしょうか?
よろしくお願いいたします。
回答
-
> IDENTITYの指定をはいで増分1にしてあるのですが、
> https://blogs.msdn.microsoft.com/jpsql/2014/05/01/identity/
> 上記の内容によると、IDが連続で採番されることが保証されていないとなっております。
それはもうその通りで、質問者さんが遭遇した番号が飛ぶという現象が、最初の質問に書いてあった URL の記事の "INSERTされたテーブルのIDENTITYの一意性を担保するため" ということであれば(正常な現象であれば)何の問題もないと思うのですが。
そもそも連番になることを期待して設計するのは間違っていると言ってもよさそうな気がします。
以下の記事の「ID 列の概要」セクションに書いてあったことの抜粋ですが "ID 列は、「サーバーの範囲内で」一意である整数値をテーブルで提供するために使用します。それ以上のものではありません" と考えるべきと思います。
@@IDENTITY クライシスを管理する
https://msdn.microsoft.com/ja-jp/library/ms971502.aspx
ただし、tinyint を Identity の ID に使うのはダメです。上に紹介した記事の「SQL Server で ID 値を管理する」を読んでください。ため息が出るそうです。
その部分を抜粋しておきます。
"ID 値が足りないという不平を聞いたことがあります。その人は 255 行しかない "tinyint" を使用していました。溜息がでます。孤立した ID 値の復元方法についてはここでは説明しません。説明が困難ですし、長年の経験から説明する価値もないとわかっていますので。次世紀または会社が合併吸収されるまで (そのときは全部書き直しになるでしょう) 足りる十分な桁数の整数を使用してください"- 編集済み SurferOnWww 2018年7月11日 1:39 リンク設定
- 回答としてマーク tt_nobu 2018年7月11日 1:49
すべての返信
-
説明が不足しており申し訳ありません。
マスタ設定というのは開発システム内の話でしたので、表記すべきでなかったですね。
添付していただいた画像のようにSSMSにて、テーブルの主キーの列(tinyint)を確認して
IDENTITYの指定をはいで増分1にしてあるのですが、
https://blogs.msdn.microsoft.com/jpsql/2014/05/01/identity/
上記の内容によると、IDが連続で採番されることが保証されていないとなっております。
(であれば増分とは?という疑問もありますが。)
※さらに上記内容によると、tinyintの場合100飛ぶようで、現に症状としては104の次が204、
その次が304といったように100ずつ飛んでしまうのです。
そしてその回避方法として 起動時パラメータに -T272を付加して起動しても回避できず、
困っているという状況です。
-
> IDENTITYの指定をはいで増分1にしてあるのですが、
> https://blogs.msdn.microsoft.com/jpsql/2014/05/01/identity/
> 上記の内容によると、IDが連続で採番されることが保証されていないとなっております。
それはもうその通りで、質問者さんが遭遇した番号が飛ぶという現象が、最初の質問に書いてあった URL の記事の "INSERTされたテーブルのIDENTITYの一意性を担保するため" ということであれば(正常な現象であれば)何の問題もないと思うのですが。
そもそも連番になることを期待して設計するのは間違っていると言ってもよさそうな気がします。
以下の記事の「ID 列の概要」セクションに書いてあったことの抜粋ですが "ID 列は、「サーバーの範囲内で」一意である整数値をテーブルで提供するために使用します。それ以上のものではありません" と考えるべきと思います。
@@IDENTITY クライシスを管理する
https://msdn.microsoft.com/ja-jp/library/ms971502.aspx
ただし、tinyint を Identity の ID に使うのはダメです。上に紹介した記事の「SQL Server で ID 値を管理する」を読んでください。ため息が出るそうです。
その部分を抜粋しておきます。
"ID 値が足りないという不平を聞いたことがあります。その人は 255 行しかない "tinyint" を使用していました。溜息がでます。孤立した ID 値の復元方法についてはここでは説明しません。説明が困難ですし、長年の経験から説明する価値もないとわかっていますので。次世紀または会社が合併吸収されるまで (そのときは全部書き直しになるでしょう) 足りる十分な桁数の整数を使用してください"- 編集済み SurferOnWww 2018年7月11日 1:39 リンク設定
- 回答としてマーク tt_nobu 2018年7月11日 1:49
-
毎回100ずつ飛んでいるということは、ID値のキャッシュが何かおかしくなっているのかもしれません。少しテストしてみた方が良いかもしれません。例えば、Identityを一度いいえにして保存し、再度はいにするとどうなるか? IDの増分を他の値にした場合はどうなるのか? 新しくテーブルを作成しても同じようになるのか? などです。
ちなみに-T272と書かれているので問題ないと思いますが、「T」は大文字である必要があるようです。
また、SQL ServerのログやWindowsのイベントログには何か出ていませんでしょうか?
修復インストール、もしくはSQL Server 2012の再インストール(ちなみにサービスパックは当てられていますか?)が必要かもしれません。ある日、突然ですし、-T272も効かない、かといってプロセスが再起動しているわけでもないのに100ずつ飛ぶというのであれば、理屈に合いません。何かしらID値のキャッシュがおかしくなっているような気がします。
#ちなみにSQL Server 2017からは、次のようにID値のキャッシュのコントロールができるようになっていますので、可能であればSQL Server 2017を使われると良いかもしれません。
ALTER DATABASE SCOPED CONFIGURATION (Transact-SQL)
https://docs.microsoft.com/ja-jp/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql?view=sql-server-2017★良い回答には質問者は回答済みマークを、閲覧者は投票を!