1

PKがかなり速く成長するテーブルがありますが、行はかなり一貫して削除されるため、次のようにすぐに非常にまばらなテーブルになります。

   ID     VALUE
 ----------------
   1     'Test'
   5     'Test 2'
   24    'Test 3'
   67    'Test 4'

不足しているIDに次の値を自動的に挿入して、そのIDが極端に大きくならないようにする方法はありますか?たとえば、ID2の「テスト5」を挿入したいと思います。

4

4 に答える 4

2

私はそれをしません。

コメントで他の人がすでに説明しているように、数字のギャップを埋めても何も得られません。

さらに、これらのIDを他の場所で参照すると、意図せずにデータを台無しにする可能性があります。
たとえば、ある行がID 2あり、それを削除したとします。
次に、完全に新しい行を挿入して再利用しますID 2
これで、を参照するデータがどこかにある場合ID 2、古い値ではなく新しい値に突然リンクします。

(nit-pickersへの注意:はい、参照整合性が適切に設定されている場合、これは発生しないはずです。しかし、これはどこでも当てはまるわけではないので、誰が知っていますか...)

于 2012-06-25T19:01:37.900 に答える
2

私はあなたがやろうとしていることをすることを提案していません、しかしあなたがそれをしたいのなら、これはその方法です。私は質問に答えているだけで、問題を解決していません。

procでは、これを実行している間、テーブルをロックして、潜入しないようにします。何かを使用して、次のリンクを使用します。

EXEC @result = sp_getapplock @Resource = @LockResource, 
                                 @LockMode = 'Exclusive'

EXEC sp_releaseapplock @Resource = @LockResource

テーブル

DECLARE @table TABLE ( id INT, val VARCHAR(20) )

データ

INSERT  INTO @table
        (
          id,
          val
        )
        SELECT  1,
                'Test'
        UNION ALL
        SELECT  2,
                'Test'
        UNION ALL
        SELECT  5,
                'Test 2'
        UNION ALL
        SELECT  24,
                'Test 3'
        UNION ALL
        SELECT  67,
                'Test 4' 

クエリ

INSERT  INTO @table
        SELECT TOP 1
                id + 1,
                'TEST'
        FROM    @table t1
        WHERE   NOT EXISTS ( SELECT TOP 1
                                    1
                             FROM   @table
                             WHERE  id = t1.id + 1 )
        ORDER BY id

INSERT  INTO @table
        SELECT TOP 1
                id + 1,
                'TEST'
        FROM    @table t1
        WHERE   NOT EXISTS ( SELECT TOP 1
                                    1
                             FROM   @table
                             WHERE  id = t1.id + 1 )
        ORDER BY id

SELECT  *
FROM    @table

結果

id  val
1   Test
2   Test
5   Test 2
24  Test 3
67  Test 4
3   TEST
4   TEST
于 2012-06-25T18:58:34.200 に答える
1

彼らは関与していないので、私はアイデンティティについての私の答えを削除しました。ギャップを埋めると、値を厳密に増やすという経験則に違反するため、これをクラスター化されたインデックスキーとして使用しているかどうかを確認するのは興味深いことです。

ギャップを埋めるのは自己結合で比較的簡単です。主キーがあるので、このクエリをすばやく実行して最初のギャップを見つける必要があります(もちろん、挿入とロックの同時処理はどのように行っていますか?):

SELECT lhs.ID + 1 AS firstgap
FROM tablename AS lhs
LEFT JOIN tablename AS rhs
    ON rhs.ID = lhs.ID + 1
WHERE rhs.ID IS NULL

また、レコードのバッチを挿入するには、各挿入を個別に実行する必要がありますが、IDENTITYはそれを処理できます...

于 2012-06-25T18:53:06.277 に答える
-2

前に述べたように、未使用のIDについて心配する必要はありません。

ただし、多くの削除が発生した場合は、テーブルを最適化することをお勧めします。

MySQLでは、次の方法でこれを行うことができます。

optimize table tablename
于 2012-06-25T18:44:28.233 に答える