Thiết kế CSDL và Denormalizing để tối ưu hiệu năng (Phần 4)

Trong phần này là phần cuối của series bài về việc thiết kế phi chuản trong CSDL nhằm mục đích tối ưu hiệu năng. Phần này mình sẽ nêu chi tiết về các kĩ thuật khi chúng ta áp dụng denormalize để dảm bảo được tính toàn vẹn cho dữ liệu

Chúng ta sẽ có 3 cách để thực hiện đó là:

  • Triggers: khi tiến hành thực hiện thao tác insert/update/delete 1 dòng dữ liệu thì sẽ có 1 trigger để chuyển dữ liệu hoặc cập nhật dữ liệu vào các cột hoặc các bảng dư thừa
  • Application logic: Thực hiện cập nhật dữ liệu trong ứng dụng hay trong code đối với các đoạn thực thi logic trong 1 transaction
  • Batch Reconciliation: Có 1 tiến trình hay 1 job hoặc 1 scheduler được đặt lịch thực thi dùng để cập nhật cho các dữ liệu denormalize

Trigger

Ví dụ như hình vẽ cột sum_adv trong các bảng Title. Ta sẽ có 1 trigger trong bảng TitleAuthor. Mỗi khi có 1 dòng trong bảng TitleAuthor được thêm vào hoặc xóa đi thì trigger này sẽ tính toán lại giá trị cho cột Sum_adv

fig2_17.gif

Application logic

Nếu ứng dụng của bạn phải đảm bảo tính toàn vẹn dữ liệu (đặc biệt là trong các ứng dụng doanh nghiệp), thì việc đảm bảo rằng các câu lệnh Insert/Delete/Update phải được thực thi trong một transaction duy nhất.

Bạn có thể áp dụng ngay trong code hoặc trong 1 store nào đó. Bên dưới là mẫu 1 transaction cho Sql các bạn có thể sử dụng

SET XACT_ABORT ON
BEGIN TRAN
BEGIN TRY
   -- lệnh 1
   -- lệnh 2
  -- ...
COMMIT
END TRY
BEGIN CATCH
   ROLLBACK
   DECLARE @ErrorMessage NVARCHAR(2000)
   SELECT @ErrorMessage = N'Lỗi: ' + ERROR_MESSAGE()
   RAISERROR(@ErrorMessage, 16, 1)
END CATCH

Nếu bạn áp dụng cách này thì nhớ phải ghi lại tài liệu đầy đủ và chi tiết để còn cho các dev hoặc các anh em DBA biết không thì đến lúc bạn đi mất chả ai rõ phải thêm vào nhiều bảng như thế đâu :))

Lưu ý: cách này dùng để quản lý denormalize thực sự là có khá nhiều rủi ro nên mình không khuyến khích cách này

Batch Reconciliation

Nếu dữ liệu không đảm bảo phải chuẩn chỉ 100% mọi lúc mọi nơi thì bạn có thể có 1 job hoặc thực thi 1 store đẻ xóa đi các dữ liệu thừa hoặc tính toán giá trị cho các cột các bảng

18030963-time-to-get-a-job-words-on-a-clock-counting-down-hours-and-minutes-to-finding-work-and-employement-t-stock-photo

Về job bạn có thể tham khảo link sau:

https://blogs.msdn.microsoft.com/sqlagent/2010/10/12/create-a-database-backup-job-using-sql-server-management-studio/

Các vấn nạn khi áp dụng denormalize của mình

Hiện tại thì ở công ty mình cũng đang áp dụng denormalize cho việc tối ưu ứng dụng tuy nhiên thì mình thấy nó đang có khá nhiều vấn đề.

Gần như các bảng có liên kết (bảng danh mục) vào bảng chính (bảng hồ sơ) thì trong bảng chính được thiết kế cho cả Id và Tên của đối tượng trong danh mục. Bảng liên kết đến 5 6 cái danh mục thì thêm gần như 10 đến 12 cái cột để tránh JOIN. Mặc dù các danh mục này nhiều khi khá ít chỉ 10-20 dòng dữ liệu là chủ yếu, nhiều nhất cũng chỉ 200 => Hiệu quả về JOIN thì chưa thấy đâu nhưng dữ liệu phát sinh thêm cần thêm ổ cứng để chưa đã tốn rồi. Chưa kể điều này làm cho các bảng này khá là lớn rất khó để 1 màn hình có thể xem được hết các cột.

Do thiết kế kiểu đó nhưng họ lại không chú ý vấn để quản lý dữ liệu dẫn đến tình trạng khách hàng phản ánh liên tục là ở hồ sơ thì hiển thị 1 thông tin nhưng các thành phần chi tiết 1 thông tin. ==> Mình suốt ngày phải đi cập nhật lại thông tin. Vấn đề này mình có phản ánh ở phần Tách gộp bảng ở các bảng lịch sử trong bài trước

Chưa kể tuy bảo là thiết kế để tăng hiệu năng nhưng nhiều khi toàn phải JOIN lại các bảng danh muc để lấy đầy đủ các cột dữ liệu ==> Việc thiết kế dư thừa cột là lãng phí.

Chính vì thế mình muốn nói là nếu ko hiểu kĩ thì tốt nhất là không nên áp dụng. CÓ dự án mình tham gia thì thiết kế đã denormalize rồi mà có 2000-3000 bản ghi cũng đã treo liên tục nên vấn đề nhiều khi không phải vì vài câu lệnh JOIN đã bỏ là hết.

Kết

Đến đây là hết rồi nhé :)) Trong các series tiếp mình cũng sẽ chỉ các bạn 1 số kĩ thuật để tối ưu cho CSDL mà chưa cần áp dụng để denormalize mà mình thường áp dụng.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s