← يتطلب: SQL على IRIS البرمجة متوسط ⏱ 6 ساعات الدورة 10

تصميم نماذج البيانات المتقدمة

Advanced Data Modeling

🎯 أهداف التعلم

1تصميم العلاقات المتقدمة
2استخدام Relationships
3إدارة الفهارس
4تطبيق أنماط CQRS

01 العلاقات المتقدمة

تصميم العلاقات بين الكائنات بشكل صحيح.

Class MyApp.Department Extends %Persistent {
  Property Name As %String;
  Relationship Employees As MyApp.Employee [ Cardinality = children, Inverse = Department ];
}
Class MyApp.Employee Extends %Persistent {
  Property Name As %String;
  Relationship Department As MyApp.Department [ Cardinality = one, Inverse = Employees ];
  Index DeptIdx On Department;
}

02 الفهارس المتقدمة

الفهارس ضرورية لتحسين الأداء.

Class MyApp.Product Extends %Persistent {
  Property Name As %String;
  Property Category As %String;
  Index CatPriceIdx On (Category, Price);
  Index NameTrgm On Name [ Type = bitmap ];
}

03 أنماط Event Sourcing

نمط Event Sourcing يحفظ كل تغيير كحدث بدلاً من الحالة النهائية.

// تعريف حدث
Class MyApp.Events.OrderEvent Extends %Persistent {
  Property OrderId As %Integer;
  Property EventType As %String; // Created, Updated, Cancelled
  Property EventData As %DynamicObject;
  Property Timestamp As %TimeStamp;
  Index OrderIdx On OrderId;
}

// تسجيل حدث
ClassMethod RegisterEvent(orderId, type, data) {
  Set event = ##class(MyApp.Events.OrderEvent).%New()
  Set event.OrderId = orderId
  Set event.EventType = type
  Set event.EventData = data
  Set event.Timestamp = $ZDT($H,3)
  Do event.%Save()
  
  // تحديث Read Model
  Do ..UpdateProjection(orderId)
}

// إعادة بناء الحالة من الأحداث
ClassMethod RebuildState(orderId) {
  Set state = {}
  &sql(SELECT * FROM MyApp.Events.OrderEvent WHERE OrderId = :orderId ORDER BY Timestamp)
  // تطبيق الأحداث بالترتيب
}

04 نمط CQRS مع IRIS

CQRS (Command Query Responsibility Segregation) يفصل بين عمليات القراءة والكتابة لتحسين الأداء.

// Command Side - Write Model
Class MyApp.Commands.CreateOrder Extends %Persistent {
  Property CustomerId As %Integer;
  Property Items As list Of OrderItem;
  Property TotalAmount As %Numeric;
  
  Method Execute() As %Status {
    Set sc = ..Validate()
    If $$$ISERR(sc) Return sc
    
    Set order = ##class(MyApp.Order).%New()
    Set order.CustomerId = ..CustomerId
    // copy items...
    Set sc = order.%Save()
    
    // إنشاء حدث
    Set event = ##class(MyApp.Events.OrderCreated).%New()
    Set event.OrderId = order.%Id()
    Set event.Timestamp = $ZDT($H, 3)
    Do event.Save()
    
    // تحديث Read Model
    Do ..UpdateReadModel(order)
    Return $$$OK
  }
}

// Query Side - Read Model (محسّن للاستعلامات)
Class MyApp.ReadModels.OrderSummary Extends %Persistent {
  Property OrderId As %Integer;
  Property CustomerName As %String;
  Property ItemCount As %Integer;
  Property TotalAmount As %Numeric;
  Property Status As %String;
  Index CustomerIdx On CustomerName;
  Index StatusIdx On Status;
}

05 Event Sourcing

نمط Event Sourcing يحفظ كل تغيير كحدث بدلاً من الحالة النهائية، مما يتيح إعادة بناء الحالة في أي وقت.

// تعريف حدث
Class MyApp.Events.BaseEvent Extends %Persistent {
  Property AggregateId As %Integer;
  Property EventType As %String;
  Property EventData As %DynamicObject;
  Property Timestamp As %TimeStamp;
  Property UserId As %String;
  Index AggregateIdx On AggregateId;
}

// تسجيل حدث
ClassMethod RegisterEvent(aggregateId, type, data) {
  Set event = ##class(MyApp.Events.BaseEvent).%New()
  Set event.AggregateId = aggregateId
  Set event.EventType = type
  Set event.EventData = data
  Set event.Timestamp = $ZDT($H, 3)
  Do event.%Save()
  
  // تحديث الإسقاط (Projection)
  Do ..UpdateProjection(aggregateId)
}

// إعادة بناء الحالة من الأحداث
ClassMethod RebuildState(aggregateId) As %DynamicObject {
  Set state = {}
  &sql(SELECT EventType, EventData INTO :type, :data 
       FROM MyApp.Events.BaseEvent 
       WHERE AggregateId = :aggregateId 
       ORDER BY Timestamp)
  While SQLCODE = 0 {
    // تطبيق الحدث على الحالة
    Set state = ..ApplyEvent(state, type, data)
    &sql(FETCH MyApp.Events.BaseEvent INTO :type, :data)
  }
  Return state
}

📝 اختبار التحقق

1. ما هو الفرق بين Relationship و list؟

Relationship توفر سلامة البيانات المرجعية

ما هو نمط Event Sourcing؟

Event Sourcing يحفظ كل تغيير كحدث، مما يتيح إعادة بناء الحالة في أي وقت

ما هو الفرق بين Serial و Persistent objects؟
💡 الشرح

Serial objects مدمجة في كائنات أخرى ولا وجود مستقل لها

💡 النقاط الرئيسية

  • نمط Value Object يحسن تصميم الكائنات المضمّنة
  • الفئات الوسيطة تضيف خصائص على العلاقات Many-to-Many
  • الفهارس المركبة تحسن أداء الاستعلامات المعقدة
  • نمط DTO يفصل بين طبقة البيانات وطبقة العرض
  • استراتيجيات معالجة البيانات الكبيرة ضرورية للإنتاج