Mysql

code.org 究竟是如何失去 32 位索引的數據的?假設他們使用 MySQL 數據庫

  • January 23, 2017

今天的標題是 32 位狗吃了 1600 萬份孩子的 CS 作業。引自blog.code.org

我們儲存學生編碼活動的方式是在一個表中,直到今天它還有一個 32 位索引。這意味著數據庫表只能儲存 40 億行編碼活動資訊。我們沒有意識到我們已經跑到了極限,桌子已經滿了。我們現在製作了一個新的學生活動表,用於儲存學生的進度。使用新表,我們將切換到一個 64 位索引,該索引將容納多達 18 個 quintillion 行的資訊。從好的方面來說,這個新表將能夠儲存數百萬年的學生編碼資訊。不利的一面是,在我們將所有內容移到新表之前,今天之前的一些學生程式碼可能暫時不會出現,所以請耐心等待我們修復它。

我們現在假設使用 MariaDB/MySQL。你能詳細解釋一下(用 SQL 語句和錯誤消息)這個問題嗎?我不太了解這種數據失去。

通過index,他實際上是指鍵列。INTMySQL 可以在有符號列中儲存的最大值為 2147483647(文件連結),以 32 位(4 字節,2 的 32 次方)儲存。

當表達到 2147483647 行時(如果有間隙則更少),他們的問題就會發生 - 任何後續INSERT的 s 都會失敗,並且數據會失去。

很容易重現發生的事情:

創建一個帶有INT主鍵的測試表:

mysql> create table incfail 
      ( 
         pk INT PRIMARY KEY AUTO_INCREMENT
      );
Query OK, 0 rows affected (0.01 sec)

將主鍵值設置為接近最大值:

mysql> alter table incfail AUTO_INCREMENT= 2147483646;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

INSERT幾個值:

mysql> insert into incfail values (NULL);
Query OK, 1 row affected (0.00 sec)

mysql> insert into incfail values (NULL);
Query OK, 1 row affected (0.00 sec)

mysql> select * from incfail;
+------------+
| pk         |
+------------+
| 2147483646 |
| 2147483647 |
+------------+
2 rows in set (0.01 sec)

mysql>

主鍵現在處於最大值,下一個INSERT將失敗:

mysql> insert into incfail values (NULL);
ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'
mysql>

數據失去:

mysql> select * from incfail;
+------------+
| pk         |
+------------+
| 2147483646 |
| 2147483647 |
+------------+
2 rows in set (0.01 sec)

mysql>

引用自:https://dba.stackexchange.com/questions/161929