- thống kê số học sinh nghỉ học có phép, nghỉ không phép.
- đầu ra: thống kê theo toàn bộ sở, phòng giáo dục, trường học.
- ví dụ: nếu thống kê các trường cấp 3 của sở HN, thì trả về 1 ds các trường ở HN đã điểm danh dữ liệu bao gồm: tổng học sinh, hs nghỉ có phép, hs nghỉ không phép.
- có 2 tính năng đang tác động đến thống kê này: đơn nghỉ học, và điểm danh lớp học.
- Mỗi khi có đơn xin nghỉ phép từ PH => GV, GV duyệt đơn => hs nghỉ có phép.
- Mỗi khi giáo viên điểm danh HS là nghỉ có phép => hs nghỉ có phép. Điểm danh học sinh nghỉ không phép => ds nghỉ không phép.
- tính năng đơn nghỉ phép: PH tạo đơn xin nghỉ phép cho hs, gửi đến GV, GV duyệt đơn hoặc huỷ đơn.
- tính năng điểm danh: GV điểm danh 1 danh sách học sinh trong lớp, mỗi học sinh có 3 trạng thái: đi học, nghỉ có phép, nghỉ không phép.
- 1 ngày có thể điểm danh nhiều lần, mỗi lần đc chọn 1 trạng thái điểm danh khác nhau.
- case đặc biệt:
- Nếu trc đó đã có đơn nghỉ phép, GV điểm danh nghỉ có phép => đơn đc duyệt.
- Nếu trc đó đã có đơn nghỉ phép, GV điểm danh đi học => đơn bị huỷ.
- Nếu trc đó đã có đơn nghỉ phép được duyệt, GV điểm danh đi học => đơn bị huỷ.
- GV có thể điểm danh các ngày trong quá khứ => có thể thay đổi giá trị.
- bảng
don_nghi_phep
lưu dữ liệu về đơn xin nghỉ phép. Mỗi lần có 1 đơn nghỉ phép => 1 bản ghi. Hiện tại có 5.419.011 bản ghi. - bảng
diem_danh_lop_hoc
, mỗi 1 lần giáo viên điểm danh theo ds học sinh, 1 học sinh trong 1 ngày sẽ sinh ra 1 bản ghi (các lần điểm danh trong ngày sẽ nằm trong mảng trạng thái của bản ghi đó). Hiện tại có 192.119.364 bản ghi.
- mỗi khi có query thống kê => đọc trực tiếp ở 2 bảng trên => tổng hợp dữ liệu. Khi dữ liệu tăng lên quá nhiều => api response chậm
- Lưu trong bảng
thong_ke_nghi_phep
: Mỗinhà trường
trong1 ngày
sẽ có 1 bản ghi. Lưu giá trị số củahs nghỉ phép
,hs nghỉ không phép
. - Mỗi khi có hoạt động về đơn nghỉ phép hay điểm danh thì phải tính toán dữ liệu để cộng hoặc trừ lại dữ liệu.
- Đơn nghỉ phép có thể được huỷ (trừ dữ liệu trong bảng thống kê).
- Khi đã có đơn nghỉ phép được duyệt (số hs nghỉ phép được +1), nhưng khi điểm danh học sinh đó là đi học => phải check lại trạng thái trước đó của học sinh đó, để biết dữ liệu cộng hay trừ.
- Hoặc lần đểm danh thứ N gv điểm danh học sinh A là nghỉ học, nhưng đến lần N + i có thể điểm danh là đi học => phải check lại dữ liệu trước đó của A để biết là số liệu của học sinh A thay đổi => trừ đi cái số HS nghỉ học.
- Khi phát sinh những nghiệp vụ mới => khó kiểm soát việc cộng trừ dữ liệu hơn.
- Hướng xử lý đang nghĩ tới có 2 cách.
- Kiểm soát hết các case để cộng trừ.
- 1 job định kỳ (throttle) để quét hết bảng ghi trong ngày => tổng hợp dữ liệu để update vào bảng đọc.
- Hướng xử lý đang nghĩ tới có 2 cách.
Bài toán này được chia làm 2 phần như sau:
Phần db hoạt động
Xử lý nghiệp vụ liên quan đến điểm danh, nộp đơn xin nghỉ, lịch sử xin nghỉ phía app,...
Phần này là phần data raw, cần xem xét tốc độ tăng lên của data (1 ngày phát sinh bao nhiêu bản ghi raw) để xem xét biến nó thành time-series data với kiến trúc data tăng theo thời gian và có tính hot-cold (data lâu sẽ cold, data mới sẽ hot). Phương pháp lưu trữ data dạng này là partitioning theo time (tạo collection mới theo từng tháng hoặc tuần,...). Đảo bảo tốc độ truy vấn cho data hot (gần đây) bằng việc giữ size collection nhỏ, size index nhỏ để fit trên ram.
Nhìn chung kỹ thuật partitioning theo time chỉ phát sinh 1 vấn đề là việc query data giữa các partition sẽ phải thực hiện thủ công (nhưng cũng nên tránh). Do đó khi thiết kế app cần consider vấn đề này và tạo ra limit khi query data. Ví dụ xem lịch sử điểm danh bắt buộc phải theo tháng,...
Phần db analytic
Xử lý nghiệp vụ liên quan tới analytic như tính tổng theo trường, lớp, sở,...
Đây là nghiệp vụ riêng biệt không liên quan tới phần hoạt động và có 2 hướng làm như sau:
Với bài toán và các vấn đề hiện tại thì anh nghĩ có thể xem xét hướng sử dụng 1 database chuyên analytic cho việc tính toán thống kê chứ nếu yêu cầu thống kê thay đổi thì mongodb sẽ khó đáp ứng hết. Với mongo hiện tại thì sẽ áp dụng việc partitioning để tăng khả năng truy vấn data raw là được.
Hiện tại database của bọn anh cũng có sử dụng mongodb làm db hoạt động (user activity, lịch sử học các thứ). Tuy nhiên toàn bộ phần thống kê thì mongo không đáp ứng được do đó đã sync phần lớn data với 1 db khác là postgres để chuyên xử lý các query analytic.
Tham khảo kiến trúc: https://kipalog.com/posts/He-thong-analytic--suong-suong--tu-du-lieu-30-trieu-nguoi-dung