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ệu
NVARCHAR
,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ệu
CHAR
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ệu
CHAR(30)
tức là bạn có thể lưu trữ tối đa 30 ký tự.
- Ví dụ: Một cột có kiểu dữ liệu
- 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.
- Cách lấy dữ liệu ra.
Điều kiện so sánh | CHAR(size) |
VARCHAR(size) |
---|---|---|
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 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à CHAR(36) , 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òn VARCHAR 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ằng size mà bạn đã chỉ định khi khai báo. Chữ VAR 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ểu VARCHAR , 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ơn size , 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 size |
- Đối với VARCHAR , MySQL sẽ KHÔNG TỰ THÊM khoảng trắng ở cuối chuỗi insert vào. |
Maximum length | size của CHAR có thể có giá trị từ 0 đến 255 |
- Trong khi với VARCHAR , size có thể có giá trị từ 0 đến 65,535 . - 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 (65,535 bytes , đượ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ị size trong từng cột VARCHAR vẫn nhỏ hơn 65,535 . Nhưng khi cộng tổng tất cả các cột vào thì nó đã lên tới 66,000 > 65,535 . Và MySQL đã trả về thông báo lỗi Row size too large: |
Cá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
CHAR(4)
vàVARCHAR(4)
: -
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
hayVARCHAR
, 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ệu
CHAR
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
.
- Đánh đổi thứ nhất:
2. TEXT
-
Có 4 kiểu dữ liệu
TEXT
làTINYTEXT
: "Tiny" nghĩa là nhỏ xíu, rất nhỏ. Các cột có kiểu dữ liệuTINYTEXT
sẽ có thể lưu các chuỗi với chiều dài tối đa là255
ký tự (= - 1).TEXT
: normal-text, bình thường. Các cột có kiểu dữ liệuTEXT
sẽ có thể lưu các chuỗi với chiều dài tối đa là65,535
ký tự (= - 1).MEDIUMTEXT
: "Medium" là trung bình. Các cột có kiểu dữ liệuMEDIUMTEXT
sẽ có thể lưu các chuỗi với chiều dài tối đa là16,777,215
ký tự (= - 1).LONGTEXT
: "Long" là dài. Các cột có kiểu dữ liệuLONGTEXT
sẽ có thể lưu các chuỗi với chiều dài tối đa là4,294,967,295
ký tự (= - 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ự
MEDIUMTEXT
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
INTEGER
, thì size củaINT
sẽ lớn hơnMEDIUMINT
. - Tuy nhiên, khi đặt tên với
TEXT
, thì MySQL lại để max length củaTEXT
nhỏ hơnMEDIUMTEXT
😮💨 - Vì vậy, các bạn hãy để ý điểm này để không bị nhầm nhé.
- Đó là: Với kiểu dữ liệu
-
Sự khác nhau giữa
TEXT
vớiCHAR
,VARCHAR
:TEXT CHAR(size), VARCHAR(size) Fix cứng max size là 65,535
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ừ 0
đến65,535
.- 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ụ:CREATE TABLE test_table (text_col TEXT, INDEX(text_col(10)));
- Ý nghĩa của đoạn code trên là bạn sẽ đánh index cho cộttext_col
, nhưng sẽ chỉ sử dụng 10 ký tự đầu tiên trong các giá trị của cộttext_col
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ộtTEXT
, bạn có thể đánh index kiểuFULLTEXT
. Tuy nhiên, MySQL khuyến nghị cách đánh indexFULLTEXT
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ặcVARCHAR
nếu có thể.
TÀI LIỆU THAM KHẢO
- String Data Types - MySQL 8.0 Reference Manual: https://dev.mysql.com/doc/refman/8.0/en/string-types.html
- MySQL Data Types - w3schools: https://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