giảm tải data base
- Sao chép liên kết
- Chia sẻ với Facebook
- Chia sẻ với X
- Chia sẻ với Pinterest
- Chia sẻ với Linkedin
- Gửi bài qua Email
gửi email cho tác giả
tôi làm biên bản. mỗi lần tạo biên bản mới, nhập tiền tố vào. nó làm tăng dung lượng data base không? nếu 100 hoặc 1000 biên bản thì thế nào
Tiền tố (tien_to_truong, ví dụ "TU", "TI"...) tự nó không phải là thứ làm phình database. Nhìn vào code:
1. Tiền tố chỉ là chuỗi ký tự ngắn dùng làm khóa (key) trong JSON
key = f"{tien_to}{i}" # ví dụ: "TU1", "TU2", ..., "TU100"Toàn bộ dữ liệu nhập của một biên bản được gộp vào cột du_lieu_nhap (kiểu JSONB). Với so_luong_truong mặc định 100 trường, mỗi trường tên TUx + giá trị nhập vào, cả cột này thường chỉ tốn vài KB/biên bản – không đáng kể dù có 1.000 hay 10.000 bản ghi.
2. Thứ thực sự làm phình database là 2 cột lưu file nhị phân (LargeBinary):
file_bien_ban_xuat = db.Column(db.LargeBinary) # file Word đã render, lưu THẲNG vào Postgres
file_gcn_xuat = db.Column(db.LargeBinary) # tương tự, nếu có mẫu GCNMỗi lần tạo/sửa biên bản, hệ thống render lại toàn bộ file .docx từ template rồi lưu nguyên file nhị phân vào 2 cột này (db.session.commit() sau khi doc_bb.save(io_bb)). Đây mới là phần nặng.
Ước tính dung lượng:
Kích thước 1 file .docx sau khi render phụ thuộc vào bản mẫu (file_phoi_bien_ban/file_phoi_gcn) – có logo, ảnh, định dạng phức tạp hay không:
| Kích thước mỗi file docx | 1 biên bản (2 file) | 100 biên bản | 1.000 biên bản |
|---|---|---|---|
| ~50 KB (template đơn giản) | ~100 KB | ~10 MB | ~100 MB |
| ~200 KB (có logo/ảnh) | ~400 KB | ~40 MB | ~400 MB |
| ~1 MB (nhiều ảnh/scan chèn vào) | ~2 MB | ~200 MB | ~2 GB |
→ Nếu template có logo/ảnh, con số này nhân đôi cho mỗi biên bản vì mỗi record lưu bản sao đầy đủ của file docx, không dùng chung tài nguyên với template gốc.
Ngoài ra file scan PDF (file_pdf_scan) thì không lưu vào DB — chỉ lưu path trên đĩa (UPLOAD_FOLDER), nên phần đó không tính vào dung lượng CSDL.
Tóm lại: với 100–1.000 biên bản, mức tăng CSDL nằm trong khoảng chục đến vài trăm MB (thậm chí vài GB nếu template có nhiều ảnh) — hoàn toàn do 2 file docx render lưu dạng BLOB, chứ không phải do tiền tố hay dữ liệu JSON nhập vào.
Nếu bạn lo về việc CSDL phình to, có thể cân nhắc: chuyển file_bien_ban_xuat/file_gcn_xuat ra lưu file trên đĩa (giống cách đang làm với PDF scan) và chỉ lưu đường dẫn trong DB — sẽ nhẹ Postgres hơn nhiều và dễ backup/restore hơn.
có cách nào giảm dung lượng data base không? khi tôi nhập hồ sơ mới thì hệ thống lưu joson và template có sẵn. chứ không phải ghi luôn file nhập hồ sơ mới
Ý tưởng này rất đúng — và tin tốt là hệ thống đã có sẵn cơ chế render-theo-yêu-cầu ở route tải xuống, chỉ là code hiện tại đang làm dư một bước: vừa render-on-demand khi tải, vừa lưu thêm 1 bản render tĩnh vào DB mà không có route nào đọc lại nó cả. Tôi kiểm tra kỹ thì thấy:
/tai-xuong/...→ render trực tiếp từmau.file_phoi_bien_ban(template) +hoso.du_lieu_nhap(JSON) — không dùngfile_bien_ban_xuat/ho-so/live-preview/...→ cũng render trực tiếp từ template + JSON/ho-so/chi-tiet/...→ cũng vậy
→ Cột file_bien_ban_xuat và file_gcn_xuat bị ghi vào nhưng không bao giờ đọc ra để phục vụ người dùng. Đây chính là phần "thừa" đang chiếm dung lượng DB một cách vô ích.
Cách sửa: bỏ hẳn việc render + lưu file nhị phân ở 4 chỗ sau, chỉ giữ lại du_lieu_nhap (JSON):
luu_ho_so()— khi tạo hồ sơ mớicap_nhat_chinh_thuc()— khi sửa hồ sơcap_nhat_hoan_thanh()— khi tích checkbox hoàn thànhsao_chep_ho_so()— khi copy hồ sơ (đang copy luôn 2 cột binary)
Tôi làm luôn cho bạn:
Chỉ còn định nghĩa cột trong model — không còn nơi nào ghi vào nữa. Tôi giữ nguyên cột trong model (không xoá) để tránh vỡ những hồ sơ cũ đã có sẵn dữ liệu, và để bạn không cần chạy migration ngay.
Đã sửa ở 4 chỗ: luu_ho_so (tạo mới), cap_nhat_chinh_thuc (sửa), cap_nhat_hoan_thanh (tick checkbox), sao_chep_ho_so (nhân bản) — tất cả giờ chỉ lưu du_lieu_nhap (JSON), không render+lưu file .docx vào DB nữa. Các route hiển thị/tải xuống (/tai-xuong, /ho-so/live-preview, /ho-so/chi-tiet) vẫn hoạt động y hệt vì chúng vốn đã tự render từ template + JSON, không hề đụng tới 2 cột đó.
Để dọn luôn dung lượng đã chiếm sẵn của các hồ sơ cũ, chạy trong Postgres:
UPDATE ho_so_thiet_bi_dong SET file_bien_ban_xuat = NULL, file_gcn_xuat = NULL;
VACUUM FULL ho_so_thiet_bi_dong;(VACUUM FULL sẽ khoá bảng tạm thời — nên chạy lúc ít người dùng.)
Vài lưu ý cần cân nhắc:
- File chỉ còn tồn tại "ảo" — sinh ra lúc bấm tải/xem, không lưu bản cứng. Nếu sau này bạn sửa template phôi mẫu (
mau.file_phoi_bien_ban), thì các hồ sơ cũ khi tải lại sẽ dùng template mới, không giữ nguyên định dạng lúc tạo ban đầu. Trước đây với cách lưu file tĩnh, hồ sơ cũ luôn giữ đúng bản gốc dù template có đổi. Nếu tính chất pháp lý của biên bản đòi hỏi phải "đóng băng" hình thức tại thời điểm ký/duyệt, đây là điểm cần lưu ý. - Việc render tốn thêm chút CPU mỗi lần tải/xem thay vì đọc thẳng từ DB — nhưng docx nhỏ nên gần như không đáng kể.
Với code mới (chỉ lưu JSON, không lưu file docx), dung lượng tăng thêm gần như không đáng kể. Tính cụ thể:
Mỗi biên bản giờ chỉ còn lưu:
- Cột
du_lieu_nhap(JSONB) — dữ liệu các trườngTU1,TU2...TU100(giả sử mẫu có 100 trường như mặc địnhso_luong_truong) - Vài cột text/số nhỏ khác:
ten_ho_so,ngay_tao,nguoi_tao,trang_thai_duyet...
Ước tính JSONB cho 1 biên bản (100 trường):
| Thành phần | Kích thước |
|---|---|
1 key (vd "TU37") | ~6 byte |
| 1 giá trị (vd ngày, số seri, tên...) | ~15–25 byte |
Dấu :, ,, "..." (overhead JSON) | ~5 byte |
| Tổng 1 trường | ~25–35 byte |
| 100 trường | ~2,5 – 3,5 KB |
Cộng thêm các cột phụ (tên hồ sơ, ngày giờ, người tạo...) khoảng 0,3–0,5 KB nữa.
→ Mỗi biên bản mới ≈ 3 – 4 KB
Bảng tổng hợp:
| Số biên bản | Dung lượng tăng thêm (code mới) | So với code cũ (có lưu file docx ~100-400KB/bản) |
|---|---|---|
| 100 | ~0,3 – 0,4 MB | trước đây ~10–40 MB |
| 1.000 | ~3 – 4 MB | trước đây ~100–400 MB |
| 10.000 | ~30 – 40 MB | trước đây ~1–4 GB |
Tức là giảm khoảng 100–1000 lần so với cách lưu cũ.
Lưu ý:
- Con số trên giả định mẫu có 100 trường (
so_luong_truong). Nếu mẫu ít trường hơn (vd 30-50 trường) thì còn nhẹ hơn nữa. - Nếu giá trị nhập vào dài hơn (ghi chú, mô tả chi tiết...) thì mỗi bản ghi có thể lên 5-8 KB, vẫn rất nhỏ.
- Muốn biết chính xác thực tế trên hệ thống của bạn, chạy lệnh này sau khi test tạo vài chục hồ sơ:
SELECT pg_size_pretty(pg_total_relation_size('ho_so_thiet_bi_dong')) AS kich_thuoc_bang;lệnh này cho ra dung lượng thật của cả bảng (kể cả index), so sánh trước/sau khi tạo thêm biên bản để biết chính xác mức tăng trên máy chủ của bạn.
về nguyên lý hoạt động chức năng vẫn giữ được như cũ chứ. chức năng tải file , nhập liệu...
Đúng, toàn bộ nguyên lý hoạt động và trải nghiệm người dùng giữ nguyên 100% — không mất chức năng nào. Vì tôi chỉ cắt bỏ đúng 1 bước "lưu thêm 1 bản sao file docx vào DB" mà không có chỗ nào đọc lại nó, nên rà theo từng chức năng:
| Chức năng | Trước | Sau | Có đổi gì không? |
|---|---|---|---|
Nhập liệu / Tạo hồ sơ mới (luu-ho-so) | Lưu JSON + render sẵn 2 file docx vào DB | Chỉ lưu JSON | Người dùng nhập y hệt, kết quả lưu thành công y hệt |
Sửa hồ sơ (cap-nhat-chinh-thuc) | Cập nhật JSON + render lại 2 file lưu vào DB | Chỉ cập nhật JSON | Giao diện, luồng thao tác không đổi |
| Tick checkbox hoàn thành | Cập nhật JSON + render lại lưu vào DB | Chỉ cập nhật JSON | Trả về đúng thông báo "Cập nhật... thành công!" như cũ |
| Nhân bản hồ sơ | Copy JSON + copy 2 file docx | Chỉ copy JSON | Hồ sơ mới vẫn đủ dữ liệu để tải/xem lại |
Xem trước (preview) online (live-preview) | Vốn dĩ đã render trực tiếp từ template + JSON, không đụng file lưu sẵn | Không đổi | Không đổi gì |
Xem chi tiết hồ sơ (chi-tiet) | Gọi tới live-preview để hiển thị | Không đổi | Không đổi gì |
Tải file Word về máy (tai-xuong) | Vốn dĩ đã render trực tiếp từ template + JSON, không đọc file lưu sẵn | Không đổi | File tải về y hệt như cũ, vẫn đúng nội dung đã nhập |
Vì sao đảm bảo an toàn: file docx cuối cùng luôn chỉ phụ thuộc vào 2 thứ: template gốc (mau.file_phoi_bien_ban) và dữ liệu JSON đã nhập (hoso.du_lieu_nhap). Cả 2 route hiển thị (live-preview) và tải xuống (tai-xuong) từ trước tới giờ đều tự render lại từ 2 nguồn này mỗi lần gọi — cột file_bien_ban_xuat/file_gcn_xuat chỉ là một bản sao "chết", ghi vào cho có chứ chưa từng được đọc ra dùng ở đâu cả. Nên bỏ bước ghi đó đi không ảnh hưởng gì đến kết quả cuối cùng người dùng nhìn thấy.
Điều duy nhất khác biệt (đã nói ở câu trả lời trước): nếu sau này bạn sửa lại template phôi mẫu, các hồ sơ cũ khi tải/xem lại sẽ áp theo template mới thay vì giữ nguyên bản gốc lúc tạo — đây là điểm duy nhất thay đổi về mặt hành vi, không phải lỗi chức năng.

