นี่เป็นวิธีง่ายๆในการดำเนินการนี้:
ขั้นแรกสร้างตารางประวัติสำหรับแต่ละตารางข้อมูลที่คุณต้องการติดตาม (ตัวอย่างแบบสอบถามด้านล่าง) ตารางนี้จะมีรายการสำหรับการแทรกอัปเดตและลบคิวรีที่ดำเนินการในแต่ละแถวในตารางข้อมูล
โครงสร้างของตารางประวัติจะเหมือนกับตารางข้อมูลที่ติดตามยกเว้นคอลัมน์เพิ่มเติมสามคอลัมน์: คอลัมน์สำหรับจัดเก็บการดำเนินการที่เกิดขึ้น (เรียกว่า 'การกระทำ') วันที่และเวลาของการดำเนินการและคอลัมน์ เพื่อจัดเก็บหมายเลขลำดับ ('การแก้ไข') ซึ่งจะเพิ่มขึ้นต่อการดำเนินการและจัดกลุ่มตามคอลัมน์คีย์หลักของตารางข้อมูล
ในการทำพฤติกรรมการเรียงลำดับนี้ดัชนีสองคอลัมน์ (คอมโพสิต) จะถูกสร้างขึ้นบนคอลัมน์คีย์หลักและคอลัมน์การแก้ไข โปรดทราบว่าคุณสามารถจัดลำดับได้เฉพาะในกรณีที่เอ็นจิ้นที่ใช้ในตารางประวัติคือ MyISAM ( ดู 'บันทึก MyISAM' ในหน้านี้)
ตารางประวัติค่อนข้างง่ายในการสร้าง ในแบบสอบถาม ALTER TABLE ด้านล่าง (และในแบบสอบถามทริกเกอร์ด้านล่าง) ให้แทนที่ 'primary_key_column' ด้วยชื่อจริงของคอลัมน์นั้นในตารางข้อมูลของคุณ
CREATE TABLE MyDB.data_history LIKE MyDB.data;
ALTER TABLE MyDB.data_history MODIFY COLUMN primary_key_column int(11) NOT NULL,
DROP PRIMARY KEY, ENGINE = MyISAM, ADD action VARCHAR(8) DEFAULT 'insert' FIRST,
ADD revision INT(6) NOT NULL AUTO_INCREMENT AFTER action,
ADD dt_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER revision,
ADD PRIMARY KEY (primary_key_column, revision);
จากนั้นคุณสร้างทริกเกอร์:
DROP TRIGGER IF EXISTS MyDB.data__ai;
DROP TRIGGER IF EXISTS MyDB.data__au;
DROP TRIGGER IF EXISTS MyDB.data__bd;
CREATE TRIGGER MyDB.data__ai AFTER INSERT ON MyDB.data FOR EACH ROW
INSERT INTO MyDB.data_history SELECT 'insert', NULL, NOW(), d.*
FROM MyDB.data AS d WHERE d.primary_key_column = NEW.primary_key_column;
CREATE TRIGGER MyDB.data__au AFTER UPDATE ON MyDB.data FOR EACH ROW
INSERT INTO MyDB.data_history SELECT 'update', NULL, NOW(), d.*
FROM MyDB.data AS d WHERE d.primary_key_column = NEW.primary_key_column;
CREATE TRIGGER MyDB.data__bd BEFORE DELETE ON MyDB.data FOR EACH ROW
INSERT INTO MyDB.data_history SELECT 'delete', NULL, NOW(), d.*
FROM MyDB.data AS d WHERE d.primary_key_column = OLD.primary_key_column;
และคุณทำเสร็จแล้ว ตอนนี้ส่วนแทรกการอัปเดตและการลบทั้งหมดใน "MyDb.data" จะถูกบันทึกไว้ใน "MyDb.data_history" โดยให้ตารางประวัติเป็นแบบนี้ (ลบคอลัมน์ "data_columns" ที่สร้างไว้)
ID revision action data columns..
1 1 'insert' .... initial entry for row where ID = 1
1 2 'update' .... changes made to row where ID = 1
2 1 'insert' .... initial entry, ID = 2
3 1 'insert' .... initial entry, ID = 3
1 3 'update' .... more changes made to row where ID = 1
3 2 'update' .... changes made to row where ID = 3
2 2 'delete' .... deletion of row where ID = 2
ในการแสดงการเปลี่ยนแปลงของคอลัมน์หรือคอลัมน์ที่กำหนดจากการอัปเดตไปจนถึงการอัปเดตคุณจะต้องรวมตารางประวัติเข้ากับตัวเองในคีย์หลักและคอลัมน์ลำดับ คุณสามารถสร้างมุมมองสำหรับจุดประสงค์นี้ตัวอย่างเช่น:
CREATE VIEW data_history_changes AS
SELECT t2.dt_datetime, t2.action, t1.primary_key_column as 'row id',
IF(t1.a_column = t2.a_column, t1.a_column, CONCAT(t1.a_column, " to ", t2.a_column)) as a_column
FROM MyDB.data_history as t1 INNER join MyDB.data_history as t2 on t1.primary_key_column = t2.primary_key_column
WHERE (t1.revision = 1 AND t2.revision = 1) OR t2.revision = t1.revision+1
ORDER BY t1.primary_key_column ASC, t2.revision ASC
Edit: โอ้ว้าวคนชอบตารางประวัติของฉันเมื่อ 6 ปีที่แล้ว: P
การใช้งานของฉันยังคงฮัมเพลงไปพร้อม ๆ กันการใหญ่ขึ้นและเทอะทะมากขึ้นฉันคิดว่า ฉันเขียนมุมมองและ UI ที่สวยงามเพื่อดูประวัติในฐานข้อมูลนี้ แต่ฉันไม่คิดว่ามันเคยถูกใช้มากนัก มันจะไป
ในการจัดการกับความคิดเห็นบางส่วนตามลำดับ:
ฉันใช้งาน PHP ของตัวเองซึ่งเกี่ยวข้องมากกว่าเล็กน้อยและหลีกเลี่ยงปัญหาบางอย่างที่อธิบายไว้ในความคิดเห็น (มีการโอนดัชนีไปอย่างมีนัยสำคัญหากคุณถ่ายโอนดัชนีที่ไม่ซ้ำกันไปยังตารางประวัติสิ่งต่างๆจะพังมีวิธีแก้ไขสำหรับ นี้ในความคิดเห็น) การติดตามโพสต์นี้ไปยังจดหมายอาจเป็นการผจญภัยขึ้นอยู่กับว่าฐานข้อมูลของคุณเป็นอย่างไร
หากความสัมพันธ์ระหว่างคีย์หลักและคอลัมน์การแก้ไขดูเหมือนปิดอยู่ก็มักจะหมายความว่าคีย์คอมโพสิตนั้นมีปัญหา มีบางครั้งที่เกิดขึ้นได้ยากและสูญเสียสาเหตุ
ฉันพบว่าโซลูชันนี้มีประสิทธิภาพโดยใช้ทริกเกอร์เหมือนเดิม นอกจากนี้ MyISAM ยังเร็วในการแทรกซึ่งเป็นตัวกระตุ้นทั้งหมด คุณสามารถปรับปรุงสิ่งนี้เพิ่มเติมได้ด้วยการจัดทำดัชนีอัจฉริยะ (หรือขาด ... ) การแทรกแถวเดียวลงในตาราง MyISAM ด้วยคีย์หลักไม่ควรเป็นการดำเนินการที่คุณต้องปรับให้เหมาะสมจริง ๆ เว้นแต่คุณจะมีปัญหาสำคัญเกิดขึ้นที่อื่น ตลอดเวลาที่ฉันใช้งานฐานข้อมูล MySQL การใช้งานตารางประวัตินี้เปิดใช้งานอยู่มันไม่เคยเป็นสาเหตุของปัญหาประสิทธิภาพการทำงาน (หลายอย่าง) ที่เกิดขึ้น
หากคุณได้รับการแทรกซ้ำให้ตรวจสอบเลเยอร์ซอฟต์แวร์ของคุณสำหรับการค้นหาประเภท INSERT IGNORE อืมตอนนี้จำไม่ได้แล้ว แต่ฉันคิดว่ามีปัญหากับโครงการนี้และธุรกรรมซึ่งในที่สุดก็ล้มเหลวหลังจากเรียกใช้การดำเนินการ DML หลายรายการ สิ่งที่ควรระวังอย่างน้อยที่สุด
สิ่งสำคัญคือฟิลด์ในตารางประวัติและตารางข้อมูลจะต้องตรงกัน หรือว่าตารางข้อมูลของคุณไม่มีคอลัมน์มากกว่าตารางประวัติ มิฉะนั้นการค้นหาการแทรก / อัปเดต / เดลในตารางข้อมูลจะล้มเหลวเมื่อการแทรกในตารางประวัติทำให้คอลัมน์ในแบบสอบถามไม่มีอยู่ (เนื่องจาก d. * ในแบบสอบถามทริกเกอร์) และทริกเกอร์ล้มเหลว จะดีมากถ้า MySQL มีบางอย่างเช่นสคีมาทริกเกอร์ซึ่งคุณสามารถเปลี่ยนตารางประวัติได้หากมีการเพิ่มคอลัมน์ลงในตารางข้อมูล ตอนนี้ MySQL มีหรือไม่? ฉันทำปฏิกิริยาในวันนี้: P