Các loại trong MySQL: BigInt (20) so với Int (20)


221

Tôi đã tự hỏi sự khác biệt giữa BigInt, MediumIntInt... có vẻ như rõ ràng là họ sẽ cho phép số lượng lớn hơn; tuy nhiên, tôi có thể tạo một Int(20)hoặc một BigInt(20)và điều đó dường như không nhất thiết là về kích thước.

Một số cái nhìn sâu sắc sẽ là tuyệt vời, chỉ là loại tò mò. Tôi đã sử dụng MySQL một thời gian và cố gắng áp dụng các nhu cầu kinh doanh khi chọn loại, nhưng tôi không bao giờ hiểu khía cạnh này.

Câu trả lời:


478

Xem http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html

  • INT là một số nguyên có ký hiệu bốn byte.

  • BIGINT là một số nguyên có ký hiệu tám byte.

Mỗi cái đều chấp nhận không nhiều hơn và không ít giá trị hơn mức có thể được lưu trữ trong số byte tương ứng của chúng. Điều đó có nghĩa là 2 32 giá trị trong một INTvà 2 64 giá trị trong a BIGINT.

20 trong INT(20)BIGINT(20)có nghĩa là gần như không có gì. Đó là một gợi ý cho chiều rộng màn hình. Nó không liên quan gì đến việc lưu trữ, cũng như phạm vi các giá trị mà cột sẽ chấp nhận.

Thực tế, nó chỉ ảnh hưởng đến ZEROFILLtùy chọn:

CREATE TABLE foo ( bar INT(20) ZEROFILL );
INSERT INTO foo (bar) VALUES (1234);
SELECT bar from foo;

+----------------------+
| bar                  |
+----------------------+
| 00000000000000001234 |
+----------------------+

Đây là một nguồn gây nhầm lẫn phổ biến cho người dùng MySQL để xem INT(20)và cho rằng đó là giới hạn kích thước, một cái gì đó tương tự CHAR(20). Đây không phải là trường hợp.


4
Wow, bài đăng này đã xóa tan sự nhầm lẫn của tôi về chủ đề này một cách hoàn hảo. Có vẻ như là một sự lựa chọn kỳ lạ của các nhà phát triển - như tôi đã đoán nó là chiều rộng + giá trị tối đa, hoặc bit / vv.
Sh4d0wsPlyr

27
`nó chỉ ảnh hưởng đến tùy chọn ZEROFILL: 'bây giờ sự tò mò của tôi kết thúc
Umair

6
Tôi thực sự muốn rằng họ đã thiết kế cú pháp với màn hình hiển thị trên ZEROFILL thay vì INT. Ví dụ : bar INT ZEROFILL(20). Nó sẽ rõ ràng hơn rất nhiều. Nhưng quyết định đó đã được đưa ra từ lâu và việc thay đổi nó bây giờ sẽ phá vỡ hàng triệu cài đặt cơ sở dữ liệu.
Bill Karwin

1
Tôi đồng ý điều này rất khó hiểu. Tôi đã có ấn tượng rằng con số đó là giới hạn toàn bộ thời gian này. Thậm chí lo lắng về việc làm cho một số số nhỏ hơn khi tôi biết dữ liệu sẽ nằm trong một phạm vi nhất định.
jDub9

2
@ jDub9, vâng, và điều khó hiểu hơn nữa là NUMERIC / DECIMAL có một đối số chính xác ảnh hưởng đến phạm vi của các giá trị và kích thước của cột.
Bill Karwin

40

Số trong ngoặc đơn trong khai báo kiểu là chiều rộng hiển thị , không liên quan đến phạm vi giá trị có thể được lưu trữ trong một loại dữ liệu. Chỉ vì bạn có thể khai báo Int(20)không có nghĩa là bạn có thể lưu trữ giá trị lên tới 10 ^ 20 trong đó:

[...] Chiều rộng hiển thị tùy chọn này có thể được các ứng dụng sử dụng để hiển thị các giá trị nguyên có chiều rộng nhỏ hơn chiều rộng được chỉ định cho cột bằng cách đệm trái chúng bằng khoảng trắng. ...

Độ rộng hiển thị không giới hạn phạm vi của các giá trị có thể được lưu trữ trong cột, cũng như số chữ số được hiển thị cho các giá trị có chiều rộng vượt quá chỉ định cho cột. Ví dụ: một cột được chỉ định là SMALLINT (3) có phạm vi SMALLINT thông thường từ -32768 đến 32767 và các giá trị ngoài phạm vi cho phép của ba ký tự được hiển thị bằng nhiều hơn ba ký tự.

Để biết danh sách các giá trị tối đa và tối thiểu có thể được lưu trữ trong mỗi kiểu dữ liệu MySQL, xem tại đây .


18

Trích dẫn :

Đặc tả "BIGINT (20)" không phải là giới hạn chữ số. Nó chỉ có nghĩa là khi dữ liệu được hiển thị, nếu nó sử dụng ít hơn 20 chữ số, nó sẽ được đệm trái với các số không. 2 ^ 64 là giới hạn cứng cho loại BIGINT và có 20 chữ số, do đó BIGINT (20) chỉ có nghĩa là mọi thứ dưới 10 ^ 20 sẽ được đệm trái với khoảng trắng trên màn hình.


3
2 ^ 64 (không dấu) thực sự có 21 chữ số. BIGINT (20) là nguy hiểm. Những người sử dụng nó dường như biện minh cho việc sử dụng của họ trên ý tưởng rằng 2 ^ 64 phù hợp với 20 chữ số thập phân. Nếu đó là trường hợp, tại sao chỉ định giới hạn chiều rộng ở tất cả? Hóa ra, điều đó cũng không đúng. 21 chữ số là cần thiết để hiển thị đúng 2 ^ 64.
Heath Hunnicutt

@HeathHunnicutt Trừ khi tôi nhầm, 2 ^ 64 = 18446744073709551616, có 20 chữ số. Điều gì khiến bạn nói nó có 21?
drmercer

3

Theo tôi biết, chỉ có một sự khác biệt nhỏ là khi bạn đang cố gắng chèn giá trị nằm ngoài phạm vi.

Trong các ví dụ tôi sẽ sử dụng 401421228216, đó là 101110101110110100100011101100010111000(độ dài 39 ký tự)

  • Nếu bạn có INT(20)hệ thống, điều này có nghĩa là phân bổ trong bộ nhớ tối thiểu 20 bit. Nhưng nếu bạn sẽ chèn giá trị lớn hơn 2^20, nó sẽ được lưu trữ thành công, chỉ khi nó ít hơn INT(32) -> 2147483647(hoặc 2 * INT(32) -> 4294967295cho UNSIGNED)

Thí dụ:

mysql> describe `test`;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(20) unsigned | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
1 row in set (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SET sql_mode = '';
Query OK, 0 rows affected, 1 warning (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
Query OK, 1 row affected, 1 warning (0,06 sec)

mysql> SELECT * FROM `test`;
+------------+
| id         |
+------------+
| 4294967295 |
+------------+
1 row in set (0,00 sec)
  • Nếu bạn có BIGINT(20)hệ thống, điều này có nghĩa là phân bổ trong bộ nhớ tối thiểu 20 bit. Nhưng nếu bạn sẽ chèn giá trị lớn hơn 2^20, nó sẽ được lưu trữ thành công, nếu nó ít hơn BIGINT(64) -> 9223372036854775807(hoặc 2 * BIGINT(64) -> 18446744073709551615cho UNSIGNED)

Thí dụ:

mysql> describe `test`;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| id    | bigint(20) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
Query OK, 1 row affected (0,04 sec)

mysql> SELECT * FROM `test`;
+--------------+
| id           |
+--------------+
| 401421228216 |
+--------------+
1 row in set (0,00 sec)

1

Tôi muốn thêm một điểm nữa là, nếu bạn đang lưu trữ một số lượng thực sự lớn như 902054990011312 thì người ta có thể dễ dàng thấy sự khác biệt của INT(20)BIGINT(20). Đó là khuyến khích để lưu trữ trong BIGINT.


1

Hãy lấy một ví dụ cho int (10) một với từ khóa zerofill, một không, bảng thích:

create table tb_test_int_type(
    int_10 int(10),
    int_10_with_zf int(10) zerofill,
    unit int unsigned
);

Hãy chèn một số dữ liệu:

insert into tb_test_int_type(int_10, int_10_with_zf, unit)
values (123456, 123456,3147483647), (123456, 4294967291,3147483647) 
;

Sau đó

select * from tb_test_int_type; 

# int_10, int_10_with_zf, unit
'123456', '0000123456', '3147483647'
'123456', '4294967291', '3147483647'

Chúng tôi có thể thấy điều đó

  • với từ khóa zerofill, num dưới 10 sẽ điền 0, nhưng không có zerofillnó sẽ không

  • Thứ hai với từ khóa zerofill, int_10_with_zf trở thành kiểu int không dấu, nếu bạn chèn một dấu trừ bạn sẽ gặp lỗi Out of range value for column...... Nhưng bạn có thể chèn trừ vào int_10. Ngoài ra nếu bạn chèn 4294967291 vào int_10, bạn sẽ gặp lỗiOut of range value for column.....

Phần kết luận:

  1. int (X) không có từ khóa zerofill, bằng với phạm vi int -2147483648 ~ 2147483647

  2. int (X) với từ khóa zerofill, trường bằng với phạm vi int không dấu 0 ~ 4294967295, nếu độ dài của num nhỏ hơn X, nó sẽ điền 0 sang trái

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.