Mysql
code.org 究竟是如何失去 32 位索引的數據的?假設他們使用 MySQL 數據庫
今天的標題是 32 位狗吃了 1600 萬份孩子的 CS 作業。引自blog.code.org
我們儲存學生編碼活動的方式是在一個表中,直到今天它還有一個 32 位索引。這意味著數據庫表只能儲存 40 億行編碼活動資訊。我們沒有意識到我們已經跑到了極限,桌子已經滿了。我們現在製作了一個新的學生活動表,用於儲存學生的進度。使用新表,我們將切換到一個 64 位索引,該索引將容納多達 18 個 quintillion 行的資訊。從好的方面來說,這個新表將能夠儲存數百萬年的學生編碼資訊。不利的一面是,在我們將所有內容移到新表之前,今天之前的一些學生程式碼可能暫時不會出現,所以請耐心等待我們修復它。
我們現在假設使用 MariaDB/MySQL。你能詳細解釋一下(用 SQL 語句和錯誤消息)這個問題嗎?我不太了解這種數據失去。
通過
index
,他實際上是指鍵列。INT
MySQL 可以在有符號列中儲存的最大值為 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>