TÓM TẮT ĐỀ TÀI Tiếng Việt Đề tài “Xây dựng ứng dụng quản lý quán cà phê” là một đề tài mang tính ứng dụng thực tiễn trong đời sống hàng ngày khi ngành công nghiệp cà phê ngày càng phát t
XÁC ĐỊNH VÀ PHÂN TÍCH YÊU CẦU
Khảo sát hiện trạng
2.1.1.1 Kế hoạch phỏng vấn tổng quát
Bảng 2 1 Kế hoạch phỏng vấn tổng quát
Kế hoạch phỏng vấn tổng quát
Hệ thống: Quán cà phê PING
Người lập bảng: Đỗ Mai Như Quỳnh Ngày lập: 22/03/2023
STT Chủ đề Yêu cầu Ngày bắt đầu
1 Quy trình quản lý nhân viên
Nắm được quy trình lưu trữ và khai thác thông tin nhân viên để vận hành công việc hiệu quả
2 Quy trình quản lý khách hàng
Nắm được quy trình lưu trữ và khai thác thông tin của khách hàng để áp dụng vào hệ thống
3 Quy trình quản lý sản phẩm
Hiểu rõ cách quản lý sản phẩm, định giá sản phẩm phù hợp
4 Quy trình quản lý khuyến mãi
Nắm rõ quy trình đề ra và áp dụng các chương trình khuyến mãi
5 Quy trình quản lý hóa đơn
Nắm rõ quy trình quản lý các hóa đơn 25/03/2023 25/03/2023
6 Quy trình quản lý tài chính
Hiểu được quy trình thống kê, tạo báo cáo doanh thu về số lượng sản phẩm bán được dựa trên số liệu trong hệ thống
2.1.1.2 Bảng kế hoạch phỏng vấn
Bảng 2 2 Bảng kế hoạch phỏng vấn
Bảng kế hoạch phỏng vấn
Hệ thống: Quán cà phê PING
- Hoàng Gia Lộc – Quản lý hệ thống quán cà phê PING
- Võ Hồng Kim Anh – Nhân viên hệ thống quán cà phê PING
- Vũ Thanh Doan – Trưởng bộ phận chăm sóc khách hàng hệ thống quán cà phê PING
- Trần Thị Mỹ Xoan – Kế toán hệ thống quán cà phê PING
Vị trí: Phòng nhân viên tại quán café
Thời gian bắt đầu: 8h30, 25/03/2023 Thời gian kết thúc: 12h, 25/03/2023 Mục tiêu: Thu thập thông tin và hiểu được quy trình hoạt động của hệ thống quản lý quán cà phê PING
Chi tiết buổi phỏng vấn
- Tổng quan về hệ thống
- Sơ lược về buổi phỏng vấn:
• Chủ đề 1 : Quy trình quản lý nhân viên
• Chủ đề 2 : Quy trình quản lý khách hàng
• Chủ đề 3 : Quy trình quản lý sản phẩm
• Chủ đề 4 : Quy trình quản lý khuyến mãi
• Chủ đề 5 : Quy trình quản lý hóa đơn
• Chủ đề 6 : Quy trình thống kê, báo cáo doanh thu
Phát sinh ngoài dự kiến
2.1.1.3 Bảng câu hỏi và ghi nhận
Bảng 2 3 Bảng câu hỏi và ghi nhận
BẢNG CÂU HỎI VÀ GHI NHẬN
Câu trả lời Thái độ
Người được phỏng vấn: Hoàng Gia Lộc Ngày phỏng vấn: 25/03/2023
Chủ đề 1 : Quy trình quản lý nhân viên
Câu hỏi 1: Có bao nhiêu loại nhân viên trong quán?
Câu hỏi 2: Những thông tin nào cần lưu trữ về nhân viên của quán?
- Đối với nhân viên part-time: Họ và tên, quê quán, địa chỉ nơi ở hiện tại, Chắc chắn
Trang 20 số CCCD/CMND, trường học (nếu có), số điện thoại
- Đối với nhân viên full-time: Họ và tên, số điện thoại, quê quán, địa chỉ nơi ở hiện tại, số CCCD/CMND, mã số thuế, số hợp đồng
Câu hỏi 3: Lương của nhân viên được tính theo cách thức nào?
Tính lương theo bảng chấm công
- Đối với nhân viên part-time: tính theo số giờ làm việc thực tế theo ca trong ngày Lương là 23.000đ/h
- Đối với nhân viên full-time: Lương là
- Đối với nhân viên kế toán: Lương là
- Đối với quản lý: Lương là
Nếu như đi làm đầy đủ và không nghỉ thì sẽ được thưởng thêm 500.000đ
Chủ đề 2 : Quy trình quản lý khách hàng
Câu hỏi 1: Thông tin cần lưu trữ về khách hàng khi khách hàng tiến hành đăng ký thành viên là gì?
Họ tên, ngày sinh, số điện thoại, địa chỉ, email, ngày đăng ký thành viên Chắc chắn
Câu hỏi 2: Có tính năng phân loại khách hàng theo mức độ thân thiết không?
Nếu có thì đó là những loại khách hàng nào và làm sao để có thể phân loại như vậy?
Có Sẽ có 3 hạng thành viên: hạng Thành viên (Member), hạng Bạc (Silver), hạng Vàng (Gold)
Phân loại khách hàng sẽ dựa trên số điểm tích lũy qua các lần mua hàng (1 điểm 10.000đ)
Câu hỏi 3: Hãy nói cụ thể hơn về cách phân loại thành viên?
- Hạng Thành viên (Member) dành cho khách hàng đăng ký lần đầu thành công
- Hạng Bạc (Silver) dành cho khách hàng tích lũy đủ 150 điểm
- Hạng Vàng (Gold) dành cho khách hàng có số điểm tích lũy là 300 điểm
Mỗi cấp độ thành viên sẽ được hưởng cơ chế ưu đãi khác nhau
Câu hỏi 4: Cấp độ của khách hàng sẽ giữ nguyên hay sẽ được làm mới lại?
Cấp độ của thành viên sẽ được làm mới vào ngày 01/01 hàng năm Tùy thuộc vào số điểm tích lũy của khách hàng có đủ điều kiện cần để duy trì cấp độ của mình hay không
- Hạng Thành viên (Member) không cần có số điểm tích lũy tối thiểu
- Hạng Bạc (Silver) cần phải duy trì số điểm tích lũy tối thiểu là 150 điểm
- Hạng Vàng (Gold) cần đạt được số điểm tối thiểu là 300 điểm
Người được phỏng vấn: Võ Hồng Kim Anh Ngày phỏng vấn: 25/03/2023
Chủ đề 3 : Quy trình quản lý sản phẩm
Câu hỏi 1: Thông tin chi tiết nào về sản phẩm cần được lưu trữ trong hệ thống?
Mã sản phẩm, tên sản phẩm, giá bán, tên danh mục sản phẩm Chắc chắn
Câu hỏi 2: Thông tin về danh mục sản phẩm có những gì?
Danh mục sản phẩm có thể chứa các thông tin như mã danh mục, tên danh mục
Câu hỏi 3: Khi xóa danh mục sản phẩm thì những sản phẩm thuộc danh mục đó sẽ bị ảnh hưởng như thế nào?
Khi xóa một danh mục nào đó thì tất cả sản phẩm của danh mục cũng sẽ bị xóa khỏi cơ sở dữ liệu
Câu hỏi 4: Có cần thêm đánh giá của khách hàng đối với mỗi sản phẩm hay không? Nếu có, sẽ đánh giá như thế nào?
Có thể có đánh giá bằng số sao (tối đa 5 sao)
Dựa trên số sao trung bình đánh giá sẽ hiển thị món best - seller để khách hàng có thể tham khảo và cân nhắc lựa chọn mua sản phẩm
Người được phỏng vấn: Vũ Thanh Doan Ngày phỏng vấn: 25/03/2023
Chủ đề 4: Quy trình quản lý khuyến mãi
Câu hỏi 1: Chương trình khuyến mãi sẽ diễn ra vào khoảng thời gian nào?
Theo những hình thức gì?
Nhằm tăng độ hài lòng và mức độ thân thiết với khách hàng, các chương trình khuyến mãi sẽ diễn ra trong các ngày lễ, ngày sinh nhật , và sẽ theo hình thức giảm giá trực tiếp
Ngoài ra khách hàng còn nhận được ưu đãi theo thứ hạng thành viên của mình bất kể ngày thường hay ngày lễ
Câu hỏi 2: Hãy nói chi tiết hơn về chương trình ưu đãi thành viên
- Ở hạng Member, khách hàng sẽ không nhận được ưu đãi
- Ở hạng Silver, khách hàng sẽ được chiết khấu 5% trên tổng hóa đơn
- Ở hạng Gold, khách hàng sẽ được chiết khấu 8% trên tổng hóa đơn
- Ngoài ra còn có các voucher ưu đãi giảm giá 5% trên tổng hóa đơn khi đến sinh nhật của khách hàng
Người được phỏng vấn: Trần Thị Mỹ Xoan Ngày phỏng vấn: 25/03/2023
Chủ đề 5: Quy trình quản lý hóa đơn
Câu hỏi 1: Thông tin hóa đớn gồm những gì?
Mã hoá đơn, tên sản phẩm, số lượng, giá tiền theo từng món, tổng trị giá hoá đơn
Tên khách hàng, voucher áp dụng của chương trình khách hàng thành viên (nếu có), giá tiền sau khi áp dụng voucher
Chủ đề 6 : Quy trình quản lý tài chính
Câu hỏi 1: Bao lâu thì sẽ tổng kết doanh thu của quán?
Tổng kết doanh thu vào lúc kết ca hằng ngày để có thể nắm được tình hình kinh doanh của quán mỗi ngày
Vào cuối mỗi tháng, kế toán sẽ báo cáo thu chi chi tiết cho quản lý
Câu hỏi 4: Thời hạn lưu trữ thống kê doanh thu của quán?
Quán muốn lưu trữ dữ liệu trong thời gian 12 tháng, có thể dễ dàng truy xuất được thông tin về doanh thu theo ngày, tháng khi có nhu cầu
Câu hỏi 5: Những ai có thể truy cập vào những thống kê về doanh thu của quán?
Thu ngân và quản lý được cấp quyền truy cập để xem báo cáo doanh thu của quán
2.1.2 Khảo sát cơ cấu tổ chức
2.1.2.2 Chức năng mỗi bộ phận
• Quản lý danh sách sản phẩm
• Quản lý các hóa đơn và chỉ quản lý mới được xóa hóa đơn đã đặt
• Quản lý mã giảm giá, khuyến mãi cho khách hàng
• Quản lý thông tin nhân viên và tài khoản nhân viên
• Quản lý việc đặt đồ ăn, thức uống từ khách hàng
• Đăng ký thành viên mới, xóa thông tin khách hàng, cập nhật thông tin cho khách hàng
• Tích điểm thưởng cho khách hàng
• Tiến hành thanh toán và lập hoá đơn thanh toán cho các khách hàng
• Phục vụ, pha chế đồ thức ăn, đồ uống
2.1.3 Các quy trình, nghiệp vụ
- Quản lý thông tin hóa đơn và thông tin về doanh thu
- Quản lý khuyến mãi cho từng hạng thành viên
Hình 2 1 Cơ cấu tổ chức.
- Nghiệp vụ tính điểm tích lũy của khách hàng dựa trên lịch sử mua hàng của khách hàng, từ đó xếp hạng thành viên cho khách hàng và áp dụng mức ưu đãi riêng cho từng hạng thành viên
- Nghiệp vụ tính trị giá hóa đơn
2.1.4 Khảo sát hệ thống hiện có
Có nhiều phần mềm và ứng dụng có sẵn để hỗ trợ quản lý quán cà phê Có thể kể đến một số phần mềm và ứng dụng phổ biến như eHopper, Lightspeed, SAPO, MISA CUKCUK
2.1.4.1 eHopper và Lightspeed eHopper và Lightspeed đều là hệ thống POS (Point of Sale) dựa trên đám mây cung cấp các tính năng như quản lý kho, quản lý nhân viên và quản lý khách hàng Ưu điểm của cả hai hệ thống này là giao diện dễ sử dụng, thân thiện với người dùng, cung cấp các tính năng giúp quản lý toàn diện như quản lý sản phẩm, quản lý khách hàng, thanh toán, báo cáo… Tuy nhiên việc tích hợp hay tương thích với một số phần mềm, thiết bị của các doanh nghiệp vẫn còn hạn chế và chi phí của cả hai hệ thống này cao hơn so với một số giải pháp POS khác trên thị trường
SAPO là nền tảng bán hàng và quản lý đa kênh, hỗ trợ người bán quản lý kho hàng, khách hàng và đơn hàng tại một nơi duy nhất
SAPO mang những ưu điểm như: linh hoạt, đơn giản, dễ sử dụng, trực quan, tích hợp đa kênh, cho phép quản lý trên nhiều nền tảng khác nhau, tích hợp các phương thức thanh toán và có chức năng báo cáo, phân tích giúp theo dõi hiệu suất kinh doanh, xu hướng tiêu dùng và biểu đồ doanh thu
Bên cạnh đó, SAPO có thể có giới hạn đối với một số tính năng, chi phí sử dụng khá cao so với các giải pháp POS khác, tính năng hỗ trợ khách hàng đôi khi còn khó khăn và bị gián đoạn…
MISA CUKCUK là ứng dụng quản lý nhà hàng, quán ăn, quán cà phê được phát triển nhằm giúp việc quản lý trở nên dễ dàng hơn Với MISA CUKCUK, ta có thể quản lý đơn hàng, thực đơn, khách hàng, nhân viên một cách hiệu quả và tiện lợi
Giao diện dễ sử dụng, trực quan, có tính năng quản lý toàn diện như quản lý thực đơn, quản lý đặt bàn, quản lý nhân viên, quản lý sản phẩm… nhằm tăng cường hiệu suất và tối ưu hóa tăng cường kinh doanh, tích hợp nhiều phương thức thanh toán và cung cấp công cụ báo cáo phân tích đáng tin cậy là những ưu điểm để người dùng lựa chọn sử dụng MISA CUKCUK
Tuy nhiên, vẫn còn một số khó khăn và hạn chế khi sử dụng ứng dụng quản lý này Có thể kể đến việc giới hạn tính năng tùy chỉnh, giới hạn sự linh hoạt trong việc điều chỉnh hệ thống theo yêu cầu cụ thể của doanh nghiệp hay việc tương thích với các phần mềm khác đôi khi còn chưa hiệu quả
Yêu cầu phần mềm
- Lưu trữ thông tin nhân viên: mã nhân viên, họ tên nhân viên, số CCCD, quê quán, số điện thoại, địa chỉ, loại nhân viên (partime/fulltime), vị trí, mã số thuế (đối với fulltime), mã số hợp đồng (đối với fulltime)
- Lưu trữ thông tin sản phẩm: mã sản phẩm, tên sản phẩm, giá tiền, loại sản phẩm
- Lưu trữ thông tin hóa đơn: mã hoá đơn, ngày hóa đơn, họ tên khách hàng, số tiền
- Thông tin doanh thu theo ngày
- Lưu trữ thông tin khách hàng thành viên: mã khách hàng, tên khách hàng, ngày sinh, địa chỉ, số điện thoại, email, loại thành viên, số điểm thành viên
- Tìm kiếm thông tin nhân viên
- Tìm kiếm thông tin khách hàng
- Tìm kiếm thông tin menu
• Thêm/xoá thông tin: mã hoá đơn, mã khách hàng (nếu có), món ăn, thức uống, số lượng, ghi chú, hình thức thanh toán
- Huỷ đơn hàng: huỷ một đơn hàng khi có yêu cầu
• Thay đổi sản phẩm: mã sản phẩm, số lượng
• Thêm sản phẩm vào đơn hàng
- Thanh toán: tính toán số tiền của đơn hàng, giảm giá cho hoá đơn (nếu có mã giảm giá), tính toán số tiền trả lại (nếu khách hàng đưa dư)
- Tích điểm cho khách hàng thành viên
- Cập nhật thông tin nhân viên
2.2.1.5 Quản lý khách hàng thành viên
- Đăng ký mới thông tin khách hàng thành viên
- Xoá khách hàng thành viên
- Cập nhật thông tin cho khách hàng
- Thêm sản phẩm: tên sản phẩm, giá sản phẩm, tên danh mục sản phẩm
- Cập nhật thông tin sản phẩm
- Thêm danh mục sản phẩm
- Xóa danh mục sản phẩm
- Xem thông tin hóa đơn
- Xóa hóa đơn khi cần thiết
- Cập nhật mã giảm giá
- Thống kê số lượng hóa đơn theo ngày
- Thống kê và báo cáo doanh thu theo ngày/tháng
- Thống kê sản phẩm bán chạy và bán chậm nhất
2.2.2 Yêu cầu phi chức năng
2.2.2.1 Yêu cầu về vận hành
- Hệ thống phải chạy được trên máy tính bàn
2.2.2.2 Yêu cầu về hiệu suất
- Hệ thống phải có tốc độ truy cập cao
- Hệ thống phải cập nhật dữ liệu và tính toán nhanh chóng và chính xác
- Hệ thống phải hoạt động ổn định để giảm thiểu thời gian gián đoạn và giảm thiểu sự cố
2.2.2.3 Yêu cầu về giao diện
- Giao diện gần gũi, thân thiện
- Người dùng có thể sử dụng dễ dàng, thuận tiện và có tính tương tác cao
- Thao tác nhanh gọn, dễ sử dụng
2.2.2.4 Yêu cầu về bảo mật
- Chỉ có quản lý mới có toàn bộ quyền truy cập vào hệ thống
THIẾT KẾ DỮ LIỆU
Mô hình dữ liệu quan hệ (mức vật lý)
Hình 3 1 Mô hình dữ liệu quan hệ cho toàn bộ hệ thống (mức vật lý)
Ánh xạ cơ sở dữ liệu
EMPLOYEES (employeeID, employeeName, employeePhone, employeeAddress, employeeCID, employeeHometown, employeeType, employeePosition, employeeTaxID, employeeContractID, employeeEmail, status)
CUSTOMER (customerID, customerName, customerDOB, customerPhone, customerAddress, customerEmail, customerStartDate, customerRate, customerPhone)
FOOD_ITEM (itemID, itemName, itemPrice, categoryName, categoryID)
DISCOUNT (discountID, discountName, discountQuantity, dicountValue, discountStartDay, discountEndDay)
BILL (billID, employeeID, customerID, billDate, customerName, billPrice, customerPhone) BILL_DETAIL (billID, itemID, itemName, quantity, totalPrice)
SYSTEM_ACCESS (sysUsername, sysPassword, type, employeeID)
Phân tích và thiết kế Cơ sở dữ liệu
Dựa trên việc xác định và phân tích yêu cầu, ứng dụng bao gồm các bảng sau đây:
Tên trường Kiểu dữ liệu Ràng buộc Mô tả customerID INT(11) Khoá chính Mã khách hàng customerName VARCHAR(50) Tên khách hàng customerDOB DATE Ngày sinh không được lớn hơn ngày bắt đầu Ngày sinh khách hàng customerPhone VARCHAR(11) Số điện thoại khách hàng customerAddress VARCHAR(50) Địa chỉ khách hàng customerEmail VARCHAR(50) Email khách hàng customerStartDate DATE Ngày bắt đầu phải lớn hơn ngày sinh
Ngày đăng ký thành viên customerRate VARCHAR(20)
Loại khách hàng customerPoint INT(11) Điểm khách hàng
Tên trường Kiểu dữ liệu Ràng buộc Mô tả employeeID INT(11) Khoá chính Mã nhân viên employeeName VARCHAR(30) Tên nhân viên employeePhone VARCHAR(20) Số điện thoại nhân viên employeeAddress VARCHAR(50) Địa chỉ nhân viên employeeCID VARCHAR(20) Số CCCD của nhân viên employeeHometown VARCHAR(100) Quê quán nhân viên employeeType VARCHAR(30)
Loại nhân viên employeePosition VARCHAR(30) Vị trí nhân viên employeeTaxID VARCHAR(20)
Nhân viên parttime thì không có mã số thuế
Mã số thuế nhân viên employeeContractID VARCHAR(11)
Nhân viên parttime thì không có mã hợp đồng
Mã hợp đồng nhân viên employeeEmail VARCHAR(50) Email nhân viên status VARCHAR(30)
Có giá trị ‘Đang làm việc’ hoặc
Tên trường Kiểu dữ liệu Ràng buộc Mô tả categoryID INT(11) Khoá chính Mã danh mục categoryName VARCHAR(20) Tên danh mục
Tên trường Kiểu dữ liệu Ràng buộc Mô tả itemID INT(11) Khoá chính Mã sản phẩm categoryID INT(11)
Mã danh mục Khóa ngoại tới bảng CATEGORY itemName VARCHAR(30) Tên sản phẩm itemPrice INT(11) Giá sản phẩm categoryName VARCHAR(50) Tên danh mục
Tên trường Kiểu dữ liệu Ràng buộc Mô tả
Trang 35 discountID VARCHAR(20) Khoá chính Mã khuyến mãi discountName VARCHAR(50) Tên khuyến mãi discountQuantity INT(11) Số lượng khuyến mãi discountValue INT(11) Phần trăm khuyến mãi discountStartDay DATE Ngày có hiệu lực discountEndDay DATE Ngày hết hiệu lực
Tên trường Kiểu dữ liệu Ràng buộc Mô tả billID INT(11) Khóa chính Mã hóa đơn employeeID INT(11) Khóa ngoại tới bảng
Mã nhân viên tạo hóa đơn customerID INT(11) Khóa ngoại tới bảng
Mã khách hàng thành viên billDate DATE Ngày hóa đơn customerName VARCHAR(50) Tên khách hàng billPrice INT(11) Trị giá hóa đơn customerPhone VARCHAR(20) Số điện thoại khách hàng
Tên trường Kiểu dữ liệu Ràng buộc Mô tả billID INT(11)
Mã hóa đơn Khóa ngoại tới bảng BILL itemID VARCHAR(50)
Khóa ngoại tới bảng FOOD_ITEM itemName VARCHAR(50) Tên sản phẩm quantity INT(11) Số lượng sản phẩm totalPrice INT(11) Tổng tiền
Tên trường Kiểu dữ liệu Ràng buộc Mô tả sysUsername VARCHAR(20) Khóa chính Tên đăng nhập sysPassword VARCHAR(10) Mật khẩu type VARCHAR(20) Loại user employeeID INT(11) Khóa ngoại tới bảng
Mô tả ràng buộc toàn vẹn
Bảng 3 9 Danh sách ràng buộc toàn vẹn
RBTV Ký hiệu Mô tả
R1 Thuộc tính customerID trong bảng CUSTOMERS là duy nhất
R2 Thuộc tính employeeID trong bảng EMPLOYEES là duy nhất
R3 Thuộc tính categoryID trong bảng CATEGORY là duy nhất
R4 Thuộc tính itemID trong bảng FOOD_ITEM là duy nhất
R5 Thuộc tính discountID trong bảng DISCOUNT là duy nhất
R6 Thuộc tính billID trong bảng BILL là duy nhất
R7 Thuộc tính billID, itemID trong bảng BILL_DETAIL là duy nhất R8 Thuộc tính sysUsername trong bảng SYSTEM_ACCESS là duy nhất
R9 Một sản phẩm thuộc một danh mục
R10 Một hóa đơn được tạo bởi một nhân viên
R11 Một hóa đơn thuộc về một khách hàng
R12 Tập các giá trị billID trong quan hệ BILL_DETAIL phải được tìm thấy trong tập các giá trị billID trong quan hệ BILL
R13 Tập các giá trị itemID trong quan hệ BILL_DETAIL phải được tìm thấy trong tập các giá trị itemID trong quan hệ FOOD_ITEM
R14 Một tài khoản thuộc về một nhân viên
R15 Loại nhân viên chỉ có thể là “fulltime” hoặc “parttime”
R16 Trạng thái nhân viên chỉ có thể là “Đang làm việc” hoặc “Đã nghỉ”
R17 Ngày sinh của khách hàng không được lớn hơn ngày bắt đầu làm thành viên
R18 Ngày bắt đầu làm thành viên của khách hàng phải lớn hơn ngày sinh của khách hàng
3.4.1 Ràng buộc toàn vẹn khóa chính
3.4.1.1 Thuộc tính customerID trong bảng CUSTOMERS là duy nhất
Bảng 3 10 Bảng tầm ảnh hưởng ràng buộc R1
3.4.1.2 Thuộc tính employeeID trong bảng EMPLOYEES là duy nhất
Bảng 3 11 Bảng tầm ảnh hưởng ràng buộc R2
3.4.1.3 Thuộc tính categoryID trong bảng CATEGORY là duy nhất
Bảng 3 12 Bảng tầm ảnh hưởng ràng buộc R3
3.4.1.4 Thuộc tính itemID trong bảng FOOD_ITEM là duy nhất
Bảng 3 13 Bảng tầm ảnh hưởng ràng buộc R4
3.4.1.5 Thuộc tính discountID trong bảng DISCOUNT là duy nhất
Bảng 3 14 Bảng tầm ảnh hưởng ràng buộc R5
3.4.1.6 Thuộc tính billID trong bảng BILL là duy nhất
Bảng 3 15 Bảng tầm ảnh hưởng ràng buộc R6
3.4.1.7 Thuộc tính billID, itemID trong bảng BILL_DETAIL là duy nhất
Bảng 3 16 Bảng tầm ảnh hưởng ràng buộc R7
3.4.1.8 Thuộc tính sysUsername trong bảng SYSTEM_ACCESS là duy nhất
Bảng 3 17 Bảng tầm ảnh hưởng ràng buộc R8
3.4.2 Ràng buộc toàn vẹn khóa ngoại
3.4.2.1 Một sản phẩm thuộc một danh mục
- Bối cảnh: FOOD_ITEM, CATEGORY
Bảng 3 18 Bảng tầm ảnh hưởng ràng buộc R9
3.4.2.2 Một hóa đơn được tạo bởi một nhân viên
Bảng 3 19 Bảng tầm ảnh hưởng ràng buộc R10
3.4.2.3 Một hóa đơn thuộc về một khách hàng
Bảng 3 20 Bảng tầm ảnh hưởng ràng buộc R11
3.4.2.4 Tập các giá trị billID trong quan hệ BILL_DETAIL phải được tìm thấy trong tập các giá trị billID trong quan hệ BILL
- Bối cảnh: BILL_DETAIL, BILL
Bảng 3 21 Bảng tầm ảnh hưởng ràng buộc R12
3.4.2.5 Tập các giá trị itemID trong quan hệ BILL_DETAIL phải được tìm thấy trong tập các giá trị itemID trong quan hệ FOOD_ITEM
- Bối cảnh: BILL_DETAIL, FOOD_ITEM
Bảng 3 22 Bảng tầm ảnh hưởng ràng buộc R13
3.4.2.6 Một tài khoản thuộc về một nhân viên
- Bối cảnh: SYSTEM_ACCESS, EMPLOYEES
Bảng 3 23 Bảng tầm ảnh hưởng ràng buộc R14
3.4.3 Ràng buộc toàn vẹn khác
3.4.3.1 Loại nhân viên chỉ có thể là “fulltime” hoặc “parttime”
Bảng 3 24 Bảng tầm ảnh hưởng ràng buộc R15
3.4.3.2 Trạng thái nhân viên chỉ có thể là “Đang làm việc” hoặc “Đã nghỉ”
Bảng 3 25 Bảng tầm ảnh hưởng ràng buộc R16
3.4.3.3 Ngày sinh của khách hàng không được lớn hơn ngày bắt đầu làm thành viên
Bảng 3 26 Bảng tầm ảnh hưởng ràng buộc R17
3.4.3.4 Ngày bắt đầu làm thành viên của khách hàng phải lớn hơn ngày sinh của khách hàng
Bảng 3 27 Bảng tầm ảnh hưởng ràng buộc R18
CHƯƠNG 4 CÔNG NGHỆ SỬ DỤNG
Trong chương 04, nhóm thực hiện trình bày các công nghệ được sử dụng trong quá trình triển khai và phát triển ứng dụng quản lý quán cà phê
Các công nghệ được sử dụng trong quá trình xây dựng ứng dụng của nhóm bao gồm: MySQL, Netbeans, JDBC.
MySQL
MySQL là một hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở miễn phí, được sử dụng rộng rãi trên thế giới MySQL có thể hoạt động trên nhiều hệ điều hành khác nhau và hỗ trợ nhiều ngôn ngữ lập trình như Node.js, PHP, Perl, và nhiều ngôn ngữ khác MySQL có tốc độ và tính bảo mật cao, thích hợp cho các ứng dụng có truy cập cơ sở dữ liệu trên internet
MySQL có hai phiên bản chính là MySQL Community Edition và MySQL Enterprise Edition MySQL Community Edition là phiên bản miễn phí và được hỗ trợ bởi cộng đồng các nhà phát triển mã nguồn mở MySQL Enterprise Edition là phiên bản có tính năng nâng cao, công cụ quản lý và hỗ trợ kỹ thuật để đạt được mức độ cao nhất về khả năng mở rộng, bảo mật, độ tin cậy và thời gian hoạt động của MySQL
Cấu trúc của MySQL gồm có các thành phần sau:
- Máy chủ MySQL: là phần mềm quản lý cơ sở dữ liệu, chịu trách nhiệm lưu trữ, xử lý và trả về dữ liệu cho các máy khách
- Máy khách MySQL: là các ứng dụng hoặc công cụ kết nối với máy chủ MySQL để gửi yêu cầu hoặc nhận kết quả Có nhiều loại máy khách MySQL khác nhau, chẳng hạn như dòng lệnh MySQL, phpMyAdmin, Workbench, Navicat
- Cơ sở dữ liệu MySQL: là tập hợp các bảng dữ liệu và các đối tượng liên quan như chỉ mục, khóa, ràng buộc, chế độ xem, thủ tục
- Bảng dữ liệu MySQL: là cấu trúc lưu trữ dữ liệu theo dạng hàng và cột Mỗi bảng có một tên duy nhất và có thể chứa nhiều cột với các kiểu dữ liệu khác nhau
- Ngôn ngữ SQL: là ngôn ngữ truy vấn có cấu trúc để tương tác với cơ sở dữ liệu MySQL
SQL cho phép thực hiện các thao tác như tạo, thêm, xóa, sửa, tìm kiếm, sắp xếp, nhóm dữ liệu
Có thể liệt kê một số ưu điểm của MySQL như:
- Miễn phí và mã nguồn mở: MySQL không tốn chi phí để sử dụng và có mã nguồn mở cho phép người dùng thay đổi và cải tiến theo nhu cầu
- Dễ sử dụng: MySQL có giao diện người dùng đơn giản và thân thiện, cho phép người dùng làm việc với cơ sở dữ liệu một cách hiệu quả và tiện lợi
- Tương thích: MySQL có thể hoạt động trên nhiều hệ điều hành khác nhau và hỗ trợ nhiều ngôn ngữ lập trình như Node.js, PHP, Perl MySQL cũng có thể kết nối với nhiều loại cơ sở dữ liệu khác như Oracle, SQL Server, PostgreSQL
- Bảo mật: MySQL có nhiều tính năng bảo mật để đảm bảo an toàn cho dữ liệu, chẳng hạn như mã hóa, xác thực, phân quyền, sao lưu, khôi phục
- Vận hành mạnh mẽ và mở rộng dễ dàng: MySQL có khả năng xử lý một lượng lớn dữ liệu Bên cạnh đó, người dùng có thể mở rộng nó nếu có nhu cầu
- Nhanh chóng: Tốc độ hoạt động của MySQL nhanh hơn các phần mềm khác nhờ các tiêu chuẩn được tích hợp sẵn.
NetBeans
NetBeans là một IDE miễn phí, mã nguồn mở, phổ biến dành cho ngôn ngữ lập trình Java và các ngôn ngữ khác như PHP, C, C++, HTML5 và JavaScript Nó cung cấp một môi trường phát triển đơn giản, dễ sử dụng, bao gồm các công cụ hỗ trợ viết mã, kiểm tra, gỡ lỗi và quản lý dự án
NetBeans bắt đầu năm 1996 với tên gọi Xelfi (chơi chữ của Delphi), một dự án Java IDE của sinh viên dưới sự hướng dẫn của Khoa Toán - Lý tại Charles University tại Prague Năm
1997, Roman Staněk đã thành lập một công ty xung quanh dự án và sản xuất các phiên bản thương mại của NetBeans IDE cho đến khi Sun Microsystem mua lại nó năm 1999 Sun mở mã nguồn của NetBeans IDE vào tháng 6 năm sau Kể từ đó, Cộng đồng NetBeans tiếp tục phát triển
Một số ưu điểm của NetBeans:
- Miễn phí và mã nguồn mở: NetBeans không tốn chi phí để sử dụng và có mã nguồn mở cho phép người dùng thay đổi và cải tiến theo nhu cầu
- Dễ sử dụng: NetBeans có giao diện người dùng đơn giản và thân thiện, cho phép người dùng làm việc với dự án một cách hiệu quả và tiện lợi
- Tương thích: NetBeans có thể hoạt động trên nhiều hệ điều hành khác nhau và hỗ trợ nhiều ngôn ngữ lập trình như Node.js, PHP, Perl…NetBeans cũng có thể kết nối với nhiều loại cơ sở dữ liệu khác như Oracle, SQL Server, PostgreSQL…
- Bảo mật: NetBeans có nhiều tính năng bảo mật để đảm bảo an toàn cho mã nguồn, chẳng hạn như mã hóa, xác thực, phân quyền…
- Vận hành mạnh mẽ và mở rộng dễ dàng: NetBeans có khả năng xử lý một lượng lớn mã nguồn Bên cạnh đó, người dùng có thể mở rộng nó nếu có nhu cầu.
JDBC
JDBC (Java Database Connectivity) là một API (Application Programming Interface) trong ngôn ngữ lập trình Java cho phép các ứng dụng Java kết nối và tương tác với cơ sở dữ liệu quan hệ (Relational Database Management System - RDBMS)
JDBC cho phép nhà phát triển ứng dụng Java thiết lập kết nối đến các cơ sở dữ liệu khác nhau như Oracle, MySQL, Microsoft SQL Server và nhiều hệ quản trị cơ sở dữ liệu khác Nó cung cấp một giao diện tiêu chuẩn cho việc tương tác với cơ sở dữ liệu, giúp giảm sự phụ thuộc vào một hệ quản trị cơ sở dữ liệu cụ thể
JDBC cung cấp một tập hợp các lớp và giao diện để thực hiện các hoạt động liên quan đến cơ sở dữ liệu như kết nối đến cơ sở dữ liệu, thực thi các truy vấn SQL, cập nhật dữ liệu và xử lý kết quả truy vấn Các lớp quan trọng trong JDBC bao gồm DriverManager, Connection, Statement và ResultSet
JDBC được phân thành 4 loại:
- Loại 1 (Type 1): Sử dụng cầu nối ODBC – Open Database Connectivity (JDBC – ODBC Bridge Driver) Sử dụng ODBC, yêu cầu bạn phải cấu hình trên hệ thống một DSN (Data Source Name) đại diện cho cơ sở dữ liệu muốn sử dụng
- Loại 2 (Type 2): JDBC-Native API
- Loại 3 (Type 3): JDBC kết nối thông qua các ứng dụng mạng trung gian
- Loại 4 (Type 4): JDBC kết nối trực tiếp với trình điều khiển cơ sở dữ liệu (100% Pure Java)
XÂY DỰNG VÀ QUẢN LÝ GIAO TÁC
Transaction (giao tác)
Transaction là một nhóm các tác vụ (task) thực hiện một chức năng duy nhất trong hệ quản trị cơ sở dữ liệu Mỗi tác vụ là đơn vị xử lý tối thiểu không thể chia nhỏ hơn Trong một transaction tất cả các tác vụ được thực hiện thành công hoặc không có tác vụ nào được thực hiện thành công
Một transaction đòi hỏi phải có tính chất ACID ACID là viết tắt của cụm từ Atomicity (nguyên tử), Consistency (nhất quán), Isolation (cô lập), và Durability (lâu bền) Đây là các thuộc tính mà mọi transaction đều được đảm bảo bởi hệ quản trị cơ sở dữ liệu
- Atomicity: Mọi thay đổi về mặt dữ liệu phải được thục hiện trọn vẹn khi transaction thực hiện thành công hoặc không có bất kì sự thay đổi nào về mặt dữ liệu nếu có xẩy ra sự cố
- Consistency: Sau khi một transaction kết thúc thì tất cả dữ liệu phải được nhất quán dù thành công hay thất bại
- Isolation: Các transaction khi đồng thời thực thi trên hệ thống thì không có bất kì ảnh hưởng gì tời nhau Các thay đổi dữ liệu bên trong mỗi transaction sẽ được cô lập, các transaction khác sẽ không thể nhìn thấy cho đến khi nó được đồng bộ xuống database
- Durability: Sau khi một transaction thành công thì tác dụng mà nó tạo ra phải bền vững trong cơ sở dữ liệu cho dù hệ thống có xảy ra lỗi hoặc bị mất điện.
Cơ chế khóa
Trong MySQL, cơ chế khóa (locking mechanism) là một phần quan trọng của hệ quản trị cơ sở dữ liệu để đảm bảo tính nhất quán và đồng thời truy cập đúng của các giao dịch đối với dữ liệu Khi nhiều giao dịch cùng thao tác trên cùng một tài nguyên (ví dụ: bảng, hàng hoặc
Trang 49 cột), cơ chế khóa giúp đồng bộ hóa truy cập để tránh các xung đột và lỗi dữ liệu không nhất quán
MySQL sử dụng các cơ chế khóa khác nhau để quản lý khóa, bao gồm:
- Khóa hàng (Row-level locking): MySQL hỗ trợ khóa hàng, cho phép khóa chỉ áp dụng cho các hàng cụ thể trong một bảng Điều này cho phép các giao dịch khác nhau truy cập đồng thời vào các hàng khác nhau của cùng một bảng
- Khóa bảng (Table-level locking): MySQL cũng hỗ trợ khóa bảng, nghĩa là toàn bộ bảng được khóa trong quá trình giao dịch đang diễn ra Điều này có thể dẫn đến hiện tượng xung đột nếu có nhiều giao dịch cố gắng truy cập cùng một bảng cùng một lúc Để quản lý cơ chế khóa trong MySQL, có thể sử dụng các câu lệnh như LOCK TABLES và UNLOCK TABLES để khóa và mở khóa bảng, hoặc sử dụng các câu lệnh khác nhau như SELECT FOR UPDATE để sử dụng khóa đọc hoặc UPDATE/DELETE WHERE để sử dụng khóa ghi
Lưu ý rằng cơ chế khóa trong MySQL có thể ảnh hưởng đến hiệu suất của hệ thống,
5.2.2 Các loại khóa chính trong MySQL
Trong MySQL, có hai loại khóa chính trong cơ chế khóa: khóa đọc (Read Lock) và khóa ghi (Write Lock)
- Khóa đọc được sử dụng trong các truy vấn chỉ đọc dữ liệu như SELECT
- Khi một giao dịch giữ khóa đọc trên một tài nguyên (ví dụ: bảng, hàng hoặc cột), các giao dịch khác cũng có thể đọc tài nguyên đó
- Tuy nhiên, khóa đọc không cho phép giao dịch khác thực hiện ghi (INSERT, UPDATE, DELETE) trên tài nguyên đó trong khi khóa đọc đang được giữ
- Khóa ghi được sử dụng trong các truy vấn ghi dữ liệu như INSERT, UPDATE, DELETE
- Khi một giao dịch giữ khóa ghi trên một tài nguyên, nó sẽ ngăn chặn các giao dịch khác đọc và ghi dữ liệu trên tài nguyên đó trong khi khóa ghi đang được giữ
- Khóa ghi đảm bảo tính nhất quán và đồng thời truy cập đúng của các giao dịch trên dữ liệu
- Cơ chế khóa này giúp đồng bộ hóa truy cập vào dữ liệu và tránh xung đột giữa các giao dịch Khi một giao dịch yêu cầu khóa trên tài nguyên, nếu khóa đã được giữ bởi giao dịch khác, giao dịch mới sẽ phải chờ đến khi khóa được giải phóng để tiếp tục thực hiện
- MySQL tự động quản lý các khóa này dựa trên câu lệnh truy vấn và cấu trúc của các bảng trong cơ sở dữ liệu Tuy nhiên, người phát triển có thể sử dụng các câu lệnh như LOCK TABLES và UNLOCK TABLES để tường minh khóa và mở khóa các bảng trong quá trình thực thi giao dịch
Cơ chế khóa trong hệ quản trị cơ sở dữ liệu như MySQL có vai trò quan trọng trong việc đảm bảo tính nhất quán và đồng thời truy cập đúng của các giao dịch đối với dữ liệu Dưới đây là các chức năng chính của cơ chế khóa:
- Đồng bộ hóa truy cập đến dữ liệu: Cơ chế khóa đảm bảo rằng chỉ một giao dịch có quyền truy cập và thay đổi dữ liệu trong cùng một thời điểm Khi một giao dịch đã khóa một tài nguyên, các giao dịch khác phải chờ đợi cho đến khi khóa được giải phóng trước khi có thể truy cập vào tài nguyên đó
- Ngăn chặn xung đột: Khi nhiều giao dịch cùng thao tác trên cùng một tài nguyên, cơ chế khóa giúp ngăn chặn xung đột xảy ra Nó đảm bảo rằng chỉ một giao dịch có thể thay đổi dữ liệu tại một thời điểm, giúp tránh lỗi dữ liệu không nhất quán do xung đột ghi
- Bảo vệ tính nhất quán của dữ liệu: Bằng cách sử dụng khóa, cơ chế khóa đảm bảo tính nhất quán của dữ liệu Nó đảm bảo rằng các thay đổi dữ liệu được áp dụng một cách tuần tự và không bị xung đột với các thay đổi khác
- Hỗ trợ giao dịch: Cơ chế khóa là một phần quan trọng của giao dịch Khi một giao dịch được bắt đầu, nó có thể khóa các tài nguyên cần thiết và giữ các khóa đó cho đến khi giao dịch hoàn thành hoặc bị hủy Điều này đảm bảo rằng các thay đổi được thực hiện bởi giao dịch chỉ được áp dụng nếu giao dịch hoàn thành thành công
- Quản lý đồng thời truy cập: Cơ chế khóa cũng giúp quản lý đồng thời truy cập của nhiều giao dịch Nó cho phép các giao dịch cùng truy cập vào dữ liệu cùng một lúc, đồng thời đảm bảo tính nhất quán và tránh xung đột
Deadlock
Deadlock là một tình huống xảy ra trong hệ quản trị cơ sở dữ liệu khi hai hoặc nhiều giao dịch đang chờ đợi lẫn nhau để giải phóng khóa, dẫn đến tình trạng tắc nghẽn và không thể tiếp tục thực thi MySQL cũng có thể gặp phải deadlock trong một số tình huống Khi deadlock xảy ra, các giao dịch liên quan sẽ bị mắc kẹt và không thể tiếp tục thực thi, gây tắc nghẽn và ảnh hưởng đến hiệu suất hệ thống
MySQL sử dụng cơ chế khóa để quản lý truy cập đồng thời vào dữ liệu Tuy nhiên, nếu không quản lý khóa một cách cẩn thận, deadlock có thể xảy ra Một deadlock thường xảy ra khi các giao dịch cùng thực hiện các thao tác đọc và ghi trên các tài nguyên trong một thứ tự không nhất quán Ví dụ, giao dịch A đang giữ khóa X và yêu cầu khóa Y, trong khi giao dịch
B đang giữ khóa Y và yêu cầu khóa X Điều này dẫn đến tình huống mắc kẹt và không thể tiếp tục thực thi
- Deadlock Detection (Phát hiện deadlock): MySQL sử dụng thuật toán phát hiện deadlock để xác định khi nào một deadlock xảy ra Khi một deadlock được phát hiện, MySQL sẽ chọn một giao dịch để hủy bỏ và giải phóng các khóa để cho phép các giao dịch khác tiếp tục thực thi
- Deadlock Prevention (Ngăn chặn deadlock): Một cách để ngăn chặn deadlock là thiết kế cẩn thận cấu trúc các truy vấn và giao dịch sao cho luôn tuân thủ một thứ tự nhất định khi truy cập các tài nguyên Ví dụ, đảm bảo rằng tất cả các giao dịch truy cập vào các bảng trong cùng một thứ tự nhất định để tránh deadlock
- Deadlock Avoidance (Tránh deadlock): MySQL hỗ trợ sử dụng các câu lệnh khóa như SELECT FOR UPDATE hoặc INSERT INTO SELECT FOR UPDATE để tường minh yêu cầu khóa và tránh deadlock Bằng cách sử dụng chính sách khóa hợp lý, các giao dịch có thể tránh mắc kẹt và đảm bảo tính nhất quán
- Deadlock Timeout (Hết thời gian chờ mắc kẹt): MySQL cung cấp cài đặt timeout cho các giao dịch Khi một giao dịch chờ đợi một khóa quá lâu mà không thể giải phóng, nó sẽ bị hủy bỏ để tránh deadlock
Transaction và thiết lập các mức cô lập trong Java
Trong MySQL, giao dịch (transaction) là một tập hợp các hoạt động cơ sở dữ liệu được thực hiện như một đơn vị duy nhất và không chia cắt Giao dịch bao gồm một chuỗi các câu lệnh SQL như SELECT, INSERT, UPDATE, DELETE được gom nhóm lại để thực thi một cách đồng thời và đảm bảo tính nhất quán của cơ sở dữ liệu
Giao dịch được sử dụng để đảm bảo tính nhất quán và độ tin cậy của dữ liệu trong môi trường đa người dùng và đa giao dịch Nếu một giao dịch không được hoàn thành thành công, các thay đổi được áp dụng trong giao dịch đó sẽ bị hủy bỏ và cơ sở dữ liệu sẽ được khôi phục về trạng thái ban đầu
MySQL hỗ trợ giao dịch bằng cách sử dụng các câu lệnh SQL sau đây:
- BEGIN hoặc START TRANSACTION: Bắt đầu một giao dịch và xác định điểm bắt đầu của giao dịch
- COMMIT: Xác nhận và áp dụng các thay đổi đã được thực hiện trong giao dịch và kết thúc giao dịch Các thay đổi sẽ được lưu vào cơ sở dữ liệu
- ROLLBACK: Hủy bỏ các thay đổi đã được thực hiện trong giao dịch và kết thúc giao dịch Cơ sở dữ liệu sẽ được khôi phục về trạng thái ban đầu
- SAVEPOINT: Xác định một điểm lưu trữ trong giao dịch để có thể rollback đến điểm đó nếu cần thiết
- SET autocommit: Định nghĩa xem câu lệnh SQL có tự động commit ngay sau khi thực thi hay không Nếu autocommit được bật, mỗi câu lệnh SQL được thực thi sẽ được coi là một giao dịch riêng biệt và được tự động commit
5.4.2 Thiết lập các mức cô lập trong Java
Trong Java, khi làm việc với MySQL, chúng ta có thể thiết lập mức độ cô lập của giao dịch bằng cách sử dụng các hằng số được cung cấp bởi giao diện java.sql.Connection Dưới đây là một số mức cô lập thông thường có sẵn trong MySQL và cách thiết lập chúng trong Java
Mức cô lập mặc định được xác định bởi hệ thống quản lý cơ sở dữ liệu MySQL
Trong Java, mức cô lập mặc định có thể được thiết lập bằng cách sử dụng hằng số java.sql.Connection.TRANSACTION_READ_COMMITTED
Ví dụ: connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
- Mức cô lập này chỉ đảm bảo rằng các giao dịch không đọc dữ liệu chưa được commit bởi các giao dịch khác
- Trong Java, mức cô lập này có thể được thiết lập bằng cách sử dụng hằng số java.sql.Connection.TRANSACTION_READ_COMMITTED
- Ví dụ: connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITT ED);
- Mức cô lập này không đảm bảo tính nhất quán dữ liệu và cho phép các giao dịch đọc dữ liệu chưa được commit bởi các giao dịch khác
- Trong Java, mức cô lập này có thể được thiết lập bằng cách sử dụng hằng số java.sql.Connection.TRANSACTION_READ_UNCOMMITTED
- Ví dụ: connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMI TTED);
- Mức cô lập này đảm bảo rằng các giao dịch đọc dữ liệu từ cùng một vị trí trong cơ sở dữ liệu sẽ luôn nhận được cùng một giá trị
- Trong Java, mức cô lập này có thể được thiết lập bằng cách sử dụng hằng số java.sql.Connection.TRANSACTION_REPEATABLE_READ
- Ví dụ: connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_RE AD);
- Mức cô lập này đảm bảo rằng các giao dịch sẽ xảy ra theo thứ tự tuần tự và không bị xung đột
- Trong Java, mức cô lập này có thể được thiết lập bằng cách sử dụng hằng số java.sql.Connection.TRANSACTION_SERIALIZABLE
- Ví dụ: connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Trigger
Trigger là một đối tượng trong cơ sở dữ liệu và được gắn với một sự kiện xảy ra trên một bảng nào đó Nó được tự động thực thi khi có sự kiện xảy ra trên bảng đó Các sự kiện đó bao gồm INSERT, UPDATE và DELETE
Một số đặc điểm của trigger:
- Trigger được kích hoạt tự động mỗi khi xảy ra sự kiện ở trên bảng mà trigger được gắn với nó
- Trigger có thể được sử dụng để kiểm soát và đảm bảo tính nhất quán của dữ liệu trong cơ sở dữ liệu
- Trigger có thể được sử dụng để ghi lại thông tin về các thay đổi dữ liệu, bao gồm thời gian, người thực hiện và chi tiết thay đổi
{INSERT | UPDATE | DELETE} ON [table_name]
- CREATE TRIGGER [trigger_name]: tạo một trigger có tên [trigger_name]
- [trigger_name]: tên của trigger
- {BEFORE | AFTER}: thời điểm trigger thực thi (trước hoặc sau các sự kiện)
- {INSERT | UPDATE | DELETE}: Loại sự kiện mà trigger được kích hoạt
- [table_name]: tên bảng mà trigger được gắn tới
- FOR EACH ROW: xác định trigger được kích hoạt cho mỗi hàng bị ảnh hưởng bởi sự kiện
- BEGIN và END: đánh dấu phạm vi thực hiện của trigger Khối code trong đoạn này sẽ được thực thi khi trigger được kích hoạt
1 tg_check_duplicate_category Insert CATEGORY Kiểm tra điều kiện trùng lặp danh mục
2 tg_check_duplicate_customerPhone Insert CUSTOMERS
Kiểm tra điều kiện trùng lặp của số điện thoại khách hàng
3 tg_check_item_price_INSERT Insert FOOD_ITEM
Kiểm tra điều kiện giá bán của sản phẩm
4 tg_check_item_price_UPDATE Update FOOD_ITEM
Kiểm tra điều kiện giá bán của sản phẩm
5 tg_check_start_date Insert CUSTOMERS
Kiểm tra điều kiện ngày đăng ký của khách hàng
6 tg_increment_customerID Insert CUSTOMERS
Tự động tạo ID của khách hàng khi đăng ký thành viên
7 tg_set_default_values Update CUSTOMERS
Xoá điểm của khách hàng và cài đặt lại mức xếp hạng thành viên
8 tg_customerbirthday_check_insert Insert CUSTOMERS Kiểm tra điều kiện ngày sinh
9 tg_customerphone_check_update Update CUSTOMERS Kiểm tra định dạng của số điện thoại
10 tg_customerrate_check_insert Insert CUSTOMERS
Kiểm tra điều kiện xếp hạng của khách hàng
11 tg_customerphone_check_update Update CUSTOMERS Kiểm tra định dạng của số điện thoại
12 tg_check_discount_dates Insert DISCOUNT
Kiểm tra ràng buộc ngày bắt đầu phải nhỏ hơn ngày kết thúc
13 tg_check_discount_dates_update Update DISCOUNT
Kiểm tra ràng buộc ngày bắt đầu phải nhỏ hơn ngày kết thúc
5.5.3 Mô tả một số trigger
5.5.3.1 Kiểm tra điều kiện trùng lặp danh mục
- Tên: tg_check_duplicate_category
- Nội dung: Kiểm tra điều kiện trùng lặp của một danh mục khi thêm mới danh mục Nếu đã tồn tại danh mục sản phẩm thì báo lỗi và không cho phép thêm
Bảng 5 2 Bảng tầm ảnh hưởng trigger tg_check_duplicate_category
Hình 5 1 Trigger tg_check_duplicate_category
5.5.3.2 Kiểm tra điều kiện trùng lặp số điện thoại của khách hàng
- Tên: tg_check_duplicate_customerPhone
- Nội dung: Kiểm tra sự tồn tại của số điện thoại của khách hàng khi đăng ký khách hàng thành viên cho khách hàng Nếu đã tồn tại số điện thoại thì báo lỗi và không cho phép đăng ký
Bảng 5 3 Bảng tầm ảnh hưởng trigger tg_check_duplicate_customerPhone
Hình 5 2 Trigger tg_check_duplicate_customerPhone
5.5.3.3 Kiểm tra điều kiện ngày đăng ký của khách hàng
- Tên: tg_check_start_date
- Nội dung: Kiểm tra ràng buộc ngày đăng ký thành viên của khách hàng Nếu ngày đăng ký của khách hàng nhỏ hơn ngày sinh thì báo lỗi và không cho phép đăng ký
Bảng 5 4 Bảng tầm ảnh hưởng trigger tg_check_start_date
Hình 5 3 Trigger tg_check_start_date
5.5.3.4 Tự động tạo ID của khách hàng khi đăng ký khách hàng thành viên
- Nội dung: Khi đăng ký khách hàng thành viên, tự động tạo ra ID mới cho khách hàng
Bảng 5 5 Bảng tầm ảnh hưởng trigger tg_increment_customerID
Hình 5 4 Trigger tg_increment_customerID
Stored procedure trong MySQL là một khối mã SQL đặt tên và lưu trữ trên máy chủ cơ sở dữ liệu Nó chứa một tập hợp các câu lệnh SQL được thực thi một cách có tổ chức và có thể được gọi lại từ các ứng dụng hoặc các stored procedure khác
Một số đặc điểm của stored procedure trong MySQL:
- Tính tổ chức và tái sử dụng: Stored procedure cho phép tổ chức mã SQL thành các khối logic và có thể được sử dụng lại trong nhiều ngữ cảnh khác nhau Điều này giúp giảm lặp lại mã và tăng tính modular và maintainable của ứng dụng
- Tham số đầu vào và đầu ra: Stored procedure có thể nhận tham số đầu vào và trả về kết quả thông qua các tham số đầu ra Điều này cho phép truyền dữ liệu vào và lấy dữ liệu ra từ stored procedure, tạo sự linh hoạt và tuỳ chỉnh
- Xử lý lỗi và xác nhận: Stored procedure có khả năng xử lý các lỗi và ngoại lệ thông qua việc sử dụng cấu trúc TRY-CATCH hoặc khối IF-ELSE Ngoài ra, stored procedure cũng cho phép sử dụng câu lệnh COMMIT và ROLLBACK để xác nhận hoặc hủy bỏ các thay đổi trong giao dịch
- Quyền truy cập và bảo mật: Stored procedure trong MySQL có quyền truy cập vào các đối tượng trong cơ sở dữ liệu, bao gồm bảng, view và các stored procedure khác Điều này cho phép kiểm soát quyền truy cập và bảo mật dữ liệu
- Tối ưu hóa và hiệu suất: Stored procedure có thể được biên dịch và lưu trữ trên máy chủ cơ sở dữ liệu, giúp cải thiện hiệu suất và tối ưu hóa thời gian thực thi Ngoài ra, nó cũng giúp giảm băng thông mạng bởi việc truy vấn dữ liệu và xử lý logic trực tiếp trên máy chủ
- Khả năng tích hợp: Stored procedure có thể được gọi từ các ngôn ngữ lập trình khác nhau, như PHP, Java hoặc NET, để thực hiện các chức năng cụ thể trong ứng dụng
- Gỡ lỗi và theo dõi: Stored procedure trong MySQL cho phép gỡ lỗi và theo dõi thực thi bằng cách sử dụng các công cụ như trình biên dịch và bộ xử lý lỗi Nó cung cấp thông tin chi tiết về lỗi và dấu vết thực thi, giúp tìm ra và sửa lỗi hiệu quả
Tóm lại, stored procedure trong MySQL mang đến tính tổ chức, tái sử dụng, linh hoạt và bảo mật Nó cung cấp khả năng xử lý lỗi, tối ưu hóa hiệu suất và tích hợp với các ngôn ngữ lập trình khác
CREATE PROCEDURE [procedure_name] [[IN | OUT | INOUT] parameter_name datatype [, parameter datatype]) ]
- DELIMITER: Định nghĩa một ký tự phân cách khác để tránh xung đột với dấu chấm phẩy trong các câu lệnh bên trong khối lệnh
- CREATE PROCEDURE [procedure_name]: Tạo một stored procedure có tên [procedure_name]
- [procedure_name]: Tên của stored procedure
- parameter_name: Tên của tham số trong stored procedure
- datatype: Kiểu dữ liệu của tham số
- Declaration_section: Được sử dụng để khai báo các biến
- Executable_section: Chứa các câu lệnh SQL và các câu lệnh điều khiển để thực hiện tác vụ cụ thể trong stored procedure
5.6.2 Danh sách các stored procedure
Bảng 5 6 Danh sách stored procedure
Tham số đầu vào Tham số đầu ra Ý nghĩa
1 SP_AddBill p_billDate, p_customerName, p_billPrice, p_customerPhone, p_employeeID, p_customerID
Thêm một hóa đơn mới vào bảng BILL
2 SP_AddDiscount p_discountID, p_discountName, p_discountQuantity, p_discountValue, p_discountStartDay, p_discountEndDay
Thêm mã giảm giá mới
3 SP_AddCustomer p_customerName, p_customerDOB, p_customerAddress, p_customerPhone, p_customerEmail
4 SP_AddCategory categoryName Không có
Thêm danh mục sản phẩm mới
5 SP_ApplyDiscount p_name Không có
Giảm số lượng mã giảm giá sau khi áp dụng mã giảm giá và xóa khi số lượng về 0
6 SP_GetBestSellingDrinksInTimeRange startDate, endDate Không có
Thống kê các món bán chạy nhất trong khoảng thời gian cụ thể
7 SP_GetBillPriceByMonth yearInput Không có
Hiển thị số tiền đã bán từng tháng trong năm
8 SP_GetBillPriceByMonthYear inputMonth, inputYear Không có
Hiển thị số tiền đã bán từng ngày trong tháng
9 SP_GetSalesForDate saleDate Không có
Lấy thông tin các mặt hàng đã bán trong ngày
10 SP_UpdateCustomerPointsPlus p_discountStartDay customerPhoneNumber additionalPoints
Cập nhật điểm tích lũy cho khách hàng
11 SP_UpdateDiscount p_discountName, p_discountValue, p_discountStartDay, p_discountEndDay, p_discountID
Cập nhật thông tin mã giảm giá cho bảng DISCOUNT
12 SP_UpdateFoodItem p_itemID, p_newPrice, p_newCategoryName, p_newItemName
Cập nhật thông tin cho bảng FOOD_ITEM
13 SP_UpdateFoodItemCategoryID categoryNameParam Không có
Lấy thông tin categoryID cho FOOD_ITEM từ bảng CATEGORY
14 SP_UpdateRate customer_phone Không có
Cập nhật Rate cho khách hàng sau khi mua hàng thành công
15 SP_UpdateItemID itemNameParam Không có
Cập nhật thông tin itemID tương ứng itemName
16 SP_DeleteCategory p_categoryID Không có Xóa danh mục sản phẩm
17 SP_ViewTotalBillAmountByDate search_date total_amount
Xem tổng tiền bán được trong ngày
18 SP_ViewBillsByDate search_date Không có
Xem các hóa đơn trong ngày, tháng, năm
19 SP_ListEmployeesByStatus statusInput Không có Xem số lượng và thông tin
Trang 64 nhân viên có trạng thái tương ứng
5.6.3 Mô tả một số stored procedure
5.6.3.1 Xóa danh mục sản phẩm
- Nội dung: Xóa danh mục và các món liên quan
- Tham số đầu vào: p_categoryID
- Tham số đầu ra: Không có
1 Kiểm tra sự tồn tại của categoryID:
1.1 Tìm kiếm categoryID trong bảng CATEGORY
1.2 Nếu không tìm thấy categoryID, thông báo "Không tìm thấy categoryID" và dừng procedure
2 Kiểm tra sự tồn tại của FOOD_ITEM trong BILL_DETAIL:
2.1 Kiểm tra xem FOOD_ITEM của CATEGORY có phát sinh trong bảng BILL_DETAIL hay không
2.2 Nếu có FOOD_ITEM của CATEGORY trong BILL_DETAIL, thông báo
"Không thể xóa CATEGORY vì có FOOD_ITEM của CATEGORY trong BILL_DETAIL" và dừng procedure
3 Xóa FOOD_ITEM của CATEGORY:
3.1 Đếm số lượng FOOD_ITEM của CATEGORY sẽ bị xóa
3.2 Xóa các FOOD_ITEM của CATEGORY trong bảng FOOD_ITEM
3.3 Lưu trữ danh sách FOOD_ITEM đã xóa vào bảng tạm
3.4 Kiểm tra xem có FOOD_ITEM nào được xóa hay không
3.4.1 Nếu có FOOD_ITEM được xóa, đánh dấu biến "foodItemsDeleted" là TRUE
3.4.2 Hiển thị thông báo "Đã xóa [số lượng] FOOD_ITEM của CATEGORY [categoryID] trong bảng FOOD_ITEM "
3.4.3 Nếu không có FOOD_ITEM nào được xóa, đánh dấu biến
"foodItemsDeleted" là FALSE và hiển thị thông báo "Không có FOOD_ITEM để xóa"
4 Kiểm tra xem FOOD_ITEM đã xóa có trong bảng tạm hay không:
4.1 Nếu có FOOD_ITEM đã xóa, hiển thị danh sách FOOD_ITEM đã xóa từ bảng tạm "temp_DeletedFoodItems"
5 Xóa CATEGORY và FOOD_ITEM đã xóa trong bảng CATEGORY:
5.1 Xóa CATEGORY có categoryID tương ứng trong bảng CATEGORY
5.2 Nếu có FOOD_ITEM đã xóa, hiển thị danh sách FOOD_ITEM đã xóa từ bảng tạm "temp_DeletedFoodItems"
5.3 Hiển thị thông báo "Đã xóa CATEGORY [categoryID] trong bảng CATEGORY"
CREATE PROCEDURE sp_deletecategory(IN p_categoryID INT)
Biến cờ để đánh dấu xem categoryID có tồn tại hay không
Biến cờ để đánh dấu xem có food_item trong bill_detail của category hay không
Biến lưu trữ số lượng food_item đã xóa
Biến để kiểm tra xem có food_item nào được xóa hay không
DECLARE foodItemsDeleted BOOLEAN DEFAULT FALSE;
Tạo bảng tạm để lưu trữ danh sách food_item đã xóa
CREATE TEMPORARY TABLE IF NOT EXISTS temp_DeletedFoodItems ( itemID INT, itemName VARCHAR(40)
Tìm kiếm categoryID trong bảng category
Nếu không tìm thấy categoryID, thông báo và dừng procedure
SELECT 'Không tìm thấy categoryID.' AS Message;
Kiểm tra xem food_item của category có phát sinh trong bill_detail hay không
Nếu có food_item của category trong bill_detail, thông báo và dừng procedure
SELECT 'Không thể xóa category vì có food_item của category trong bill_detail.' AS Message;
Đếm số lượng food_item sẽ bị xóa
Lấy danh sách food_item đã xóa
INSERT INTO temp_DeletedFoodItems (itemID, itemName)
Xóa food_item của category trong bảng food_item
DELETE FROM food_item WHERE categoryID = p_categoryID;
Kiểm tra xem có food_item nào được xóa hay không
SELECT CONCAT('Đã xóa ', deletedItemCount, ' food_item của category ', p_categoryID, ' trong bảng food_item.') AS Message;
SELECT 'Không có food_item để xóa.' AS Message;
Hiển thị danh sách food_item đã xóa từ bảng tạm
SELECT CONCAT('Đã xóa food_item ', itemID, ': ', itemName) AS DeletedItem
DROP TEMPORARY TABLE IF EXISTS temp_DeletedFoodItems;
Xóa category trong bảng category
DELETE FROM category WHERE categoryID = p_categoryID;
SELECT CONCAT('Đã xóa category ', p_categoryID, ' trong bảng category.') AS Message;
5.6.3.2 Thống kê các món bán chạy nhất trong khoảng thời gian cụ thể
- Nội dung: Lấy thông tin về những đồ uống bán chạy nhất trong khoảng thời gian cụ thể
- Tham số đầu vào: startDate, endDate
- Tham số đầu ra: Không có
1 Truy vấn các thông tin các món được bán trong thời gian chỉ được từ bảng BILL_DETAIL và FOOD_ITEM
2 Truy vấn thông tin của các món chưa được bán từ bảng FOOD_ITEM (tức không tồn tại trong bảng BILL_DETAIL)
3 UNION ALL - kết hợp kết quả của hai truy vấn thành một tập kết quả duy nhất
4 Tập kết quả được kết hợp được sắp xếp theo totalQuantity theo thứ tự giảm dần và itemPrice theo thứ tự giảm dần
CREATE PROCEDURE `SP_GetBestSellingDrinksInTimeRange` (IN `startDate` DATE, IN `endDate` DATE) BEGIN
SELECT itemName, itemPrice, totalQuantity, totalAmount
SELECT bd.itemName, fi.itemPrice, SUM(bd.quantity) AS totalQuantity, SUM(bd.quantity * fi.itemPrice) AS totalAmount
INNER JOIN food_item fi ON bd.itemName = fi.itemName
INNER JOIN bill b ON bd.billID = b.billID
WHERE b.billDate BETWEEN startDate AND endDate
SELECT fi2.itemName, fi2.itemPrice, 0 AS totalQuantity, 0 AS totalAmount
WHERE fi2.itemName NOT IN (SELECT itemName FROM bill_detail) ) AS result
ORDER BY totalQuantity DESC, itemPrice DESC;
5.6.3.3 Hiển thị số tiền đã bán từng tháng trong năm
- Nội dung: Lấy thông tin tổng tiền các tháng từ một năm cụ thể
- Tham số đầu vào: yearInput
- Tham số đầu ra: Không có
1 Đặt giá trị ban đầu cho biến monthCounter là 1 và totalMonths là 12 (Đây là biến dùng để đếm các tháng trong vòng lặp)
2 Tạo một bảng tạm thời có tên tempBillPriceByMonth (nếu chưa tồn tại) để lưu trữ kết quả
3 Khởi tạo bảng tạm thời với giá trị 0 cho tất cả các tháng Sử dụng vòng lặp WHILE để lặp qua các tháng từ 1 đến 12, và chèn các bản ghi vào bảng tạm thời với monthCounter và giá trị 0
4 Cập nhật bảng tạm thời với các giá trị thực tế
5 Trả về kết quả từ bảng tạm thời Sử dụng câu lệnh SELECT để chọn các cột month và price từ bảng tempBillPriceByMonth
6 Tính toán và hiển thị tổng giá trị Sử dụng câu lệnh SELECT CONCAT('Tổng cộng: ', SUM(price)) AS Total Price FROM tempBillPriceByMonth; để tính tổng các giá trị price trong bảng tạm thời và hiển thị kết quả với tiền tố "Tổng cộng: "
7 Xóa bảng tạm thời Sử dụng câu lệnh DROP TABLE IF EXISTS tempBillPriceByMonth; để xóa bảng tạm thời sau khi đã sử dụng xong
CREATE PROCEDURE `SP_GetBillPriceByMonth` (IN `yearInput` INT) BEGIN DECLARE monthCounter INT DEFAULT 1;
Create a temporary table to store the result
CREATE TEMPORARY TABLE IF NOT EXISTS tempBillPriceByMonth (
Initialize the temporary table with 0 price for all months WHILE monthCounter = 0 AND customer_point = 150 AND customer_point