- vừa được xem lúc

Fullstack Vỡ Lòng 04: Các kiểu dữ liệu thường dùng nhất trong MySQL - Numeric Data Types

0 0 23

Người đăng: Trần Minh Sáng

Theo Viblo Asia

GIỚI THIỆU CHUNG VỀ SERIES 3 BÀI VIẾT LIÊN QUAN ĐẾN KIỂU DỮ LIỆU:

  • Kiểu dữ liệu (Data Type) của một column trong bảng, giúp chúng ta định nghĩa được giá trị mà column đó có thể giữ là gì. Chúng có thể là integer, character, date, time, binary, ...
  • Mỗi column trong bảng BẮT BUỘC phải có 2 thành phần:
    • Tên
    • Kiểu dữ liệu.
  • Khi thiết kế database, chúng ta cần xác định được kiểu dữ liệu sẽ lưu trong mỗi column là gì. Kiểu dữ liệu sẽ giúp cho SQL hiểu được chúng ta mong muốn lưu dữ liệu như thế nào trong column tương ứng. Bên cạnh đó, nó cũng xác định cách SQL sẽ tương tác với những dữ liệu đã được lưu trữ.
  • Ban đầu mình dự định sẽ viết một bài viết chung để mô tả ngắn gọn hết tất cả các kiểu dữ liệu thường dùng. Tuy nhiên, sau nhiều lần đắn đo, mình cảm thấy có NHIỀU ĐIỀU HAY HO HƠN để viết về các kiểu dữ liệu. Dựa trên kinh nghiệm làm việc thực tế thì mình thấy các bạn sinh viên/fresher/junior NÊN BIẾT những kiến thức này, không đơn giản là chỉ cần nắm được trong MySQL có những kiểu dữ liệu nào, mà chúng ta cũng cần hiểu rõ SỰ KHÁC NHAU giữa những kiểu dữ liệu nhìn có vẻ "TỰA TỰA GIỐNG NHAU". Trường hợp nào thì nên dùng kiểu A, trường hợp nào thì nên dùng kiểu B.
  • Do đó, nội dung về "Các kiểu dữ liệu thường dùng nhất trong MySQL" sẽ được chia làm 3 phần:
    • Numeric Data Types: BIT, TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, BOOL, FLOAT, DOUBLE, DECIMAL.
    • String Data Types: CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT.
    • Date and Time Data Types: DATE, TIME, DATETIME, TIMESTAMP

LƯU Ý:

  • Những kiến thức trong bài viết sẽ áp dụng với MySQL version 8.0.32.
  • Do đó, nó có thể sẽ không đúng với các version trước đó, hoặc những version trong tương lai của MySQL.
  • Nếu các bạn học và thực hành theo những chia sẻ trong series "Fullstack Vỡ Lòng" của mình, thì hãy lưu ý sử dụng MySQL version 8.0.32 nhé.

Trong nội dung bài hôm nay, mình sẽ chia sẻ về "Kiểu dữ liệu dạng số - Numeric Data Types"

Mô tả chung về Numeric 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 đó, JavaC# 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á.
  • Cùng là kiểu dữ liệu dạng số, nhưng chúng ta có thể phân tách nhỏ hơn nữa thành 4 KIỂU NHỎ HƠN KHÁC NHAU, bao gồm:
    • Bit-Value Type
    • Integer Types
    • Fixed-Point Types
    • Floating-Point Types numeric.png

1. Bit-Value Type

BIT

  • Có rất nhiều bạn HỌC LƯỚT phần này, nên HIỂU NHẦM rằng "khi set 1 cột có kiểu dữ liệu BIT, thì giá trị của cột đó chỉ có thể có duy nhất 2 giá trị là 01."
    • Thực tế, kết luận trên chỉ đúng với trường hợp mặc định, khi ta không set số lượng bit có thể có trong một cột (chỉ có chữ BIT, không có phần mở ngoặc đơn đi kèm), hoặc ta set cột đó có kiểu dữ liệu là BIT(1)
    • Còn khi ta muốn dùng nhiều hơn 1 bit để lưu các giá trị, thì ta có thể khai báo kiểu dữ liệu của cột đó là BIT(size). Với size là số lượng bit có thể lưu trữ trong một cột. Trong đó, size có thể có giá trị từ 1 đến 64.
  • Và khi sử dụng giá trị size từ 2 trở lên, các bạn sinh viên lại thường có thêm một HIỂU LẦM PHỔ BIẾN nữa như sau:
  • Ví dụ: Khi set một cột trong bảng có kiểu dữ liệu là BIT(2), nhiều bạn nghĩ rằng dữ liệu của chúng sẽ chỉ có thể các giá trị 00, 01, 10, 11 -> ĐIỀU NÀY LÀ SAI HOÀN TOÀN
    • Các bạn có thể thử và kiểm nghiệm, nếu insert vào dữ liệu là 10 thì MySQL sẽ báo lỗi Data too long for column 'X' at row 1.
    • Lý do là vì: Khi insert giá trị 10, MySQL đang hiểu đó là số dạng thập phân, chuyển đổi sang dạng nhị phân sẽ có giá trị là 1010, tức là cần dùng 4 bit, nhiều hơn 2 bit so với kiểu dữ liệu BIT(2) mà bạn đang set. Do đó, nó mới trả về lỗi Data too long for column 'X' at row 1.
    • Vậy làm sao để chúng ta có thể lưu chuỗi bit có giá trị 10 trong trường hợp này? Trong MySQL, có 2 cách để các bạn làm được việc đó:
      • Cách 1: Các bạn insert vào cột đó dữ liệu là số 2dạng thập phân. Vì số 2 khi chuyển sang nhị phân sẽ có giá trị là 10. Đúng với giá trị mình đang muốn lưu trữ.
      • Cách 2: Các bạn insert vào cột dữ liệu là b'10'. Đây là cú pháp chuẩn trong MySQL để lưu dữ liệu dạng bit.
    • Nếu sử dụng công cụ dbForge Studio for MySQL để xem dữ liệu, các bạn sẽ thấy, dù dùng Cách 1 hay Cách 2 ở trên thì khi select dữ liệu ta cũng sẽ nhìn thấy con số 2 ở dạng thập phân (Các bạn có thể xem thêm nội dung giới thiệu công cụ dbForge Studio for MySQL tại link sau: Fullstack Vỡ Lòng 03: Công cụ quản trị cơ sở dữ liệu - dbForge Studio for MySQL)
    • Nếu muốn xem dạng nhị phân của dữ liệu đó, các bạn có thể dùng hàm BIN() khi SELECT:
  • Điểm cần lưu ý thứ 3, đó là nếu bạn insert một giá trị nhị phân có số bit nhỏ hơn size, thì MySQL sẽ tự động thêm vào bên trái giá trị nhị phân đó các bit 0.
    • Ví dụ: insert giá trị b'101' vào một cột có kiểu dữ liệu là BIT(6), sẽ tương đương với việc insert giá trị b'000101'

2. Integer Types

  • Các bạn sinh viên/fresher/junior hãy ĐẶC BIỆT LƯU Ý phần này nhé, vì khi làm việc với các bạn fresher ở công ty mình, mình thấy các bạn ấy hầu như lúc nào cũng sử dụng INT.

    • Có thể vì nó quen thuộc khi học trên trường, hoặc các bạn không biết ngoài INT ra thì còn có các kiểu dữ liệu khác để thể hiện cho Integer nữa.
    • Tựu chung lại là do các bạn ấy chưa thực sự hiểu khi nào thì nên dùng INT, khi nào thì không.
  • Ngoài 2 kiểu dữ liệu Integer tiêu chuẩn mà hệ quản trị cơ sở dữ liệu quan hệ nào cũng có là INTSMALLINT, thì MySQL còn hỗ trợ thêm một số kiểu dữ liệu Integer khác như: TINYINT, MEDIUMINTBIGINT.

  • Có thể thấy ngay sự khác nhau khi nhìn vào phần prefix của các kiểu dữ liệu này:

    • TINY: "nhỏ xíu, rất nhỏ"
    • SMALL: "nhỏ"
    • MEDIUM: "trung bình"
    • BIG: "lớn"
  • Và điều này cũng đúng khi chúng ta nhìn vào sự khác nhau giữa phạm vi lưu trữ dữ liệu của chúng: image.png

  • Các bạn hãy ĐẶC BIỆT CHÚ Ý vào cột Storage (Bytes), bởi vì con số này sẽ luôn là cố định, dù cho con số mà bạn lưu trữ có thực sự cần đến 4 bytes hay không.

    • Ví dụ: Bạn muốn lưu số 1, bạn hoàn toàn có thể dùng cả 5 kiểu dữ liệu trên. Tuy nhiên, kiểu dữ liệu BIGINT sẽ sử dụng 8 bytes để lưu số 1 này, trong khi TINYINT chỉ cần sử dụng 1 bytes
  • Thêm vào đó, trong quá trình làm việc thực tế, một điều QUAN TRỌNG các bạn cần phải hiểu đó là lựa chọn kiểu dữ liệu nào trong 5 kiểu trên trong một bài toán.

    • Ví dụ:
      • Chúng ta có một cột tên là EmployeeCount, dùng để lưu số lượng nhân viên của một công ty.
      • Nếu chúng ta sử dụng kiểu dữ liệu INT thì sẽ là rất DƯ THỪA.
      • Bởi vì số lớn nhấtINT có thể lưu lên tới hơn 4 tỷ.
      • Trong khi công ty lớn nhất trên thế giới hiện tại cũng chỉ có khoảng 2.3 triệu nhân viên (theo Wikipedia) image.png
      • Vì vậy, trong bài toán này, thực tế bạn chỉ cần dùng MEDIUMINT là đã đủ để lưu thoải mái EmployeeCount, vì MEDIUMINT có thể lưu các số từ 0 đến hơn 16 triệu

BOOL, BOOLEAN

  • Nhiều bạn nghĩ kiểu dữ liệu BOOL, BOOLEAN phải nằm trong nhóm Bit-Value Type chứ.
  • Nhưng thực tế thì không phải như vậy. BOOLBOOLEANtương tự với TINYINT(1). Trong đó, Giá trị 0 tương ứng với false. Các giá trị khác 0 tương ứng với true. image.png
  • Ngoài ra, các bạn cũng cần hiểu rõ ràng rằng, các giá trị TRUEFALSE chỉ là bí danh tương ứng cho 10, như ở ví dụ dưới đây:

image.png

  • 2 câu lệnh SELECT dưới cùng chỉ ra rằng: phép so sánh 2 = TRUE2 = FALSEfalse.
  • Chỉ có 1 = TRUE0 = FALSE, thì mới trả về kết quả là true.

3. Fixed-Point Types và Floating-Point Types

  • Mình gom 2 loại này vào chung một mục để so sánh cho các bạn thấy sự khác nhau giữa chúng
  • Fixed-Point Types có 2 kiểu dữ liệu đại diện là DECIMALNUMERIC.
    • Trong MySQL, NUMERIC cũng được implemented giống hệt DECIMAL. Vì vậy, các nội dung phía dưới mình sẽ chỉ mô tả với DECIMAL, các bạn có thể hiểu là NUMERIC thì cũng như thế.
  • Còn với Floating-Point Types, cũng có 2 kiểu dữ liệu đại diện là FLOATDOUBLE.
  • Về Phạm vi lưu trữ dữ liệu:
    • FLOAT cho phép lưu trữ dữ liệu có giá trị từ -3.402823466E+38 đến -1.175494351E-38, 0, và từ 1.175494351E-38 đến 3.402823466E+38.
    • DOUBLE cho phép lưu trữ dữ liệu có giá trị từ -1.7976931348623157E+308 đến -2.2250738585072014E-308, 0, và từ 2.2250738585072014E-308 đến 1.7976931348623157E+308.
    • DECIMAL(size, d), trong đó:
      • sizetổng toàn bộ các số kể cả phần nguyên và phần thập phân (tiếng Anh gọi là precision). Giá trị tối đa của size65. Nếu size không được khai báo thì mặc định sẽ lấy giá trị 10.
      • dtổng các số ở phần thập phân, phía sau dấu chấm (tiếng Anh gọi là scale). Giá trị tối đa của d30. Nếu d không được khai báo thì mặc định sẽ lấy giá trị 0. image.png
  • Ngoài phạm vi lưu trữ dữ liệu, thì sự khác nhau lớn nhất giữa FLOAT/DOUBLE vs DECIMAL là "FLOATDOUBLE gây ra vấn đề về việc làm tròn số".
    • Ví dụ: Nếu bạn thực hiện phép toán 0.1 + 0.2, bạn sẽ nhận được kết quả là 0.30000000000000004.

    • Do đó, thường thì các dữ liệu về tiền tệ sẽ không nên lưu theo kiểu dữ liệu Floating-Point như FLOAT hay DOUBLE.

    • Các bạn có thể xem ví dụ dưới đây để hiểu rõ hơn sự khác nhau này: image.png

    • Chúng ta tạo ra một bảng có tên là t1, trong đó bao gồm ba cột là i, d1d2. Với d1d2 có kiểu dữ liệu DOUBLE.

    • Sau đó, chúng ta insert thêm 4 bản ghi cho bảng t1

    • Rồi thực hiện câu lệnh SELECT để tính tổng hai cột d1d2, với điều kiện sẽ chỉ SELECT ra dữ liệu nếu "tổng của cột d1" KHÁC "tổng của cột d2".

    • Theo phép cộng thông thường, chúng ta có thể dễ dàng tính toán được là: sum(d1) = 0-13.2+59.6+30.4 = 76.8 = sum(d2) = 0+0+46.4+30.4

    • Tuy nhiên, kết quả của MySQL cho thấy, 2 giá trị của sum(d1)sum(d2) là khác nhau 0.00000000000001

    • Cùng dữ liệu như vậy, nếu chúng ta lưu d1d2 là kiểu DECIMAL thì kết quả sẽ đúng như mong đợi: 2 tổng sum(d1)sum(d2)kết quả giống nhau (Kết quả trả về của câu SELECTEmpty set, bởi vì nó đang kiểm tra điều kiện nếu sum(d1) != sum(d2) thì mới SELECT ra dữ liệu. Trường hợp này sum(d1)sum(d2) bằng nhau nên kết quả trả về là Empty set.) image.png

TÀI LIỆU THAM KHẢO

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

Bình luận

Bài viết tương tự

- vừa được xem lúc

Index trong Mysql và cách sử dụng

Một số database là một cấu trúc dữ liệu để cải thiện tốc độ của các hoạt động trong một bảng. Trong khi tạo index, nó cần được xem xét rằng các cột đó sẽ được sử dụng để thực hiện các truy vấn SQL và tạo ra một hoặc nhiều chỉ số trên các cột đó là gì.

0 0 43

- vừa được xem lúc

Tạo ER Diagram của một Database bằng MySQL Workbench

Trong số chúng ta ai cũng đều đã từng trải qua một thời sinh viên tràn ngập đồ án này, đồ án kia đúng không? Mình cũng đã từng có một thời như thế Mà chuyên ngành chúng ta là công nghệ thông tin thì làm việc với Database trong mỗi đồ án là điều không thể thiếu rồi. Chuyện sẽ chẳng có gì to tát cho đ

0 0 65

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần II).

Chào mọi người, lại là mình đây, ở phần trước mình đã giới thiệu với mọi người về Window Functions Phần I. Nếu chưa rõ nó là gì thì mọi người nên đọc lại trước nha, để nắm được định nghĩa và các key words, tránh mắt chữ O mồm chứ A vì phần này mình chủ yếu sẽ thực hành với các Window Functions.

0 0 107

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần I).

Chào mọi người, mình mới tìm hiểu đc topic Window Functions cá nhân mình cảm thấy khá là hay và mình đánh giá nó là phần nâng cao. Vì ít người biết nên Window Functions thấy rất ít khi sử dụng, thay vì đó là những câu subquery dài dằng dặc như tin nhắn nhắn cho crush, và người khác đọc hiểu được câu

0 0 923

- vừa được xem lúc

Mysql index strategy

Trong Mysql, index hỗ trợ việc tìm kiếm các rows theo từng giá trị của các columns trong bảng trở nên nhanh chóng. Việc tìm kiếm sẽ phải scan toàn bộ table nếu các column trong câu query không được đánh index một cách thích hợp. . .

0 0 65

- vừa được xem lúc

CRUD Nodejs với mysql

Mở Đầu. Xin chào các bạn tiếp tục với series Nodejs cơ bản, bài hôm nay mình sẽ tiếp tục làm thêm các chức năng xem chi tiết và sửa và xóa sản phẩm.

0 0 77