JuniorDatabase

Database migration là gì? Thêm một cột NOT NULL vào bảng đang có dữ liệu thì cần lưu ý gì?

Migration là một file (thường là SQL) mô tả một thay đổi của schema, ví dụ tạo bảng, thêm cột, thêm index. Các file được đặt tên theo thứ tự thời gian, commit vào Git và chạy lần lượt, nên database ở máy dev, staging và production luôn đi qua đúng cùng các bước. Thay đổi schema nhờ vậy cũng được review trong pull request như code.

Với câu thêm cột NOT NULL, người phỏng vấn muốn nghe hai ý.

Thứ nhất, alter table posts add column tags text[] not null sẽ lỗi trên bảng có dữ liệu: các dòng cũ không có giá trị cho cột mới, tức là null, vi phạm ràng buộc (PostgreSQL báo column "tags" of relation "posts" contains null values). Trên máy dev với bảng rỗng thì nó lại chạy được, nên lỗi chỉ lộ ra khi lên production. Cách sửa là cho giá trị mặc định: not null default '{}'. Nếu không có giá trị mặc định hợp lý, chia làm nhiều bước: thêm cột cho phép null, điền dữ liệu, rồi mới đặt not null.

Thứ hai là tương thích ngược. Khi deploy, migration và code mới không đổi cùng một lúc. Thường có một khoảng thời gian bản code cũ chạy trên schema mới, nên migration không được làm hỏng bản cũ: không xóa hay đổi tên cột mà code cũ còn dùng, cột mới phải có mặc định để câu insert cũ vẫn chạy.

Điểm cộng: nói rằng migration đã chạy trên production thì không sửa lại, muốn đổi thì viết migration mới.