SQL Antipatterns: Phần 1 - Tối ưu hóa thiết kế cơ sở dữ liệu

Thiết kế cơ sở dữ liệu

Về việc thiết kế cơ sở dữ liệu cần lưu ý các vấn đề sau

  • Tránh lưu trữ giá trị dạng đa giá trị
    • Không sử dụng các trường lưu trữ dạng 1 cột nhiều giá trị
      • VD: bảng USER không nên tạo 1 trường PHONG_BAN_IDS chứa giá trị dạng ID1, ID2 … kiểu 1,2,3
  • Tránh lưu trữ bảng dạng đệ quy phụ thuộc
    • Không sử dụng kiểu trong 1 bảng, khóa ngoại lại trỏ vào khóa chính của bảng đó
    • Ví dụ:
      • Bảng Category thường sẽ là CategoryID, ParentCategoryID, Name
      • Bạn có thể tạo ra 1 bảng
        • Bảng Category (CategoryID, Name)
        • Và bảng Category_Xref (CategoryID, ParentCategoryID) làm bảng quan hệ cha-con
  • Khóa chính không tồn tại
    • Bất kỳ bảng nào cũng nên có khóa chính
    • Mục tiêu là khi truy cập vào 1 bản ghi trong bảng rất dễ dàng theo khóa chính để thao tác như cập nhật, xóa.
    • Kiểm tra trùng lặp bản ghi (dựa vào khóa chính đã có)
  • Không đặt tên khóa chính tên dạng chung chung như (ID)
    • Thay vì đặt tên khóa chính cho một bảng tên là Id thì chúng ta nên đặt tên có ý nghĩa hơn như: CategoryID, UserID, DepartmentID
    • Mục đích là khi tạo các mối quan hệ giữa các bảng thì bạn có thể nhìn thấy luôn khóa ngoại là của bảng nào, tương ứng với khóa chính ở bảng nào
    • VD:
      • Không nên: Category (ID, Name, Note)
      • Nên: Category (CategoryID, CategoryName, Note), Product (ProductID, ProductName, CategoryID)
  • Xem xét thêm khóa ngoại cho bảng nếu cần thiết
    • Một số trường hợp bỏ khóa ngoại thì có vẻ sẽ giúp cho DB nhẹ hơn, linh hoạt hơn, tuy nhiên đánh đổi lại là chúng ta phải tự quản lý tính toàn vẹn dữ liệu. Đôi khi cái giá phải trả là rất đắt.
    • Thêm khóa ngoại sẽ giúp việc ràng buộc dữ liệu chặt chẽ, nên thêm đối với những chức năng cần tính ràng buộc dữ liệu chặt chẽ.
  • Không tạo nhiều cột để lưu các giá trị khác nhau của một thuộc tính
    • Ví dụ:
      • Không nên: USER (UserID, Active, InActive)
      • Nên USER (UserID, STATUS_ID), USER_STATUS (STATUS_ID, STATUS_NAME) với giá trị STATUS_ID là 1: Active, 2: InActive
  • Chia nhỏ dữ liệu của một bảng hoặc theo năm
    • Có thể đánh partition theo năm cho bảng dữ liệu

0 comments:

Đăng nhận xét

Có nhận xét mới

Like