Bài 14: Project thực tế – Xây dựng Ứng dụng Quản lý Chi tiêu cá nhân (Expense Manager)


I. Mục đích (Objectives)

Đây là dự án tổng kết giúp người học:

  • Tư duy thiết kế CSDL: Từ yêu cầu thực tế chuyển hóa thành bảng (Table) và quan hệ (Relationship).
  • Vận dụng tổng hợp: Sử dụng INSERT (thêm chi tiêu), SELECT JOIN (xem lịch sử), GROUP BY (báo cáo thống kê).
  • Xử lý kiểu dữ liệu Ngày tháng: Một kỹ năng quan trọng vì SQLite lưu ngày tháng dưới dạng chuỗi (Text).

II. Phân tích yêu cầu (Requirement Analysis)

Trước khi code, hãy đặt mình vào vị trí người dùng. Một ứng dụng quản lý chi tiêu tối thiểu cần làm được gì?

  1. Quản lý Danh mục: Người dùng cần phân loại (Ăn uống, Đi lại, Tiền nhà, Giải trí…).
  2. Ghi chép chi tiêu: Nhập số tiền, ngày chi, nội dung và chọn danh mục.
  3. Xem báo cáo:

    • Tháng này đã tiêu hết bao nhiêu?
    • Tiêu vào việc gì nhiều nhất?

III. Thiết kế Cơ sở dữ liệu (Database Design)

Chúng ta không nên nhồi nhét tất cả vào 1 bảng. Hãy áp dụng kiến thức Bài 8: Khóa chính (Primary Key) và Khóa ngoại (Foreign Key) – Sợi dây kết nối dữ liệu để tách thành 2 bảng.

1. Bảng DanhMuc (Categories)

Lưu các loại chi tiêu cố định.

  • id_dm: Khóa chính, tự tăng.
  • ten_dm: Tên danh mục (Ví dụ: “Ăn uống”).

2. Bảng ChiTieu (Expenses)

Lưu từng giao dịch phát sinh.

  • id: Khóa chính.
  • noi_dung: Mua cái gì (Ví dụ: “Cà phê sáng”).
  • so_tien: Số tiền (REAL).
  • ngay_chi: Ngày tháng (TEXT – Định dạng YYYY-MM-DD).
  • ma_dm_id: Khóa ngoại trỏ sang bảng DanhMuc.

3. Script tạo bảng (SQL)

-- 1. Tạo bảng Danh mục
CREATE TABLE DanhMuc (
    id_dm INTEGER PRIMARY KEY AUTOINCREMENT,
    ten_dm TEXT NOT NULL
);

-- 2. Tạo bảng Chi tiêu
CREATE TABLE ChiTieu (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    noi_dung TEXT,
    so_tien REAL NOT NULL,
    ngay_chi TEXT NOT NULL, -- Lưu dạng '2023-12-31'
    ma_dm_id INTEGER,
    FOREIGN KEY (ma_dm_id) REFERENCES DanhMuc(id_dm)
);

-- 3. Thêm dữ liệu mẫu cho Danh mục (Seed Data)
INSERT INTO DanhMuc (ten_dm) VALUES ('Ăn uống'), ('Di chuyển'), ('Hóa đơn'), ('Mua sắm');

IV. Các câu truy vấn nghiệp vụ (Business Logic Queries)

Đây là phần “linh hồn” của ứng dụng mà bạn cần viết trong code (Python/C#).

1. Chức năng: Thêm mới một khoản chi (INSERT)

Khi người dùng nhập: “Ăn phở”, 50k, ngày hôm nay, loại “Ăn uống” (id=1).

INSERT INTO ChiTieu (noi_dung, so_tien, ngay_chi, ma_dm_id)
VALUES ('Ăn phở', 50000, '2023-10-25', 1);

2. Chức năng: Xem lịch sử chi tiêu (SELECT + JOIN)

Yêu cầu: Hiển thị danh sách kèm Tên danh mục (thay vì số 1, 2, 3 khó hiểu).

SELECT 
    c.id,
    c.ngay_chi,
    c.noi_dung,
    c.so_tien,
    d.ten_dm
FROM ChiTieu c
INNER JOIN DanhMuc d ON c.ma_dm_id = d.id_dm
ORDER BY c.ngay_chi DESC; -- Mới nhất lên đầu

3. Chức năng: Báo cáo tổng chi theo Danh mục (GROUP BY)

Yêu cầu: Vẽ biểu đồ xem tháng này tốn tiền vào cái gì nhất.

SELECT 
    d.ten_dm,
    SUM(c.so_tien) as tong_tien
FROM ChiTieu c
JOIN DanhMuc d ON c.ma_dm_id = d.id_dm
GROUP BY d.ten_dm
ORDER BY tong_tien DESC;

Kết quả mẫu:

  • Ăn uống: 1.500.000
  • Di chuyển: 300.000

4. Chức năng: Lọc theo tháng (WHERE LIKE)

SQLite không có hàm MONTH() như SQL Server, ta xử lý chuỗi ngày tháng YYYY-MM-DD. Ví dụ: Tìm các khoản chi trong Tháng 10/2023.

SELECT * FROM ChiTieu 
WHERE ngay_chi LIKE '2023-10-%';

V. Gợi ý hướng dẫn Lập trình (Integration Guide)

Tùy vào việc bạn dùng Python hay C#, hãy thiết kế giao diện (UI) tương ứng.

  • ComboBox (Dropdown): Load dữ liệu từ bảng DanhMuc lên đây để người dùng chọn (Không cho nhập tay tên danh mục để tránh sai sót).
  • DateTimePicker: Để chọn ngày tháng, sau đó format thành chuỗi yyyy-MM-dd trước khi lưu xuống SQLite.
  • DataGridView/Table: Hiển thị kết quả câu lệnh SELECT JOIN.
  • Label Tổng tiền: Chạy câu lệnh SELECT SUM(so_tien) FROM ChiTieu để hiển thị con số tổng quát ở góc màn hình.

VI. Mở rộng (Homework)

Để phân loại học sinh Giỏi, hãy ra thêm bài tập mở rộng:

  1. Thêm tính năng “Ngân sách” (Budget): Đặt giới hạn chi tiêu cho mỗi danh mục (Ví dụ: Ăn uống max 2 triệu). Nếu chi quá -> Cảnh báo.
  2. Thêm bảng “Thu nhập” (Income): Để tính được Số dư (Balance = Thu – Chi).
  3. Biểu đồ: Sử dụng thư viện vẽ biểu đồ (Matplotlib trong Python hoặc Chart Control trong C#) để trực quan hóa dữ liệu từ câu lệnh GROUP BY.

Lời kết cho chuỗi bài viết

Chúc mừng bạn đã hoàn thành trọn bộ lộ trình “Làm chủ SQLite từ con số 0”.
Chúng ta đã đi từ những khái niệm cơ bản nhất (Table, Column) đến những kỹ thuật nâng cao (Index, Transaction) và cuối cùng là tích hợp vào ứng dụng thực tế. Hy vọng chuỗi bài viết này trên Tìm Ở Đây sẽ là tài liệu tham khảo giá trị cho cộng đồng học sinh, sinh viên và những người mới bắt đầu lập trình.
Hẹn gặp lại các bạn trong những series hướng dẫn công nghệ tiếp theo!

You may also like...

Để lại một bình luận