I have declared a column of type NVARCHAR[MAX]
in SQL Server 2008, what would be its exact maximum characters having the MAX as the length?
marc_s
739k176 gold badges1345 silver badges1465 bronze badges
asked Jun 21, 2012 at 5:24
Jerameel RescoJerameel Resco
3,4997 gold badges24 silver badges30 bronze badges
0
The max size for a column of type NVARCHAR[MAX]
is 2 GByte of storage.
Since NVARCHAR
uses 2 bytes per character, that's approx. 1 billion characters.
Leo Tolstoj's War and Peace is a 1'440 page book, containing about 600'000 words - so that might be 6 million characters - well rounded up. So you could stick about 166 copies of the entire War and Peace book into each NVARCHAR[MAX]
column.
Is that enough space for your needs? :-]
answered Jun 21, 2012 at 5:26
marc_smarc_s
739k176 gold badges1345 silver badges1465 bronze badges
3
From MSDN Documentation
nvarchar [ [ n | max ] ]Variable-length Unicode string data. n defines the string length and can be a value from 1 through 4,000. max indicates that the maximum storage size is 2^31-1 bytes [2 GB]. The storage size, in bytes, is two times the actual length of data entered + 2 bytes
Trong nội dung bài viết trước, mình đã chia sẻ về "Kiểu dữ liệu dạng số - Numeric Data Types". Các bạn khi đọc bài viết ấy nhớ để ý những phần LƯU Ý của mình ở đầu bài, cũng như trong bài viết nhé. Đặc biệt là lưu ý những bài viết trong series Fullstack Vỡ Lòng của mình đang sử dụng MySQL version 8.0.32, vì vậy có thể có những điểm bạn đọc thấy không giống với kiến thức ở các version trước hoặc sau này.
Hôm nay, mình sẽ chia sẻ tiếp phần tiếp theo trong chuỗi 3 bài về "Các kiểu dữ liệu thường dùng nhất trong MySQL", đó là String Data Types.
Mô tả chung về String Data Types
Anh em cần lưu ý rằng: Các kiểu dữ liệu có thể có cách đặt tên KHÁC NHAU ở các HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU KHÁC NHAU. Ví dụ: Nhiều bạn đã từng dùng các hệ quản trị cơ sở dữ liệu khác như SQL Server chẳng hạn, khi chuyển sang học MySQL sẽ không thấy kiểu dữ liệuNVARCHAR
,UNIQUEIDENTIFIER
. Các bạn có thể coi điều là này BÌNH THƯỜNG, giống như ngôn ngữ lập trình vậy đó, Java và C# cùng dùng trong lập trình hướng đối tượng, nhưng cú pháp của nó cũng khác nhau kha khá. String Data Types trong MySQL bao gồm rất nhiều kiểu dữ liệu khác nhau nhưCHAR
,VARCHAR
,TEXT
,BINARY
,VARBINARY
,BLOB
,ENUM
,SET
. Tuy nhiên, trong khuôn khổ bài viết này, mình sẽ chỉ tập trung vào những kiểu dữ liệu thường được dùng nhất, đó làCHAR
,VARCHAR
vàTEXT
. Các kiểu dữ liệu còn lại trong String Data Types, các bạn có thể tìm hiểu thêm trên document của MySQL tại đây.1. CHAR và VARCHAR
Kiểu dữ liệuCHAR
vàVARCHAR
tương đối giống nhau. CảCHAR
vàVARCHAR
đều cho phép bạn chỉ định độ dài tối đa cho số ký tự mà bạn muốn lưu trữ. Ví dụ: Một cột có kiểu dữ liệuUNIQUEIDENTIFIER`7 tức là bạn có thể lưu trữ tối đa 30 ký tự. SỰ KHÁC NHAU giữa chúng nằm ở 4 điểm sau: Cách lưu trữ dữ liệu vào. Các khoảng trắng ở cuối [trailing spaces]. Maximum length.
sẽ được fix cố định sau khi bạn tạo bảng. Ví dụ bạn khai báo một cột là
- Cách lấy dữ liệu ra. Điều kiện so sánh`UNIQUEIDENTIFIER`8`UNIQUEIDENTIFIER`9 Cách lưu trữ dữ liệu vào - Số ký tự của một cột có kiểu dữ liệu `CHAR
CHAR`1, thì tất cả các dữ liệu sau này được insert vào cột đó sẽ đều chiếm 36 ký tự, bất kể bạn nhập ít hay nhiều hơn 36 ký tự. - Nếu không bật strict mode, khi bạn cố insert một chuỗi có nhiều ký tự hơn max size, thì chuỗi đó sẽ bị cắt bớt đi để fit với size. Sẽ có warning đi kèm khi MySQL thực hiện việc này. - Ngược lại, nếu bạn bật strict mode, khi số ký tự dài hơn max size, MySQL sẽ trả về thông báo lỗi và không cho phép insert vào database. - Đối với các cột dữ liệu kiểu `CHAR
, việc cắt bỏ các khoảng trắng dư thừa ở cuối từ giá trị insert vào sẽ được thực hiện tự động mà không có warning, bất kể ở SQL mode nào. - CònVARCHAR
thì chỉ lưu trữ đúng số lượng ký tự mà bạn nhập vào, miễn là số ký tự đó nhỏ hơn hoặc bằngCHAR`4 mà bạn đã chỉ định khi khai báo. Chữ `CHAR`5 trong `VARCHAR
là viết tắt của từ Variable - Tương tựCHAR
, nếu không bật strict mode, khi bạn cố insert một chuỗi có nhiều ký tự hơn max size, thì chuỗi đó sẽ bị cắt bớt đi để fit với size. Sẽ có warning đi kèm khi MySQL thực hiện việc này. - Ngược lại, nếu bạn bật strict mode, khi số ký tự dài hơn max size, sẽ trả về thông báo lỗi và không cho phép insert vào database. - Đối với các cột dữ liệu kiểuVARCHAR
, các khoảng trắng ở cuối cũng sẽ được cắt đi, nhưng sẽ có đi kèm với warning message. Các khoảng trắng ở cuối [trailing spaces] - Khi lưu dữ liệu, nếu số ký tự của chuỗi bạn nhập vào nhỏ hơnCHAR`4, thì MySQL sẽ tự thêm các khoảng trắng vào bên phải của chuỗi đó, cho đến khi số ký tự của chuỗi bằng với `CHAR`4 - Đối với `VARCHAR
, MySQL sẽ KHÔNG TỰ THÊM khoảng trắng ở cuối chuỗi insert vào. Maximum length`CHAR`4 của CHAR có thể có giá trị từVARCHAR`3 đến `VARCHAR`4 - Trong khi với `VARCHAR
,CHAR`4 có thể có giá trị từ `VARCHAR`3 đến `VARCHAR`8. - Các bạn cần ĐẶC BIỆT LƯU Ý, độ dài tối đa của `VARCHAR
còn tùy thuộc vào maximum row size [TEXT`0, được chia sẻ cho tất cả các cột] và character set được sử dụng là gì. - Ví dụ dễ hiểu về một trường hợp lỗi sau đây, mặc dù các giá trị `CHAR`4 trong từng cột `VARCHAR
vẫn nhỏ hơnVARCHAR`8. Nhưng khi cộng tổng tất cả các cột vào thì nó đã lên tới `TEXT`4 > `VARCHAR`8. Và MySQL đã trả về thông báo lỗi Row size too large:
hayCách lấy dữ liệu ra Khi lấy dữ liệu ra, MẶC ĐỊNH các khoảng trắng ở đầu và cuối chuỗi sẽ được loại bỏ [trim] Khi lấy dữ liệu ra, các khoảng trắng ở đầu và cuối chuỗi sẽ KHÔNG BỊ LOẠI BỎ. - Ví dụ dưới đây sẽ giúp bạn hiểu rõ hơn:Bổ sung thêm một ví dụ, mô tả sự khác nhau giữa `TEXT`6 và `TEXT`7:LƯU Ý: Giá trị ở dòng cuối cùng trong bảng trên, sẽ chỉ đúng trong trường hợp strict mode bị tắt. Còn nếu bạn bật strict mode, và chuỗi insert vào vượt quá giá trị max size, thì chuỗi đó sẽ không được lưu lại, kèm theo một thông báo lỗi.Một thuật ngữ khá phổ biến trong lập trình đó là "Tradeoff" - "Đánh đổi". Trong trường hợp để lựa chọn kiểu dữ liệu cho một cột là `CHAR VARCHAR
, bạn cũng cần cân nhắc giữa những sự đánh đổi này, đặc biệt trong trường hợp bảng dữ liệu của bạn lên tới HÀNG TRIỆU DÒNG, hoặc đánh index cho các cột : Đánh đổi thứ nhất:VARCHAR
lưu chuỗi theo độ dài của chính nó [variable-length], chứ không thêm các khoảng trắng vào cuối nhưCHAR
[fixed-length]. Vì vậy, đối với những cột thường xuyên có sự khác nhau giữa độ dài của các dòng trong bảng, thì lưu trữ theo kiểuVARCHAR
sẽ tối ưu hơn, tốn ít dùng lượng lưu trữ hơn. Đánh đổi thứ hai: Nhờ việc fix cứng chiều dài của mình, các thao tác chuỗi với kiểu dữ liệuCHAR
sẽ nhanh hơnVARCHAR
, vì các thao tác với chuỗi sẽ phải có thêm việc check length nếu bạn sử dụngVARCHAR
. Ví dụ với việc đánh index, trung bình việc tìm kiếm dữ liệu với index của cộtCHAR
sẽ nhanh hơn 20% so với cộtVARCHAR
.2. TEXT
Có 4 kiểu dữ liệuTEXT
làBINARY`9: "Tiny" nghĩa là nhỏ xíu, rất nhỏ. Các cột có kiểu dữ liệu `BINARY`9 sẽ có thể lưu các chuỗi với chiều dài tối đa là `VARCHAR`4 ký tự [= 28{2^8} - 1].
: normal-text, bình thường. Các cột có kiểu dữ liệu
- `TEXT
TEXT
sẽ có thể lưu các chuỗi với chiều dài tối đa làVARCHAR`8 ký tự [= 216{2^{16}} - 1]. `VARBINARY`5: "Medium" là trung bình. Các cột có kiểu dữ liệu `VARBINARY`5 sẽ có thể lưu các chuỗi với chiều dài tối đa là `VARBINARY`7 ký tự [= 224{2^{24}} - 1]. `VARBINARY`8: "Long" là dài. Các cột có kiểu dữ liệu `VARBINARY`8 sẽ có thể lưu các chuỗi với chiều dài tối đa là `BLOB`0 ký tự [= 232{2^{32}} - 1]. Trong dự án mình làm trước, có chức năng Soạn mail và Gửi mail marketing. Để lưu trữ được nội dung HTML của email marketing mà người dùng đã soạn, thì mình đã phải sử dụng đến kiểu ký tự `VARBINARY`5 mới đủ để lưu trữ. Nếu các bạn đã đọc bài viết về "Kiểu dữ liệu dạng số - Numeric Data Types" thì sẽ thấy một sự KHÔNG NHẤT QUÁN nho nhỏ trong cách đặt tên của MySQL. Đó là: Với kiểu dữ liệu `BLOB`2, thì size của `BLOB`3 sẽ lớn hơn `BLOB`4. Tuy nhiên, khi đặt tên với `TEXT
, thì MySQL lại để max length củaTEXT
nhỏ hơnVARBINARY`5 😮💨 Vì vậy, các bạn hãy để ý điểm này để không bị nhầm nhé. Sự khác nhau giữa `TEXT
vớiCHAR
,VARCHAR
: TEXT CHAR[size], VARCHAR[size] Fix cứng max size làVARCHAR`8 ký tự [bạn không thể tùy biến giá trị max size này] Bạn có thể tùy biến giá trị size để quyết định số ký tự trong một cột. Giá trị size sẽ nằm trong khoảng từ `VARCHAR`3 đến `VARCHAR`8. - Nếu muốn đánh index cho cột có kiểu dữ liệu `TEXT
, bạn cần phải chỉ định số ký tự bạn sẽ đánh index cho một cột có kiểu dữ liệu TEXT.- Ví dụ:
ENUM`5 - Ý nghĩa của đoạn code trên là bạn sẽ đánh index cho cột `ENUM`6, nhưng sẽ chỉ sử dụng 10 ký tự đầu tiên trong các giá trị của cột `ENUM`6 này. - Ngoại trừ một trường hợp đặc biệt, nếu bạn vẫn muốn đánh index sử dụng tất cả ký tự trong cột `TEXT
, bạn có thể đánh index kiểuENUM`9. Tuy nhiên, MySQL khuyến nghị cách đánh index `ENUM`9 sẽ chậm hơn. Vì vậy, nếu muốn đánh index cho cột, thì bạn nên lựa chọn `CHAR
hoặc`VARCHAR` nếu có thể.TÀI LIỆU THAM KHẢO
String Data Types - MySQL 8.0 Reference Manual: //dev.mysql.com/doc/refman/8.0/en/string-types.html MySQL Data Types - w3schools: //www.w3schools.com/mysql/mysql_datatypes.asp Ngoài ra, các bạn cũng có thể follow page Facebook và channel Youtube này để cập nhật những thông tin thú vị về Lập trình nhé: Facebook Youtube