Tôi nghĩ về một cấu trúc cơ sở dữ liệu không phổ biến và tự hỏi nếu có ai đã nhìn thấy nó được sử dụng trước đây. Về cơ bản, nó sử dụng 2 cơ sở dữ liệu:
- Cơ sở dữ liệu đầu tiên chỉ giữ dữ liệu hiện tại hợp lệ
- Cơ sở dữ liệu thứ hai chứa lịch sử của tất cả mọi thứ đã được nhập, cập nhật hoặc xóa trong cơ sở dữ liệu đầu tiên
Kịch bản
Tôi đang làm việc trong một dự án mà tôi bắt buộc phải ghi nhật ký mọi thứ xảy ra và dữ liệu thay đổi thường xuyên.
Ví dụ (không phải thực tế)
Bạn phải làm thiết kế cơ sở dữ liệu cho một giải bóng đá. Trong giải đấu này có người chơi và đội. Các cầu thủ thường chuyển đội.
- Yêu cầu đầu tiên : Cơ sở dữ liệu phải chứa thông tin cần thiết để chơi trận đấu tiếp theo. Điều này có nghĩa là một danh sách của mỗi người chơi, đội và đội hiện tại mỗi đội.
- Yêu cầu thứ hai : Cơ sở dữ liệu phải giữ các giá trị lịch sử mà chúng ta sẽ sử dụng để tạo số liệu thống kê. Điều này có nghĩa là danh sách tất cả các cầu thủ đã từng là một phần của đội hoặc danh sách tất cả các đội mà một cầu thủ đã tham gia.
Vấn đề
Hai yêu cầu này là trái ngược nhau. Tôi đã cố gắng làm mọi thứ trong cùng một cơ sở dữ liệu nhưng nó không có ý nghĩa gì. Yêu cầu đầu tiên chỉ quan tâm đến "chơi trận tiếp theo" trong khi yêu cầu thứ hai chỉ quan tâm đến "tạo số liệu thống kê".
Để làm mọi thứ trong cùng một cơ sở dữ liệu, tôi đã sử dụng một loại cơ sở dữ liệu "chỉ chèn" bằng cách xóa phần mềm rõ ràng để xóa / cập nhật thông tin ...
Ban đầu có vẻ như là một nhiệm vụ dễ dàng, việc nắm giữ một danh sách các cầu thủ, đội và đội hiện tại của mỗi người chơi, đột nhiên trở nên khó khăn hơn rất nhiều. Logic ứng dụng cần thiết để chơi trận đấu tiếp theo đã đủ phức tạp nhưng giờ đây cơ sở dữ liệu có thiết kế rất không hữu ích khi ứng dụng được yêu cầu thêm "bị xóa" kiểm tra trên mỗi truy vấn duy nhất để chơi trận đấu tiếp theo.
Bạn có muốn trở thành huấn luyện viên đó hét lên "tất cả các cầu thủ trong đội, đến với tôi" và sau đó 2000 cầu thủ đến với bạn. Tại thời điểm đó, bạn có thể sẽ hét lên "tất cả những người chơi không bị xóa trong đội, hãy đến với tôi" (trong khi thề về thiết kế ngu ngốc này).
Kết luận của tôi
Tôi đã tự hỏi tại sao bạn cần phải đặt mọi thứ trong cùng một cơ sở dữ liệu. Xóa mềm không chỉ làm một công việc kém khi ghi nhật ký mọi thứ trừ khi bạn thêm nhiều cột (time_created, who_created_it, time_delatted, who_delatted_it) mà còn làm phức tạp mọi thứ. Nó làm phức tạp thiết kế cơ sở dữ liệu và nó làm phức tạp thiết kế ứng dụng.
Ngoài ra, tôi nhận được 2 yêu cầu này như là một phần của một ứng dụng duy nhất không thể tách rời nhưng tôi vẫn nghĩ: đây là 2 ứng dụng hoàn toàn khác biệt. Tại sao tôi lại cố gắng làm mọi thứ cùng nhau.
Đó là khi tôi nghĩ về việc chia đôi cơ sở dữ liệu. Một cơ sở dữ liệu hoạt động chỉ được sử dụng để chơi trận đấu tiếp theo và chỉ chứa thông tin hiện tại hợp lệ và cơ sở dữ liệu lịch sử chứa tất cả thông tin từng tồn tại, khi nó được tạo, xóa và ai đã làm điều đó.
Mục tiêu là giữ cho cơ sở dữ liệu đầu tiên (hoạt động) và ứng dụng đơn giản nhất có thể trong khi có càng nhiều thông tin càng tốt trong cơ sở dữ liệu thứ hai (lịch sử).
Câu hỏi
- Bạn đã thấy thiết kế đó trước đây? Nó có tên không?
- Có bất kỳ cạm bẫy rõ ràng mà tôi đang thiếu?
EDIT 2015/03/2016
Kiến trúc hiện tại
Về cơ bản, bạn có thể nghĩ về toàn bộ kiến trúc như một quá trình gồm 2 bước.
Bước 1 :
- Ứng dụng đang chạy và người dùng đang thực hiện một số hành động
- Mỗi khi một sự kiện xảy ra, nó sẽ được ghi lại tự động (giải pháp kiểm toán) trong một bảng sự kiện
- Sau đó, hàng đúng, trong cơ sở dữ liệu hoạt động được cập nhật
Bước 2 :
- Một công việc đọc phần chèn mới nhất trong bảng sự kiện và chèn dữ liệu mới này vào cơ sở dữ liệu lịch sử.
- Người dùng truy vấn cơ sở dữ liệu lịch sử để lấy thông tin mà họ cần.
Chỉ cần từ bảng sự kiện, bạn có thể xây dựng lại thông tin đến bất kỳ thời điểm nào. Vấn đề là bảng sự kiện này không dễ truy vấn. Đây là nơi cơ sở dữ liệu lịch sử khởi động; để trình bày dữ liệu theo cách dễ dàng truy xuất chính xác những gì chúng ta muốn.
Các vấn đề khác khi đặt mọi thứ vào cùng một bảng
Tôi đã bày tỏ mối quan tâm của mình về sự phức tạp thêm của việc kiểm tra "bị xóa" trên mỗi truy vấn. Nhưng có một vấn đề khác: tính toàn vẹn .
Tôi sử dụng nhiều khóa ngoại và ràng buộc để đảm bảo rằng tại bất kỳ thời điểm nào, dữ liệu trong cơ sở dữ liệu của tôi là hợp lệ.
Hãy xem xét một ví dụ:
Hạn chế: Chỉ có thể có một thủ môn mỗi đội.
Thật dễ dàng để thêm một chỉ mục duy nhất để kiểm tra nếu chỉ có một người giữ mục tiêu cho mỗi đội. Nhưng sau đó những gì xảy ra khi bạn thay đổi thủ môn. Bạn vẫn cần lưu giữ thông tin về người trước nhưng hiện tại bạn có 2 người giữ mục tiêu trong cùng một đội, một người hoạt động và một người không hoạt động, điều này mâu thuẫn với sự ràng buộc của bạn.
Chắc chắn thật dễ dàng để thêm một kiểm tra vào ràng buộc của bạn, nhưng đó là một điều khác để quản lý và suy nghĩ.