Tôi đang viết lược đồ cho một cơ sở dữ liệu ngân hàng đơn giản. Dưới đây là các thông số kỹ thuật cơ bản:
- Cơ sở dữ liệu sẽ lưu trữ các giao dịch chống lại người dùng và tiền tệ.
- Mỗi người dùng có một số dư trên mỗi loại tiền, vì vậy mỗi số dư chỉ đơn giản là tổng của tất cả các giao dịch so với một người dùng và loại tiền nhất định.
- Một số dư không thể âm.
Ứng dụng ngân hàng sẽ liên lạc với cơ sở dữ liệu của mình thông qua các thủ tục được lưu trữ.
Tôi hy vọng cơ sở dữ liệu này chấp nhận hàng trăm ngàn giao dịch mới mỗi ngày, cũng như các truy vấn cân bằng ở mức độ cao hơn. Để phục vụ số dư rất nhanh, tôi cần tổng hợp chúng trước. Đồng thời, tôi cần đảm bảo rằng số dư không bao giờ mâu thuẫn với lịch sử giao dịch của nó.
Lựa chọn của tôi là:
Có một
balances
bảng riêng và thực hiện một trong những điều sau đây:Áp dụng giao dịch cho cả bảng
transactions
vàbalances
. Sử dụngTRANSACTION
logic trong lớp thủ tục được lưu trữ của tôi để đảm bảo rằng số dư và giao dịch luôn đồng bộ. (Được hỗ trợ bởi Jack .)Áp dụng các giao dịch vào
transactions
bảng và có một trình kích hoạt cập nhậtbalances
bảng cho tôi với số tiền giao dịch.Áp dụng các giao dịch vào
balances
bảng và có một trình kích hoạt thêm một mục mới trongtransactions
bảng cho tôi với số tiền giao dịch.
Tôi phải dựa vào các phương pháp dựa trên bảo mật để đảm bảo không có thay đổi nào có thể được thực hiện ngoài các thủ tục được lưu trữ. Mặt khác, ví dụ, một số quy trình có thể chèn trực tiếp một giao dịch vào
transactions
bảng và theo sơ đồ1.3
, số dư có liên quan sẽ không đồng bộ.Có một
balances
cái nhìn được lập chỉ mục tổng hợp các giao dịch một cách thích hợp. Số dư được đảm bảo bởi công cụ lưu trữ để đồng bộ với các giao dịch của họ, vì vậy tôi không cần phải dựa vào các phương pháp dựa trên bảo mật để đảm bảo điều này. Mặt khác, tôi không thể thực thi số dư là không âm nữa vì các chế độ xem - ngay cả các chế độ xem được lập chỉ mục - không thể có cácCHECK
ràng buộc. (Được hỗ trợ bởi Denny .)Chỉ có một
transactions
bảng nhưng có một cột bổ sung để lưu trữ số dư có hiệu lực ngay sau khi giao dịch đó được thực hiện. Do đó, hồ sơ giao dịch mới nhất cho người dùng và tiền tệ cũng chứa số dư hiện tại của họ. (Được đề xuất dưới đây bởi Andrew ; biến thể được đề xuất bởi garik .)
Khi tôi lần đầu tiên giải quyết vấn đề này, tôi đọc những hai cuộc thảo luận và quyết định lựa chọn 2
. Để tham khảo, bạn có thể thấy một triển khai xương cốt của nó ở đây .
Bạn đã thiết kế hoặc quản lý một cơ sở dữ liệu như thế này với cấu hình tải cao chưa? Giải pháp của bạn cho vấn đề này là gì?
Bạn có nghĩ rằng tôi đã lựa chọn thiết kế đúng? Có điều gì tôi nên ghi nhớ?
Ví dụ, tôi biết các thay đổi lược đồ cho
transactions
bảng sẽ yêu cầu tôi xây dựng lạibalances
khung nhìn. Ngay cả khi tôi đang lưu trữ các giao dịch để giữ cho cơ sở dữ liệu nhỏ (ví dụ: bằng cách di chuyển chúng sang nơi khác và thay thế chúng bằng các giao dịch tóm tắt), việc phải xây dựng lại chế độ xem hàng chục triệu giao dịch với mỗi bản cập nhật lược đồ có thể có nghĩa là thời gian ngừng hoạt động nhiều hơn đáng kể.Nếu chế độ xem được lập chỉ mục là con đường để đi, làm thế nào tôi có thể đảm bảo rằng không có số dư nào là âm?
Giao dịch lưu trữ:
Hãy để tôi giải thích một chút về lưu trữ các giao dịch và "giao dịch tóm tắt" mà tôi đã đề cập ở trên. Đầu tiên, lưu trữ thường xuyên sẽ là một điều cần thiết trong một hệ thống tải cao như thế này. Tôi muốn duy trì tính nhất quán giữa số dư và lịch sử giao dịch của họ trong khi cho phép các giao dịch cũ được chuyển đi nơi khác. Để làm điều này, tôi sẽ thay thế mọi lô giao dịch được lưu trữ bằng một bản tóm tắt số tiền của mỗi người dùng và tiền tệ.
Vì vậy, ví dụ, danh sách các giao dịch này:
user_id currency_id amount is_summary
------------------------------------------------
3 1 10.60 0
3 1 -55.00 0
3 1 -12.12 0
được lưu trữ và thay thế bằng cái này:
user_id currency_id amount is_summary
------------------------------------------------
3 1 -56.52 1
Theo cách này, số dư với các giao dịch lưu trữ duy trì một lịch sử giao dịch đầy đủ và nhất quán.