1. Database Migration là gì?

Database Migration là quá trình quản lý và áp dụng các thay đổi đối với cấu trúc hoặc dữ liệu trong database theo từng phiên bản có thể theo dõi và kiểm soát.

Trong quá trình phát triển phần mềm, database hiếm khi giữ nguyên cấu trúc từ đầu đến cuối. Ban đầu, hệ thống có thể chỉ có bảng users. Sau đó, khi nghiệp vụ phát triển, cần thêm bảng roles, bổ sung cột phone, tạo index cho email, thay đổi constraint hoặc chuyển đổi dữ liệu cũ sang cấu trúc mới.

2. Vì sao cần Database Migration?

Giữ database nhất quán giữa các môi trường

Một ứng dụng thường có nhiều môi trường:

  • Local: môi trường phát triển trên máy cá nhân.
  • Development: môi trường tích hợp dành cho đội phát triển.
  • Staging: môi trường kiểm thử gần với production.
  • Production: môi trường phục vụ người dùng thực tế.

Nếu mỗi môi trường được chỉnh sửa database theo cách thủ công, cấu trúc có thể khác nhau.

Migration giúp các môi trường áp dụng cùng một tập thay đổi theo cùng thứ tự. Tuy nhiên, điều đó chỉ hiệu quả khi quy trình triển khai thực sự chạy migration và không có những thay đổi thủ công ngoài quy trình.

Lưu lại lịch sử thay đổi schema

Giả sử bảng users ban đầu chỉ có:

CREATE TABLE users (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

Sau đó, hệ thống cần email:

ALTER TABLE users
ADD COLUMN email VARCHAR(255);

Vài tháng sau, email trở thành thông tin bắt buộc:

ALTER TABLE users
ALTER COLUMN email SET NOT NULL;

Đây là ba trạng thái schema khác nhau. Migration lưu lại các bước chuyển đổi giữa những trạng thái đó, giúp developer biết thay đổi nào đã diễn ra và thay đổi nào còn cần áp dụng.

Hỗ trợ làm việc nhóm

hi nhiều developer cùng làm việc trên một codebase, migration được lưu trong Git để mọi người có thể review, kiểm thử và triển khai cùng nhau.

Nếu một developer thêm cột phone, còn người khác thêm bảng orders, cả hai thay đổi có thể được theo dõi như một phần của lịch sử dự án.

3. Phân biệt Schema Migration và Data Migration

Schema Migration

Schema Migration thay đổi cấu trúc database, ví dụ:

  • Tạo bảng mới.
  • Thêm, đổi tên hoặc xóa cột.
  • Tạo index.
  • Thêm foreign key.
  • Thay đổi constraint.
  • Thay đổi kiểu dữ liệu.

Ví dụ:

ALTER TABLE users
ADD COLUMN phone VARCHAR(20);

Lệnh này thay đổi cấu trúc bảng users.

Data Migration

Data Migration chuyển đổi hoặc cập nhật dữ liệu đang tồn tại, ví dụ:

  • Chuyển dữ liệu từ cột cũ sang cột mới.
  • Chuẩn hóa định dạng số điện thoại.
  • Chuyển giá trị trạng thái từ dạng số sang dạng chuỗi.
  • Gộp dữ liệu từ nhiều bảng.
  • Tính toán và điền giá trị cho các bản ghi cũ.

Ví dụ:

UPDATE users
SET full_name = TRIM(first_name || ' ' || last_name)
WHERE full_name IS NULL;

Đây là ví dụ cho PostgreSQL, trong đó dữ liệu từ first_name và last_name được kết hợp vào full_name.

Trong thực tế, data migration có thể chạy hàng triệu bản ghi. Khi đó, cần quan tâm đến batch processing, thời gian thực thi, transaction, khả năng chạy lại và tác động lên hệ thống đang hoạt động.

4. Up Migration và Down Migration

Ví dụ tạo bảng users.

File 001_create_users.up.sql:

CREATE TABLE users (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

File 001_create_users.down.sql:

DROP TABLE users;

Lệnh up tạo bảng. Lệnh down xóa bảng.

Tuy nhiên, cần hiểu rằng Down Migration không phải lúc nào cũng khôi phục được dữ liệu ban đầu.

Nếu bảng đã được tạo và chứa dữ liệu thật, chạy DROP TABLE sẽ làm mất dữ liệu trong bảng. Nếu migration trước đó xóa một cột, migration down có thể tạo lại cột nhưng không khôi phục được giá trị đã mất.

5. Tổng kết

Database Migration là quy trình có phiên bản để quản lý thay đổi schema và dữ liệu trong suốt vòng đời ứng dụng.

Bài viết khác

Redis & Caching là gì?

Redis & Caching là gì? Hướng dẫn sử dụng Redis trong Go 1. Caching là gì? Vì sao cần cache khi đã có database? Caching (bộ nhớ đệm) là kỹ thuật lưu tạm dữ liệu thường được truy cập để có thể lấy lại nhanh chóng khi cần, thay vì phải thực hiện lại toàn […]

Database Migration là gì?

1. Database Migration là gì? Database Migration là quá trình quản lý và áp dụng những thay đổi đối với cấu trúc hoặc dữ liệu trong cơ sở dữ liệu theo từng phiên bản của ứng dụng. Trong quá trình phát triển phần mềm, yêu cầu nghiệp vụ thường xuyên thay đổi. Một bảng có […]

Bun ORM là gì?

Bun ORM là gì? Hướng dẫn sử dụng Bun ORM với Go và PostgreSQL 1. Bun ORM là gì? Bun là một thư viện ORM dành cho ngôn ngữ Go, được thiết kế theo hướng SQL-first. Thay vì cố gắng che giấu hoàn toàn SQL phía sau các phương thức trừu tượng, Bun cho phép […]

Redis & Caching – Hướng dẫn toàn diện về Cache, TTL, Cache Invalidation và tối ưu hiệu năng Backend

1. Caching là gì? Caching là kỹ thuật lưu tạm dữ liệu đã được tính toán hoặc truy xuất trước đó để có thể sử dụng lại nhanh hơn trong những lần truy cập tiếp theo. Giả sử một API lấy thông tin sản phẩm từ PostgreSQL. Mỗi request đều truy vấn database, chuyển đổi […]

Saga Pattern

Saga Pattern là gì? Quản lý Transaction trong kiến trúc Microservices 1. Saga Pattern là gì? Saga Pattern là một mẫu thiết kế được sử dụng để quản lý các nghiệp vụ phân tán gồm nhiều bước xử lý, trong đó mỗi bước có thể thực hiện một local transaction tại một service hoặc Database […]

Two-Phase Locking (2PL)

Two-Phase Locking (2PL) là gì? Cơ chế khóa hai pha trong Database 1. Two-Phase Locking (2PL) là gì? Two-Phase Locking (2PL — khóa hai pha) là một giao thức quản lý khóa trong Database, quy định cách một transaction được phép lấy và giải phóng lock trong quá trình thực thi. Khi nhiều transaction cùng […]

Leave a Reply

Your email address will not be published. Required fields are marked *