Table Per Subclass (TPS) একটি Inheritance Mapping Strategy যেখানে এক্সটেনডেড ক্লাসের জন্য আলাদা আলাদা টেবিল তৈরি করা হয়, কিন্তু সব টেবিলের মধ্যে সম্পর্ক স্থাপিত থাকে। এই কৌশলে, মূল ক্লাসের জন্য একটি টেবিল তৈরি হয় এবং সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়, যেখানে মূল ক্লাসের ফিল্ডগুলি সাবক্লাসে ইনহেরিট করা হয় এবং প্রত্যেক সাবক্লাসের জন্য নিজের ফিল্ড থাকে।
NHibernate এ Table Per Subclass Mapping এর মাধ্যমে আপনি সহজেই ইনহেরিটেন্স স্ট্রাকচার তৈরি করতে পারেন যেখানে সব সাবক্লাসের ডেটা তাদের নিজস্ব টেবিলে সেভ করা হয়, তবে সাধারণ তথ্য মূল টেবিলে থাকে।
Table Per Subclass Mapping এর উদাহরণ
ধরা যাক, আমাদের একটি Employee ক্লাস এবং এর দুটি সাবক্লাস Manager এবং Developer আছে। আমরা চাই যে, Employee এর জন্য একটি টেবিল এবং Manager ও Developer এর জন্য আলাদা টেবিল তৈরি করা হোক।
1. Entity Classes তৈরি করা
প্রথমে আমরা Employee, Manager, এবং Developer ক্লাস তৈরি করি।
public class Employee
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Position { get; set; }
}
public class Manager : Employee
{
public virtual int TeamSize { get; set; }
}
public class Developer : Employee
{
public virtual string ProgrammingLanguage { get; set; }
}
এখানে:
Employeeহল বেস ক্লাস, এবংManagerওDeveloperসাবক্লাস।Managerএর জন্য একটি অতিরিক্ত প্রপার্টিTeamSizeএবংDeveloperএর জন্যProgrammingLanguageপ্রপার্টি রয়েছে।
2. Mapping File তৈরি করা (XML Mapping)
এখন আমরা Mapping File তৈরি করব। এখানে আমরা Employee ক্লাসের জন্য একটি টেবিল এবং Manager ও Developer এর জন্য আলাদা আলাদা টেবিল তৈরি করব। Mapping ফাইলের মাধ্যমে NHibernate জানবে যে কোন ক্লাসের জন্য কোন টেবিল তৈরি হবে।
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<!-- Employee class to table mapping -->
<class name="Employee" table="Employees">
<id name="Id" column="EmployeeID">
<generator class="identity"/>
</id>
<property name="Name" column="Name"/>
<property name="Position" column="Position"/>
</class>
<!-- Manager class to its own table mapping -->
<subclass name="Manager" table="Managers">
<key column="EmployeeID"/>
<property name="TeamSize" column="TeamSize"/>
</subclass>
<!-- Developer class to its own table mapping -->
<subclass name="Developer" table="Developers">
<key column="EmployeeID"/>
<property name="ProgrammingLanguage" column="ProgrammingLanguage"/>
</subclass>
</hibernate-mapping>
এখানে:
Employeeক্লাসটিEmployeesটেবিলের সাথে ম্যাপ করা হয়েছে।ManagerএবংDeveloperক্লাস দুটি আলাদা টেবিলManagersএবংDevelopersএর সাথে ম্যাপ করা হয়েছে।<subclass>ট্যাগের মাধ্যমে আমরা সাবক্লাসগুলির জন্য আলাদা টেবিল নির্দেশ করেছি এবং তাদের প্রোপার্টিগুলি ম্যাপ করেছি।
3. Fluent Mapping ব্যবহার করা
Fluent Mapping এর মাধ্যমে একই কাজ করা সম্ভব। নিচে FluentNHibernate ব্যবহার করে এই মডেলটি ম্যাপ করা হয়েছে:
using FluentNHibernate.Mapping;
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Table("Employees");
Id(x => x.Id).Column("EmployeeID").GeneratedBy.Identity();
Map(x => x.Name).Column("Name");
Map(x => x.Position).Column("Position");
}
}
public class ManagerMap : SubclassMap<Manager>
{
public ManagerMap()
{
Table("Managers");
KeyColumn("EmployeeID");
Map(x => x.TeamSize).Column("TeamSize");
}
}
public class DeveloperMap : SubclassMap<Developer>
{
public DeveloperMap()
{
Table("Developers");
KeyColumn("EmployeeID");
Map(x => x.ProgrammingLanguage).Column("ProgrammingLanguage");
}
}
এখানে:
- EmployeeMap ক্লাসটি
Employeeটেবিলের সাথে সম্পর্কিত। - ManagerMap এবং DeveloperMap সাবক্লাসের জন্য আলাদা টেবিল নির্দেশ করেছে।
KeyColumn("EmployeeID")নির্দেশ করে যে, সাবক্লাসগুলির জন্যEmployeeIDমূল টেবিলের প্রাইমারি কী হবে।
4. Table Per Subclass এর সুবিধা ও অসুবিধা
সুবিধা:
- Data Integrity: সব সাবক্লাসের জন্য নিজস্ব টেবিল থাকা সত্ত্বেও তারা মূল ক্লাসের সাথে সম্পর্কিত থাকে, তাই ডেটাবেসে ডেটা সমন্বিত থাকে।
- Performance: যেহেতু সাবক্লাসের জন্য আলাদা টেবিল রয়েছে, এতে শুধুমাত্র প্রয়োজনীয় ডেটা পড়া বা আপডেট করা হয়, যেটি পারফরম্যান্সের জন্য উপকারী।
- Easy to Extend: নতুন সাবক্লাস যোগ করা সহজ, কারণ শুধুমাত্র নতুন টেবিল এবং ম্যাপিং ফাইল যোগ করতে হয়।
অসুবিধা:
- Complex Queries: যখন একাধিক সাবক্লাসের ডেটা একসাথে প্রয়োজন হয়, তখন টেবিলগুলির মধ্যে জয়েন (join) করতে হতে পারে, যা কিছুটা জটিল হতে পারে।
- Redundant Columns: সাবক্লাসের মধ্যে একাধিক টেবিলের কলাম পুণরাবৃত্তি হতে পারে (যেমন,
EmployeeID), যার কারণে কিছুটা অতিরিক্ত স্টোরেজ ব্যবহার হতে পারে।
Table Per Subclass মেপিং NHibernate এর জন্য একটি শক্তিশালী কৌশল, যেটি ইনহেরিটেন্স ভিত্তিক ডেটাবেস ডিজাইনকে বাস্তবায়ন করতে সহায়তা করে।
Read more