目次
1 mysql データベースは自動インクリメントキーを持つテーブルを作成します
3 自動インクリメントキーが 4294967295 のテーブルを再作成します
まずは、まず現状を
mysql の ID は、自動インクリメント ID、埋め込み ID、ID なしの 3 つの状況に分けられます。
2 つの自動インクリメント ID
mysql の自動インクリメント ID が使い果たされた場合はどうすればよいですか?
1 mysql データベースは自動インクリメントキーを持つテーブルを作成します
まず、自動インクリメント ID のみを含む最も単純なテーブルを作成し、データを挿入します。
CREATE TABLE テスト
(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
) ;
テスト値に挿入(null);
2 エクスポートテーブルの構造
次に、テーブル構造を表示して、テーブルの作成テストを表示します。
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
AUTO_INCREMENT が自動的に 2 に変更されていますが、まだ使い切れるには程遠いです 現在宣言されている自己インクリメント ID の最大値が計算できます ここで定義されているため、最大値は 2 の累乗に達します32乗intunsigned
- 1 = 4294967295
3 自動インクリメントキーが 4294967295 のテーブルを再作成します
ここにちょっとしたトリックがあります。テーブル作成時に AUTO_INCREMENT の初期値を直接宣言できます。
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
テスト値に挿入(null);
4 テーブル構造の表示
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
5 例外テスト
AUTO_INCREMENTが4294967295になっていることがわかります。再度データを挿入しようとすると以下のような異常な結果が得られます
実行されたクエリ 1 件、成功 0 件、エラー 1 件、警告 0 件
クエリ: テスト値に挿入(null)
エラー コード: 1062
キー 'test.PRIMARY' のエントリ '4294967295' が重複しています
再度挿入する場合、使用される自動インクリメント ID は依然として4294967295
主キーの競合エラーであることに注意してください。
4294967295、この数値はすでにほとんどのシナリオに対応できます。サービスが頻繁にデータの挿入と削除を行う場合は、不足するリスクがまだあります。 bigint unsignedを使用することをお勧めします。この数値は大きいです。
トリプルパディングの主キー
1 まずテストテーブルを作成します。主キーは増加しません
CREATE TABLE `test` (
`id` int unsigned NOT NULL ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
2 主キーの最大値を挿入します
テスト値に挿入
(
4294967295
);
3 主キーの最大値+1を再度挿入
テスト値に挿入
(
4294967295
);
次のようにフィールドが範囲外であることがわかります:
INSERT INTO test VALUES ( 4294967296 )
エラー コード: 1264
行 1 の列 'id' の値が範囲外です
4 主キーが宣言されていません
1 テーブルの作成時に主キーが宣言されていません
この場合、InnoDB は長さ 6 バイトの非表示の row_id を自動的に作成します。また、InnoDB はグローバル dictsys.row_id を維持するため、未定義の主キーを持つテーブルは row_id を共有し、データの挿入ごとに、グローバル row_id は主キー ID とみなされ、グローバル row_id は 1 ずつ増加します。
グローバル row_id はコード実装で bigint unsigned 型を使用しますが、実際には row_id 用に予約されているのは 6 バイトだけです。この設計には問題があります: グローバル row_id が増加し続けると、2 の 48 乗まで増加し続けます。このとき、-1、+1とすると、row_idの下位48ビットはすべて0になります。その結果、新しいデータ行を挿入する際に取得されるrow_idは0となり、主キーが競合する可能性があります。
したがって、この隠れた危険を回避するには、各テーブルに主キーが必要です。