Tôi sẽ giải thích chi tiết cách làm việc với database trong Golang, bao gồm kết nối bằng database/sql, sử dụng ORM (GORM), quản lý transaction (Begin, Commit, Rollback), và tối ưu hóa truy vấn với indexing. Mỗi phần sẽ có ví dụ thực tế và best practices.
1. Kết nối Database với database/sql và ORM (GORM)
database/sql - Kết nối cơ bản
Package database/sql là cách chuẩn để làm việc với SQL trong Go, hỗ trợ nhiều driver (MySQL, PostgreSQL, SQLite, v.v.).
Defer Rollback: Với database/sql, dùng defer để đảm bảo rollback nếu lỗi.
Kiểm tra điều kiện: Validate trước khi thực hiện transaction (ví dụ: đủ số dư).
Giới hạn phạm vi: Chỉ dùng transaction cho các thao tác cần atomicity.
3. Indexing & Query Optimization
Indexing
Index tăng tốc độ truy vấn bằng cách giảm số hàng cần quét.
Các loại index:
Primary Key: Tự động có index.
Unique Index: Đảm bảo giá trị duy nhất (ví dụ: email).
Composite Index: Kết hợp nhiều cột (ví dụ: name + created_at).
Tạo Index với SQL:
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
Với GORM:
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string `gorm:"index:idx_email,unique"` // Index trên email
}
type Order struct {
ID uint `gorm:"primaryKey"`
UserID uint
CreatedAt time.Time `gorm:"index:idx_user_date,composite:user_id"` // Composite index
}
Query Optimization
Giảm quét toàn bảng: Dùng WHERE với cột có index.
**Tránh SELECT * **: Chỉ lấy cột cần thiết.
Sử dụng EXPLAIN: Phân tích kế hoạch truy vấn.
Ví dụ tối ưu với database/sql:
// Truy vấn không tối ưu
rows, err := db.Query("SELECT * FROM users WHERE name LIKE '%john%'")
// Tối ưu: Dùng index trên email
rows, err := db.Query("SELECT id, name FROM users WHERE email = ?", "john@example.com")
Với GORM:
// Không tối ưu
var users []User
db.Where("name LIKE ?", "%john%").Find(&users)
// Tối ưu
var user User
db.Select("id", "name").Where("email = ?", "john@example.com").First(&user)
Phân tích với EXPLAIN:
Chạy EXPLAIN SELECT ... trong MySQL/PostgreSQL để xem kế hoạch truy vấn:
EXPLAIN SELECT id, name FROM users WHERE email = 'john@example.com';
Kiểm tra key (index được dùng) và rows (số hàng quét).
Best Practices:
Index cẩn thận: Quá nhiều index làm chậm INSERT/UPDATE.
Profile truy vấn: Dùng db.Debug() (GORM) hoặc EXPLAIN để tìm bottleneck.