পাঠ্যক্রম খুলুন
মধ্যবর্তী পর্যায়

Normalization ও Denormalization: ডেটা সাজানোর trade-off

Normalization and Denormalization

এই পাঠের কুইজ ↓৫ মিনিট পড়াPHP 8.3+ · Laravel 12
এই পাঠের সূচিপত্র

এই পাঠে যা শিখবেন

  • Update anomaly ও normalized source
  • Intentional denormalization ও snapshots
  • Read model synchronization cost

সমস্যা দিয়ে শুরু

Customer address প্রতিটি order row-এ কপি করলে address বদলাতে অনেক row update করতে হচ্ছে। কিন্তু delivery history-তে পুরোনো address থাকা আবার সঠিক। সব duplication খারাপ নয়; একই বর্তমান fact-এর copy এবং সময়ের নির্দিষ্ট historical snapshot আলাদা। Normalization শেখার সময় এই meaning distinction জরুরি।

সহজ করে বুঝি

Normalization functional dependencies অনুযায়ী facts আলাদা রাখে, যাতে update/insert/delete anomaly কমে। Customer profile-এর নাম customer entity-তে একবার রাখা যায়। Order-এর shipping address সেই order placement-এর snapshot হতে পারে। Denormalization read efficiency-এর জন্য derived বা repeated data সচেতনভাবে রাখা। Join cost কমলেও synchronization, backfill ও inconsistency risk যোগ হয়। Normal form শুধু “table ছোট করো” rule নয়; dependency ও fact ownership বোঝার পদ্ধতি।

পরিচিত একটি উপমা

স্কুলের বর্তমান ছাত্র register এক জায়গায় থাকে। কিন্তু গত বছরের certificate-এ তখনকার নাম বা class record সংরক্ষণ করা হয়। প্রতিটি বর্তমান তালিকায় আলাদা copy বদলানো error-prone, অথচ certificate snapshot মুছে current class বসালে ইতিহাস ভুল হয়।

নকশাটি দেখুন

Diagram লোড হচ্ছে…

Current profile ও product data order placement-এর সময় read হয়।
Diagram-এর text flow দেখুন
flowchart TD
 C[(Customer profile current truth)] --> O[Order placement action]
 O --> S[(Shipping address snapshot)]
 P[(Product current price)] --> O
 O --> I[(Purchased item price snapshot)]
 I --> R[Invoice read model]

Current profile ও product data order placement-এর সময় read হয়। Order-specific snapshots সেই transaction-এর fact রাখে। Invoice read model সেই facts থেকে বানানো যায়। Profile update থেকে পুরোনো shipping snapshot automatic update হওয়া উচিত নয়। অন্যদিকে cached current customer display name derived হলে invalidation policy দরকার।

PHP ও Laravel-এ প্রয়োগ

Action-method fragment। Authenticated authorized customer, validated address এবং product pricing action আগে থেকে আছে। Order model-এ shipping_address array/JSON cast configured; fillable fields সচেতনভাবে বেছে নিন। এটি address snapshot creation, complete stock/payment transaction নয়।

php
use App\Models\Order;

$order = Order::create([
    'user_id' => $customer->id,
    'status' => 'pending',
    'shipping_address' => [
        'recipient' => $validatedAddress['recipient'],
        'line' => $validatedAddress['line'],
        'city' => $validatedAddress['city'],
        'postal_code' => $validatedAddress['postal_code'],
    ],
]);

সুবিধা, সীমাবদ্ধতা ও trade-off

Normalized source consistent update সহজ করে। Denormalized read model join/aggregate cost কমাতে পারে, বিশেষত reporting বা feed-এ। তবে source change থেকে projection update synchronous নাকি async হবে তা ঠিক করতে হয়। Async হলে lag ও rebuild process লাগবে। Historical snapshot stale data নয়, intentional record; এটিকে সাধারণ cache-এর মতো refresh করলে business meaning ভাঙতে পারে।

সাধারণ ভুল

  • Duplicate field দেখলেই history না বুঝে remove করা।
  • Performance না মেপে সব data এক giant table-এ রাখা।
  • Projection-এর source, version ও rebuild path না রাখা।

আরও একটু গভীরে

Derived order_count customer row-এ রাখলে concurrent updates, refunds ও historical corrections-এর semantics লিখুন। Counter increment atomic হতে পারে, কিন্তু source event duplicate হলে count তবু ভুল। Reconciliation query বা rebuild job drift ধরতে পারে। Denormalized field consumer-কে current truth নাকি eventually updated estimate বলে expose করছেন তা API contract-এ লিখুন। Database constraints normalized boundary-তে শক্ত থাকে; cross-projection invariant সাধারণত আরও coordination চায়।

মনে রাখুন

Duplication-এর meaning যাচাই করুন। Current fact এক owner-এ রাখুন, historical snapshot ইচ্ছাকৃতভাবে স্থির রাখুন। Read optimization-এর সঙ্গে synchronization ও rebuild দায়িত্ব আসে।

নিজে চেষ্টা করুন

Customer নাম, shipping address, product নাম, purchase price এবং monthly sales total-এর জন্য current fact/snapshot/derived projection label দিন। প্রতিটির owner, update trigger ও correction policy লিখুন। কোনো label যেন শুধু field name দেখে না হয়।

নিজের বোঝা যাচাই করুন

1. Normalization কেন?

এক fact-এর বহু current copy update anomaly সৃষ্টি করে। Dependency অনুযায়ী আলাদা entity সেই অসংগতি কমাতে সাহায্য করে।

2. সব duplicate কি ভুল?

না। Historical snapshot ও read projection intentional duplication। Lifecycle ও source পরিষ্কার থাকলে এটি যুক্তিসংগত design।

3. Shipping address profile থেকে join করব?

বর্তমান profile নয়, order-এর delivery agreement history লাগতে পারে। Requirement অনুযায়ী snapshot রাখা উপযুক্ত।

4. Denormalization free speed?

Read কম work করতে পারে, কিন্তু write amplification, lag, repair ও storage cost যোগ হয়। Measurement দিয়ে trade-off বিচার করুন।

5. Projection ভুল হলে?

Authoritative source থেকে replay/rebuild বা reconciliation দরকার। Source identity ও update version সংরক্ষণ recovery সহজ করে।

আরও পড়ুন

এই পাঠের কুইজ

এই পাঠ থেকে ২টি প্রশ্ন। উত্তর দিয়ে ব্যাখ্যা দেখুন; অধ্যায়ের কুইজ আলাদাভাবে দিতে হবে।

এই পাঠের ২টি প্রশ্নের উত্তর দিন। পাস করতে দুটিই সঠিক হতে হবে।

জমা দেওয়ার পর সঠিক উত্তর ও ব্যাখ্যা দেখবেন। ফলাফল এই ব্রাউজারে সংরক্ষিত থাকবে। অনুশীলনের ফল অধ্যায় সম্পন্নের হিসাবে যোগ হয় না।

সব বিষয় মিলিয়ে অনুশীলন করুন →

অগ্রগতি এই ব্রাউজারে সংরক্ষিত থাকে। শুধু পাঠ খুললে সম্পন্ন হয় না।