แนวทางปฏิบัติที่ดีที่สุดสำหรับตารางประวัติ / เวลา


11

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

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

โดยที่ MyObjectHistory มีฟิลด์ที่ถูกติดตามสำหรับทุกคนยกเว้นการแก้ไขล่าสุด หรือควรเขตข้อมูลที่ถูกติดตามทั้งหมดอยู่ในตารางเดียวและการแก้ไขทั้งหมดรวมถึงเขตข้อมูลล่าสุดอยู่ในตารางนั้นเช่นเดียวกับใน:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

ฉันเห็นด้วยกับ
@Joel

คำตอบ:


7

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

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


2

ฉันต้องการรุ่นแรกเพราะคุณอาจไม่ต้องการดูประวัติ แต่คุณจะต้องดูค่าปัจจุบันบ่อยครั้ง ตารางประวัติควรมีการเติมข้อมูลจากทริกเกอร์ดังนั้นคุณไม่จำเป็นต้องกังวลเกี่ยวกับข้อมูลที่ได้รับจากการซิงค์โดยทั่วไป ดังนั้นสมมติว่าคุณมีบันทึกนับล้านใน MyObject แล้วคุณมี 10,000,000 บันทึกใน MyObjectHistory คุณต้องการเข้าร่วมตารางที่มีหลายระเบียนเพื่อรับค่าปัจจุบันหรือไม่

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

BTW ฉันจะเพิ่มเขตข้อมูลวันที่ลงในตารางประวัติเพื่อให้สามารถบอกสิ่งที่สั่งการเปลี่ยนแปลงที่เกิดขึ้น คุณไม่สามารถพึ่งพาข้อมูลประจำตัวสำหรับการสั่งซื้อทางโลก กรุณาถ้ามีคำถามเกี่ยวกับค่า previosu และเมื่อมีการเปลี่ยนแปลงคุณจะต้อง knwo ฉันอาจใส่ค่าสำหรับแอปพลิเคชันที่การเปลี่ยนแปลงมาจาก (หากคุณมีหลายแอปพลิเคชัน) และ / หรือบุคคลที่ทำการเปลี่ยนแปลง


0

มีเหตุผลสำคัญสองสามข้อสำหรับ # 1 ประเด็นแรกคือปัญหาขนาด HLGEM ชี้ให้เห็น แต่ก็มีประเด็นสำคัญอื่น ๆ เช่นกัน

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

แน่นอนว่าอาจมีบางกรณีที่คุณต้องการรวมเข้าด้วยกันอย่างสมบูรณ์ (เช่นที่เราทำกับอัตราภาษีใน LedgerSMB) เนื่องจากอาจใช้ข้อมูลประวัติสำหรับการคำนวณในปัจจุบันและจำนวนระเบียนมีแนวโน้มที่จะค่อนข้างเล็ก

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


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