การออกแบบที่ดีที่สุดสำหรับตารางฐานข้อมูลการเปลี่ยนแปลง / การตรวจสอบ? [ปิด]


114

ฉันต้องการสร้างตารางฐานข้อมูลเพื่อจัดเก็บบันทึกการเปลี่ยนแปลง / การตรวจสอบต่างๆ (เมื่อมีการเพิ่มลบแก้ไข ฯลฯ ) ฉันไม่จำเป็นต้องเก็บข้อมูลรายละเอียดโดยเฉพาะดังนั้นฉันจึงคิดบางอย่างตามแนวของ:

  • id (สำหรับเหตุการณ์)
  • ผู้ใช้ที่เรียกใช้
  • ชื่อเหตุการณ์
  • คำอธิบายเหตุการณ์
  • การประทับเวลาของเหตุการณ์

ฉันขาดอะไรที่นี่? เห็นได้ชัดว่าฉันสามารถปรับปรุงการออกแบบได้เรื่อย ๆ แม้ว่าฉันจะไม่ได้วางแผนที่จะทำให้มันซับซ้อน (การสร้างตารางอื่น ๆ สำหรับประเภทเหตุการณ์หรือสิ่งต่างๆเช่นนั้นไม่ใช่เรื่องที่น่าสงสัยเนื่องจากเป็นความซับซ้อนสำหรับความต้องการของฉัน)


ฉันอ่านคำตอบของคุณแล้วฉันแปลกใจที่ไม่มีใครพูดถึงกฎหมาย ฉันรู้ว่ากฎหมายหรือเอกสารการปฏิบัติที่ดีบางอย่างอธิบายว่าเราต้องใช้ตารางการตรวจสอบ (อ่านอย่างเดียว) อย่างไร แต่ฉันไม่มีข้อมูลมากไปกว่านี้ ฉันเพิ่งรู้ว่ามันมีอยู่จริง ฉันกำลังคิดถึงเส้นทางการตรวจสอบใน CFR 21 ตอนที่ 11
Bastien Vandamme

12
อาจมีประโยชน์: ludwigstuyck.wordpress.com/2013/04/04/history-tracking
L-Four

คำตอบ:


70

ในโครงการที่ฉันกำลังดำเนินการบันทึกการตรวจสอบยังเริ่มต้นจากการออกแบบที่เรียบง่ายเช่นที่คุณอธิบายไว้:

event ID
event date/time
event type
user ID
description

ความคิดเหมือนกัน: เพื่อให้สิ่งต่างๆเรียบง่าย

อย่างไรก็ตามเห็นได้ชัดอย่างรวดเร็วว่าการออกแบบที่เรียบง่ายนี้ไม่เพียงพอ การตรวจสอบทั่วไปทำให้เกิดคำถามเช่นนี้:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

ดังนั้นเพื่อให้สามารถตอบคำถามดังกล่าวได้อย่างรวดเร็ว (โดยใช้ SQL) เราจึงมีคอลัมน์เพิ่มเติมอีกสองคอลัมน์ในตารางการตรวจสอบ

object type (or table name)
object ID

นั่นคือตอนที่การออกแบบบันทึกการตรวจสอบของเรามีความเสถียร (เป็นเวลาไม่กี่ปีแล้ว)

แน่นอนว่า "การปรับปรุง" ครั้งสุดท้ายจะใช้ได้กับตารางที่มีคีย์ตัวแทนเท่านั้น แต่เดาอะไร? ตารางทั้งหมดของเราที่ควรค่าแก่การตรวจสอบมีกุญแจสำคัญ!


ปัญหาเดียวที่ฉันมีกับการออกแบบนี้ (เส้นทางการตรวจสอบตามคำอธิบาย) คือการแปลภาษาที่ใช้ในฟิลด์นั้น
Sam Wilson

@ แซมฉันไม่เห็นปัญหาดังกล่าวหากข้อความถูกสร้างขึ้นโดยระบบเพียงแค่ใช้คีย์ที่นี่สำหรับสตริงการแปล
JCM

4
@Hiru: เมื่อคุณ "ผสมผสาน" แนวคิดที่แตกต่างกันตั้งแต่สองแนวคิดขึ้นไปในคอลัมน์เดียวบ่อยครั้งที่มันจะย้อนกลับมาไม่ช้าก็เร็ว ตัวอย่างเช่นหากคุณ "รวม" ประเภทเหตุการณ์และประเภทอ็อบเจ็กต์มันจะส่งผลต่อการค้นหาเช่น "แสดงเรกคอร์ดสำหรับอ็อบเจ็กต์ทั้งหมดของประเภทที่ระบุ" และ "แสดงเรกคอร์ดสำหรับเหตุการณ์ทั้งหมดในประเภทที่กำหนด" (ข้อความค้นหาจะมากกว่านี้ ซับซ้อนและน่าจะทำงานช้ากว่ามาก)
Yarik

3
นอกเหนือไปจากคอลัมน์เหล่านี้หนึ่งสามารถมีคอลัมน์พิเศษสำหรับคำอธิบายโครงสร้าง / โครงสร้างน้ำหนักบรรทุกเหตุการณ์ คอลัมน์นี้จะเก็บรายละเอียดเหตุการณ์ (ไม่ว่าจะซับซ้อนเพียงใดก็ตาม) ในรูปแบบที่คอมพิวเตอร์อ่านได้คือ XML / JSON ง่ายต่อการทำให้เป็นอนุกรมเพื่อสอบถาม (อย่างน้อยก็ใน Postgres / MSSQL) เพื่อให้เหตุผลเกี่ยวกับ
turdus-merula

1
@ เบ็นจามิน: คำตอบอยู่ในรูปแบบโดเมน (aka business model) หากโมเดลอนุญาตให้สร้างเอนทิตีพร้อมกัน (เช่นเป็นส่วนหนึ่งของธุรกรรมเชิงตรรกะ) ฉันก็ไม่เห็นปัญหาใด ๆ ในการมีบันทึกบันทึกหลายรายการที่มีการประทับเวลาเดียวกัน เช่นหากการสร้างใบสั่งซื้อ (เป็นธุรกรรม) สามารถรวมการสร้างรายการสั่งซื้อ N รายการบันทึก 1 + N ที่เกี่ยวข้องทั้งหมดจะมีการประทับเวลาเดียวกัน การวิเคราะห์บันทึกดังกล่าวในภายหลังสามารถใช้ประโยชน์จากสิ่งนี้ได้โดยการปฏิบัติต่อบันทึก 1 + N เหล่านี้ไม่ใช่บันทึกที่เป็นอิสระ แต่เป็นองค์ประกอบของธุรกรรมเชิงตรรกะ หวังว่านี่จะสมเหตุสมผล
Yarik

24

นอกจากนี้เรายังบันทึกค่าเก่าและใหม่และคอลัมน์ที่มาจากเช่นเดียวกับคีย์หลักของตารางที่ตรวจสอบในตารางรายละเอียดการตรวจสอบ คิดว่าคุณต้องการตารางการตรวจสอบเพื่ออะไร? คุณไม่เพียงต้องการทราบว่าใครเป็นผู้ทำการเปลี่ยนแปลงและเมื่อใด แต่เมื่อมีการเปลี่ยนแปลงที่ไม่ดีเกิดขึ้นคุณยังต้องการวิธีที่รวดเร็วในการนำข้อมูลกลับคืนมา

ในขณะที่คุณออกแบบคุณควรเขียนโค้ดเพื่อกู้คืนข้อมูล เมื่อคุณจำเป็นต้องฟื้นตัวมักจะรีบควรเตรียมตัวให้พร้อม


1
มันดีมากฉันไม่เข้าใจว่าทำไมคนถึงไม่สนใจโพสต์ล่าสุด
Maddy Shik

3
การจัดหาเหตุการณ์เป็นอีกทางเลือกหนึ่งในการจัดหาฟังก์ชันย้อนกลับในขณะที่รักษาประวัติไว้
แซม

23

มีหลายสิ่งที่คุณอาจต้องการตรวจสอบเช่นชื่อตาราง / คอลัมน์คอมพิวเตอร์ / แอปพลิเคชันที่ใช้อัปเดตและอื่น ๆ

ตอนนี้ขึ้นอยู่กับว่าคุณต้องการการตรวจสอบโดยละเอียดเพียงใดและในระดับใด

เราเริ่มสร้างโซลูชันการตรวจสอบตามทริกเกอร์ของเราเองและเราต้องการตรวจสอบทุกอย่างและยังมีตัวเลือกในการกู้คืน สิ่งนี้ซับซ้อนเกินไปดังนั้นเราจึงลงเอยด้วยการทำวิศวกรรมย้อนกลับApexSQLเครื่องมือของบุคคลที่สามตามทริกเกอร์เพื่อสร้างโซลูชันที่กำหนดเองของเราเอง

เคล็ดลับ:

  • รวมค่าก่อน / หลัง

  • รวม 3-4 คอลัมน์สำหรับจัดเก็บคีย์หลัก (ในกรณีที่เป็นคีย์ผสม)

  • จัดเก็บข้อมูลนอกฐานข้อมูลหลักตามที่โรเบิร์ตแนะนำแล้ว

  • ใช้เวลาอย่างเหมาะสมในการจัดเตรียมรายงานโดยเฉพาะอย่างยิ่งที่คุณอาจต้องใช้ในการกู้คืน

  • แผนการจัดเก็บชื่อโฮสต์ / แอปพลิเคชัน - สิ่งนี้อาจมีประโยชน์มากสำหรับการติดตามกิจกรรมที่น่าสงสัย


2
ทำไมคุณต้องทำวิศวกรรมย้อนกลับแทนที่จะซื้อ
Jowen

1
ควบคุมผลิตภัณฑ์ได้มากขึ้น
Tebe

1
หวังว่าพวกเขาจะไม่ฟ้องคุณ
ตัวเรียงลำดับ

9

มีคำตอบที่น่าสนใจมากมายที่นี่และในคำถามที่คล้ายกัน สิ่งเดียวที่ฉันสามารถเพิ่มได้จากประสบการณ์ส่วนตัวคือ:

  1. ใส่ตารางการตรวจสอบของคุณในฐานข้อมูลอื่น ตามหลักการแล้วคุณต้องการแยกออกจากข้อมูลเดิม หากคุณต้องการกู้คืนฐานข้อมูลคุณไม่ต้องการกู้คืนเส้นทางการตรวจสอบ

  2. ทำให้ผิดปกติมากที่สุดเท่าที่จะเป็นไปได้ คุณต้องการให้ตารางมีการอ้างอิงกับข้อมูลต้นฉบับให้น้อยที่สุด ตารางการตรวจสอบควรเรียบง่ายและรวดเร็วในการดึงข้อมูลจาก ไม่มีการรวมหรือการค้นหาในตารางอื่น ๆ เพื่อเข้าถึงข้อมูล


8
ข้อมูลที่ผิดปกติจะอ่านได้เร็วกว่าเมื่อเทียบกับข้อมูลปกติที่มีดัชนีที่เหมาะสมหรือไม่? (การทำซ้ำทั้งหมดจะไม่ส่งผลให้อ่านข้อมูลเพิ่มเติมจาก HDD หรือไม่)
แซม

4

สิ่งที่เรามีในตารางของเรา: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

รหัสทั่วไปจะชี้ที่แถวในตารางที่อัปเดตและชื่อตารางคือชื่อของตารางนั้นเป็นสตริง ไม่ใช่การออกแบบฐานข้อมูลที่ดี แต่ใช้งานได้ดี ตารางทั้งหมดของเรามีคอลัมน์คีย์ตัวแทนเดียวดังนั้นจึงทำงานได้ดี


2
"จำนวนเงิน" แสดงถึงอะไร?
turdus-merula

เป็นแอปพลิเคชันทางการเงินดังนั้นจึงเป็นค่าเงินดอลลาร์ของสิ่งที่ได้รับอนุญาต ฯลฯ
WW

4

ในการตรวจสอบแบบกำหนดเองทั่วไป (การสร้างตารางต่างๆ) เป็นตัวเลือกที่ไม่ดี ทริกเกอร์ฐานข้อมูล / ตารางสามารถปิดใช้งานเพื่อข้ามกิจกรรมบันทึกบางอย่างได้ ตารางการตรวจสอบที่กำหนดเองสามารถแก้ไขได้ อาจมีข้อยกเว้นที่จะนำไปใช้ ไม่กล่าวถึงปัญหาในการออกแบบโซลูชันที่มีประสิทธิภาพ จนถึงตอนนี้ฉันเห็นกรณีง่ายๆในการสนทนานี้ คุณต้องแยกออกจากฐานข้อมูลปัจจุบันและจากผู้ใช้ที่มีสิทธิ์ (DBA, Developers) RDBMS กระแสหลักทุกตัวมีสิ่งอำนวยความสะดวกในการตรวจสอบที่แม้แต่ DBA ก็ไม่สามารถปิดใช้งานการปลอมแปลงเป็นความลับ ดังนั้นความสามารถในการตรวจสอบที่ระบุโดยผู้ขาย RDBMS จะต้องเป็นตัวเลือกแรก ตัวเลือกอื่น ๆ จะเป็นโปรแกรมอ่านบันทึกธุรกรรมของบุคคลที่สามหรือโปรแกรมอ่านบันทึกที่กำหนดเองซึ่งจะผลักดันข้อมูลที่ถูกย่อยสลายไปยังระบบการส่งข้อความที่ลงท้ายด้วยรูปแบบของการตรวจสอบคลังข้อมูลหรือตัวจัดการเหตุการณ์แบบเรียลไทม์ สรุป: Solution Architect / "Hands on Data Architect" จำเป็นต้องมีส่วนร่วมในการกำหนดระบบดังกล่าวตามข้อกำหนด โดยปกติแล้วจะเป็นเรื่องที่ร้ายแรงเกินกว่าที่จะส่งมอบให้กับนักพัฒนาเพื่อแก้ไขปัญหา


3

มีหลายวิธีในการทำเช่นนี้ วิธีที่ฉันชอบคือ:

  1. เพิ่มmod_userเขตข้อมูลในตารางต้นทางของคุณ (ช่องที่คุณต้องการบันทึก)

  2. สร้างตารางบันทึกที่มีเขตข้อมูลที่คุณต้องการบันทึกรวมทั้งเขตข้อมูล log_datetimeและ เป็นคีย์หลักseq_numseq_num

  3. สร้างทริกเกอร์บนตารางต้นทางที่แทรกระเบียนปัจจุบันลงในตารางบันทึกเมื่อใดก็ตามที่มีการเปลี่ยนแปลงฟิลด์ที่ถูกตรวจสอบ

ตอนนี้คุณมีบันทึกการเปลี่ยนแปลงทุกอย่างและใครเป็นคนทำ


แล้ว ... ฟิลด์ mod_user ควรทำอะไร?
conny

1
บอกคุณว่าใครเป็นผู้เปลี่ยนแปลง การอัปเดตโค้ดควรมีบางอย่างเพื่อตั้งค่าฟิลด์นั้นให้กับผู้ใช้ปัจจุบัน
JosephStyons

แล้วการลบล่ะ? หากคุณลบแถวคุณจะจัดการกับค่าสำหรับคอลัมน์ mod_user ได้อย่างไร
Kenn Cal

@KennCal Triggers สามารถใช้ตารางเสมือนคุณสามารถดูข้อมูลหลังและก่อนหน้าภายในทริกเกอร์เดียวกัน ไม่สำคัญการดำเนินการ stackoverflow.com/questions/6282618/…
Renan Cavalieri

2
@KennCal คุณถูกต้องทริกเกอร์การลบจะต้องจัดเก็บข้อมูลนั้นไว้สำหรับคุณ แม้ว่าปีศาจจะอยู่ในรายละเอียด - หากคุณใช้การตรวจสอบสิทธิ์ SQL ทริกเกอร์สามารถเรียกใช้ [เลือก CURRENT_USER] หากเป็นแอปพลิเคชันไคลเอนต์รหัสไคลเอ็นต์จำเป็นต้องประกาศว่าเป็นใคร หากเป็นการเรียก API ผู้ใช้ที่กำลังลบจะต้องเป็นพารามิเตอร์ที่จำเป็นสำหรับการโทร
JosephStyons

1

ตามหลักการแยก:

  1. การตรวจสอบตารางข้อมูลจำเป็นต้องแยกจากฐานข้อมูลหลัก เนื่องจากฐานข้อมูลการตรวจสอบสามารถมีข้อมูลประวัติจำนวนมากได้ดังนั้นจึงควรแยกจากมุมมองการใช้หน่วยความจำ

  2. อย่าใช้ทริกเกอร์ในการตรวจสอบฐานข้อมูลทั้งหมดเพราะคุณจะต้องใช้ฐานข้อมูลที่แตกต่างกันเพื่อรองรับ คุณจะต้องเขียนหนึ่งสำหรับ DB2, SQLServer, Mysql และอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.