萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> mysql 整型(int)數字溢出在程序和數據庫設計中的考慮

mysql 整型(int)數字溢出在程序和數據庫設計中的考慮

在數據庫設計和程序中需要考慮數字的范圍,否則可能導致一些問題。主要是考慮溢出的問題,比如如果數據庫中有一個整型的數字字段,裡面的數據可能隨著業務的增長而膨脹,而這個數字有可能會超出列屬性的范圍,也就是溢出,與此同時,程序中也需要處理這個日益龐大的數字,如果其中有運算、數字類型的邏輯比較等等,也可能導致某天就出現了異常。而這種錯誤又是難以發現的。

    以下試以整型(int)拋磚引玉:

一:MySQL5

    以MySQL5版本為例,大多數管理員可能把自增數字、或者其它應用數字字段的列屬性設置為int類型,int占用4個字節,而int又分為無符號型和有符號性。對於無符號型的范圍是0 到 4294967295;有符號型的范圍是-2147483648 到 2147483647。參考資料可見mysql手冊:11.2. 數值類型.

    當要在一個數值列內保存一個超出該列允許范圍的值時,MySQL的操作取決於此時有效的SQL模式。如果模式未設置,MySQL將值裁剪到范圍的相應端點,並保存裁減好的值。但是,如果模式設置為traditional(“嚴格模式”),超出范圍的值將被拒絕並提示錯誤,並且根據SQL標准插入會失敗。請參見mysql手冊5.3.2節:“SQL服務器模式”。

    如果INT列是UNSIGNED,列范圍的大小相同,但其端點會變為到0和4294967295。如果你試圖保存-9999999999和9999999999,以非嚴格模式保存到列中的值是0和4294967296。

    如果在浮點或定點列中分配的值超過指定(或默認)精度和標度規定的范圍,MySQL以非嚴格模式保存表示范圍相應端點的值。

    當MySQL沒有工作在嚴格模式時,對於ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT語句,由於裁剪發生的轉換將報告為警告。當MySQL工作在嚴格模式時,這些語句將失敗,並且部分或全部值不會插入或更改,取決於是否表為事務表和其它因素。詳情參見mysql手冊5.3.2節:“SQL服務器模式”。
二:php5:
 
    1:整型數的字長和平台有關,PHP 不支持無符號整數。
    2:如果給定的一個數超出了 integer 的范圍,將會被解釋為 float。同樣如果執行的運算結果超出了 integer 范圍,也會返回 float。如果在程序中有對數字類型做比較,可能會產生問題。
    3:可以查看PHP_INT_SIZE、PHP_INT_MAX,以確定整數的范圍。
 
以下列子可供參考:
 
在32位服務器下:


以下是代碼片段:

 代碼如下 復制代碼 [shengting@localhost ~]$ php -r "echo PHP_INT_SIZE;"
4
[shengting@localhost ~]$ php -r "echo PHP_INT_MAX;"
2147483647
[shengting@localhost ~]$ php -r "var_dump(2147483647);"
int(2147483647)
[shengting@localhost ~]$ php -r "var_dump(2147483648);"
float(2147483648)
[shengting@localhost ~]$ php -r "var_dump(-2147483647);"
int(-2147483647)
[shengting@localhost ~]$ php -r "var_dump(-2147483648);"
float(-2147483648)
[shengting@localhost ~]$ php -r "var_dump(4294967295);"
float(4294967295)
[shengting@localhost ~]$ php -r "var_dump(4294967296);"
float(4294967296)

在64位服務器下:
 

以下是代碼片段:

 代碼如下 復制代碼 [root@login shengting]# php -r "echo PHP_INT_SIZE;"
8
[root@login shengting]# php -r "echo PHP_INT_MAX;"
9223372036854775807
[root@login shengting]# php -r "var_dump(2147483647);"
int(2147483647)
[root@login shengting]# php -r "var_dump(2147483648);"
int(2147483648)
[root@login shengting]# php -r "var_dump(-2147483647);"
int(-2147483647)
[root@login shengting]# php -r "var_dump(-2147483648);"
int(-2147483648)
[root@login shengting]# php -r "var_dump(4294967295);"
int(4294967295)
[root@login shengting]# php -r "var_dump(4294967296);"
int(4294967296)
 


三:C/C++
 
    對C/C++也存在有符號和無符號類型的問題。
 
    對於32位系統,如果使用有符號int、long來定義變量保存唯一號就可能出現溢出,並出現上述問題。

    對於64位系統,如果使用int來定義變量保存唯一號就可能出現溢出,並出現上述問題

copyright © 萬盛學電腦網 all rights reserved