Dữ liệu kiểm toán của bạn nên được lưu trữ trên mỗi bảng, thay vì tất cả ở một nơi. Những gì bạn cần làm là tạo một bảng kiểm tra cho mỗi bảng bạn muốn theo dõi và tạo trình kích hoạt để tạo bản ghi trong bảng kiểm tra cho bất kỳ hoạt động thao tác dữ liệu nào trên bảng đã kiểm toán.
Chắc chắn bạn nên không cho phép DELETE
các thao tác trên items
và item_options
bảng - thêm cờ như item_active
và item_option_active
để thay vào đó bạn có thể xóa mềm chúng. Đây là thực tế bình thường trong các tình huống mà bạn đang làm những việc như lưu trữ hóa đơn tham chiếu các sản phẩm đã đặt hàng trước đây và cần dữ liệu cho mục đích báo cáo lịch sử, nhưng không phải để sử dụng hàng ngày.
Các bảng kiểm tra của bạn không phải là thứ bạn nên sử dụng để tham chiếu dữ liệu cũ, mô hình dữ liệu thông thường của bạn chỉ hỗ trợ "ẩn" dữ liệu cũ ở những nơi có khả năng dữ liệu đó vẫn được sử dụng và lưu trữ nhiều phiên bản dữ liệu sẽ thay đổi theo thời gian.
Để kiểm tra, việc lưu trữ tên người dùng của người dùng cuối cùng để sửa đổi một bản ghi đã cho cũng rất hữu ích - khi được sử dụng từ một ứng dụng web, bạn không thể sử dụng USER()
của MySQL chức năng để nhận bất kỳ thông tin hữu ích nào về người đã đăng nhập. Thêm một cột và điền vào cột đó có nghĩa là bạn có thể sử dụng thông tin đó trong trình kích hoạt kiểm tra của mình.
NB: Tôi sẽ giả định rằng bạn sẽ không cho phép thay đổi ID mặt hàng trong điều kiện bình thường - điều đó sẽ làm cho hệ thống kiểm tra của bạn phức tạp hơn.
Nếu bạn thêm cờ đang hoạt động và dữ liệu được sửa đổi lần cuối vào bảng của mình, chúng sẽ trông giống như sau:
Bảng mục:
mysql> desc items;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| item_id | int(11) | NO | PRI | NULL | auto_increment |
| item_name | varchar(100) | YES | | NULL | |
| item_description | text | YES | | NULL | |
| item_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
Bảng tùy chọn mặt hàng:
mysql> desc item_options;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| option_id | int(11) | NO | PRI | NULL | auto_increment |
| item_id | int(11) | YES | MUL | NULL | |
| option_name | varchar(100) | YES | | NULL | |
| option_price | int(11) | YES | | NULL | |
| option_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
Các bảng kiểm toán của bạn cần phải lưu trữ bốn phần thông tin bổ sung:
- ID kiểm tra - ID này chỉ là duy nhất cho lịch sử của điều này bảng, nó không phải là giá trị toàn cầu
- Thay đổi được thực hiện bởi - người dùng cơ sở dữ liệu đã thực hiện thay đổi
- Thay đổi ngày / giờ
- Loại hành động -
INSERT
hoặcUPDATE
(hoặcDELETE
nếu bạn cho phép nó)
Các bảng kiểm tra của bạn sẽ trông giống như sau:
Bảng kiểm tra các hạng mục:
mysql> desc items_audit;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| audit_id | int(11) | NO | PRI | NULL | auto_increment |
| item_id | int(11) | YES | | NULL | |
| item_name | varchar(100) | YES | | NULL | |
| item_description | text | YES | | NULL | |
| item_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
| change_by | varchar(50) | YES | | NULL | |
| change_date | datetime | YES | | NULL | |
| action | varchar(10) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
Bảng kiểm tra tùy chọn mặt hàng:
mysql> desc item_options_audit;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| audit_id | int(11) | NO | PRI | NULL | auto_increment |
| option_id | int(11) | YES | | NULL | |
| item_id | int(11) | YES | | NULL | |
| option_name | varchar(100) | YES | | NULL | |
| option_price | int(11) | YES | | NULL | |
| option_active | tinyint(4) | YES | | NULL | |
| modified_by | varchar(50) | YES | | NULL | |
| change_by | varchar(50) | YES | | NULL | |
| change_date | datetime | YES | | NULL | |
| action | varchar(10) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
Không sử dụng khóa ngoại trên bảng kiểm tra của bạn; các hàng trong bảng kiểm tra không phải là hàng con của các bản ghi mà chúng đang kiểm tra, vì vậy khóa ngoại không có tác dụng gì.
Trình kích hoạt
NB: MySQL không hỗ trợ trình kích hoạt kiểu nhiều câu lệnh, vì vậy bạn cần một trình kích hoạt cho mỗi INSERT
, UPDATE
và DELETE
(nếu có).
Trình kích hoạt của bạn chỉ cần INSERT
tất cả NEW
giá trị vào bảng kiểm toán. Định nghĩa kích hoạt cho các items
bảng có thể là:
/* Trigger for INSERT statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_insert_audit
AFTER INSERT ON items
FOR EACH ROW BEGIN
INSERT INTO items_audit (
item_id, item_name, item_description,
item_active, modified_by, change_by,
change_date, action
) VALUES (
NEW.item_id, NEW.item_name, NEW.item_description,
NEW.item_active, NEW.modified_by, USER(),
NOW(), 'INSERT'
);
END;
/* Trigger for UPDATE statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_update_audit
AFTER UPDATE ON items
FOR EACH ROW BEGIN
INSERT INTO items_audit (
item_id, item_name, item_description,
item_active, modified_by, change_by,
change_date, action
) VALUES (
NEW.item_id, NEW.item_name, NEW.item_description,
NEW.item_active, NEW.modified_by, USER(),
NOW(), 'UPDATE'
);
END;
Tạo các trình kích hoạt tương tự cho item_options
bảng.
Cập nhật:Lịch sử dữ liệu trong thương mại điện tử
Việc kiểm tra mà chúng tôi đã thực hiện ở trên sẽ cho phép bạn lưu giữ lịch sử của bất kỳ bảng cơ sở dữ liệu nhất định nào, nhưng tạo ra một kho lưu trữ dữ liệu không phù hợp để sử dụng cho dữ liệu cần được truy cập thường xuyên.
Trong hệ thống thương mại điện tử, việc giữ nguyên có thể sử dụng được dữ liệu lịch sử rất quan trọng để bạn có thể thay đổi các thuộc tính trong khi vẫn hiển thị các giá trị cũ trong một số trường hợp nhất định.
Điều này phải hoàn toàn tách biệt với giải pháp kiểm toán của bạn
Cách tốt nhất để lưu trữ lịch sử là tạo bảng lịch sử cho từng thuộc tính cần được lưu trữ trong lịch sử. Câu hỏi Stackoverflow này có một số thông tin tốt về việc lưu giữ lịch sử của một thuộc tính nhất định .
Trong tình huống của bạn, nếu bạn chỉ quan tâm đến giá cả và tiêu đề, bạn sẽ tạo prices
bảng và một item_titles
bàn. Mỗi cái sẽ có một khóa ngoại cho item_options
bảng hoặc items
bảng (bảng chính sẽ vẫn lưu trữ hiện tại giá hoặc tiêu đề), và sẽ có giá hoặc tiêu đề, với ngày có hiệu lực của nó. Các bảng này phải có các quyền chi tiết (có thể dựa trên cột) để tránh cập nhật effective_from
ngày và các giá trị thực sau khi bản ghi được chèn.
Bạn cũng nên sử dụng giải pháp kiểm tra ở trên trên các bảng này.