+7

Fullstack Vỡ Lòng 06: Các kiểu dữ liệu thường dùng nhất trong MySQL - Date and Time Data Types - TƯỞNG KHÔNG KHÓ, MÀ LẠI KHÓ KHÔNG TƯỞNG

Mayfest2023

🙍‍♀️ Chị Tester: "Con lươn kiaaaaaa, mày lại đây chị bảoooooo 😡 Sao chị vừa Thêm mới một email lúc 9h13, mà trên màn hình danh sách nó hiện lên là "Chỉnh sửa gần nhất" lúc 2h13 thế nàyyyyyy???"

👼 Anh Dev Frontend Ngây Ther: "Chị đùa em àaaaaaaa. Chị có nhớ nhầm email không. Chị check xem có đúng email chị vừa tạo không? Nhà bao việc 😫"

🙍‍♀️ Chị Tester: "Từ qua đến nay có mỗi tau tạo email thôi mày. M nghĩ tau rảnh 2h sáng dậy test email cho m à 🙃"

👼 Anh Dev Frontend Ngây Ther: "Đâu em xem nào. Hay có ông nào sửa nhầm email của chị"

🙍‍♀️ Chị Tester: "M hâm à. Tau tạo email này lúc 9h sáng, mà giờ nó báo "Chỉnh sửa gần nhất" lúc 2h sáng. M không thấy vô lý àaaaaa con điêng kia 🤬"

👼 Anh Dev Frontend Ngây Ther: "Ờ nhỉ. Ảo v~. Thôiiiiii. Em không biết đâu. Chị hỏi thằng làm Backend ý. Nó cung cấp API thế nào thì em dùng thế thôi. Ai mà biết được 😒"

🙆‍♂️ Anh Dev Backend Vô Số Tội: "M ảo à. T test đi test lại API rồi có vấn đề gì đâu. M lại đây 🤨"

*🙆‍♂️ Anh Backend mở Postman gọi thử API demo cho anh Frontend xem*

*👼 Anh Frontend gãi đầu lia lịa*

*🙍‍♀️ Chị Tester ngày càng nóng mắt*

🙍‍♀️ Chị Tester: "Thế giờ tóm lại như nàoooooo. Chúng m có định phát hành không 2 con lươn này."

*Vấn đề vẫn đang rơi vào bế tắc. Tu bi con tì niu...*


Những anh em đã có kinh nghiệm lập trình, chắc hẳn khi đọc câu chuyện trên sẽ thấy rất thân quen, có thể chính anh em đã từng gặp phải khi mới vào nghề.

Còn những anh em hiện đang là sinh viên/fresher/junior, thậm chí có thể còn chưa từng nghĩ tới case này luôn.

Gần như 100% anh em fresher mình đã từng làm việc cùng, và chính bản thân mình khi mới làm dự án, cũng đã gặp phải vấn đề với Date & Time này.

Đó cũng là lý do mà mình tách phần Date and Time Data Types ra thành một bài viết riêng.

Bây giờ, chúng ta hãy cùng đi vào nội dung chính:

Lưu ý chung

  • Trong series Fullstack Vỡ Lòng, mình đang sử dụng MySQL version 8.0.32 để chia sẻ với các bạn. Do đó, nó có thể sẽ không mapping hoàn toàn với các hệ quản trị cơ sở dữ liệu khác như SQL Server hay PostgreSQL.
  • Ví dụ sẽ có thể có kiểu dữ liệu khác hoặc 2 kiểu dữ liệu cùng tên ở 2 hệ cơ sở dữ liệu khác nhau nhưng phạm vi lưu trữ của chúng lại khác nhau.
  • Vì vậy, các bạn hãy lưu ý điều này khi đọc bài viết của mình ha.

Những kiểu dữ liệu dạng Date and Time thường dùng

image.png

Ngoài ra còn có kiểu dữ liệu TIMEYEAR, nhưng chúng ít được sử dụng hơn. Các bạn có thể đọc thêm về 2 kiểu dữ liệu này tại document của MySQL nhé.

Sự khác nhau giữa DATETIME và TIMESTAMP

Ví dụ demo:

👉️ Link GitHub: https://github.com/tmsangdev/difference-between-datetime-and-timestamp-mysql

Các bạn có thể thử nghiệm trong dbForge Studio for MySQL

  • Bước 1: Chạy câu lệnh SHOW VARIABLES LIKE '%time_zone%'; để biết time zone hiện tại trên máy mình là bao nhiêu. Hiện tại máy mình là +07:00 image.png
  • Bước 2: Chạy 3 câu lệnh kế tiếp để Tạo bảng, INSERT dữ liệuSELECT dữ liệu từ bảng DateDemo image.png
  • Bước 3: Chạy câu lệnh SET TIME_ZONE="-12:00"; để chuyển sang time zone khác
  • Bước 4: Chạy lại câu lệnh SELECT * FROM DateDemo; để thấy sự khác nhau. Dữ liệu hiển thị khi SELECT của cột DATETIME vẫn không đổi, trong khi cột TIMESTAMP sẽ bị thay đổi theo time zone -12:00 image.png

Quay lại với Giải pháp khắc phục vấn đề ở đầu bài

  • Giải pháp mà trước giờ dự án của mình vẫn sử dụng đó là:

    • Trong code Backend (ví dụ C#, Java, PHP), trước khi lưu dữ liệu xuống MySQL, bọn mình sẽ convert từ time zone của Backend sang time zone +00:00, và lưu xuống Database dạng DATETIME.
    • Khi lấy dữ liệu từ MySQL ra, code Backend sẽ convert lại từ time zone +00:00 sang time zone mà Frontend yêu cầu (Frontend có thể truyền thông tin time zone yêu cầu này vào request header khi gọi xuống Backend ).
    • Một VẤN ĐỀ của giải pháp này là, nếu có anh em Dev nào không làm đúng 2 bước trên, ví dụ khi lưu dữ liệu vào Database, bạn ấy vẫn đề time zone +07:00 chẳng hạn, thì lúc convert dữ liệu ngược lại lấy ra từ Database sẽ khiến kết quả bị sai.
    • Hiện tại, dự án mình vẫn đang chấp nhận sự ĐÁNH ĐỔI (Tradeoff) đó, chấp nhận rằng có thể kết quả sẽ có thể bị sai. Để xác suất xảy ra sai sót thấp nhất có thể, thì Dev sẽ phải là người cẩn thận đầu tiên, sau đó Dev Lead hoặc SA là người review cũng phải soi kỹ những đoạn code với DateTime. Và cuối cùng là Tester sẽ test kỹ những trường hợp này.
  • Vậy còn dự án của các bạn đang làm thì sao? Nếu các bạn có giải pháp nào hay hơn thì có thể comment dưới bài viết này để chúng ta cùng học tập lẫn nhau nhé 🫶

(Updated 17/05/2023: Dưới phần comment, bạn Đỗ Văn Cường có chia sẻ chi tiết về giải pháp mà bạn và dự án của bạn ấy đang áp dụng. Rất hay và rõ ràng, các bạn có thể tham khảo nhé. Upvote cho Cường nếu các bạn cảm thấy hữu ích nha 🫶)

Kinh nghiệm để Dev test các case liên quan đến Date and Time Data Types, trước khi bàn giao cho Tester

  1. Trao đổi rõ ràng với đồng nghiệp làm vị trí BA (Business Analyst) xem khách hàng của mình là ai. Mục tiêu của dự án có phải là phát triển mạng lưới người dùng đa quốc gia hay không? Bởi vì, ví dụ dự án của bạn đang làm sản phẩm cho đơn vị hành chính nhà nước, muôn đời sẽ chỉ phục vụ cho người dùng Việt Nam, trên lãnh thổ Việt Nam với múi giờ +7, thì vấn đề về Date and Time Data Types sẽ nhẹ nhàng hơn nhiều.
  2. Kiểm tra chức năng hoạt động đúng hay sai: Đang lấy theo ngày giờ của client hay server.
  3. Kiểm tra Date Picker có click để lựa chọn được không?
  4. Kiểm tra tính ràng buộc giữa các trường dữ liệu như Ngày bắt đầu <= Ngày kết thúc, Giờ bắt đầu <= Giờ kết thúc.
  5. Trường hợp được nhập datetime thì kiểm tra giá trị ngày thứ 31 của tháng 4, 6, 9, 1130 ngày.
  6. Trường hợp được nhập datetime thì kiểm tra giá trị ngày 29 của tháng 228 ngày - năm không nhuận.
  7. Trường hợp được nhập datetime thì kiểm tra giá trị ngày 29 của tháng 229 ngày - năm nhuận.
  8. Kiếm tra xem dữ liệu trả về có đúng với bộ lọc thời gian mình đã chọn hay không? Dev dự án mình đã từng gặp lỗi: Chọn thời gian lấy dữ liệu báo cáo là từ ngày thứ 2 đến chủ nhật tuần này, nhưng dữ liệu trả ra lại là từ thứ 3 tuần này đến thứ 2 tuần sau. Lý do là vì cách đặt số thứ tự trong code của thư viện khác với cách mà chúng ta đọc. Và bạn Dev quên mất điều đó.

(Phần chia sẻ về các case test thường dùng này, mình có tham khảo từ bài viết của tác giả Phạm Thị Thu Hằng. Một bài viết rất chất lượng trên Viblo, chia sẻ về Các trường hợp test cơ bản. Các bạn có thể đọc thử và ủng hộ tác giả nha)

Lời khuyên cuối

  • Trong ngành lập trình, "danh tiếng" (reputation) là một thứ rất quan trọng. Danh tiếng ở đây không phải mang ý nghĩa tiêu cực để ra oai, "ra dẻ" với ai, mà là để chúng ta nhìn lại xem bản thân làm việc đã thực sự "có tâm", đã tìm cách làm tốt nhất có thể hay chưa.

  • Nhiều anh em mới lần đầu đi làm thực tế, chắc hẳn sẽ cảm thấy năng suất làm việcsố bug phát sinh của mình với những anh em có kinh nghiệm khác như Dev Lead hay SA hình như còn cách xa nhau một trời một vực.

  • Việc này thường xảy ra bởi các nguyên nhân sau:

    • Chúng ta chưa va chạm với các bài toán thực tế bao giờ, nên chưa hình dung ra mức độ phức tạpvùng ảnh hưởng của chúng.
    • Do chúng ta làm việc cẩu thả, chỉ muốn làm ù ù cho xong.
    • Đôi khi là do muốn gây ấn tượng với đồng nghiệp, cấp trên nên chạy theo tốc độ nhiều quá, mà chưa thực sự chú trọng dành thời gian để ý đến chất lượng đầu ra.
    • ...
  • Để giải quyết vấn đề này, thì theo kinh nghiệm của mình, cách nhanh nhất là hãy đi HỎI.

    • Hỏi Google
    • Hỏi các anh em Dev đồng nghiệp
    • Hỏi Dev Lead, SA
    • Hỏi Tester
    • ...
  • Có một câu chuyện rất hay, mà anh SA trong dự án mình từng chia sẻ với anh em Dev như này:

Khi anh nhận được một bài toán, anh sẽ giành 80% thời gian để lên Giải pháp thi công, chuẩn bị các unit test thật cẩn thận, tỉ mỉ. Còn lại 20% thời gian anh sẽ dùng để code chức năng đó. Giống như câu nói nổi tiếng của Abraham Lincoln: "Nếu cho tôi 6 tiếng để đốn hạ một cái cây, tôi sẽ dành 4 tiếng đầu tiên để mài sắc lưỡi rìu."

lincoln.png

  • Và các bạn hãy ĐẶC BIỆT LƯU Ý, trước khi hỏi người khác, thì bạn hãy chuẩn bị ra các test case của mình trước nhé.

  • Đừng đi hỏi khi trong đầu trống rỗng. Tự nghĩ ra các test case hoặc Google khoảng 3 lần, để mình có những test case cơ bản trước. Sau đó mới đi nhờ các anh chị em đồng nghiệp review và góp ý kiến.

  • Như vậy bạn cũng sẽ được họ ghi nhận là đã cố gắng tìm hiểu và đưa ra giải pháp. Giải pháp hiện tại của bạn có thể chưa tối ưu, nhưng ít nhất không phải là CHƯA CÓ GÌ.

  • Đi hỏi với một cái đầu trống rỗng chẳng khác nào bạn đang đẩy công việc của mình cho người khác. Nó có thể ảnh hưởng đến sự phát triển về tư duy logic của chính các bạn sau này. Những gì cần suy nghĩ, cần sử dụng chất xám thì đồng nghiệp họ làm hết giúp bạn rồi còn đâu đúng không nào?

task.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: Tờ Mờ Sáng học Lập trình

Youtube: Tờ Mờ Sáng học Lập trình


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí