0Pricing
SQL Academy · درس

لماذا نحتفظ بالسجل التاريخي

التدقيق والتراجع وإجراء التحليلات استنادًا إلى الماضي

لماذا نحتفظ بالسجل التاريخي درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.

مشكلة الكتابة فوق البيانات

في كل مرة تنفذ فيها UPDATE أو DELETE، تختفي البيانات القديمة إلى الأبد. قد يبدو ذلك فعالاً، لكنه يسبب مشكلات حقيقية؛ إذ لا يمكنك الإجابة عن أسئلة مثل ما السعر يوم الثلاثاء الماضي؟ أو من غيّر هذا السجل ومتى؟

يعني الاحتفاظ بالسجل التاريخي تخزين كل إصدار من الصف، وليس أحدث إصدار فقط. يستكشف هذا الدرس أهمية ذلك وكيف تساعدك SQL على تنفيذه.

ثلاثة أسباب للاحتفاظ بالسجل التاريخي

هناك ثلاثة أسباب أساسية للحفاظ على البيانات التاريخية في قاعدة البيانات:

1. التدقيق — إثبات حدوث التغيير، ومعرفة من أجراه ومتى.
2. التراجع — التراجع عن خطأ من دون استعادة قاعدة البيانات بأكملها.
3. التحليلات — الإجابة عن أسئلة حول الماضي، واكتشاف الاتجاهات، ومقارنة الفترات.

تلبي استراتيجية السجل التاريخي المصممة جيداً الاحتياجات الثلاثة جميعها من دون مضاعفة مساحة التخزين أكثر من اللازم.

جدول تدقيق بسيط

أبسط نهج هو إنشاء جدول تدقيق منفصل يسجل كل تغيير. يلتقط كل صف القيمة القديمة، والقيمة الجديدة، ومن أجرى التغيير، ووقت حدوثه.

فيما يلي جدول تدقيق لجدول products. ويخزن العمود operation إحدى القيم INSERT أو UPDATE أو DELETE.

CREATE TABLE products_audit (
  audit_id   SERIAL PRIMARY KEY,
  product_id INT            NOT NULL,
  operation  VARCHAR(6)     NOT NULL,  -- INSERT / UPDATE / DELETE
  old_price  NUMERIC(10,2),
  new_price  NUMERIC(10,2),
  changed_by TEXT           NOT NULL,
  changed_at TIMESTAMPTZ    NOT NULL DEFAULT NOW()
);

ملء جدول التدقيق

يمكنك الكتابة إلى جدول التدقيق يدوياً، لكن النهج الأكثر موثوقية هو استخدام مشغّل قاعدة بيانات يعمل تلقائياً كلما تغيرت البيانات. وبذلك لا يستطيع أي جزء من شيفرة التطبيق تجاوز السجل.

نُدرج هنا صف تدقيق واحداً مباشرةً لتوضيح البنية قبل تناول المشغّلات.

INSERT INTO products_audit (product_id, operation, old_price, new_price, changed_by)
VALUES (42, 'UPDATE', 9.99, 12.49, 'alice');

SELECT * FROM products_audit ORDER BY changed_at DESC LIMIT 5;

قراءة سجل التدقيق

بعد تراكم الصفوف في جدول التدقيق، يمكنك الاستعلام عنها للإجابة عن أسئلة التدقيق. يعرض الاستعلام أدناه السجل الكامل لتغيّرات سعر منتج واحد، بدءاً من الأحدث.

SELECT
  changed_at,
  changed_by,
  operation,
  old_price,
  new_price
FROM products_audit
WHERE product_id = 42
ORDER BY changed_at DESC;

التواريخ الفعلية: السجل وفق وقت الصلاحية

يسجل جدول التدقيق وقت إجراء التغيير (وقت المعاملة). وأحياناً تحتاج أيضاً إلى تتبّع الوقت الذي كانت فيه حالة ما صحيحة في العالم الحقيقي، ويُسمى ذلك وقت الصلاحية.

يؤدي إضافة العمودين valid_from وvalid_to إلى الجدول الرئيسي إلى إنشاء سجل وفق وقت الصلاحية، ويُسمى أحياناً البُعد المتغير ببطء (SCD Type 2).

CREATE TABLE employee_history (
  id          SERIAL PRIMARY KEY,
  employee_id INT            NOT NULL,
  department  TEXT           NOT NULL,
  salary      NUMERIC(10,2)  NOT NULL,
  valid_from  DATE           NOT NULL,
  valid_to    DATE           -- NULL means current record
);

-- Current record for employee 7
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Engineering', 85000, '2023-01-01');

تحديث سجل متغير ببطء

عندما ينتقل موظف بين الأقسام، لا تُحدّث صفه باستخدام UPDATE. بدلاً من ذلك، تغلق الصف القديم بتعيين قيمة valid_to، ثم تُدرج صفاً جديداً مفتوح النهاية. وبذلك تحافظ على السجل التاريخي الكامل.

-- Step 1: close the current record
UPDATE employee_history
SET valid_to = '2024-06-01'
WHERE employee_id = 7 AND valid_to IS NULL;

-- Step 2: insert the new record
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Product', 90000, '2024-06-01');

-- Verify history
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
ORDER BY valid_from;

الاستعلام عن نقطة زمنية

باستخدام أعمدة وقت الصلاحية، يمكنك السؤال ما الحالة التي كانت صحيحة في تاريخ محدد؟، وهو استعلام يستحيل تنفيذه باستخدام نموذج UPDATE العادي.

تتحقق عبارة WHERE من وقوع التاريخ المستهدف ضمن فترة صلاحية الصف.

-- What department and salary did employee 7 have on 2023-09-15?
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
  AND valid_from <= '2023-09-15'
  AND (valid_to > '2023-09-15' OR valid_to IS NULL);

الجداول الزمنية ذات الإصدارات النظامية

تدعم قواعد بيانات SQL الحديثة (PostgreSQL 16+ وSQL Server وMySQL 8) الجداول الزمنية ذات الإصدارات النظامية. إذ تتتبّع قاعدة البيانات وقت المعاملة تلقائياً في أعمدة مخفية، ويمكنك الاستعلام عن الحالات السابقة باستخدام صياغة خاصة.

مثال على SQL Server — المفهوم نفسه في مختلف المحركات:

-- SQL Server / MariaDB style (illustrative)
CREATE TABLE orders (
  order_id    INT PRIMARY KEY,
  status      VARCHAR(20),
  total       NUMERIC(10,2),
  SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
  SysEndTime   DATETIME2 GENERATED ALWAYS AS ROW END,
  PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);

-- Query historical state
SELECT * FROM orders FOR SYSTEM_TIME AS OF '2024-01-15 12:00:00'
WHERE order_id = 100;

استخدام السجل للتراجع

جداول السجل ليست مخصصة للقراءة فقط، بل يمكنك استخدامها للتراجع عن الأخطاء. فإذا أتلفت مهمة معالجة دفعية 500 سجل من سجلات الأسعار، يمكنك استعادتها من جدول التدقيق من دون الحاجة إلى استخدام نسخة احتياطية.

-- Undo all price changes made by the bad batch job at a specific time
UPDATE products p
SET price = a.old_price
FROM products_audit a
WHERE p.id         = a.product_id
  AND a.operation  = 'UPDATE'
  AND a.changed_by = 'batch_job'
  AND a.changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';

-- Confirm affected rows
SELECT COUNT(*) AS rows_restored FROM products_audit
WHERE changed_by = 'batch_job'
  AND changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';

التحليلات عبر الزمن

تتيح بيانات السجل إجراء تحليلات زمنية متقدمة. يمكنك تتبع كيفية تطور مقياس ما، أو مقارنة أرقام كل شهر بالشهر السابق، أو اكتشاف الحالات الشاذة، وكل ذلك من دون استخدام مستودع بيانات منفصل.

يعرض هذا الاستعلام متوسط سعر منتج في كل شهر تقويمي باستخدام جدول التدقيق.

SELECT
  DATE_TRUNC('month', changed_at) AS month,
  ROUND(AVG(new_price), 2)         AS avg_price
FROM products_audit
WHERE product_id = 42
  AND operation IN ('INSERT', 'UPDATE')
GROUP BY 1
ORDER BY 1;

اختبار المعرفة

اختبر مدى فهمك لتخزين البيانات التاريخية في SQL.

مراجعة: لماذا نحتفظ بالسجل

تعلمت في هذا الدرس لماذا تُعد الكتابة فوق البيانات أمرًا محفوفًا بالمخاطر، وكيف تحافظ أنماط SQL على السجل لأغراض التدقيق والتراجع والتحليلات.

أهم النقاط:

  • جداول التدقيق تسجل كل عملية INSERT وUPDATE وDELETE، مع تسجيل من نفذها ومتى.
  • تستخدم الصفوف ذات زمن السريان (SCD Type 2) العمودين valid_from وvalid_to لتسجيل الجداول الزمنية في العالم الحقيقي.
  • تجيب الاستعلامات عند نقطة زمنية عن الأسئلة التاريخية من خلال التصفية باستخدام أعمدة التاريخ تلك.
  • تعمل الجداول الزمنية ذات الإصدار النظامي على أتمتة تتبع زمن المعاملة على مستوى قاعدة البيانات.
  • تتيح بيانات السجل التراجع الانتقائي والتحليلات الزمنية المتقدمة من دون الحاجة إلى نسخ احتياطية.

إن الحفاظ على الماضي ليس عبئًا إضافيًا، بل هو الأساس لبناء أنظمة موثوقة وقابلة للتدقيق.

الأسئلة الشائعة

هل درس «لماذا نحتفظ بالسجل التاريخي» مجاني؟

نعم — نص درس «لماذا نحتفظ بالسجل التاريخي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.

ماذا ستتعلم في «لماذا نحتفظ بالسجل التاريخي»؟

التدقيق والتراجع وإجراء التحليلات استنادًا إلى الماضي تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟

لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «لماذا نحتفظ بالسجل التاريخي»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟

نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا نحتفظ بالسجل التاريخي
  2. جداول الأحداث ذات الإلحاق فقط
  3. الصفوف الزمنية والمُدارة بالإصدارات
  4. إعادة بناء الحالة من الأحداث
← العودة إلى SQL Academy