ইউজার স্টোরি থেকে ডেটাবেস স্কিমা: AI-নির্দেশিত পদ্ধতি
ইউজার স্টোরি, সত্তা, এবং ওয়ার্কফ্লোকে কিভাবে পরিষ্কার ডেটাবেস স্কিমায় রূপান্তর করবেন এবং কীভাবে AI যুক্তিবাদ আপনাকে গ্যাপ ও নিয়ম পরীক্ষা করতে সাহায্য করতে পারে তা শিখুন।

আপনি যা তৈরি করছেন: বাস্তব কাজের সাথে মিলবে এমন একটি স্কিমা
একটি ডেটাবেস স্কিমা হলো আপনার অ্যাপ কীভাবে বিষয়গুলি মনে রাখবে তার পরিকল্পনা। ব্যবহারিকভাবে, এটি হল:
- টেবিলগুলো: তথ্যের “বাকেট” (Customers, Orders, Tickets)
- ফিল্ড (কলাম): প্রতিটি বস্তুর জন্য আপনি যে বিস্তারিত রাখবেন (customer_name, order_date)
- সম্পর্ক: কিভাবে বাকেটগুলো সংযুক্ত (একটি Order একটি Customer-র সাথে সম্পর্কিত; একটি Customer-এর অনেক Order থাকতে পারে)
যখন স্কিমা বাস্তব কাজের সাথে মিলে যায়, তখন তা মানুষের করা কাজগুলো—create, review, approve, schedule, assign, cancel—প্রতিফলিত করে, সাদা বোর্ডে সুন্দর শোনা কথার বদলে।
কেন ইউজার স্টোরি থেকেই শুরু করবেন?
ইউজার স্টোরি ও অ্যাকসেপ্টেন্স ক্রাইটেরিয়া বাস্তব প্রয়োজনগুলো সহজ ভাষায় বলে: কে কি করে, এবং “সম্পূর্ণ” মানে কি। যদি আপনি এগুলোকে উৎস হিসেবে ব্যবহার করেন, তাহলে স্কিমা গুরুত্বপূর্ণ বিবরণ মিস করার সম্ভাবনা কম (যেমন “আমাদের কে রিফান্ড অনুমোদন করেছে তা ট্র্যাক করতে হবে” বা “একটি বুকিং একাধিকবার reschedule করা যেতে পারে”)।
স্টোরি থেকে শুরু করলে স্কোপ সম্পর্কে সৎ থাকা সহজ হয়। যদি এটা স্টোরিতে (অথবা ওয়ার্কফ্লোতে) না থাকে, তবে এটিকে ঐচ্ছিক হিসেবে বিবেচনা করুন, না যে চুপচাপ জটিল মডেল তৈরি করবেন “কখনও লাগতে পারে” বলে।
AI এখানে কী করতে পারে, আর কী পারে না
AI আপনাকে দ্রুত করতে সাহায্য করতে পারে:
- প্রার্থী সত্তাগুলো বের করা (স্টোরির গুরুত্বপূর্ণ "বস্তু")
- অ্যাকসেপ্টেন্স ক্রাইটেরিয়া থেকে নির্দেশিত ফিল্ডগুলো পরামর্শ দেওয়া (টাইমস্ট্যাম্প, স্ট্যাটাস, রেফারেন্স)
- সম্ভাব্য সম্পর্ক ও গ্যাপ চিহ্নিত করা ("আপনি approvals বলেছেন কিন্তু approver সংরক্ষণ করেননি")
AI নির্ভরযোগ্যভাবে করতে পারে না:
- আপনার অজানা ব্যবসায়িক নিয়ম বা না-লিখিত এজ কেসগুলো জানানো
- বিনিময়শীলতাগুলি (সাদাসিধে বনাম নমনীয়) ছাড়া “সঠিক” বিশদ-স্তর নির্ধারণ করা
- রিপোর্টিং, সিকিউরিটি, বা কমপ্লায়েন্সের চাহিদা পূরণ নিশ্চিত করা
AI-কে একটি শক্তিশালী সহকারী হিসেবে দেখুন, সিদ্ধান্ত-নির্ধারক হিসেবে নয়।
যদি আপনি সেই সহকারীকে গতিশীল করতে চান, একটি ভাইব-কোডিং প্ল্যাটফর্ম যেমন Koder.ai আপনাকে স্কিমা সিদ্ধান্ত থেকে কাজ করা React + Go + PostgreSQL অ্যাপে দ্রুত পৌঁছাতে সাহায্য করতে পারে—এবং আপনি মডেল, কনস্ট্রেইন্ট, ও মাইগ্রেশন কন্ট্রোলেই রাখতে পারবেন।
প্রত্যাশা নির্ধারণ: ইটারেটিভ, এক-শট নয়
স্কিমা ডিজাইন একটি লুপ: ড্রাফট → স্টোরির বিরুদ্ধে টেস্ট → মিসিং ডেটা খোঁজা → পরিমার্জন। লক্ষ্যটি প্রথমবারে নিখুঁত আউটপুট নয়; বরং এমন একটি মডেল যেটি আপনি প্রতিটি ইউজার স্টোরির সঙ্গে ট্রেস করতে পারবেন এবং আত্মবিশ্বাসের সঙ্গে বলতে পারবেন: “হ্যাঁ, আমরা এই ওয়ার্কফ্লোতে যা কিছু দরকার তা স্টোর করতে পারি—এবং প্রতিটি টেবিল কেন আছে সেটা ব্যাখ্যা করতে পারি।”
ইনপুট: ইউজার স্টোরি, অ্যাকসেপ্টেন্স ক্রাইটেরিয়া, এবং বাস্তব উদাহরণ
রিকোয়ারমেন্টগুলো টেবিলে রূপান্তর করার আগে, আপনি কী মডেল করছেন সেটা স্পষ্ট করুন। একটি ভালো স্কিমা খুব কমই শূন্য পেজ থেকে শুরু করে—এটি মানুষ যে কংক্রিট কাজগুলো করে এবং পরে যে প্রমাণ লাগবে (স্ক্রীন, আউটপুট, এজ কেস) থেকে শুরু হয়।
একটি জায়ে থাকা ইনপুট তালিকা
ইউজার স্টোরি শিরোনাম হলেও, একজোট করুন:
- ইউজার স্টোরি + রোলস (কে কি করে এবং কেন)
- অ্যাকসেপ্টেন্স ক্রাইটেরিয়া (যে নিয়মগুলো অবশ্যই সত্য)
- ফর্ম/স্ক্রিন (ইউজার কোন ফিল্ড টাইপ করে, পছন্দ করে, বা দেখে)
- রিপোর্ট/এক্সপোর্ট (কি সারাংশ দরকার, গ্রুপ/ফিল্টার করে দেখাতে হবে)
- বাস্তব উদাহরণ (নমুনা অর্ডার, ইনভয়েস, টিকিট, ক্যালেন্ডার—যেকোনো প্রতিনিধিত্বমূলক)
যদি আপনি AI ব্যবহার করেন, এই ইনপুটগুলো মডেলকে ভিত্তি দেয়। AI দ্রুত সত্তা ও ফিল্ড প্রস্তাব করতে পারে, কিন্তু বাস্তব আর্টিফ্যাক্ট ছাড়া এটি এমন স্ট্রাকচার উদ্ভাবন করতে পারে যা আপনার প্রোডাক্টের সাথে মেলে না।
অ্যাকসেপ্টেন্স ক্রাইটেরিয়া: লুকানো কনস্ট্রেইন্টের উৎস
অ্যাকসেপ্টেন্স ক্রাইটেরিয়াগুলোই প্রায়শই সবচেয়ে গুরুত্বপূর্ণ ডেটাবেস নিয়ম রাখে, যদিও সেগুলো সরাসরি ডেটা উল্লেখ না করে। এরকম বিবৃতি খুঁজুন:
- “Email must be unique” (ইউনিকনেস)
- “Status can be Draft, Submitted, Approved” (অনুমোদিত মান)
- “Only managers can approve” (পারমিশন, সম্ভবত অডিট ফিল্ড লাগবে)
- “Can’t delete an invoice with payments” (রেফারেনশিয়াল নিয়ম)
সাধারণ পিটফলগুলো আগে ঠিক করুন
অস্পষ্ট স্টোরি ("As a user, I can manage projects") অনেক সত্তা ও ওয়ার্কফ্লো লুকিয়ে রাখতে পারে। অন্য একটি সাধারণ গ্যাপ হলো ক্যান্সেলেশন, রিট্রাই, পার্শিয়াল রিফান্ড, বা রিএসাইনমেন্টের মতো এজ কেসগুলো অনুপস্থিত থাকা।
দ্রুত স্টোরি-কোয়ালিটি চেকলিস্ট (মডেলিংয়ের আগে)
- অ্যাক্টর/রোল স্পষ্ট আছে।
- অবজেক্ট নির্দিষ্ট ("data" বা "things" নয়)।
- কমপক্ষে একটি বাস্তব উদাহরণ আছে।
- অ্যাকসেপ্টেন্স ক্রাইটেরিয়া ভ্যালিডেশন ও সীমা অন্তর্ভুক্ত করে।
- ত্রুটি ও “কি হবে যদি” কেসগুলো উল্লিখিত (অথবা স্পষ্টভাবে পরে করার জন্য স্থগিত)।
ধাপ 1 — স্টোরি থেকে সত্তা বের করা (নাউনগুলো)
টেবিল বা ডায়াগ্রাম ভাবার আগে, ইউজার স্টোরিগুলো পড়ে নাউনগুলো হাইলাইট করুন। রিকোয়ারমেন্ট লেখায় নাউনগুলো প্রায়শই সেই “বস্তু” নির্দেশ করে যেগুলো সিস্টেমকে মনে রাখতে হবে—এগুলো সাধারণত আপনার স্কিমায় সত্তা হয়।
একটি দ্রুত মানসিক মডেল: নাউনগুলো সত্তায় পরিণত হয়, আর ভার্বগুলো অ্যাকশন বা ওয়ার্কফ্লো নির্দেশ করে। যদি স্টোরিটা বলে “A manager assigns a technician to a job,” সম্ভাব্য সত্তাগুলো হল manager, technician, এবং job—আর "assigns" একটি সম্পর্ক মডেল করার ইঙ্গিত দেয়।
কিভাবে বোঝবেন কোন নাউন আসল সত্তা
প্রতিটি নাউন আলাদা টেবিলের যোগ্য নয়। একটি নাউন শক্ত প্রার্থী যখন:
- নিজের একটি পরিচয় আছে: নির্দিষ্ট উদাহরণকে ইন্ডিকেট করা যায় (Job #1042, Customer A)
- সময় ধরে পরিবর্তিত হয়: এর একটি লাইফসাইকেল আছে (একটি job scheduled → completed)
- একাধিক জায়গায় ব্যবহার হয়: একাধিক স্টোরি এতে রেফার করে, বা বহু ওয়ার্কফ্লো এতে ছোঁয়
যদি একটি নাউন কেবল একবার আসে, বা অন্য কিছুকে বর্ণনা করে ("red button", "Friday"), তাহলে সম্ভবত এটি সত্তা নয়।
অ্যাট্রিবিউট বনাম আলাদা সত্তা ("Address" এবং "Tag" টেস্ট)
সব বিস্তারিত আলাদা টেবিলে পরিণত করার ভুল করবেন না। এই নীতিটি অনুসরণ করুন:
- যদি এটি একটি মান যা একটি জিনিসকে বর্ণনা করে, সাধারণত এটি অ্যাট্রিবিউট (যেমন
Customer.phone_number)। - যদি এটি পুনরাবৃত্তি যোগ্য, শেয়ার করা, বা কাঠামোবদ্ধ, তবে এটি সাধারণত আলাদা সত্তা।
দুটি ক্লাসিক উদাহরণ:
- Address: যদি আপনি শিপিং ও বিলিং ঠিকানা রাখেন, ইতিহাস রাখেন, বা ঠিকানাগুলো পুনরায় ব্যবহার করেন, তাহলে Address আলাদা সত্তা হওয়ার সম্ভবনা বেশি। যদি কেবল একটি মেইলিং ঠিকানাই দরকার এবং পুনরায় ব্যবহার না হয়, তাহলে এটিকে অ্যাট্রিবিউট হিসেবে রাখুন।
- Tag: ট্যাগ প্রায়শই আলাদা সত্তা হয় কারণ এগুলো পুনরাবৃত্তি যোগ্য এবং many-to-many (একটি Job-এ অনেক Tag থাকতে পারে; একটি Tag বহু Job-এ প্রযোজ্য)।
AI ব্যবহার করে প্রার্থী সত্তা সাজেস্ট করা (সাবধানে)
AI স্টোরি স্ক্যান করে দ্রুত প্রার্থী নাউনের তালিকা গ্রুপ করে দিতে পারে (লোক, ওয়ার্ক আইটেম, ডকুমেন্ট, লোকেশন ইত্যাদি)। একটি ভালো প্রম্পট হতে পারে: “Extract nouns that represent data we must store, and group duplicates/synonyms.”
আউটপুটকে শুরু হিসেবে নিন, উত্তর হিসেবে নয়। ফলো-আপ জিজ্ঞাসা করুন যেমন:
- “এগুলোর মধ্যে কোনগুলো লাইফসাইকেল বা নিজস্ব ID প্রয়োজন?”
- “কোনগুলো আসলে স্ট্যাটাস, ক্যাটাগরি, বা অ্যাট্রিবিউট?”
- “কোনগুলো সমার্থক (উদাহরণ: ‘client’ বনাম ‘customer’)?”
ধাপ 1-এর লক্ষ্য একটি সংক্ষিপ্ত, পরিষ্কার সত্তার তালিকা যা আপনি বাস্তব স্টোরি দিয়ে রক্ষা করতে পারবেন।
ধাপ 2 — ডিটেইলগুলোকে ফিল্ডে পরিণত করা (আপনি যা মিস করবেন তা)
একবার আপনি সত্তাগুলো নামকরণ করলে (যেমন Order, Customer, Ticket), পরবর্তী কাজ হল পরে যা প্রয়োজন তা ক্যাপচার করা। ডেটাবেসে সেই ডিটেইলগুলো ফিল্ড (বা অ্যাট্রিবিউট)—আপনার সিস্টেম যে রিমাইন্ডারগুলো ভুলে যেতে পারবেনা সেগুলো।
কিভাবে ফিল্ড বাছবেন (অনুমান ছাড়া)
ইউজার স্টোরি দিয়ে শুরু করে, তারপর অ্যাকসেপ্টেন্স ক্রাইটেরিয়াকে একটি চেকলিস্ট হিসেবে পড়ুন কোনগুলো অবশ্যই স্টোর করা দরকার।
যদি একটি রিকোয়ারমেন্ট বলে “Users can filter orders by delivery date,” তাহলে delivery_date অপশনাল নয়—এটি একটি ফিল্ড হিসেবে থাকতে হবে (অথবা অন্য সংরক্ষিত ডেটা থেকে নির্ভরযোগ্যভাবে ডেরাইভ করা যাবে)। যদি লেখা থাকে “Show who approved the request and when,” আপনাকে সম্ভবত approved_by এবং approved_at রাখতে হবে।
একটি বাস্তব পরীক্ষাঃ একজন কেউ এইটা ডিসপ্লে, সার্চ, সোর্ট, অডিট, বা হিসাব করার জন্য প্রয়োজন হবে? যদি হ্যাঁ, তাহলে হয়ত এটা একটি ফিল্ড।
পরিষ্কার ফিল্ডের জন্য সহজ নিয়ম
- মানগুলো অ্যাটমিক রাখুন: “First name” এবং “Last name” আলাদা রাখুন যদি আপনি নাম ধরে সার্চ বা সোর্ট করবেন। একাধিক মান এক ফিল্ডে ভরাবেন না (উদাহরণ: “red, blue”)।
- ধরন একরকম রাখুন: তারিখগুলো=date, অর্থ=mdecimal, বুলিয়ান=true/false—মিশ্র ফরম্যাট যেমন “$10”, "10 USD" এড়িয়ে চলুন।
- টেক্সট কপি করা এড়ান: গ্রাহকের ঠিকানাটি প্রতিটি অর্ডার লাইনে কপি করবেন না। একবার
Customers-এ রাখুন এবং অন্য জায়গায় রেফার করুন।
কন্ট্রোলড ভোকাবুলারি: স্ট্যাটাস, টাইপ, ক্যাটাগরি
অনেক স্টোরিতে “status”, “type”, বা “priority” মতো শব্দ থাকে। এগুলোকে কন্ট্রোলড ভোকাবুলারি হিসেবে যান—অপরিমিত মানের একটি সীমিত সেট।
যদি সেট ছোট ও স্থিতিশীল হয়, একটি enum-স্টাইল ফিল্ড কাজ করবে। যদি এটা বাড়তে পারে, লেবেল দরকার, বা পারমিশন-ভিত্তিক (উদাহরণ: অ্যাডমিন-ম্যানেজড ক্যাটাগরি), তাহলে আলাদা লুকআপ টেবিল (যেমন status_codes) ব্যবহার করুন এবং রেফারেন্স রাখুন।
এভাবেই স্টোরিগুলো এমন ফিল্ডে রূপান্তর পায় যা বিশ্বাসযোগ্য—সার্চযোগ্য, রিপোর্টেবল, এবং ভুল প্রবেশ করা কঠিন।
ধাপ 3 — সত্তাগুলোকে সম্পর্ক দিয়ে যুক্ত করা
একবার আপনি সত্তাগুলো (User, Order, Invoice, Comment, ইত্যাদি) এবং তাদের ফিল্ডগুলো ড্রাফট করে ফেললে, পরবর্তী ধাপ হলো সেগুলোকে সংযুক্ত করা। সম্পর্কগুলো হলো "কীভাবে এই জিনিসগুলো পরস্পরের সাথে মিথস্ক্রিয়া করে"—এগুলো আপনার স্টোরিগুলোতে ইঙ্গিত থাকে।
তিনটি সম্পর্কের ধরন (সরল ভাষায়)
One-to-one (1:1) মানে “একটি বস্তুর ঠিক একটি আরেকটি বস্তু আছে।”
- স্টোরি ফ্রেজ: “Each user has one profile.”
- মডেল ধারণা:
User↔Profile(সাধারণত একত্রিত করা যায় যদি আলাদা রাখার কারণ না থাকে)।
One-to-many (1:N) মানে “একটি জিনিসের অনেকগুলো আরেকটি জিনিস থাকতে পারে।” এটি সবচেয়ে সাধারণ।
- স্টোরি ফ্রেজ: “A user can have many orders.”
- মডেল ধারণা:
User→Order(টেবিলেuser_idরাখুন)।
Many-to-many (M:N) মানে “অনেকগুলো জিনিস অনেকগুলো জিনিশের সাথে সম্পর্কিত।” এটি একটি অতিরিক্ত টেবিল প্রয়োজন করে।
- স্টোরি ফ্রেজ: “An order can include many products, and a product can be in many orders.”
M:N: জয়েন টেবিল ট্রিক
ডেটাবেসে Order-এর মধ্যে “প্রোডাক্ট আইডির তালিকা” নীচে রাখার বদলে একটি জয়েন টেবিল ব্যবহার করুন।
উদাহরণ:
OrderProductOrderItem(জয়েন টেবিল)
OrderItem সাধারণত রাখে:
order_idproduct_id- স্টোরির ডিটেইলস যেমন
quantity,unit_price,discount
মনে রাখবেন স্টোরির বিস্তারিত (যেমন “quantity”) প্রায়শই সম্পর্কের উপর থাকা উচিত, দুই সত্তার উপর নয়।
আবশ্যক বনাম ঐচ্ছিক (জার্গন ছাড়া)
স্টোরিও আপনাকে বলে সম্পর্কটি অবশ্যক নাকি মাঝে মাঝে অনুপস্থিত।
- “An order must belong to a user” → প্রতিটি
Order-এরuser_idথাকা উচিত (খালি থাকা উচিত নয়)। - “A user may have a phone number” →
phoneফাঁকা থাকতে পারে। - “An order can have a shipping address (if physical goods)” →
shipping_address_idডিজিটাল অর্ডারের জন্য ফাঁকা হতে পারে।
দ্রুত চেক: যদি স্টোরি বলে যে রেকর্ডটা তৈরি করা যাবে না সেই লিঙ্ক ছাড়া, তবে এটি আবশ্যক হিসেবে বিবেচনা করুন। যদি স্টোরি বলে “can”, “may”, বা ব্যতিক্রম দেয়, তবে সেটি ঐচ্ছিক।
স্টোরি বাক্যকে রিলেশনশিপ বাক্যে ফিরিয়ে দিন
প্রতিটি স্টোরি পড়ে এটাকে সহজ জুড়ি বাক্যে লিখুন:
- “A user can leave many comments” →
User1:NComment - “A comment belongs to one user” →
CommentN:1User
প্রতিটি ইন্টারঅ্যাকশনের জন্য এটা করুন। শেষের দিকে আপনার কাছে এমন একটি সংযুক্ত মডেল থাকবে যা কাজটি কীভাবে হয় সেটা প্রতিফলিত করে—ER টুল খুলার আগেই।
ধাপ 4 — ওয়ার্কফ্লো ব্যবহার করে স্টেট, ইভেন্ট, ও গ্যাপ খুঁজে বের করা
ইউজার স্টোরি বলে আপনি কি চান। ওয়ার্কফ্লো দেখায় কাজ কিভাবে ধাপে ধাপে এগোয়। ওয়ার্কফ্লোকে ডেটায় ট্রান্সলেট করলে প্রায়শই “আমরা যে জিনিসটি স্টোর করা ভুলে গিয়েছিলাম” সমস্যা আগে থেকেই ধরা পড়ে—বিল্ড করার আগে।
একটি সহজ ওয়ার্কফ্লো দিয়ে শুরু করুন
ওয়ার্কফ্লোকে অ্যাকশন ও স্টেট চেইন হিসেবে লিখুন। উদাহরণ:
- Create request → Draft
- Submit request → Submitted
- Manager reviews → Approved or Rejected
- If approved, work is scheduled → In progress
- Completed → Done
এই বোল্ড শব্দগুলো প্রায়ই একটি status ফিল্ড (বা ছোট "state" টেবিল) হয়ে ওঠে, স্পষ্ট অনুমোদিত মানগুলোর সঙ্গে।
ওয়ার্কফ্লো মিসিং ফিল্ডগুলো উদঘাটন করে
প্রতিটি ধাপ চালিয়ে যান এবং প্রশ্ন করুন: “পরে কী জানা লাগবে?” ওয়ার্কফ্লো সাধারণত এগুলো আবিষ্কার করে:
- টাইমস্ট্যাম্প:
submitted_at,approved_at,completed_at - নির্বাহী:
created_by,assigned_to,approved_by - কারণ/পরিপ্রেক্ষিত:
rejection_reason,approval_note - অর্ডারিং: বহু-ধাপ প্রক্রিয়ার জন্য
sequence
যদি ওয়ার্কফ্লোতে অপেক্ষা, এসকেলেশন, বা হ্যান্ডঅফ থাকে, সাধারণত আপনাকে অন্তত একটি টাইমস্ট্যাম্প এবং একটি “এখন কে এটি ধরে আছে” ফিল্ড লাগবে।
ওয়ার্কফ্লো মিসিং টেবিলও প্রকাশ করে
কিছু ওয়ার্কফ্লো স্টেপ কেবল ফিল্ড নয়—এগুলো আলাদা ডেটা স্ট্রাকচার:
- অডিট লগ/ইতিহাস "কে কখন স্ট্যাটাস বদলালো"-র জন্য
- অ্যাপ্রুভালস মাল্টি-অ্যাপ্রুভার বা কন্ডিশনাল রুলের জন্য
- অ্যাটাচমেন্টস যখন ইউজার কোন ফাইল আপলোড করে
- কমেন্টস যখন আলোচনাই প্রক্রিয়ার অংশ
AI-কে গ্যাপ চেক করতে ব্যবহার করা
AI-কে দিন: (1) ইউজার স্টোরি ও অ্যাকসেপ্টেন্স ক্রাইটেরিয়া, এবং (2) ওয়ার্কফ্লো ধাপগুলো। জিজ্ঞাসা করুন প্রতিটি ধাপের জন্য কোন ডেটা লাগবে (স্টেট, অভিনেতা, টাইমস্ট্যাম্প, আউটপুট) এবং কোন রিকোয়ারমেন্ট বর্তমান ফিল্ড/টেবিল দিয়ে সাপোর্ট হচ্ছে না—AI এগুলো হাইলাইট করতে পারে।
Koder.ai-এর মতো প্ল্যাটফর্মে এই “গ্যাপ চেক” প্রাকটিক্যাল হয়ে ওঠে কারণ আপনি দ্রুত ইটারেট করতে পারেন: স্কিমা অনুমান ঠিক করুন, স্ক্যাফোল্ড রিজেনারেট করুন, এবং দীর্ঘ ম্যানুয়াল বয়লারপ্লেট ছাড়াই আগিয়ে যান।
কী, ইউনিকনেস, ও মৌলিক কনস্ট্রেইন্ট (জার্গন ছাড়া)
ইউজার স্টোরি থেকে টেবিলে পরিণত করার সময়, আপনি শুধু ফিল্ডগুলোর তালিকা বানাচ্ছেন না—আপনি সিদ্ধান্ত নিচ্ছেন কিভাবে ডেটা সময়ের সাথে সনাক্তযোগ্য ও সামঞ্জস্যপূর্ণ থাকবে।
প্রাথমিক কী: প্রতিটি রো এর স্থায়ী "ID কার্ড"
একটি primary key একটি রেকর্ডকে অনন্যভাবে সনাক্ত করে—একটি স্থায়ী ID কার্ডের মত।
কেন প্রতিটি রো-র লাগবে: স্টোরিগুলো আপডেট, রেফারেন্স, ও ইতিহাস নির্দেশ করে। যদি স্টোরি বলে “Support can view an order and issue a refund,” আপনাকে একটি স্থিতিশীল উপায় থাকা দরকার সেই order-কে পয়েন্ট করার জন্য—গ্রাহক ইমেইল বদলালেও বা ঠিকানা এডিট হলে সেটিকে ঠিক করে রাখতে।
প্রায়শই এটি একটি অভ্যন্তরীণ id (নম্বার বা UUID) যা কখনও বদले না।
ফরেন কী: টেবিলগুলোর মধ্যে পয়েন্টার
একটি foreign key হল কিভাবে একটি টেবিল সুরক্ষিতভাবে আরেকটাকে পয়েন্ট করে। যদি orders.customer_id customers.id-কে রেফার করে, ডেটাবেস নিশ্চিত করতে পারে প্রতিটি অর্ডার বাস্তব গ্রাহকের সাথে যুক্ত।
এটি সেই স্টোরিগুলোর সাথে মেলে যেগুলো বলে “As a user, I can see my invoices.” ইনভয়েসটি ভাসমান নয়; এটি একজন গ্রাহকের সাথে সংযুক্ত।
ইউনিকনেস নিয়ম: “অবিশ্বাস্যভাবে অনন্য” কে প্রয়োগ করা
ইউজার স্টোরি প্রায়ই লুকানো ইউনিকনেস রুল রাখে:
- “Users sign up with email” → unique email আরোপ করা (বা যদি মাল্টি-টেন্যান্স থাকে, তাহলে টেন্যান্ট-নির্ভর ইউনিকনেস)
- “Finance searches by invoice number” → unique invoice_number আরোপ
এই নিয়মগুলো ডুপ্লিকেটগুলি রোধ করে যা পরে ডাটা-বাগ তৈরি করে।
ইনডেক্সিং (উচ্চ-স্তরের): সাধারণ লুকআপগুলো দ্রুত করুন
ইনডেক্সগুলো সার্চ দ্রুত করে (যেমন “find customer by email” বা “list orders by customer”)। প্রথমে সেই ইন্ডেক্সগুলো দিন যেগুলো আপনার সবচেয়ে সাধারণ কুয়েরি ও ইউনিকনেস রুলের সাথে মেলে।
কি পিছিয়ে রাখবেন: বিরল রিপোর্ট বা অনুমানীয় ফিল্টারের জন্য ভারী ইনডেক্সিং। স্কিমা নেবার পরে বাস্তব ব্যবহার ও স্লো কুয়েরি প্রমাণ দেখেই অপ্টিমাইজ করুন।
ডেটা কনসিস্টেন্ট রাখুন: একটি ব্যবহারিক নরমালাইজেশন চেকলিস্ট
নরমালাইজেশনের একটি সহজ লক্ষ্য: বিরোধী ডুপ্লিকেট প্রতিরোধ করা। একই তথ্য যদি দুই জায়গায় সংরক্ষিত থাকে, একজন কিংবা পরেই তা ভিন্ন হয়ে যাবে (দুই বানান, দুই দাম, দুই “কারেন্ট” ঠিকানা)। একটি নরমালাইজড স্কিমা প্রতিটি তথ্য একবার রাখে, তারপর রেফার করে।
এমন একটি দ্রুত চেকলিস্ট যেটা আপনি যেকোন ড্রাফট স্কিমায় চালাতে পারেন
1) পুনরাবৃত্ত গ্রুপ থেকে সতর্ক থাকুন
যদি আপনি Phone1, Phone2, Phone3 বা ItemA, ItemB, ItemC টাইপ প্যাটার্ন দেখেন, সেটা আলাদা টেবিলের জন্য ইঙ্গিত (যেমন CustomerPhones, OrderItems)।
2) একই নাম/বিবরণ একাধিক টেবিলে কপি করবেন না
যদি CustomerName Orders, Invoices, এবং Shipments-এ হয়, আপনি সত্যের একাধিক উৎস তৈরি করেছেন। গ্রাহক বিবরণ Customers-এ রাখুন এবং কেবল customer_id অন্যত্র রাখুন।
3) একই জিনিসের জন্য একাধিক কলাম এড়ান
যেমন billing_address, shipping_address, home_address—এগুলো ঠিক থাকবেই যদি তারা বাস্তবেই আলাদা ধারণা। কিন্তু যদি আপনি "ধরুন অনেক ঠিকানা টাইপ" মডেল করেন, তাহলে একটি Addresses টেবিল ব্যবহার করুন যার মধ্যে type ফিল্ড আছে।
4) লুকআপগুলোকে ফ্রি টেক্সট থেকে আলাদা করুন
যদি ইউজার একটি পরিচিত সেট থেকে পছন্দ করে (status, category, role), তাকে কনসিস্টেন্টভাবে মডেল করুন: enum বা লুকআপ টেবিল। এটা “Pending” বনাম “pending” বনাম “PENDING” সমস্যা রোধ করে।
5) পরীক্ষা করুন প্রতিটি নন-ID ফিল্ড ঠিক কী-র উপর নির্ভরশীল
একটি দ্রুত আবেগগত চেক: টেবিলে যদি একটি কলাম টেবিলের মূল সত্তা ব্যতীত অন্য কিছু বর্ণনা করে, সম্ভবত এটি অন্যত্র থাকা উচিত। উদাহরণ: Orders-এ product_price রাখা উচিত নয় যদি না এটা “অর্ডারের সময়ের মূল্য” (ইতিহাস) বোঝায়।
কখন ডেনরমালাইজেশন গ্রহণযোগ্য (পরে সিদ্ধান্ত)
কখনও কখনও আপনি ইচ্ছাকৃতভাবে ডুপ্লিকেট রাখেন:
- রিপোর্টিং/পারফরম্যান্স: প্রি-অ্যাগ্রিগেটেড টোটাল বা সামারি টেবিল
- ক্যাশিং: ভারী রিক্যালকুলেশন এড়াতে ক্যালকুল করা মান সংরক্ষণ
- অডিট/ইতিহাস: কেনাকালীন সময়কার নাম কপি করে রাখা
কী গুরুত্বপূর্ণ: এটি ইচ্ছাকৃত করা—কোন স্থানটি সত্যের উৎস এবং কপি কিভাবে আপডেট হবে তা ডকুমেন্ট করুন।
AI কোথায় সাহায্য করে—আর কোথায় মানুষ সিদ্ধান্ত নেয়
AI সন্দেহজনক ডুপ্লিকেশন (পুনরাবৃত্ত কলাম, অনুরূপ ফিল্ড নাম, অসঙ্গত “status” ফিল্ড) ফ্ল্যাগ করতে পারে এবং টেবিলে ভাগ করার পরামর্শ দিতে পারে। মানুষ এখনও ট্রেড-অফগুলো (সরলতা বনাম নমনীয়তা বনাম পারফরম্যান্স) পণ্য কিভাবে ব্যবহার হবে তার ওপর ভিত্তি করে নির্ধারণ করে।
সংরক্ষিত বনাম ক্যালকুলেটেড: ডেটাবেসে কী রাখবেন
একটি ব্যবহারযোগ্য নিয়ম: যে তথ্য আপনি বিশ্বাসযোগ্যভাবে পরে পুনরায় তৈরি করতে পারবেন না, তা রাখুন; বাকিগুলো ক্যালকুলেট করুন।
সংরক্ষিত বনাম ক্যালকুলেটেড (ডেরাইভড) ডেটা
সংরক্ষিত ডেটা হলো সত্যের উৎস: পৃথক লাইন আইটেম, টাইমস্ট্যাম্প, স্ট্যাটাস পরিবর্তন, কে কি করেছে। ক্যালকুলেটেড ডেটা হলো সেই সত্যগুলোর থেকে উৎপন্ন: টোটাল, কাউন্টার, is overdue-এর মতো ফ্ল্যাগ, এবং রোল-আপস।
যদি দুটি মান একই অ্যান্ডারলাইং ফ্যাক্ট থেকে হিসাব করা যায়, তাহলে ফ্যাক্টগুলো স্টোর করুন এবং বাকি ক্যালকুলেট করুন—অন্যথায় বিরোধ সৃষ্টি হবে।
কেন ডেরাইভড মান স্টোর করলে মismatch হয়
ডেরাইভড মানগুলো ইনপুট বদলালে বদলে যায়। যদি আপনি ইনপুট ও ডেরাইভড ফলাফল দুটোই রাখেন, তখন সেগুলোকে সব ওয়ার্কফ্লো ও এজ কেসে সিঙ্ক রাখতে হবে (এডিট, রিফান্ড, পারশিয়াল শিপমেন্ট, ব্যাকডেটেড চেঞ্জ)। একবার একটি আপডেট বাদ গেলে ডাটাবেস ভিন্ন গল্প বলা শুরু করে।
উদাহরণ: order_total স্টোর করা যখন order_items-ও আছে। কেউ quantity বদলে দিলে বা ডিসকাউন্ট দিলে এবং টোটাল আপডেট না হলে ফাইনান্স ও কার্ট আলাদা সংখ্যা দেখবে।
কোনটি সংরক্ষণ করতে হবে সিদ্ধান্তে ওয়ার্কফ্লো ব্যবহার করুন (ইতিহাস ও স্ন্যাপশট)
ওয়ার্কফ্লো আপনাকে বলে কখন ইতিহাসগত সত্য দরকার, শুধু “বর্তমান সত্য” নয়। যদি ইউজারদের জানতে হবে কিভাবে মান তত্ক্ষণিক সময়ে ছিল, তাহলে একটি স্ন্যাপশট স্টোর করুন।
একটি অর্ডারের জন্য আপনি রাখতে পারেন:
- লাইন আইটেম ও দাম (ফ্যাক্ট)
- চেকআউট-এcaptured
order_total(স্ন্যাপশট), কারণ ট্যাক্স, ডিসকাউন্ট, ও প্রাইসিং রুল পরে বদলাতে পারে
ইনভেন্ট-ভিত্তিক ডেটার জন্য (যেমন লগইন), last_login_at-এর মত ইভেন্ট টাইমস্ট্যাম্প স্টোর করুন। “গত ৩০ দিনে সক্রিয়?” টাইপ ক্যালকুলেটেড রাখুন।
ওয়ার্কড উদাহরণ: 5 ইউজার স্টোরি থেকে ER মডেল
চলুন একটি পরিচিত সাপোর্ট টিকিট অ্যাপ নিই। আমরা পাঁচটি ইউজার স্টোরি থেকে একটি সহজ ER মডেলে যাব (সত্তা + ফিল্ড + সম্পর্ক), তারপর একটি ওয়ার্কফ্লো দিয়ে চেক করব।
5 ইউজার স্টোরি → নাউন → সত্তা
- As a customer, I can create a support ticket with a subject, description, and category.
- As an agent, I can assign a ticket to myself or another agent.
- As an agent, I can add internal notes and public replies to a ticket.
- As a customer, I can see when my ticket is updated and when it’s closed.
- As a manager, I can track how long tickets stay open and who closed them.
এই নাউনের থেকে আমরা মূল সত্তাগুলো পাই:
- User (customers, agents, managers)
- Ticket
- Message (public replies + internal notes)
- Category
- TicketEvent (অডিট/ইতিহাস)
ফিল্ড ও সম্পর্ক (সংক্ষিপ্ত ER মডেল)
- User: id, name, email, role
- Category: id, name
- Ticket: id, subject, description, status, created_at, updated_at, closed_at
- সম্পর্ক: Ticket.category_id → Category.id
- সম্পর্ক: Ticket.requester_id → User.id (customer)
- সম্পর্ক: Ticket.assignee_id → User.id (agent, nullable)
- Message: id, ticket_id, author_id, body, is_internal, created_at
- সম্পর্ক: Message.ticket_id → Ticket.id
- সম্পর্ক: Message.author_id → User.id
- TicketEvent: id, ticket_id, actor_id, type, from_status, to_status, created_at
ওয়ার্কফ্লো ম্যাপিং: create → update → close
- Create: insert Ticket (status = “open”, created_at), insert TicketEvent(type = “created”).
- Update (assign, reply): insert Message বা update Ticket.assignee_id, এবং insert TicketEvent(type = “assigned”/“replied”, updated_at)।
- Close: update Ticket.status = “closed”, set closed_at, insert TicketEvent(type = “closed”, actor_id = closer)।
“আগে ও পরে”: AI একটি মিসিং কনস্ট্রেইন্ট ধরছে
আগে (সাধারণ ভুল): Ticket-এ assignee_id আছে, কিন্তু আমরা নিশ্চিত করা ভুলে গিয়েছি যে কেবলমাত্র agent-রাই assignee হতে পারবে।
পরে: AI এটাকে ফ্ল্যাগ করে এবং আপনি একটি ব্যবহারিক নিয়ম যোগ করেন: assignee অবশ্যই role = “agent” থাকা উচিত (স্ট্যাক অনুযায়ী অ্যাপ্লিকেশন ভ্যালিডেশন বা ডেটাবেস কনস্ট্রেইন্ট/পলিসি দ্বারা ইমপ্লিমেন্ট করা যেতে পারে)। এটা “কাস্টমারকে অ্যাসাইন করা” ডেটা বাধা দেয় যা পরে রিপোর্ট ভাঙাবে।
স্কিমা যাচাই: প্রতিটি স্টোরির সঙ্গে ট্রেস করুন
কোনো স্কিমা “ডন” তখনই যখন প্রতিটি ইউজার স্টোরি এমনভাবে ডাটাবেস দিয়ে উত্তরযোগ্য হয় যেটা আপনি প্রতিটি কেসে নির্ভরযোগ্যভাবে করতে পারেন। সবচেয়ে সরল যাচাইকরণ ধাপ হল প্রতিটি স্টোরি নিন এবং জিজ্ঞাসা করুন: “আমরা কি এই প্রশ্নটি ডাটাবেস থেকে নির্ভুলভাবে, প্রতিটি কেসে উত্তর করতে পারি?” যদি উত্তর “হয়ত” হয়, আপনার মডেলে গ্যাপ আছে।
প্রতিটি স্টোরিকে একটি ডাটাবেস প্রশ্নে পরিণত করুন
প্রতিটি স্টোরি এমন প্রশ্নে রিরাইট করুন যা একটি রিপোর্ট, স্ক্রীন, বা API জিজ্ঞাসা করবে। উদাহরণ:
- রিপোর্ট: “Show all open orders by customer, with totals for the last 30 days.”
- পারমিশন: “Which users are allowed to approve refunds for this store?”
- এজ কেস: “Can an order exist without a shipping address? What about digital items?”
- ডিলিশন: “If we delete a customer, what happens to orders, invoices, and notes?”
যদি আপনি একটি স্টোরিকে স্পষ্ট প্রশ্নে রূপান্তর করতে না পারেন, স্টোরিটি অস্পষ্ট। যদি রূপান্তর করা যায়—কিন্তু আপনার স্কিমা দিয়ে উত্তর করা না যায়—তাহলে ফিল্ড, সম্পর্ক, স্ট্যাটাস/ইভেন্ট, বা কনস্ট্রেইন্ট মিসিং।
দ্রুত স্যানিটি চেক হিসেবে স্যাম্পল ডেটা ব্যবহার করুন
প্রতি কী টেবিলে ছোট ডেটাসেট (5–20 সারি) তৈরি করুন যা সাধারণ ও অদ্ভুত কেস (ডুপ্লিকেট, মিসিং ভ্যালু, ক্যান্সেলেশন) অন্তর্ভুক্ত করে। তারপর সেই ডেটা নিয়ে স্টোরিগুলো “প্লে থ্রু” করুন। আপনি দ্রুতই এমন সমস্যা দেখতে পাবেন যেমন “আমাদের নেই যেভাবে বলা আছে ওই সময়ে কোন ঠিকানা ব্যবহৃত হয়েছিল তা জানা” অথবা “আমাদের কোথাও নেই যিনি অনুমোদন করেছিলেন তা স্টোর করার জন্য।”
AI-কে অনুনাসিক কেসগুলো খুঁজতে বলুন
AI-কে বলুন প্রতিটি স্টোরির জন্য ভ্যালিডেশন প্রশ্ন জেনারেট করতে (এজ কেস ও ডিলিশন সিনারিওসহ), এবং প্রতিটি প্রশ্নের উত্তর দিতে কোন ডেটা লাগবে। তারপর সেই তালিকাকে আপনার স্কিমার সাথে তুলনা করুন: কোনো মেল না হলে সেটা একটি স্পষ্ট অ্যাকশন আইটেম।
AI নিরাপদে ব্যবহার করা ও স্কিমা রক্ষণযোগ্য রাখা
AI ডেটা মডেলিং দ্রুত করতে পারে, কিন্তু এটি একই সঙ্গে সংবেদনশীল তথ্য ফাঁসের ঝুঁকি বা ভুল অনুমান হার্ড-কোড করার ঝুঁকি বাড়ায়। এটাকে দ্রুত সহকারী হিসেবে ব্যবহার করুন—উপকারী, কিন্তু গার্ডরেইল দরকার।
AI-কে কী শেয়ার করবেন (এবং কী এড়াবেন)
মডেল করার জন্য পর্যাপ্ত বাস্তবসম্মত কিন্তু নিরাপদ ইনপুট শেয়ার করুন:
- স্যানিটাইজ করা ইউজার স্টোরি (গ্রাহক, পণ্য, লোকেশন গুলোর নাম বদলে দিন)
- অ্যাকসেপ্টেন্স ক্রাইটেরিয়া ও এজ কেস (“refund within 14 days”, “one active subscription per account”)
- ফেক ডেটা সহ উদাহরণ ফিল্ড (উদাহরণ:
invoice_total: 129.50,status: "paid") - বর্তমান CSV হেডার/এক্সিস্টিং টেবিল স্ট্রাকচার (স্ট্রাকচার সাধারণত নিরাপদ; কন্টেন্ট নয়)
এড়িয়ে চলুন এমন কিছু যা ব্যক্তিকে শনাক্ত করে বা কনফিডেনশিয়াল অপারেশন ফাঁস করে:
- বাস্তব নাম, ইমেইল, ফোন, ঠিকানা
- বাস্তব অর্ডার ইতিহাস, সাপোর্ট টিকিট, ইন্টারনাল নোট
- API কী, ডেটাবেস ক্রেডেনশিয়াল, স্ক্রীনশট যাতে প্রাইভেট ডেটা আছে
যদি বাস্তবসম্মততা দরকার হয়, সিন্থেটিক নমুনা জেনারেট করুন—কখনও প্রোডাকশন সারি কপি করবেন না।
স্কিমার পাশে অনুমানগুলো রাখুন
স্কিমা সবচেয়ে বেশিই তখন ব্যর্থ হয় যখন “সবারই আলাদা ধারণা” থাকে। আপনার ER মডেল (বা একই রিপো) পাশে ছোট একটি সিদ্ধান্ত লগ রাখুন:
- সংজ্ঞা (“What counts as an ‘active’ account?”)
- কনস্ট্রেইন্ট (“A user can belong to multiple organizations”)
- ট্রেডঅফ (“We store currency code on each invoice for audits”)
এতে AI আউটপুট টিম জ্ঞানে পরিণত হয়, একক-বারের নিকাশ নয়।
পরিবর্তনের জন্য প্ল্যান: ভার্সনিং ও মাইগ্রেশন
আপনার স্কিমা স্টোরিগুলোর সঙ্গে উন্নত হবে। নিরাপদ রাখুন:
- স্কিমা পরিবর্তনের ভার্সনিং (মাইগ্রেশন ফাইল Git-এ)
- যতটা সম্ভব রিভার্সিবল মাইграশন লেখা
- সিড ও স্যাম্পল কুয়েরি আপডেট করা যাতে পরিবর্তন টেস্টযোগ্য হয়
- AI-জেনারেটেড মাইগ্রেশনগুলোকে অন্যান্য কোডের মত রিভিউ করা
যদি আপনি Koder.ai-এর মতো প্ল্যাটফর্ম ব্যবহার করেন, স্কিমা চেঞ্জ ইটারেট করার সময় স্ন্যাপশট ও রোলব্যাকের মত গার্ডরেইল ব্যবহার করুন, এবং দরকারে সোর্স কোড এক্সপোর্ট করুন।
একটি সহজ পুনরাবৃত্তি ওয়ার্কফ্লো
- স্টোরিগুলো স্যানিটাইজ করুন + 5–10 সিন্থেটিক উদাহরণ তৈরি করুন।
- AI-কে entities, fields, relationships, এবং constraints প্রস্তাব করতে বলুন।
- টিমের সঙ্গে রিভিউ করুন; অনুমানগুলো লিপিবদ্ধ করুন।
- মাইগ্রেশন ইমপ্লিমেন্ট করুন; ছোট “স্টোরি ট্রেস” টেস্ট চালান (প্রতিটি স্টোরি মডেল দিয়ে সমাধানযোগ্য কিনা)।
- স্টোরি বদলালে পুনরাবৃত্তি করুন; স্কিমা ও নোট সিংক রাখুন।
সাধারণ প্রশ্ন
How do I extract database entities from user stories?
স্টোরি থেকে শুরু করে এমন নাউনগুলো হাইলাইট করুন যেগুলো আপনার সিস্টেমকে মনে রাখতে হবে (যেমন Ticket, User, Category)।
একটি নাউনকে সত্তায় পরিণত করুন যখন:
- তার নিজের একটি ID প্রয়োজন
- সময়ের সঙ্গে পরিবর্তিত হয় (লাইফসাইকেল/স্ট্যাটাস আছে)
- একাধিক স্টোরিতে পুনরায় উপস্থিত হয়
একটি সংক্ষিপ্ত তালিকা রাখুন যা আপনি নির্দিষ্ট স্টোরি বাক্যাংশ দিয়ে ব্যাখ্যা করতে পারবেন।
When should something be a field vs. its own table?
“অ্যাট্রিবিউট বনাম সত্তা” পরীক্ষা ব্যবহার করুন:
- এটি একটি ফিল্ড করুন যদি এটি একটি একক মান যা একটি রেকর্ডকে বর্ণনা করে (যেমন
customer.phone_number). - এটি একটি আলাদা টেবিল করুন যদি এটি পুনরাবৃত্তি, শেয়ার করা, কাঠামোবদ্ধ, বা ইতিহাস দরকার (যেমন একাধিক ঠিকানা, ট্যাগ, অ্যাটাচমেন্ট)।
একটি সহজ ইঙ্গিত: যদি কখনো আপনার কাছে “অনেকগুলো” দরকার হবে, সম্ভবত আলাদা টেবিল দরকার।
How do acceptance criteria translate into fields and constraints?
এগ্রেসপ্টেন্স ক্রাইটেরিয়া-কে একটি স্টোরেজ চেকলিস্ট হিসেবে দেখুন। যদি কোনো রিকোয়ারমেন্ট বলে আপনি কিছু ফিল্টার/সার্ট/ডিসপ্লে/অডিট করবেন, তবে আপনাকে তা স্টোর করতে হবে (অথবা বিশ্বাসযোগ্যভাবে বের করতে সক্ষম হতে হবে)।
উদাহরণ:
- “Show who approved and when” →
approved_by,approved_at - “Filter by delivery date” →
delivery_date - “Email must be unique” →
email-এ ইউনিক কনস্ট্রেন্ট/ইন্ডেক্স
How do I turn story text into table relationships (1:1, 1:N, M:N)?
স্টোরি বাক্যগুলোকে রিলেশনশিপ বাক্যে রিরাইট করুন:
- “A customer can have many orders” → 1:N (টেবিলে
customer_idরাখুন, উদাহরণ:orders.customer_id) - “An order includes many products” → M:N (একটি জয়েন টেবিল যোগ করুন, উদাহরণ:
order_items)
যদি সম্পর্কের নিজের ডেটা থাকে (quantity, price, role), সেই ডেটা জয়েন টেবিলে রাখুন।
What’s the right way to model many-to-many relationships?
M:N-কে জয়েন টেবিলে মডেল করুন যা दोनों ফরেন কীস সহ সম্পর্ক-নির্দিষ্ট ফিল্ডগুলো রাখে।
সাধারণ প্যাটার্ন:
ordersproductsorder_items(রাখেorder_id,product_id,quantity,unit_price)
একক কলামে “ID-এর তালিকা” স্টোর করা থেকে বিরত থাকুন—কোয়েরি, আপডেট, এবং ইন্টিগ্রিটি বজায় রাখা সমস্যা করে দেয়।
How do workflows help me find missing tables or fields?
ওয়ার্কফ্লো ধাপে ধাপে চালিয়ে যান এবং জিজ্ঞেস করুন: “ভবিষ্যতে এটি প্রমাণ করার জন্য আমাদের কী জানতেই হবে?”
সাধারণ যোগ:
- টাইমস্ট্যাম্প:
submitted_at,closed_at - অভিনেতা:
created_by,assigned_to,closed_by - কারণ/নোট:
rejection_reason
যদি জানতে চান “কে কখন কি বদলে ফেলেছে”, একটি ইভেন্ট/অডিট টেবিল যোগ করুন—একটি একটিমাত্র ফিল্ড ওভাররাইট করার বদলে।
Which constraints should I add first (keys, uniqueness, indexes)?
প্রথমে নিচেরগুলো যোগ করুন:
- প্রতিটি টেবিলে একটি স্থায়ী প্রাথমিক কী (
id) - সম্পর্কগুলোর জন্য ফরেন কী (
orders.customer_id → customers.id) - রিকোয়ারমেন্ট থেকে প্রাপ্ত ইউনিকনেস নিয়ম (ইমেল, ইনভয়েস নম্বর)
তারপর আপনার সবচেয়ে সাধারণ লুকআপগুলোর জন্য ইন্ডেক্স দিন (যেমন email, customer_id, status + created_at)। আপাতত স্পেকুলেটিভ ইন্ডেক্সিং পিছিয়ে রাখুন—বাস্তব কুয়েরি প্যাটার্ন দেখে অপ্টিমাইজ করুন।
How do I know if my schema is normalized enough without overdoing it?
দ্রুত কনসিস্টেন্সি চেক চালান:
- যদি আপনি
Phone1/Phone2মত প্যাটার্ন দেখেন, একটি চাইল্ড টেবিলে ভাগ করুন। - একই তথ্য যদি একাধিক টেবিলে থাকে, একটি সোর্স অব ট্রুথ বেছে নিন এবং রেফার করুন।
- যদি কোনো কলাম টেবিলের মূল সত্তার বাইরে অন্য কিছু বর্ণনা করে, সেটি আলাদা টেবিলে নিয়ে যান।
পারফরম্যান্স/রিপোর্টিং/অডিট স্ন্যাপশটের মতো স্পষ্ট কারণ ছাড়া ওভার-নরমালাইজ করার ঝুঁকি নেই।
What should be stored vs. calculated in the database?
যেসব তথ্য আপনি পুনরায় নির্ভরযোগ্যভাবে পুনরায় তৈরি করতে পারবেন না সেগুলো স্টোর করুন; বাকিগুলো হিসাব করে দেখান।
স্টোর করা ভাল:
- ইভেন্ট ও টাইমস্ট্যাম্প
- লাইন আইটেম ও ঐতিহাসিক দাম
- অডিট উদ্দেশ্যে “কে কি করেছে” তথ্য
ক্যালকুলেট করা ভাল:
- টোটাল (লাইন আইটেম থেকে)
- ‘is overdue’ জাতীয় ফ্ল্যাগ (তারিখ থেকে)
যদি আপনি ডেরাইভড ভ্যালু যেমন order_total স্টোর করেন, কিভাবে সেগুলো সিঙ্ক থাকবে তা স্পষ্ট করে নিন এবং এজ কেস টেস্ট করুন (রিফান্ড, এডিট, পারশিয়াল শিপমেন্ট)।
How can I use AI safely to speed up schema design without making bad assumptions?
AI-কে ড্রাফট তৈরিতে ব্যবহার করুন, তারপর আপনার আর্টিফ্যাক্টগুলোর বিরুদ্ধে যাচাই করুন।
প্রাকটিকাল প্রম্পট উদাহরণ:
- “এই স্টোরিগুলো থেকে সম্ভাব্য সত্তা ও সমার্থক শব্দগুলো বের করো।”
- “অ্যাকসেপ্টেন্স ক্রাইটেরিয়া থেকে টাইমস্ট্যাম্প, অভিনেতা, স্ট্যাটাস ইত্যাদি ফিল্ডগুলোর তালিকা দাও।”
- “এই ওয়ার্কফ্লো অনুযায়ী প্রতিটি ধাপে কোন ডেটা লাগবে?”
গার্ডরেইলস:
- ইনপুট স্যানিটাইজ করুন (কোনও PII, ক্রেডেনশিয়াল বা প্রডাকশন সারি দেবেন না)
- সিদ্ধান্তের লগ রাখুন(schema-এ থাকা অনুমানগুলো)
- AI-জেনারেটেড মাইগ্রেশনগুলোকে অন্যান্য কোড মত রিভিউ ও ভার্সন করুন (Git-এ রাখুন)