এই পর্বে যা করবেন
- DBMS আর SQL-এর MCQ কোন কোন ছাঁচে আসে তা চেনা, আর বাদ দেওয়ার পদ্ধতি, সময় ভাগ ও ভুলে নম্বর কাটার হিসাব শেখা
- NULL = NULL, COUNT(*) বনাম COUNT(col), WHERE বনাম HAVING, 3NF বনাম BCNF, conflict বনাম view serializability — দশটি বড় ফাঁদ এড়ানো
- পুরো কোর্সের ১০৫টি প্রশ্নে নিজের দুর্বল মডিউল খুঁজে বের করা, আর সেই পর্বে ফিরে যাওয়া
- FD থেকে key আর normal form, schedule থেকে precedence graph, কোয়েরি থেকে ফল — খাতায় নির্ভুলভাবে বের করার অভ্যাস
- AI দিয়ে আরও MCQ বানানো, আর সেগুলোর “সঠিক উত্তর” SQL চালিয়ে আর পর্বের সাথে মিলিয়ে যাচাই করা
১ · DBMS আর SQL-এর MCQ কীভাবে সামলাবেন — প্রশ্নের ধরন, বাদ দেওয়ার কৌশল আর প্রচলিত ফাঁদ
ধরুন খুলনার সাবরিনা একটি ব্যাংকের IT officer পদের লিখিত পরীক্ষায় বসেছেন। প্রথম অংশে ডেটাবেসের ৩০টি MCQ, সময় ২৫ মিনিট। SQL তিনি রোজ লেখেন, normalization-ও পড়া। তবু প্রশ্নগুলো এমন: “WHERE city = NULL কয়টি সারি দেয়?” — অপশনে 1 আছে, আর সেটি দেখতে একদম ঠিক মনে হয়। “এই FD-গুলোতে relation সর্বোচ্চ কোন normal form-এ?” — অপশনে 3NF আর BCNF দুটোই। ফল এল ৩০-এ ১৮. বেশিরভাগ ভুল জ্ঞানের অভাবে নয় — প্রশ্নের একটি শব্দ বা একটি NULL চোখ এড়িয়ে যাওয়ায়।
প্রশ্নকর্তা জেনেশুনে এমন ভুল অপশন রাখেন, যা কোনো আধা-সত্য নিয়ম থেকে আসে। এমন বিভ্রান্তিকর অপশনকে বলে distractor. “NULL মানে খালি, তাই = NULL দিয়ে খোঁজা যায়”, “primary key মানেই clustered index”, “BCNF সবসময় 3NF-এর চেয়ে ভালো, তাই সেটিই উত্তর” — এগুলো একেকটি distractor-এর জন্মস্থান। ভালো খবর: distractor-গুলো ঘুরেফিরে একই দশ-বারোটি ভুল ধারণা থেকে আসে। সেগুলো চিনে ফেললে অর্ধেক কাজ শেষ।
প্রশ্নের আট ছাঁচ
বিশ্ববিদ্যালয়ের পরীক্ষা, চাকরির লিখিত পরীক্ষা (IT officer, ব্যাংকের IT, সফটওয়্যার ইঞ্জিনিয়ার বা ডেটা অ্যানালিস্টের screening) আর অনলাইন অ্যাসেসমেন্টে DBMS-এর MCQ মোটামুটি আটটি ছাঁচে পড়ে। কোন ছাঁচের প্রশ্ন, তা চিনতে পারলেই বুঝবেন কোন কৌশল লাগবে:
| ধরন | উদাহরণ | কৌশল |
|---|---|---|
| সংজ্ঞা | “physical data independence কী?”, “weak entity কী?” | সংজ্ঞার প্রতিটি শব্দ মেলান |
| SQL-এর ফল | “এই কোয়েরি কয়টি সারি দেয়?” | খাতায় ছোট টেবিল বানিয়ে যুক্তিগত ক্রমে চালান; NULL আলাদা করে দেখুন |
| কোন SQL ঠিক? | “দলের শর্ত কোথায় লিখবেন?” | প্রতিটি অপশন চলবে কি না, চললে কী দেবে — দুটিই ভাবুন |
| FD-র হিসাব | closure, candidate key, highest normal form | attribute closure ধাপে ধাপে; ডানে কখনো আসে না এমন attribute আগে খুঁজুন |
| Schedule | “conflict serializable কি?”, “সমতুল্য serial ক্রম?” | প্রতিটি item-এর conflict জোড়া থেকে precedence graph |
| খরচের হিসাব | B+ tree-র উচ্চতা, join বা sort-এর I/O | সূত্র লিখুন, তারপর সংখ্যা বসান; ⌈ ⌉ ভুলবেন না |
| কোনটি বাছবেন? | “কোন index?”, “কোন NoSQL?”, “কোন isolation level?” | কাজের ধরন (পড়া/লেখা, পরিসর/সমতা) আগে লিখুন |
| সত্য বৈশিষ্ট্য | “2PL সম্পর্কে কোনটি সত্য?” | প্রতিটি অপশন আলাদা করে সত্য/মিথ্যা |
কৌশল ১ · বাদ দেওয়ার পদ্ধতি
সঠিক উত্তর সরাসরি খোঁজার চেয়ে ভুলগুলো বাদ দেওয়া প্রায়ই সহজ। একে বলে elimination method. প্রতিটি অপশনকে জিজ্ঞেস করুন: “এটি সত্য হলে কোন নিয়মটি সত্য হতে হবে?” তারপর হয় একটি নিয়ম দিয়ে, নয়তো একটি ছোট উদাহরণ দিয়ে অপশনটি কেটে দিন। normal form-এর প্রশ্নে এটি বিশেষ কাজের, কারণ অপশনগুলো একটির ভেতরে আরেকটি বসানো: প্রতিটি BCNF relation 3NF-এ, প্রতিটি 3NF relation 2NF-এ। তাই “সর্বোচ্চ” normal form মানে সবচেয়ে কড়া যে শর্তটি এখনো খাটে। নিচের ডায়াগ্রামে এমন একটি কঠিন প্রশ্ন ধাপে ধাপে সমাধান করা হয়েছে।
- প্রশ্ন পড়া
“সর্বোচ্চ”অপশনগুলো স্তরে স্তরে - key খোঁজা
AB, ACclosure দিয়ে - 2NF?
partial নেইক বাদ - 3NF?
B primeখ বাদ - BCNF?
C → Bঘ বাদ, উত্তর গ
R(A, B, C, D) সর্বোচ্চ কোন normal form-এ আছে? ক) 1NF খ) 2NF গ) 3NF ঘ) BCNF মনে রাখুন: BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF → যে শর্ত খাটে না, তার ঠিক আগেরটিই উত্তর
A কোনো FD-র ডানে নেই → A প্রতিটি key-তে আছে
A⁺ = {A} ✗
AB⁺ = {A, B, C, D} ✓ key
AC⁺ = {A, C} → C → B → {A, B, C}
→ AB → D → {A, B, C, D} ✓ key
AD⁺ = {A, D} ✗
key: AB, AC prime: A, B, C non-prime: D
non-prime শুধু D. key-র কোনো প্রকৃত অংশ D দেয়?
A⁺ = {A} B⁺ = {B} C⁺ = {B, C}
কোনোটিতেই D নেই → partial dependency নেই
2NF ✓
ক) 1NF (2NF-ও খাটে, তাই 1NF “সর্বোচ্চ” নয়)
AB → C AB superkey ✓
AB → D AB superkey ✓
C → B C superkey নয়, কিন্তু
B prime (key AB-র অংশ) ✓
3NF ✓
খ) 2NF (3NF-ও খাটে)
C → B C⁺ = {B, C} → superkey নয় ✗
BCNF ✗
ঘ) BCNF
উত্তর: গ) 3NF
(BCNF-এ ভাঙলে CB আর ACD — তখন AB → C
কোনো একটি টেবিলে আর পরীক্ষা করা যায় না)
- প্রশ্নে “সর্বোচ্চ” শব্দে দাগ দিন। চারটি অপশন স্বাধীন দাবি নয় — একটির ভেতরে আরেকটি। BCNF খাটলে উত্তর BCNF; না খাটলে দেখুন 3NF, তারপর 2NF. তাই প্রথম কাজ: কোন শর্ত কোথায় ভাঙে, তা খোঁজা। এর জন্য আগে সব candidate key লাগবে।
- closure দিয়ে সব key বের করুন। A কোনো FD-র ডান দিকে নেই, তাই প্রতিটি key-তে A থাকবেই। A⁺ = {A}, অর্থাৎ A একা নয়। AB⁺ সব দেয় — key. AC⁺: C → B দিয়ে B আসে, তারপর AB → D দিয়ে D — এটিও key. AD⁺ = {A, D} — নয়। key দুটি: AB আর AC; prime attribute A, B, C; non-prime শুধু D.
- 2NF পরীক্ষা — partial dependency খুঁজুন। non-prime D কি কোনো key-র প্রকৃত অংশের ওপর নির্ভর করে? A⁺, B⁺, C⁺ — কোনোটিতেই D নেই। partial dependency নেই, তাই 2NF খাটে, আর “সর্বোচ্চ 1NF” মিথ্যা। ক বাদ।
- 3NF পরীক্ষা — প্রতিটি FD-র দুই দিক দেখুন। AB → C আর AB → D-তে বাঁ দিক superkey. C → B-তে C superkey নয় — কিন্তু ডান দিক B prime, আর 3NF এই ছাড় দেয়। সব FD পাস, তাই 3NF খাটে। খ বাদ — আর ঠিক এখানেই বেশিরভাগ পরীক্ষার্থী “C superkey নয়” দেখে 2NF বলে ফেলেন।
- BCNF — ছাড় ছাড়া একই পরীক্ষা। BCNF-এ প্রতিটি নন-trivial FD-র বাঁ দিক superkey হতেই হবে; ডান দিক prime হলেও ছাড় নেই। C → B তা ভাঙে। ঘ বাদ, উত্তর গ) 3NF. মজার ব্যাপার: BCNF-এ ভাঙলে (CB আর ACD) AB → C আর কোনো একটি টেবিলের ভেতরে থাকে না — 3NF-এর ছাড়টি ঠিক এই dependency রক্ষার জন্যই।
কৌশল ২ · SQL-এর ফলের প্রশ্নে খাতায় ছোট টেবিল
“এই কোয়েরি কয়টি সারি দেয়?” প্রশ্নে মাথায় হিসাব করবেন না। প্রশ্নের টেবিলটি খাতায় লিখুন, তারপর SELECT-এর যুক্তিগত ক্রমে চলুন: FROM আর JOIN (কোন জোড়াগুলো মিলল, LEFT JOIN-এ কারা NULL নিয়ে টিকে থাকল), WHERE (কোন সারি TRUE — FALSE আর UNKNOWN দুটোই বাদ), GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. প্রতিটি ধাপের পর সারি গুনুন। প্রশ্নকর্তা প্রায় সবসময় একটি অপশন রাখেন “NULL-কে সাধারণ মান ধরলে যা হতো”, আর একটি “INNER JOIN হলে যা হতো” — আপনার টেবিলে সেগুলো চোখে পড়বে। এই পাতার লাইভ এডিটরগুলো দিয়ে সেই অভ্যাসটিই পাকা করুন: আগে খাতায়, তারপর চালিয়ে।
কৌশল ৩ · তত্ত্বের প্রশ্নে একটি নির্দিষ্ট পদ্ধতি
FD, normal form আর schedule-এর প্রশ্নে আন্দাজের জায়গা নেই — প্রতিটির একটি যান্ত্রিক পদ্ধতি আছে। key চাইলে: যে attribute কোনো FD-র ডান দিকে নেই, সেগুলো দিয়ে শুরু করে attribute closure. normal form চাইলে: আগে সব key, তারপর 2NF → 3NF → BCNF ক্রমে পরীক্ষা (উপরের ডায়াগ্রাম)। serializability চাইলে: প্রতিটি item-এর জন্য conflict জোড়া, তা থেকে precedence graph, তারপর চক্র খোঁজা। পদ্ধতিটি লিখে লিখে চালালে দুই মিনিটে নিশ্চিত উত্তর, আর ভুল হলেও কোথায় ভুল তা খুঁজে পাওয়া যায়।
কৌশল ৪ · সময় ভাগ আর ভুলে নম্বর কাটার হিসাব
৩০টি প্রশ্ন ২৫ মিনিটে মানে প্রতিটিতে গড়ে ৫০ সেকেন্ড। একটি normal form বা schedule-এর প্রশ্নেই দুই মিনিট লাগতে পারে। তাই দুই দফায় চলুন: প্রথম দফায় সংজ্ঞা আর সরাসরি প্রশ্ন, দ্বিতীয় দফায় FD, schedule আর খরচের হিসাব। যেসব পরীক্ষায় ভুল উত্তরে নম্বর কাটে (negative marking), সেখানে আন্দাজ একটি হিসাবের প্রশ্ন: (ঠিক হওয়ার সম্ভাবনা × ১) − (ভুল হওয়ার সম্ভাবনা × কাটা নম্বর)। দুটি অপশন নিশ্চিতভাবে বাদ দিতে পেরেছেন আর ভুলে ০.২৫ কাটে: ০.৫ − ০.৫ × ০.২৫ = +০.৩৭৫ — লাভ। কিছুই না জেনে চারটি থেকে আন্দাজ আর ভুলে ০.৫ কাটে: ০.২৫ − ০.৭৫ × ০.৫ = −০.১২৫ — ক্ষতি। কত কাটে, পরীক্ষাভেদে আলাদা — নিজের পরীক্ষার নিয়ম আগে জেনে নিন।
দশটি বড় ফাঁদ
নিচের প্রতিটি সারি এই পাতার একাধিক প্রশ্নে distractor হয়ে ফিরে আসবে। শুরুর আগে একবার চোখ বুলিয়ে নিন, আর শেষে ভুলগুলো কোন সারিতে পড়ল, মিলিয়ে দেখুন।
| ফাঁদ | ভুল ধারণা | সঠিক কথা |
|---|---|---|
| NULL = NULL | “= NULL দিয়ে খালি ঘর খোঁজা যায়” | NULL-এর সাথে যেকোনো তুলনা UNKNOWN; WHERE শুধু TRUE রাখে। খুঁজুন IS NULL দিয়ে |
| NOT IN আর NULL | “NOT IN আর NOT EXISTS একই” | তালিকা বা subquery-তে একটি NULL থাকলে NOT IN কোনো সারি দেয় না; NOT EXISTS নিরাপদ |
| COUNT(*) বনাম COUNT(col) | “দুটিই সারি গোনে” | COUNT(*) সারি গোনে, COUNT(col) শুধু অ-NULL মান; LEFT JOIN-এর পর পার্থক্যটি বড় হয়ে দাঁড়ায় |
| LEFT JOIN আর WHERE | “ডান টেবিলের শর্ত ON বা WHERE — একই কথা” | WHERE-এ দিলে NULL-সারি ছাঁটা পড়ে, LEFT JOIN কার্যত INNER হয়ে যায় |
| WHERE বনাম HAVING | “aggregate-এর শর্ত WHERE-এ লেখা যায়” | WHERE সারি ছাঁকে দলের আগে; দলের শর্ত (COUNT, SUM) HAVING-এ |
| DELETE / TRUNCATE / DROP | “তিনটিই টেবিল মুছে দেয়” | DELETE সারি মোছে (WHERE নেয়, trigger চালায়); TRUNCATE সব সারি দ্রুত খালি করে, গঠন থাকে; DROP গঠনসহ টেবিল সরায় |
| 2NF | “প্রতিটি relation-এ 2NF পরীক্ষা জরুরি” | partial dependency শুধু যৌগিক (composite) key-তে সম্ভব; সব key এক-attribute হলে 1NF মানেই 2NF |
| BCNF বনাম 3NF | “C → B-তে C superkey নয়, তাই 3NF ভাঙে” | 3NF ছাড় দেয় যদি ডান দিক prime হয়; BCNF দেয় না। BCNF-এ dependency preservation সবসময় সম্ভব নয় |
| conflict বনাম view | “conflict serializable নয় মানে serializable-ই নয়” | blind write থাকলে schedule view serializable হতে পারে; প্রতিটি conflict serializable schedule view serializable, উল্টোটি নয় |
| primary বনাম clustered index | “primary key মানেই clustered index” | InnoDB আর (ডিফল্টে) SQL Server-এ তাই, PostgreSQL-এর heap টেবিলে নয়; clustered index টেবিলে একটিই থাকে |
এই পাতার প্রশ্নগুলো সম্পর্কে: প্রশ্নগুলো এই কোর্সের জন্য নতুন করে লেখা — বিশ্ববিদ্যালয়, চাকরির লিখিত পরীক্ষা আর ইন্টারভিউতে এ ধরনের প্রশ্ন প্রায়ই আসে, এমন ধারণা থেকে বানানো; কোনোটিই কোনো নির্দিষ্ট পরীক্ষার আসল প্রশ্ন নয়। SQL-এর প্রতিটি ফল SQLite-এ চালিয়ে মেলানো, আর closure, key, normal form, schedule ও খরচের প্রতিটি উত্তর ছোট প্রোগ্রামে যাচাই করা। অন্যভাবে বলা না থাকলে SQL-এর আচরণ মানে standard SQL, আর কোনো DBMS-ভেদে পার্থক্য থাকলে প্রশ্নেই নাম বলা আছে।
লাইভ এডিটরের নমুনা ডেটাবেস
এই পাতার এডিটরগুলো কোর্সের দুটি পরিচিত নমুনা ডেটাবেস ব্যবহার করে। দোকান (db-shop): customers (customer_id, name, city, phone, joined_on — ৮ জন, Imran Hossain-এর city NULL), categories, products (product_id, name, category_id, price, stock — ১০টি পণ্য), orders (order_id, customer_id, order_date, status — ১০টি অর্ডার) আর order_items (order_id, product_id, quantity, unit_price). বিশ্ববিদ্যালয় (db-uni): departments (CSE, EEE, BBA, English), instructors (mentor_id নিজের টেবিলকেই নির্দেশ করে), students (student_id, name, dept_id, batch, cgpa — Habib Ullah-এর dept_id আর Fahim Karim-এর cgpa NULL), courses আর enrollments (student_id, course_id, term, grade — একটি grade NULL). প্রতিবার “চালান” চাপলে নতুন করে ডেটা লোড হয়, তাই নির্ভয়ে বদলে দেখুন; এডিটরের নিচের বাক্সে পুরো ডেটা দেখা যায়।
২ · মডিউল ১ — ডেটাবেসের ভিত্তি (১১টি প্রশ্ন)
এই অংশ কোর্সের শব্দভান্ডার: ডেটা বনাম তথ্য, ফাইল-পদ্ধতির সমস্যা, three-schema architecture আর দুই রকম data independence, relation-এর তাত্ত্বিক বৈশিষ্ট্য, আর key-র পরিবার — superkey, candidate key, primary key, foreign key. পরীক্ষায় সবচেয়ে বেশি ভুল হয় দুই জায়গায়: physical আর logical data independence গুলিয়ে ফেলা, আর superkey গোনায় overlap দুবার গোনা।
- পর্ব ০১ · ডেটাবেস কেন আর পর্ব ০২ · ফাইল সিস্টেম বনাম DBMS — ডেটা বনাম তথ্য, redundancy, concurrency আর atomicity-র সমস্যা
- পর্ব ০৩ · DBMS-এর গঠন — তিন স্তর, mapping, physical আর logical data independence, DDL/DML/DCL/TCL
- পর্ব ০৪ · ডেটা মডেল আর পর্ব ০৫ · Relational model — relation, tuple, degree, cardinality, set বনাম multiset
- পর্ব ০৬ · Key আর integrity constraint — superkey গোনা, entity আর referential integrity, ON DELETE action
(সহজ) নিচের কোনটি শুধু “ডেটা” নয়, বরং “তথ্য” (information) — অর্থাৎ প্রক্রিয়া করে প্রসঙ্গসহ অর্থবহ করা হয়েছে?
- 01711000001
- Rahim Uddin, Dhaka, 2025-01-15
- “সেপ্টেম্বরে ঢাকার গ্রাহকেরা গড়ে ৮,৫০০ টাকার কেনাকাটা করেছেন”
- 15000
(সহজ) ফাইলে ডেটা রাখার পুরোনো পদ্ধতির (file-processing system) কোনটি সাধারণত সমস্যা হিসেবে গণ্য হয় না?
- একটি প্রোগ্রাম নিজের বানানো ফাইল কোনো মধ্যস্থ সফটওয়্যার ছাড়াই সরাসরি পড়তে পারে
- একই গ্রাহকের ঠিকানা দুটি ফাইলে দুই রকম লেখা
- দুজন কর্মী একসাথে একই হিসাব বদলালে একজনের কাজ হারিয়ে যাওয়া
- টাকা পাঠানোর মাঝপথে বিদ্যুৎ গেলে এক হিসাব থেকে কাটা, অন্যটিতে জমা না হওয়া
(মাঝারি) DBA একটি টেবিলে নতুন index বানালেন আর ডেটা ফাইলটি অন্য ডিস্কে সরালেন। কোনো application, view বা conceptual schema বদলাতে হলো না। এটি কোন ধারণার উদাহরণ?
- Logical data independence
- Physical data independence
- Referential integrity
- Data redundancy
(কঠিন) three-schema architecture-এ logical data independence সম্পর্কে কোনটি সবচেয়ে সঠিক?
- internal schema বদলালেও conceptual schema অপরিবর্তিত থাকে
- এক DBMS থেকে অন্য DBMS-এ ডেটা কোনো বদল ছাড়াই নেওয়া যায়
- প্রতিটি ব্যবহারকারীর জন্য ডেটার আলাদা কপি রাখা হয়
- conceptual schema বদলালেও (যেমন একটি টেবিল দুই ভাগ করা) external schema আর application অপরিবর্তিত রাখা যায়, external–conceptual mapping বদলে; এটি physical independence-এর চেয়ে কঠিন
(সহজ) SQL-এর GRANT আর REVOKE কোন শ্রেণির কমান্ড?
- DCL (Data Control Language)
- DDL (Data Definition Language)
- DML (Data Manipulation Language)
- TCL (Transaction Control Language)
(মাঝারি) Codd-এর relational model-এর তত্ত্বে কোনটি relation-এর বৈশিষ্ট্য নয়?
- প্রতিটি attribute-এর মান atomic, অর্থাৎ ভাঙা যায় না এমন একক মান
- tuple-গুলোর একটি নির্দিষ্ট ক্রম আছে, আর প্রথম ও দ্বিতীয় tuple-এর অবস্থান আলাদা অর্থ বহন করে
- একই রকম দুটি tuple থাকতে পারে না
- attribute নাম দিয়ে চেনা হয়, তাই তাদের ক্রম অর্থ বদলায় না
(মাঝারি) R(A, B, C, D)-এর একমাত্র candidate key হলো A. R-এর মোট কতটি superkey আছে?
- 1
- 15
- 4
- 8
(কঠিন) R(A, B, C, D)-এর candidate key দুটি: {A} আর {B, C}. মোট কতটি superkey?
- 12
- 8
- 10
- 6
(সহজ) “primary key-এর কোনো attribute-এ NULL রাখা যাবে না” — এই নিয়মের নাম কী?
- Entity integrity
- Referential integrity
- Domain constraint
- Transitive dependency
(মাঝারি) foreign key সম্পর্কে কোনটি সত্য?
- referencing টেবিলে FK-র মান অবশ্যই unique হতে হবে
- FK শুধু অন্য টেবিলের primary key-কেই নির্দেশ করতে পারে
- NOT NULL না লেখা থাকলে FK কলামে NULL রাখা যায়; সেই সারি তখন কোনো সারির দিকে নির্দেশ করে না
- একটি টেবিলে একটির বেশি FK থাকতে পারে না
(মাঝারি) orders.customer_id কলামটি customers(customer_id)-কে নির্দেশ করে, কোনো ON DELETE action লেখা নেই, আর foreign key চেক চালু। customer 5-এর কোনো অর্ডার নেই, customer 1-এর তিনটি অর্ডার আছে। পরপর DELETE FROM customers WHERE customer_id = 5; আর DELETE FROM customers WHERE customer_id = 1; চালালে কী হবে?
- দুটিই সফল, আর customer 1-এর তিনটি অর্ডারও মুছে যায়
- দুটিই সফল, আর তিনটি অর্ডারের customer_id NULL হয়ে যায়
- দুটিই বাতিল হয়
- প্রথমটি সফল (১টি সারি মোছে), দ্বিতীয়টি foreign key ত্রুটিতে বাতিল হয়
-- Tanvir Ahmed (5)-এর কোনো অর্ডার নেই
DELETE FROM customers WHERE customer_id = 5;
-- Rahim Uddin (1)-এর তিনটি অর্ডার আছে
DELETE FROM customers WHERE customer_id = 1;প্রথম DELETE সফল — Tanvir Ahmed-এর (customer_id 5) কোনো অর্ডার নেই, তাই ১টি সারি মোছে। দ্বিতীয়টিতে ত্রুটি আসে: FOREIGN KEY constraint failed. Rahim Uddin-এর তিনটি অর্ডার (1001, 1003, 1009) তাঁকে নির্দেশ করছে, আর ON DELETE action না থাকায় ডিফল্ট NO ACTION মোছা আটকায়। চেষ্টা করুন: দ্বিতীয় DELETE-এর আগে DELETE FROM order_items WHERE order_id IN (1001, 1003, 1009); আর DELETE FROM orders WHERE customer_id = 1; লিখে দেখুন — শিশু সারিগুলো আগে মুছলে তবেই অভিভাবক মোছা যায়।
৩ · মডিউল ২ — ডেটাবেস ডিজাইন (১১টি প্রশ্ন)
ER আর EER মডেল থেকে প্রশ্ন আসে তিন ধরনের: notation চেনা (কোন আকৃতি কী বোঝায়), সম্পর্কের নিয়ম পড়া (cardinality আর participation), আর ER থেকে টেবিলে mapping — বিশেষ করে “ন্যূনতম কয়টি টেবিল” প্রশ্ন। weak entity, specialization-এর disjoint/overlapping আর total/partial, আর aggregation — এগুলোর সংজ্ঞা হুবহু মনে রাখুন।
- পর্ব ০৭ · ER মডেল — entity, attribute-এর ধরন (multivalued, derived, composite), Chen আর crow's foot notation
- পর্ব ০৮ · Cardinality, participation আর weak entity — 1:1, 1:N, M:N, partial key, identifying relationship
- পর্ব ০৯ · EER — specialization, generalization, disjoint/overlapping, aggregation
- পর্ব ১০ · ER থেকে টেবিল আর পর্ব ১১ · ডিজাইন কেস স্টাডি — mapping-এর নিয়ম, subclass-এর তিন রকম mapping
(সহজ) Chen notation-এর ER diagram-এ দুই দাগের ellipse (double ellipse) কী বোঝায়?
- Derived attribute
- Multivalued attribute — যেমন একজন গ্রাহকের একাধিক ফোন নম্বর
- Key attribute
- Weak entity
(মাঝারি) weak entity সম্পর্কে কোনটি সত্য? (উদাহরণ: একটি ঋণের কিস্তি — “কিস্তি নং ৩” শুধু সেই ঋণের ভেতরেই অনন্য।)
- weak entity-র কোনো নিজস্ব attribute থাকে না
- weak entity মানে যে entity-তে খুব কম সারি
- owner entity-র key আর নিজের partial key মিলে একে চেনা যায়, আর identifying relationship-এ এর participation total
- টেবিলে weak entity-র primary key শুধু তার partial key
(মাঝারি) Student আর Course-এর মধ্যে M:N relationship “ভর্তি”, যার একটি attribute grade. relational টেবিলে সবচেয়ে সঠিক রূপ কোনটি?
- নতুন টেবিল enrollment(student_id, course_id, grade), যার primary key (student_id, course_id) আর দুটি কলামই foreign key
- student টেবিলে course_id foreign key আর grade কলাম যোগ করা
- course টেবিলে grade কলাম রাখা
- দুটি entity মিলিয়ে একটি বড় টেবিল বানানো
(সহজ) “একটি বিভাগে অনেক শিক্ষক, কিন্তু প্রত্যেক শিক্ষক একটিই বিভাগের” — টেবিলে এই 1:N সম্পর্ক সাধারণত কীভাবে লেখা হয়?
- departments টেবিলে instructor_id কলাম
- সবসময় আলাদা একটি junction টেবিল লাগে
- দুই টেবিলেই একে অপরের foreign key
- instructors টেবিলে dept_id নামে একটি foreign key কলাম
(কঠিন) entity E1-এর key a1, সাধারণ attribute a2 আর একটি multivalued attribute m. entity E2-এর key b1 আর attribute b2. E1 আর E2-এর মধ্যে M:N relationship R, যার attribute r. প্রতিটি টেবিল অন্তত 1NF-এ রাখতে ন্যূনতম কতটি টেবিল লাগবে?
- 3
- 4
- 2
- 5
(মাঝারি) “প্রত্যেক শিক্ষার্থীর ঠিক একজন advisor থাকতেই হবে; একজন শিক্ষক কারও advisor না-ও হতে পারেন, আবার অনেকের হতে পারেন।” টেবিলে সবচেয়ে সঠিক রূপ?
- students.advisor_id: NULL হতে পারে আর UNIQUE
- instructors টেবিলে student_id কলাম
- শর্ত ছাড়া একটি junction টেবিল advising(student_id, instructor_id)
- students টেবিলে advisor_id কলাম: NOT NULL আর instructors-এর foreign key
(মাঝারি) একজন ব্যক্তি একই সাথে শিক্ষার্থী আর বিশ্ববিদ্যালয়ের কর্মচারী (যেমন TA) হতে পারেন, আর প্রত্যেক ব্যক্তি অন্তত একটি ভূমিকায় আছেন। Person-এর specialization কেমন?
- Disjoint আর total
- Overlapping আর total
- Disjoint আর partial
- Overlapping আর partial
(সহজ) Car আর Truck-এর সাধারণ attribute (রেজিস্ট্রেশন নম্বর, মালিক, রং) মিলিয়ে নিচ থেকে ওপরে একটি superclass Vehicle বানানোর প্রক্রিয়াকে কী বলে?
- Specialization
- Aggregation
- Generalization
- Normalization
(মাঝারি) “শিক্ষক একটি প্রজেক্টে কাজ করেন” — এই relationship-টিকেই আবার “কোন যন্ত্র ব্যবহৃত হলো” relationship-এ অংশ নিতে হবে। EER-এর কোন ধারণা এটি আঁকতে দেয়?
- Aggregation
- Specialization
- Weak entity
- Multivalued attribute
(কঠিন) Vehicle superclass-এর specialization {Car, Truck} total আর disjoint; দুটি subclass-এর অনেক আলাদা attribute, আর প্রায় সব কোয়েরি একটি subclass নিয়েই। NULL এড়াতে আর subclass-কোয়েরিতে join এড়াতে কোন mapping সবচেয়ে উপযুক্ত?
- discriminator কলামসহ একটি বড় টেবিল
- superclass টেবিল আর প্রতিটি subclass-এর টেবিল, subclass-এর PK একই সাথে FK
- শুধু Vehicle টেবিল, subclass-এর attribute বাদ
- প্রতিটি subclass-এর জন্য একটি টেবিল, যাতে superclass-এর attribute-ও আছে (car, truck)
(কঠিন) ternary relationship Supplies(supplier, part, project)-কে তিনটি binary relationship-এ (supplier–part, part–project, supplier–project) ভেঙে ফেললে সাধারণত কী হয়?
- তথ্য হারাতে পারে: তিনটি জোড়া থেকে বলা যায় না কোন supplier কোন part কোন project-কে দিয়েছে
- কিছুই বদলায় না, তিনটি binary সবসময় ternary-র সমান
- শুধু টেবিলের সংখ্যা বাড়ে, তথ্য একই থাকে
- এটি normalization-এর বাধ্যতামূলক ধাপ
৪ · মডিউল ৩ — SQL-এর ভিত্তি (১৩টি প্রশ্ন)
চাকরির পরীক্ষায় সবচেয়ে বেশি প্রশ্ন আসে এই মডিউল থেকে, আর সবচেয়ে বেশি নম্বর হারায়ও এখানে — কারণ প্রায় প্রতিটি ফাঁদের কেন্দ্রে একটি NULL. তিন-মানের যুক্তি (TRUE, FALSE, UNKNOWN), LEFT JOIN-এর NULL-সারি, GROUP BY আর HAVING, anti join-এর নিরাপদ রূপ, আর UNION-এর পুনরাবৃত্তি সরানো — প্রতিটি প্রশ্নের পরে একটি লাইভ এডিটর আছে। উত্তর দিয়ে চালান, তারপর ডেটা বা শর্ত একটু বদলে নিজে নতুন প্রশ্ন বানান।
- পর্ব ১২ · SQL পরিচিতি, পর্ব ১৩ · CREATE TABLE আর পর্ব ১৪ · INSERT, UPDATE আর DELETE — DELETE, TRUNCATE আর DROP
- পর্ব ১৫ · SELECT আর পর্ব ১৬ · অপারেটর, CASE আর NULL — যুক্তিগত ক্রম, AND/OR-এর অগ্রাধিকার, তিন-মানের যুক্তি
- পর্ব ১৭ · SQL ফাংশন আর পর্ব ১৮ · GROUP BY আর HAVING — COUNT-এর তিন রূপ, aggregate আর NULL
- পর্ব ১৯ · JOIN আর পর্ব ২০ · Self, cross, semi আর anti join — ON বনাম WHERE, NULL-সারি
- পর্ব ২১ · Subquery, পর্ব ২২ · UNION, INTERSECT আর EXCEPT আর পর্ব ২৩ · ALTER TABLE আর referential action
(সহজ) SELECT কোয়েরির যুক্তিগত (logical) প্রক্রিয়াকরণ ক্রম কোনটি?
- SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
- FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
- FROM → GROUP BY → WHERE → HAVING → SELECT → ORDER BY → LIMIT
- FROM → WHERE → SELECT → GROUP BY → HAVING → ORDER BY → LIMIT
(মাঝারি) orders টেবিল থেকে শুধু সেই গ্রাহকদের customer_id আর অর্ডার-সংখ্যা চাই, যাদের অর্ডার ২টির বেশি। কোনটি ঠিক?
SELECT customer_id, COUNT(*) FROM orders WHERE COUNT(*) > 2 GROUP BY customer_id;SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id ORDER BY COUNT(*) > 2;SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id HAVING COUNT(*) > 2;SELECT customer_id, COUNT(*) FROM orders WHERE customer_id > 2 GROUP BY customer_id;
(সহজ) customers টেবিলে ৮টি সারি; তার মধ্যে ঠিক একটির city NULL. SELECT COUNT(*) FROM customers WHERE city = NULL; কী দেয়?
- 0
- 1
- 8
- syntax error
(মাঝারি) একই customers টেবিলে city-র মানগুলো: Dhaka, Chattogram, Dhaka, Rajshahi, Khulna, Sylhet, NULL, Dhaka. SELECT COUNT(*), COUNT(city), COUNT(DISTINCT city) FROM customers; কী দেয়?
- 8, 8, 6
- 7, 7, 5
- 8, 7, 6
- 8, 7, 5
-- = NULL বনাম IS NULL
SELECT COUNT(*) AS eq_null FROM customers WHERE city = NULL;
SELECT COUNT(*) AS is_null FROM customers WHERE city IS NULL;
-- তিন রকম COUNT
SELECT COUNT(*) AS all_rows, COUNT(city) AS with_city,
COUNT(DISTINCT city) AS cities
FROM customers;
-- NULL-এর তুলনা নিজেই NULL (UNKNOWN)
SELECT NULL = NULL AS eq, NULL IS NULL AS is_n;চারটি ফল: eq_null = 0, is_null = 1; তারপর 8 | 7 | 5; আর শেষ লাইনে NULL | 1. শেষেরটিই পুরো রহস্যের চাবি: NULL = NULL-এর ফল TRUE নয়, NULL (অর্থাৎ UNKNOWN) — দুটি “অজানা” মান সমান কি না, তাও অজানা। WHERE শুধু TRUE রাখে, তাই = NULL কখনো কোনো সারি দেয় না। COUNT(city) আর COUNT(DISTINCT city) দুটিই Imran Hossain-এর NULL city বাদ দেয়; Dhaka তিনবার থাকলেও DISTINCT-এ একবার।
(কঠিন) students টেবিলের dept_id কলামের ৮টি মান: 1, 1, 2, 1, 3, 2, 1, NULL. কোয়েরি X: SELECT COUNT(*) FROM students WHERE dept_id NOT IN (1); আর কোয়েরি Y: … WHERE dept_id NOT IN (1, NULL); — দুটির ফল?
- X = 4, Y = 4
- X = 3, Y = 0
- X = 4, Y = 3
- X = 3, Y = 3
-- NOT IN আর NULL
SELECT COUNT(*) AS not_in_1 FROM students WHERE dept_id NOT IN (1);
SELECT COUNT(*) AS not_in_1_null FROM students WHERE dept_id NOT IN (1, NULL);
-- NOT EXISTS: NULL dept_id-এর শিক্ষার্থীকেও ধরে
SELECT COUNT(*) AS not_exists FROM students s
WHERE NOT EXISTS (SELECT 1 FROM departments d
WHERE d.dept_id = s.dept_id AND d.dept_id = 1);তিনটি ফল: 3, 0, 4. প্রথমটিতে Habib Ullah (dept_id NULL) বাদ পড়েছেন, কারণ NULL <> 1 UNKNOWN. দ্বিতীয়টিতে x NOT IN (1, NULL) মানে x <> 1 AND x <> NULL — দ্বিতীয় অংশ সবসময় UNKNOWN, তাই কোনো সারিই TRUE নয়। subquery-র ফলে একটি NULL ঢুকে গেলেই ঠিক এটা ঘটে, আর কোনো ত্রুটি দেখায় না। তৃতীয়টি NOT EXISTS: “এই শিক্ষার্থীর বিভাগ 1 — এমন কোনো সারি আছে কি?” Habib-এর জন্য নেই, তাই তিনিও গোনা হন — 4.
(কঠিন) customers-এ ৮ জন, orders-এ ১০টি অর্ডার। delivered অর্ডার ৫টি: Rahim-এর ১টি, Karima-র ২টি, Nusrat-এর ১টি, Imran-এর ১টি। কোয়েরি X: FROM customers c LEFT JOIN orders o ON o.customer_id = c.customer_id AND o.status = 'delivered', কোয়েরি Y: … LEFT JOIN orders o ON o.customer_id = c.customer_id WHERE o.status = 'delivered' — দুটিই SELECT COUNT(*). ফল?
- X = 5, Y = 5
- X = 9, Y = 9
- X = 9, Y = 5
- X = 5, Y = 9
-- শর্ত না থাকলে: সব গ্রাহক, অর্ডারহীনরা NULL-সহ
SELECT COUNT(*) AS left_rows FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id;
-- শর্ত ON-এ
SELECT COUNT(*) AS cond_in_on FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id AND o.status = 'delivered';
-- শর্ত WHERE-এ
SELECT COUNT(*) AS cond_in_where FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.status = 'delivered';তিনটি ফল: 11, 9, 5. শর্ত ছাড়া LEFT JOIN-এ ১০টি অর্ডার-সারি আর অর্ডারহীন Tanvir-এর একটি NULL-সারি: 11. শর্ত ON-এ দিলে প্রত্যেক গ্রাহক থাকেন — delivered অর্ডার না থাকলে NULL-সহ একটি সারি: Rahim 1, Karima 2, Nusrat 1, Imran 1, আর Sabbir, Tanvir, Farhana, Mitu একটি করে — 9. WHERE-এ দিলে join-এর পর NULL status-এর সারিগুলো ছাঁকা পড়ে, থাকে শুধু ৫টি delivered অর্ডার — ফল INNER JOIN-এর সমান।
(কঠিন) departments-এ চারটি বিভাগ (CSE, EEE, BBA, English); English বিভাগে কোনো শিক্ষার্থী নেই। FROM departments d LEFT JOIN students s ON s.dept_id = d.dept_id GROUP BY d.dept_id-এর সাথে একবার COUNT(*) আর একবার COUNT(s.student_id) নিলে English-এর সারিতে কী আসে?
- দুটিই 0
- COUNT(*) = 1, COUNT(s.student_id) = 0
- দুটিই 1
- COUNT(*) = NULL, COUNT(s.student_id) = 0
-- বিভাগভিত্তিক শিক্ষার্থী: দুই রকম COUNT
SELECT d.name,
COUNT(*) AS count_star,
COUNT(s.student_id) AS count_col
FROM departments d
LEFT JOIN students s ON s.dept_id = d.dept_id
GROUP BY d.dept_id
ORDER BY d.dept_id;চারটি সারি: CSE | 4 | 4, EEE | 2 | 2, BBA | 1 | 1, English | 1 | 0. শুধু English-এ দুটি কলাম আলাদা। LEFT JOIN English-এর জন্য একটি সারি রেখেছে, যার students-এর সব কলাম NULL; COUNT(*) সেই সারিটি গুনেছে। “বিভাগে কতজন শিক্ষার্থী” প্রশ্নে তাই সবসময় ডান টেবিলের কোনো NOT NULL কলাম (এখানে s.student_id) গুনুন। Habib Ullah-এর বিভাগ NULL, তাই তিনি কোনো বিভাগেই গোনা হননি।
(সহজ) কোন কমান্ড টেবিলের সব সারির সাথে টেবিলের গঠন (definition) নিজেও মুছে দেয়?
DELETE FROM t;(WHERE ছাড়া)TRUNCATE TABLE t;DROP TABLEDELETE FROM t WHERE 1 = 1;
(মাঝারি) কোন পণ্য কখনো অর্ডার হয়নি — নিচের কোনটি সবসময় সঠিক ফল দেয়, এমনকি order_items.product_id-এ কোনো NULL থাকলেও?
SELECT p.name FROM products p WHERE NOT EXISTS (SELECT 1 FROM order_items oi WHERE oi.product_id = p.product_id);… WHERE p.product_id NOT IN (SELECT product_id FROM order_items);… FROM products p JOIN order_items oi ON oi.product_id = p.product_id WHERE oi.product_id IS NULL;… FROM products p LEFT JOIN order_items oi ON oi.product_id = p.product_id WHERE oi.product_id = NULL;
(মাঝারি) customers-এর city মানগুলো: Dhaka, Chattogram, Dhaka, Rajshahi, Khulna, Sylhet, NULL, Dhaka. SELECT city FROM customers UNION SELECT 'Dhaka'; কয়টি সারি দেয়?
- 5
- 9
- 7
- 6
-- UNION: পুনরাবৃত্তি সরায়, NULL একবার থাকে
SELECT city FROM customers
UNION
SELECT 'Dhaka';
-- UNION ALL: সব রাখে
SELECT COUNT(*) AS union_all_rows FROM (
SELECT city FROM customers UNION ALL SELECT 'Dhaka'
);প্রথম কোয়েরিতে ৬টি সারি: একটি NULL, আর Chattogram, Dhaka, Khulna, Rajshahi, Sylhet (SQLite এখানে পুনরাবৃত্তি সরাতে মানগুলো সাজিয়েছে, কিন্তু ORDER BY ছাড়া ক্রমের ওপর ভরসা করবেন না)। দ্বিতীয় কোয়েরি: 9 — UNION ALL ৮টি city আর একটি 'Dhaka' সবই রাখে। মনে রাখুন: তুলনায় NULL = NULL UNKNOWN, কিন্তু পুনরাবৃত্তি সরানোর সময় (UNION, DISTINCT, GROUP BY) দুটি NULL-কে একই দলে ধরা হয় — standard-এর ভাষায় তারা “not distinct”.
(মাঝারি) ১০টি অর্ডারের মধ্যে delivered ৫টি (তার ২টি অক্টোবরের ১ তারিখ বা পরে), shipped ২টি (১টি অক্টোবরে), বাকিগুলো pending বা cancelled. SELECT COUNT(*) FROM orders WHERE status = 'delivered' OR status = 'shipped' AND order_date >= '2025-10-01'; কী দেয়?
- 3
- 6
- 7
- 2
-- বন্ধনী ছাড়া: AND আগে বাঁধে
SELECT COUNT(*) AS no_paren FROM orders
WHERE status = 'delivered' OR status = 'shipped'
AND order_date >= '2025-10-01';
-- বন্ধনীসহ: যা সম্ভবত চাওয়া হয়েছিল
SELECT COUNT(*) AS with_paren FROM orders
WHERE (status = 'delivered' OR status = 'shipped')
AND order_date >= '2025-10-01';দুটি ফল: 6 আর 3. বন্ধনী ছাড়া DBMS পড়ে status = 'delivered' OR (status = 'shipped' AND order_date >= '2025-10-01') — ৫টি delivered আর অক্টোবরের shipped 1008. বন্ধনী দিলে অক্টোবরের তিনটি: 1007, 1010 (delivered) আর 1008 (shipped). AND আর OR মেশালে সবসময় বন্ধনী দিন — পড়ার সুবিধাও, ভুলের সম্ভাবনাও কম।
(মাঝারি) students টেবিলের ৮ জনের cgpa: 3.75, 3.40, 2.95, 3.90, 3.10, NULL, 3.55, 2.80. SELECT ROUND(AVG(cgpa), 2) FROM students; কী দেয়?
- 2.93
- NULL
- 3.35
- ত্রুটি
-- AVG NULL বাদ দেয়; SUM/COUNT(*) দিয়ে ভাগ করলে আলাদা উত্তর
SELECT ROUND(AVG(cgpa), 2) AS avg_cgpa,
COUNT(cgpa) AS n_with_cgpa,
ROUND(SUM(cgpa) / COUNT(*), 2) AS avg_over_all
FROM students;ফল: 3.35 | 7 | 2.93. AVG শুধু ৭টি অ-NULL cgpa-র গড় নেয় (Fahim Karim-এর cgpa NULL). SUM / COUNT(*) আটজনে ভাগ করে, যেন NULL মানে 0 — উত্তর বদলে যায়। কোনটি ঠিক, তা প্রশ্নের অর্থের ওপর নির্ভর করে; “ফল আসেনি” মানে 0 নয়, তাই এখানে AVG-ই অর্থপূর্ণ।
(কঠিন) enrollments টেবিলে ১৩টি সারি; grade কলামে ৪টি 'A', ১টি NULL (ফল আসেনি), বাকিগুলো অন্য grade. SELECT COUNT(*) FROM enrollments WHERE grade <> 'A'; কী দেয়?
- 9
- 13
- 4
- 8
-- <> NULL-সারি বাদ দেয়
SELECT COUNT(*) AS not_a FROM enrollments WHERE grade <> 'A';
-- IS NOT (SQLite) = IS DISTINCT FROM (standard): NULL-ও ধরে
SELECT COUNT(*) AS not_a_or_null FROM enrollments WHERE grade IS NOT 'A';দুটি ফল: 8 আর 9. ১৩টি ভর্তির ৪টিতে 'A', আর Dilruba Khatun-এর 2024-Fall-এর CSE301-এ grade NULL. <> সেই NULL-সারি বাদ দেয়; IS NOT (SQLite-এর রূপ, standard-এ IS DISTINCT FROM) NULL-কেও “A নয়” ধরে — তাই এক বেশি।
কঠিন প্রশ্নের ভেতরে — NOT IN কেন NULL পেলে চুপ হয়ে যায়
NOT IN-এর ফাঁদটি এত বেশি প্রশ্নে আর এত বেশি বাস্তব bug-এ আসে যে প্রতিটি সারির জন্য যুক্তিটি একবার নিজের হাতে চালিয়ে দেখা দরকার। নিচের ডায়াগ্রামে dept_id NOT IN (1, NULL) শর্তটি তিনটি আলাদা সারিতে ধাপে ধাপে মূল্যায়ন করা হয়েছে।
x NOT IN (1, NULL)
≡ NOT (x = 1 OR x = NULL)
≡ x <> 1 AND x <> NULL ← De Morgan
দ্বিতীয় অংশ x <> NULL — যেকোনো x-এর জন্য UNKNOWN
2 <> 1 → TRUE
2 <> NULL → UNKNOWN
TRUE AND UNKNOWN = UNKNOWN
WHERE শুধু TRUE রাখে → সারিটি বাদ
1 <> 1 → FALSE
1 <> NULL → UNKNOWN
FALSE AND UNKNOWN = FALSE
(একটি FALSE থাকলেই AND মিথ্যা) → বাদ
NULL <> 1 → UNKNOWN
NULL <> NULL → UNKNOWN
UNKNOWN AND UNKNOWN = UNKNOWN → বাদ
AND-এর সারণি: T∧U = U F∧U = F U∧U = U
আটটি সারির কোনোটিই TRUE নয় → ফল 0
-- ১) NOT EXISTS: শুধু “মিলেছে কি না”, NULL-এ অন্ধ নয় WHERE NOT EXISTS (SELECT 1 FROM t WHERE t.id = s.dept_id) -- ২) subquery থেকে NULL বাদ দিয়ে তারপর NOT IN WHERE dept_id NOT IN (SELECT id FROM t WHERE id IS NOT NULL) -- ৩) বাইরের NULL-সারিও চাইলে আলাদা করে বলুন: -- … OR dept_id IS NULL
- NOT IN আসলে কয়েকটি <>-এর AND.
x NOT IN (1, NULL)মানে “x, 1-ও নয়, NULL-ও নয়”:x <> 1 AND x <> NULL. দ্বিতীয় তুলনাটি যেকোনো x-এর জন্য UNKNOWN — কারণ অজানা মানের সাথে তুলনার ফলও অজানা। - dept_id = 2: প্রথম অংশ TRUE, দ্বিতীয় UNKNOWN. TRUE AND UNKNOWN-এর ফল UNKNOWN — পুরোটা সত্য কি না, নির্ভর করছে অজানা অংশের ওপর। WHERE শুধু TRUE সারি রাখে, তাই Chayon Roy বাদ, যদিও তাঁর বিভাগ সত্যিই 1 নয়।
- dept_id = 1: একটি FALSE-ই যথেষ্ট। 1 <> 1 FALSE, আর FALSE AND যা-ই হোক, ফল FALSE. এই সারি বাদ পড়ারই কথা ছিল — এখানে কোনো চমক নেই।
- dept_id = NULL: দুটিই UNKNOWN. UNKNOWN AND UNKNOWN = UNKNOWN, তাই বাদ। ফলে কোনো সারিই TRUE নয় — উত্তর 0. বাস্তবে তালিকাটি প্রায়ই একটি subquery, আর তার কলামে একটি NULL ঢুকলেই রিপোর্ট চুপচাপ ফাঁকা হয়ে যায়; কোনো ত্রুটি দেখায় না।
- নিরাপদ বিকল্প দুটি। NOT EXISTS প্রতিটি সারির জন্য শুধু জিজ্ঞেস করে “মেলে এমন সারি আছে কি?” — উত্তর সবসময় TRUE বা FALSE. অথবা subquery-তে
IS NOT NULLদিয়ে NULL বাদ দিন। বাইরের টেবিলের NULL-সারিটিও ফলে চাইলে সেটি আলাদা শর্তে বলতে হবে — NULL “1 নয়” কি না, SQL নিজে থেকে ধরে নেয় না।
৫ · মডিউল ৪ — উন্নত SQL (১১টি প্রশ্ন)
view আর materialized view-এর পার্থক্য, WITH CHECK OPTION, window function-এর RANK আর DENSE_RANK, ডিফল্ট window frame-এর টাই, recursive CTE-এর থামার শর্ত, trigger আর stored procedure, আর DBMS-ভেদে লেখার পার্থক্য। ইন্টারভিউতে “প্রতি দলে top-N” প্যাটার্নটি প্রায় নিশ্চিতভাবে আসে — window function কোথায় চলে আর কোথায় চলে না, সেটিই আসল প্রশ্ন।
- পর্ব ২৪ · View আর materialized view — updatable view, WITH CHECK OPTION, refresh
- পর্ব ২৫ · CTE আর recursive query — anchor, recursive অংশ, fixpoint
- পর্ব ২৬ · Window function আর পর্ব ২৭ · প্রচলিত প্যাটার্ন — ROW_NUMBER/RANK/DENSE_RANK, RANGE বনাম ROWS, top-N
- পর্ব ২৮ · Stored procedure আর পর্ব ২৯ · Trigger — row-level বনাম statement-level
- পর্ব ৩০ · JSON আর full-text search আর পর্ব ৩১ · SQL-এর উপভাষা — jsonb, LIMIT/TOP/FETCH, || বনাম CONCAT
(সহজ) সাধারণ view আর materialized view সম্পর্কে কোনটি সত্য?
- সাধারণ view ফল জমা রাখে না, প্রতিবার নিচের টেবিল থেকে হিসাব হয়; materialized view ফল জমা রাখে, তাই refresh না করা পর্যন্ত পুরোনো থাকতে পারে
- সাধারণ view ডেটার আলাদা কপি রাখে
- materialized view সবসময় নিচের টেবিলের সাথে সাথে বদলায়
- view-কে JOIN-এ ব্যবহার করা যায় না
(মাঝারি) CREATE VIEW dhaka_customers AS SELECT * FROM customers WHERE city = 'Dhaka' WITH CHECK OPTION; — এই view দিয়ে city = 'Sylhet' দিয়ে একটি গ্রাহক INSERT করলে কী হয় (যে DBMS-এ view-টি updatable, যেমন PostgreSQL বা MySQL)?
- সারি ঢোকে আর view-তেও দেখা যায়
- INSERT বাতিল হয়, কারণ নতুন সারি view-এর শর্ত মানে না
- সারি নিচের টেবিলে ঢোকে, কিন্তু view-তে দেখা যায় না
- view-এর শর্ত বদলে Sylhet হয়ে যায়
(মাঝারি) চারটি নম্বর 90, 85, 85, 70 — বড় থেকে ছোট ক্রমে RANK() আর DENSE_RANK() নিলে 70-এর মান কত?
- RANK = 3, DENSE_RANK = 3
- RANK = 4, DENSE_RANK = 4
- RANK = 3, DENSE_RANK = 4
- RANK = 4, DENSE_RANK = 3
-- টাই থাকলে তিন ranking ফাংশন
WITH s(score) AS (VALUES (90), (85), (85), (70))
SELECT score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS rn,
RANK() OVER (ORDER BY score DESC) AS rnk,
DENSE_RANK() OVER (ORDER BY score DESC) AS drnk
FROM s;চারটি সারি: 90 | 1 | 1 | 1, 85 | 2 | 2 | 2, 85 | 3 | 2 | 2, 70 | 4 | 4 | 3. ROW_NUMBER টাই ভাঙে (দুটি 85-এর কোনটি 2, কোনটি 3, তা ORDER BY-তে আরেকটি কলাম না দিলে নিশ্চিত নয়); RANK টাই রাখে আর ফাঁক দেয়; DENSE_RANK টাই রাখে, ফাঁক দেয় না।
(কঠিন) মানগুলো 10, 20, 20, 30. SELECT x, SUM(x) OVER (ORDER BY x) FROM t; — প্রথম 20-এর সারিতে যোগফল কত (কোনো frame লেখা নেই)?
- 50
- 30
- 80
- 20
-- ডিফল্ট frame (RANGE) বনাম ROWS
WITH t(x) AS (VALUES (10), (20), (20), (30))
SELECT x,
SUM(x) OVER (ORDER BY x) AS range_default,
SUM(x) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) AS rows_frame
FROM t;চারটি সারি: 10 | 10 | 10, 20 | 50 | 30, 20 | 50 | 50, 30 | 80 | 80. ডিফল্ট RANGE frame-এ দুটি 20 পরস্পরের peer, তাই দুটি সারিতেই 50. running total-এ টাই থাকলে ROWS লিখুন, আর ক্রম নিশ্চিত করতে ORDER BY-তে একটি অনন্য কলাম যোগ করুন।
(মাঝারি) WITH RECURSIVE n(x) AS (SELECT 1 UNION ALL SELECT x * 2 FROM n WHERE x < 50) SELECT COUNT(*), MAX(x) FROM n; কী দেয়?
- 6 টি সারি, সর্বোচ্চ 32
- অসীম লুপ
- 7 টি সারি, সর্বোচ্চ 64
- 7 টি সারি, সর্বোচ্চ 32
-- শর্ত দেখা হয় আগের সারিতে
WITH RECURSIVE n(x) AS (
SELECT 1 -- anchor
UNION ALL
SELECT x * 2 FROM n WHERE x < 50 -- recursive অংশ
)
SELECT COUNT(*) AS rows_made, MAX(x) AS biggest FROM n;ফল: 7 | 64. recursive অংশ প্রতিবার আগের ধাপের সারি থেকে নতুন সারি বানায়: 1 → 2 → 4 → 8 → 16 → 32 → 64. 64-এর ধাপে শর্ত x < 50 মিথ্যা, নতুন সারি আসে না, recursion থামে। 50-এর বেশি কিছু না চাইলে বাইরের কোয়েরিতে WHERE x <= 50 দিন, বা শর্তটি লিখুন x * 2 <= 50.
(মাঝারি) instructors(name, dept_id, salary) থেকে প্রতিটি বিভাগের সবচেয়ে বেশি বেতনের ২ জন চাই। কোন পদ্ধতি ঠিক?
- সরাসরি
WHERE ROW_NUMBER() OVER (…) <= 2 GROUP BY dept_id ORDER BY salary DESC LIMIT 2SELECT dept_id, MAX(salary) FROM instructors GROUP BY dept_id- CTE বা subquery-তে
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn, তারপর বাইরের কোয়েরিতেWHERE rn <= 2
(মাঝারি) একটি UPDATE ৫টি সারি বদলাল। FOR EACH ROW AFTER UPDATE trigger কতবার চলবে, আর statement-level (FOR EACH STATEMENT) AFTER UPDATE trigger কতবার?
- row-level ১ বার, statement-level ৫ বার
- দুটিই ৫ বার
- row-level ৫ বার, statement-level ১ বার
- দুটিই ১ বার
(মাঝারি) stored procedure ব্যবহারের সবচেয়ে ভারসাম্যপূর্ণ মূল্যায়ন কোনটি?
- অ্যাপ আর ডেটাবেসের মধ্যে আসা-যাওয়া (round trip) কমায় আর নিয়ম এক জায়গায় রাখে, কিন্তু ভাষা DBMS-ভেদে আলাদা — vendor lock-in, আর version control ও testing-এ বাড়তি যত্ন লাগে
- stored procedure ব্যবহার করলে SQL injection স্বয়ংক্রিয়ভাবে অসম্ভব
- stored procedure যেকোনো সাধারণ কোয়েরির চেয়ে সবসময় দ্রুত
- সব DBMS-এ একই stored procedure ভাষা চলে
(সহজ) ফলের প্রথম ৫টি সারি — কোন লেখা PostgreSQL, MySQL আর SQLite তিনটিতেই চলে, কিন্তু SQL Server-এ চলে না?
SELECT TOP 5 …… ORDER BY price DESC LIMIT 5… FETCH FIRST 5 ROWS ONLY… WHERE ROWNUM <= 5
(মাঝারি) কোন DBMS-এর ডিফল্ট সেটিংয়ে 'Dhaka' || ' City' দুটি string জোড়া দেয় না?
- MySQL
- PostgreSQL
- SQLite
- Oracle
(কঠিন) PostgreSQL-এ json আর jsonb টাইপের পার্থক্য সম্পর্কে কোনটি সত্য?
- json কোয়েরিতে দ্রুত, কারণ পার্স করা থাকে
- jsonb পার্স করে binary রূপে রাখে: whitespace আর key-এর ক্রম রাখে না, একই key দুবার থাকলে শেষটি রাখে, আর GIN index দিয়ে দ্রুত খোঁজা যায়; json লেখাটি হুবহু text হিসেবে রাখে
- jsonb whitespace আর key-এর ক্রম হুবহু রাখে
- শুধু json কলামে index বানানো যায়
৬ · মডিউল ৫ — relational algebra আর normalization (১৪টি প্রশ্ন)
বিশ্ববিদ্যালয়ের পরীক্ষায় এই মডিউলের ওজন সবচেয়ে বেশি, আর এর প্রায় প্রতিটি প্রশ্ন একটি নির্দিষ্ট পদ্ধতি দিয়ে নিশ্চিতভাবে সমাধান করা যায়। relational algebra-য় σ আর π, set বনাম bag semantics, division; তারপর functional dependency, Armstrong-এর axiom, canonical cover, আর normal form — 2NF, 3NF, BCNF আর 4NF. decomposition-এর দুই গুণ, lossless join আর dependency preservation, আলাদা করে মনে রাখুন।
- পর্ব ৩২ · Relational algebra — select, project আর set অপারেশন আর পর্ব ৩৩ · join আর division — মৌলিক বনাম derived অপারেটর
- পর্ব ৩৪ · Relational calculus — tuple আর domain calculus, safe expression, Codd-এর theorem
- পর্ব ৩৫ · Functional dependency — closure, candidate key খোঁজা, canonical cover
- পর্ব ৩৬ · Normalization — 1NF, 2NF আর 3NF আর পর্ব ৩৭ · BCNF, 4NF, 5NF — lossless পরীক্ষা, dependency preservation, MVD
- পর্ব ৩৮ · Denormalization — কখন আর কীভাবে নিয়ম ভাঙবেন
(সহজ) relational algebra-য় σ (select) আর π (project)-এর কাজ কী?
- σ কলাম বাছে, π সারি বাছে
- দুটিই সারি বাছে, শুধু π পুনরাবৃত্তি রাখে
- σ দুই টেবিল জোড়ে, π সাজায়
- σ শর্ত মেনে সারি (tuple) বাছে, π কলাম (attribute) বাছে
(মাঝারি) R(A, B)-এ তিনটি tuple: (1, x), (1, y), (2, x). relational algebra-র πA(R)-এ কয়টি tuple, আর SQL-এ SELECT A FROM R;-এ কয়টি সারি?
- দুটিতেই 3
- দুটিতেই 2
- πA(R)-এ 2, SQL-এ 3
- πA(R)-এ 3, SQL-এ 2
-- SQL: bag semantics — পুনরাবৃত্তি থাকে
SELECT a FROM r;
-- relational algebra-র π-এর মতো: set semantics
SELECT DISTINCT a FROM r;প্রথম কোয়েরিতে তিনটি সারি 1, 1, 2; দ্বিতীয়টিতে দুটি: 1, 2. SQL টেবিল multiset (bag), তাই SELECT পুনরাবৃত্তি রাখে; relational algebra-র π-এর set ফল পেতে DISTINCT লাগে। পুনরাবৃত্তি সরানো ব্যয়বহুল (sort বা hash লাগে), তাই SQL ডিফল্টে তা করে না।
(মাঝারি) relational algebra-র কোন অপারেটরটি মৌলিক (fundamental) নয়, অর্থাৎ অন্যগুলো দিয়ে প্রকাশ করা যায়?
- ∩ (intersection)
- − (set difference)
- × (Cartesian product)
- ∪ (union)
(কঠিন) Enrolled(sid, cid) = {(1, a), (1, b), (2, a), (3, a), (3, b), (3, c)} আর Req(cid) = {a, b}. Enrolled ÷ Req কী?
- {1}
- {1, 3}
- {1, 2, 3}
- {3}
-- division: দুই স্তরের NOT EXISTS
-- “এমন কোনো দরকারি কোর্স নেই, যা এই শিক্ষার্থী নেননি”
SELECT DISTINCT e.sid FROM enrolled e
WHERE NOT EXISTS (
SELECT 1 FROM req r
WHERE NOT EXISTS (SELECT 1 FROM enrolled e2
WHERE e2.sid = e.sid AND e2.cid = r.cid))
ORDER BY e.sid;
-- আরেক পথ: গুনে মেলানো
SELECT sid FROM enrolled WHERE cid IN (SELECT cid FROM req)
GROUP BY sid HAVING COUNT(DISTINCT cid) = (SELECT COUNT(*) FROM req);দুটি কোয়েরিই দেয় 1 আর 3. প্রথমটি division-এর সংজ্ঞার সরাসরি অনুবাদ: “Req-এ এমন কোনো কোর্স নেই, যা এই sid নেয়নি” — দুটি না-বাচক মিলে “সবগুলো নিয়েছে”। দ্বিতীয়টি গুনে মেলায়: দরকারি কোর্সের মধ্যে কয়টি নিয়েছে, আর তা মোট দরকারি কোর্সের সমান কি না। দ্বিতীয় পদ্ধতিতে DISTINCT ভুলবেন না — একই কোর্স দুবার থাকলে গণনা বেড়ে যেত।
(মাঝারি) Codd-এর theorem অনুযায়ী relational algebra আর relational calculus-এর সম্পর্ক কী?
- calculus বেশি শক্তিশালী, কারণ তাতে ∀ আছে
- algebra বেশি শক্তিশালী, কারণ তা procedural
- relational algebra আর safe relational calculus (tuple বা domain)-এর প্রকাশ-ক্ষমতা সমান
- দুটি সম্পর্কহীন, একটির কোয়েরি অন্যটিতে লেখা যায় না
(কঠিন) R(A, B, C, D, E)-এ FD-র সেট F = {A → B, B → C, CD → E}. R-এর candidate key কোনটি?
- A
- CD
- ACD
- AD
(কঠিন) R(A, B, C, D)-এ F = {A → B, B → C, C → A}. R-এর কয়টি candidate key?
- 3 টি: AD, BD, CD
- 1 টি: ABCD
- 1 টি: AD
- 3 টি: A, B, C
(কঠিন) R(A, B, C, D)-এ F = {AB → C, C → D}. R সর্বোচ্চ কোন normal form-এ আছে?
- 1NF
- 3NF
- 2NF
- BCNF
(মাঝারি) একটি relation 1NF-এ আছে, আর এর প্রতিটি candidate key একটিমাত্র attribute নিয়ে গঠিত। এটি নিশ্চিতভাবে কোন normal form-এ?
- অন্তত 3NF
- BCNF
- 1NF-এর বেশি কিছু বলা যায় না
- অন্তত 2NF
(কঠিন) R(A, B, C)-এ F = {A → B, B → C}. কোন decomposition একসাথে lossless আর dependency-preserving?
- {AB, AC}
- {AB, BC}
- {AC, BC}
- {A, B, C}
(মাঝারি) 3NF আর BCNF decomposition-এর নিশ্চয়তা সম্পর্কে কোনটি সত্য?
- BCNF-এ দুটিই সবসময় পাওয়া যায়
- 3NF decomposition কখনো কখনো lossy হতেই হয়
- 3NF-এ সবসময় lossless আর dependency-preserving decomposition পাওয়া যায়; BCNF-এ lossless পাওয়া যায়, কিন্তু dependency preservation সবসময় সম্ভব নয়
- কোনোটিতেই lossless নিশ্চিত নয়
(মাঝারি) Armstrong-এর তিনটি মৌলিক axiom-এর মধ্যে কোনটি পড়ে না?
- Reflexivity: Y ⊆ X হলে X → Y
- Augmentation: X → Y হলে XZ → YZ
- Transitivity: X → Y আর Y → Z হলে X → Z
- Union: X → Y আর X → Z থেকে X → YZ
(কঠিন) F = {A → BC, B → C, A → B, AB → C}-এর canonical (minimal) cover কোনটি?
- {A → BC, B → C}
- {A → B, B → C}
- {A → B, B → C, A → C}
- {AB → C, A → B}
(মাঝারি) একজন শিক্ষক একাধিক বিষয় পড়ান আর একাধিক ভাষায় কথা বলেন, যা পরস্পর স্বাধীন। টেবিল (teacher, subject, language)-এ প্রতিটি জোড়ার সব সংমিশ্রণ রাখা হলো, আর তিনটি কলাম মিলে key. কোন normal form ভাঙে?
- 4NF
- BCNF
- 2NF
- কোনোটিই না
৭ · মডিউল ৬ — স্টোরেজ, ইনডেক্স আর কোয়েরি প্রসেসিং (১১টি প্রশ্ন)
এখানে প্রশ্ন আসে দুই রকম: কোন পরিস্থিতিতে কোন গঠন (B+ tree, hash index, bitmap index, clustered index), আর খরচের হিসাব (tree-র উচ্চতা, block nested loop join, external merge sort, selectivity). খরচের প্রশ্নে সূত্রটি আগে লিখুন, তারপর সংখ্যা — আর ⌈ ⌉ (ওপরের দিকে পূর্ণসংখ্যা) ভুলবেন না। composite index-এর leftmost prefix নিয়ম SQLite-এর EXPLAIN QUERY PLAN দিয়ে নিচেই যাচাই করতে পারবেন।
- পর্ব ৩৯ · স্টোরেজ — page, buffer pool, LRU আর sequential flooding
- পর্ব ৪০ · Index — B+ tree, hash আর bitmap — উচ্চতার হিসাব, clustered বনাম secondary
- পর্ব ৪১ · Index ডিজাইন — composite, covering, sargable শর্ত, EXPLAIN
- পর্ব ৪২ · Query processing — external sort আর join অ্যালগরিদমের খরচ
- পর্ব ৪৩ · Query optimization — selectivity, statistics, EXPLAIN ANALYZE
(মাঝারি) buffer pool-এ ১০০টি frame, replacement policy LRU. ১০১ page-এর একটি টেবিল বারবার শুরু থেকে শেষ পর্যন্ত scan করা হচ্ছে (অন্য কোনো কাজ নেই)। দ্বিতীয় scan থেকে buffer hit rate কত?
- প্রায় 99%
- 50%
- 0%
- 100%
(মাঝারি) primary key আর clustered index সম্পর্কে কোনটি সত্য?
- একটি টেবিলে সর্বোচ্চ একটি clustered index থাকে; primary key আর clustered index এক জিনিস নয় — InnoDB-তে PK-ই clustered, কিন্তু PostgreSQL-এর সাধারণ (heap) টেবিলে PK একটি আলাদা B-tree index
- সব DBMS-এ primary key আপনা-আপনি clustered index
- একটি টেবিলে একাধিক clustered index রাখা যায়
- clustered index মানে hash-ভিত্তিক index
(কঠিন) একটি B+ tree-র প্রতিটি leaf-এ সর্বোচ্চ ১০০টি key আর প্রতিটি internal node-এ সর্বোচ্চ ১০০টি child pointer; সব node পুরো ভরা। ১০,০০,০০০ (দশ লাখ) key রাখতে tree-তে কয়টি স্তর (root আর leaf-সহ) লাগবে?
- 2
- 4
- 7
- 3
(মাঝারি) WHERE price BETWEEN 500 AND 1000 কোয়েরিতে নিচের কোন index প্রায় কোনো কাজে আসে না?
- price-এর ওপর B+ tree index
- price-এর ওপর hash index
- price অনুযায়ী clustered B+ tree index
- (price, name)-এর ওপর covering B+ tree index
(মাঝারি) bitmap index কোন পরিস্থিতিতে সবচেয়ে উপযুক্ত?
- data warehouse-এর মতো প্রায়-শুধু-পড়া টেবিলে কম আলাদা মানের কলাম (যেমন status, বিভাগ, লিঙ্গ), যেখানে অনেক শর্ত AND/OR দিয়ে মেলানো হয়
- OLTP টেবিলের unique primary key, যেখানে প্রতি সেকেন্ডে অনেক UPDATE
- দামের পরিসর খোঁজা, যেখানে প্রায় সব মান আলাদা
- লেখা-ভারী event log, যেখানে প্রতিটি সারি একবার লেখা হয় আর পড়া কম
(মাঝারি) customers টেবিলে (city, joined_on)-এর ওপর একটি composite B-tree index আছে। কোন কোয়েরি সাধারণত index দিয়ে সরাসরি খুঁজতে (seek/SEARCH) পারে?
WHERE joined_on >= '2025-03-01'WHERE city LIKE '%ka'WHERE lower(city) = 'dhaka'WHERE city = 'Dhaka' AND joined_on >= '2025-03-01'
-- দুই কলামেই শর্ত: index-এর leftmost prefix
EXPLAIN QUERY PLAN
SELECT name FROM customers
WHERE city = 'Dhaka' AND joined_on >= '2025-03-01';
-- শুধু দ্বিতীয় কলাম
EXPLAIN QUERY PLAN
SELECT name FROM customers WHERE joined_on >= '2025-03-01';
-- শুধু প্রথম কলাম
EXPLAIN QUERY PLAN
SELECT name FROM customers WHERE city = 'Dhaka';তিনটি plan: প্রথমটিতে SEARCH customers USING INDEX idx_city_joined (city=? AND joined_on>?); দ্বিতীয়টিতে SCAN customers; তৃতীয়টিতে SEARCH customers USING INDEX idx_city_joined (city=?). প্রথম কলামে শর্ত থাকলেই index-এর leftmost prefix কাজে আসে; শুধু দ্বিতীয় কলামে শর্ত দিলে SQLite পুরো টেবিল পড়ে। দ্বিতীয় কোয়েরি প্রায়ই চললে joined_on দিয়ে শুরু হওয়া আলাদা index ভাবুন।
(মাঝারি) products.price-এ একটি সাধারণ B-tree index আছে। কোন শর্তটি sargable, অর্থাৎ index ব্যবহার করে খুঁজতে পারে?
WHERE price * 2 > 1000WHERE ROUND(price) > 500WHERE price > 500WHERE CAST(price AS TEXT) LIKE '5%'
(কঠিন) R-এর M = 1,000 page, S-এর N = 500 page, buffer B = 52 page. R-কে outer ধরে block nested loop join-এর I/O খরচ (খরচ = M + ⌈M / (B − 2)⌉ · N, ফল লেখা বাদে) কত?
- 10,500
- 11,000
- 5,01,000
- 4,500
(কঠিন) N = 1,000 page-এর একটি ফাইল B = 11 buffer page দিয়ে external merge sort করা হলো। pass-এর সংখ্যা আর মোট I/O (প্রতি pass-এ প্রতিটি page একবার পড়া ও লেখা) কত?
- 2 pass, 4,000 I/O
- 4 pass, 8,000 I/O
- 3 pass, 3,000 I/O
- 3 pass, 6,000 I/O
(মাঝারি) একটি টেবিলে ১০,০০০ সারি, আর status কলামে ৫০টি আলাদা মান সমানভাবে ছড়ানো (uniform). WHERE status = 'x'-এ optimizer কত সারি অনুমান করবে (histogram না থাকলে প্রচলিত সূত্রে)?
- 50
- 200
- 10,000
- 1
(মাঝারি) PostgreSQL-এ EXPLAIN আর EXPLAIN ANALYZE-এর পার্থক্য কী?
- EXPLAIN শুধু optimizer-এর অনুমিত plan আর খরচ দেখায়; EXPLAIN ANALYZE কোয়েরিটি সত্যিই চালিয়ে আসল সময় আর সারির সংখ্যা দেখায় — তাই DELETE/UPDATE-এ সাবধান
- দুটিই কোয়েরি চালায়, শুধু ANALYZE বেশি বিস্তারিত
- EXPLAIN ANALYZE টেবিলের statistics আপডেট করে, কোয়েরি চালায় না
- দুটি একই জিনিস, শুধু নাম আলাদা
৮ · মডিউল ৭ — ট্রানজ্যাকশন আর কনকারেন্সি (১২টি প্রশ্ন)
ACID-এর চার অক্ষর, conflicting operation, conflict আর view serializability, 2PL আর strict 2PL, wait-die আর wound-wait, isolation level আর write skew, তারপর recovery — WAL, steal/force নীতি আর checkpoint. schedule-এর প্রশ্নে খাতায় প্রতিটি item-এর জন্য আলাদা লাইন করুন; অংশের শেষে একটি ডায়াগ্রামে পুরো পদ্ধতিটি দেখানো আছে।
- পর্ব ৪৪ · Transaction আর ACID — চারটি বৈশিষ্ট্য আর কে কোনটি নিশ্চিত করে
- পর্ব ৪৫ · Schedule আর serializability — precedence graph, blind write, recoverable আর cascadeless
- পর্ব ৪৬ · Concurrency control — lock, 2PL, deadlock, wait-die/wound-wait, timestamp
- পর্ব ৪৭ · MVCC আর isolation level — anomaly, snapshot isolation, write skew, SSI
- পর্ব ৪৮ · Recovery — WAL-এর নিয়ম, steal/no-force, checkpoint, ARIES
(সহজ) bKash-এর মতো একটি লেনদেনে Rahim-এর হিসাব থেকে ৫০০ টাকা কাটা হলো, কিন্তু Karima-র হিসাবে জমার আগেই সার্ভার বন্ধ হয়ে গেল। চালু হওয়ার পর কাটা টাকাও ফেরত এল। ACID-এর কোন বৈশিষ্ট্য এটি নিশ্চিত করল?
- Consistency
- Isolation
- Atomicity
- Durability
(সহজ) কোন জোড়া operation পরস্পর conflict করে না? (R = read, W = write, সংখ্যাটি transaction)
- R1(A), W2(A)
- R1(A), R2(A)
- W1(A), W2(A)
- W1(B), R2(B)
(কঠিন) schedule S: R1(A), W2(A), R2(B), W1(B). S সম্পর্কে কোনটি সত্য?
- conflict serializable, সমতুল্য serial ক্রম T1, T2
- conflict serializable, সমতুল্য serial ক্রম T2, T1
- conflict serializable নয় — precedence graph-এ T1 → T2 (A-তে) আর T2 → T1 (B-তে), একটি চক্র
- দুটি transaction কোনো item ভাগ করে না, তাই conflict নেই
(কঠিন) schedule S: R2(A), R1(B), W2(A), R3(A), W1(B), W3(A), R2(B), W2(B). সমতুল্য serial ক্রম কোনটি?
- T2 → T1 → T3
- T2 → T3 → T1
- conflict serializable নয়
- T1 → T2 → T3
(কঠিন) schedule S: R1(A), W2(A), W1(A), W3(A). S সম্পর্কে কোনটি সত্য?
- view serializable (T1, T2, T3-এর সমতুল্য), কিন্তু conflict serializable নয়
- conflict serializable আর view serializable দুটিই
- দুটির কোনোটিই নয়
- conflict serializable, কিন্তু view serializable নয়
(মাঝারি) two-phase locking (2PL) সম্পর্কে কোনটি সত্য?
- 2PL deadlock অসম্ভব করে তোলে
- 2PL শুধু view serializability দেয়, conflict নয়
- basic 2PL conflict serializability নিশ্চিত করে, কিন্তু deadlock আটকায় না; strict 2PL exclusive lock commit পর্যন্ত ধরে রেখে cascading abort-ও আটকায়
- 2PL-এ transaction যেকোনো সময় lock ছেড়ে আবার নিতে পারে
(কঠিন) timestamp-ভিত্তিক deadlock প্রতিরোধে T5 (timestamp 5, পুরোনো) এমন একটি lock চাইল, যা T10 (নতুন) ধরে আছে। wait-die আর wound-wait-এ কী হবে?
- wait-die-তে T5 abort হয়; wound-wait-এ T5 অপেক্ষা করে
- wait-die-তে T5 অপেক্ষা করে; wound-wait-এ T10 abort হয় (T5 তাকে “wound” করে)
- দুটিতেই T5 অপেক্ষা করে
- দুটিতেই T10 abort হয়
(মাঝারি) SQL standard-এর isolation level-গুলোর মধ্যে non-repeatable read আটকায় এমন সবচেয়ে নিচের level কোনটি?
- READ COMMITTED
- READ UNCOMMITTED
- SERIALIZABLE
- REPEATABLE READ
(কঠিন) হাসপাতালে নিয়ম: অন্তত একজন ডাক্তার on-call থাকবেন। দুজন on-call; দুজনেই একসাথে transaction শুরু করে দেখলেন “আরেকজন আছেন”, তারপর নিজের সারিতে on_call = false লিখে commit করলেন। snapshot isolation (যেমন PostgreSQL-এর REPEATABLE READ) সম্পর্কে কোনটি সত্য?
- snapshot isolation এই write skew আটকায় না, কারণ দুজন আলাদা সারি লিখেছেন; PostgreSQL-এর SERIALIZABLE (SSI) একটিকে serialization failure দিয়ে বাতিল করে
- snapshot isolation সব anomaly আটকায়, তাই এটি serializable-এর সমান
- দ্বিতীয় transaction-টি dirty read করেছে
- এটি lost update, তাই first-committer-wins এটি আটকায়
(মাঝারি) write-ahead logging (WAL)-এর মূল নিয়ম কোনটি?
- data page আগে ডিস্কে, log পরে
- কোনো বদলানো data page ডিস্কে লেখার আগে তার log record স্থায়ী স্টোরেজে লিখতে হবে; আর commit-এর আগে সেই transaction-এর সব log record (commit record-সহ) flush করতে হবে
- commit-এর সময় সব বদলানো data page ডিস্কে লিখতে হবে
- log শুধু backup-এর জন্য, recovery-তে লাগে না
(কঠিন) buffer manager steal আর no-force নীতি মানে। crash recovery-র জন্য কী কী লাগবে?
- শুধু undo
- শুধু redo
- undo আর redo দুটোই
- কোনোটিই না
(কঠিন) log-এ এই ক্রম: T1 শুরু, T1 commit, (checkpoint — তখন কোনো transaction সক্রিয় নেই), T2 শুরু, T3 শুরু, T2 commit, crash. সাধারণ (non-fuzzy) checkpoint ধরে recovery কী করবে?
- T2 redo, T3 undo, T1-কে কিছু করতে হবে না
- T1 আর T2 redo, T3 undo
- T2 আর T3 redo
- T2 undo, T3 redo
schedule-এর খাতা — precedence graph ধাপে ধাপে
“সমতুল্য serial ক্রম কোনটি?” প্রশ্নে চোখে দেখে উত্তর দিলে প্রায়ই একটি edge বাদ পড়ে। নিচে উপরের আট-operation-এর schedule-টি নিয়ে পুরো পদ্ধতি: item ধরে conflict জোড়া, edge, চক্র খোঁজা, আর একটি ছোট বদলে কীভাবে চক্র তৈরি হয়।
ক্রম: 1 2 3 4 5 6 7 8
R2(A) R1(B) W2(A) R3(A) W1(B) W3(A) R2(B) W2(B)
A: R2(A)₁ W2(A)₃ R3(A)₄ W3(A)₆
B: R1(B)₂ W1(B)₅ R2(B)₇ W2(B)₈
R2(A)₁ … W3(A)₆ → T2 → T3 W2(A)₃ … R3(A)₄ → T2 → T3 W2(A)₃ … W3(A)₆ → T2 → T3 (R2(A) আর W2(A) একই transaction — conflict নয়)
R1(B)₂ … W2(B)₈ → T1 → T2 W1(B)₅ … R2(B)₇ → T1 → T2 W1(B)₅ … W2(B)₈ → T1 → T2 T3 B ছোঁয় না
T1 ───▶ T2 ───▶ T3
edge: T1→T2, T2→T3 চক্র নেই
→ conflict serializable
→ serial ক্রম: T1, T2, T3 (একমাত্র topological ক্রম)
৫ আর ৭ অদলবদল: … R3(A) R2(B) W3(A) W1(B) W2(B) R2(B) … W1(B) → T2 → T1 (নতুন) R1(B) … W2(B) → T1 → T2 T1 ⇄ T2 চক্র → conflict serializable নয়
- প্রতিটি item-এর জন্য আলাদা লাইন। আটটি operation-এর ক্রমিক নম্বর দিন, তারপর A আর B-র operation আলাদা লাইনে লিখুন। conflict শুধু একই item-এর ভেতরে হয়, তাই এই ভাগ করলেই অর্ধেক জোড়া আর দেখতে হয় না।
- A-র লাইন থেকে edge. আলাদা transaction আর অন্তত একটি write — এমন প্রতিটি জোড়া আগেরটি থেকে পরেরটির দিকে edge দেয়। A-তে তিনটি জোড়া, তিনটিই T2 → T3. R2(A) আর W2(A) একই transaction-এর, তাই সেটি গোনা হয় না।
- B-র লাইন থেকে edge. R1(B) আর W1(B) আগে, R2(B) আর W2(B) পরে — তিনটি জোড়া, সবই T1 → T2. T3 B ছোঁয় না, তাই B থেকে T3-এর কোনো edge নেই।
- graph আঁকুন, চক্র খুঁজুন। edge মাত্র দুটি: T1 → T2 → T3. চক্র নেই, তাই schedule conflict serializable, আর topological ক্রমই সমতুল্য serial ক্রম: T1, T2, T3. একাধিক topological ক্রম থাকলে প্রতিটিই সঠিক উত্তর — অপশনে যেটি আছে।
- একটি অদলবদলেই চক্র। W1(B) আর R2(B)-র জায়গা বদলালে R2(B) আগে আসে — নতুন edge T2 → T1. সাথে R1(B) … W2(B) থেকে T1 → T2 তো আছেই। চক্র, তাই conflict serializable নয়। MCQ-তে প্রায়ই ঠিক এমন দুটি প্রায়-একই schedule পাশাপাশি দেওয়া থাকে।
৯ · মডিউল ৮ — অ্যাপ্লিকেশন, নিরাপত্তা আর পরিচালনা (১১টি প্রশ্ন)
এই মডিউলের প্রশ্ন বাস্তব কাজের সিদ্ধান্ত নিয়ে: SQL injection ঠেকানোর সঠিক উপায় (parameterized query আর allow-list), least privilege, পাসওয়ার্ড hash, connection pool, ORM-এর N + 1 সমস্যা, backup-এর RPO আর RTO, আর replication কেন backup নয়। নিরাপত্তার সব প্রশ্ন প্রতিরোধ নিয়ে — কীভাবে ঝুঁকি বন্ধ করবেন।
- পর্ব ৪৯ · অ্যাপ থেকে ডেটাবেস — driver, prepared statement, connection pool
- পর্ব ৫০ · ORM আর migration — lazy/eager loading, N + 1, expand-contract
- পর্ব ৫১ · ডেটাবেস নিরাপত্তা — injection প্রতিরোধ, privilege, পাসওয়ার্ড আর encryption
- পর্ব ৫২ · Backup, replication আর high availability — full/incremental/differential, RPO/RTO, PITR
- পর্ব ৫৩ · পারফরম্যান্স টিউনিং — আগে মাপা, তারপর বদলানো
(সহজ) অ্যাপের কোডে SQL injection ঠেকানোর প্রধান উপায় কোনটি?
- ব্যবহারকারীর লেখা থেকে উদ্ধৃতি চিহ্ন (') খুঁজে মুছে ফেলা
- ডেটাবেস ফাইল encrypt করা
- সব কোয়েরি stored procedure-এ সরিয়ে নেওয়া
- parameterized query বা prepared statement — ব্যবহারকারীর মান placeholder-এ bind করা
(মাঝারি) ব্যবহারকারী তালিকাটি কোন কলাম অনুযায়ী সাজাবেন (name, price বা date) বেছে নিতে পারেন। placeholder দিয়ে ORDER BY ? লিখলে কেন কাজ হয় না, আর নিরাপদ সমাধান কী?
- placeholder শুধু মান (value) নেয়, কলামের নামের মতো identifier নয়; নিরাপদ উপায় হলো allow-list — ব্যবহারকারীর পছন্দকে নির্দিষ্ট কয়েকটি জানা কলাম-নামের সাথে মিলিয়ে নেওয়া
- placeholder দিয়েই কাজ হয়, ডেটাবেস কলামের নাম বুঝে নেয়
- ব্যবহারকারীর লেখাটি সরাসরি জুড়ে দিলেই হয়, ORDER BY-তে injection সম্ভব নয়
- কলামের নাম encrypt করে পাঠাতে হবে
(মাঝারি) একটি ওয়েব অ্যাপ ডেটাবেসে কোন account দিয়ে যুক্ত হওয়া উচিত?
- superuser/root account, যাতে কোনো কাজে আটকে না যায়
- DBA-র নিজের account, পাসওয়ার্ড কোডে লেখা
- পাসওয়ার্ড ছাড়া account, শুধু অভ্যন্তরীণ নেটওয়ার্কে
- এমন একটি account, যার শুধু দরকারি টেবিলে দরকারি অধিকার (যেমন SELECT, INSERT, UPDATE) আছে — DDL বা superuser অধিকার নেই
(মাঝারি) ব্যবহারকারীর পাসওয়ার্ড ডেটাবেসে রাখার সঠিক উপায় কোনটি?
- AES দিয়ে encrypt করে রাখা
- MD5 বা SHA-1 hash, salt ছাড়া
- প্রতিটি পাসওয়ার্ডের জন্য আলাদা salt-সহ ইচ্ছাকৃত ধীর hash (Argon2, bcrypt বা scrypt)
- সাধারণ লেখায় রেখে টেবিলে কড়া অধিকার দেওয়া
(মাঝারি) connection pool সম্পর্কে কোনটি সত্য?
- pool যত বড়, অ্যাপ তত দ্রুত
- আগে থেকে খোলা কিছু connection বারবার ব্যবহার করে প্রতিটি অনুরোধে নতুন connection খোলার খরচ (TCP, TLS, authentication) বাঁচায়; pool-এর আকার ছোট আর মাপা রাখা ভালো
- pool থাকলে transaction-এর দরকার হয় না
- pool ব্যবহার করলে connection কখনো বন্ধ বা ফেরত দিতে হয় না
(মাঝারি) একটি ORM দিয়ে ৫০টি অর্ডারের তালিকা আনা হলো, তারপর লুপে প্রতিটির order.customer.name পড়া হলো (lazy loading). মোট কয়টি কোয়েরি যাবে, আর সমাধান কী?
- ৫১টি (১টি তালিকার জন্য + প্রতিটি অর্ডারের গ্রাহকের জন্য ১টি করে); সমাধান eager loading বা JOIN দিয়ে একবারে আনা
- ১টি — ORM সব নিজে থেকে join করে আনে
- ৫০টি
- ২টি, আর এর কোনো সমাধান দরকার নেই
(সহজ) একটি ব্যাংক বলল: “সর্বোচ্চ ৫ মিনিটের লেনদেন হারানো চলবে, আর বিপর্যয়ের পর ১ ঘণ্টার মধ্যে সেবা চালু করতে হবে।” এখানে RPO আর RTO কত?
- RPO = ১ ঘণ্টা, RTO = ৫ মিনিট
- দুটিই ৫ মিনিট
- RPO = ৫ মিনিট, RTO = ১ ঘণ্টা
- RPO = ০, RTO = ১ ঘণ্টা
(মাঝারি) একটি দোকানের ডেটাবেসের প্রতি রাত ২টায় শুধু একটি full backup নেওয়া হয়, কোনো log archiving নেই। সবচেয়ে খারাপ ক্ষেত্রে RPO কত?
- ০ — backup তো আছে
- backup restore করতে যত সময় লাগে
- ২ ঘণ্টা
- প্রায় ২৪ ঘণ্টা
(মাঝারি) একজন ভুল করে production-এ DROP TABLE orders; চালালেন। ডেটাবেসের একটি streaming replica আছে, তবে backup বা PITR নেই। কোনটি সত্য?
- replica-তে টেবিলটি থেকে যাবে, সেখান থেকে ফেরত আনা যাবে
- replica-ও কয়েক মুহূর্তের মধ্যে টেবিলটি হারাবে, কারণ replication পরিবর্তন হুবহু কপি করে — replication backup-এর বিকল্প নয়
- DROP TABLE replication-এ যায় না
- replica থাকলে কোনো ডেটা হারানো সম্ভব নয়
(মাঝারি) রবিবার full backup, আর সোমবার, মঙ্গলবার, বুধবার রাতে differential backup নেওয়া হলো। বৃহস্পতিবার সকালে ডিস্ক নষ্ট। কোনগুলো restore করতে হবে?
- রবিবারের full আর বুধবারের differential
- রবিবারের full, আর সোম, মঙ্গল, বুধ — তিনটি differential
- শুধু বুধবারের differential
- শুধু রবিবারের full
(মাঝারি) অ্যাপ হঠাৎ ধীর হয়ে গেছে। ডেটাবেসের পারফরম্যান্স ঠিক করতে প্রথম কাজ কোনটি?
- সব কলামে index বানানো
- সাথে সাথে বড় সার্ভার কেনা
- পুরো schema denormalize করা
- মেপে দেখা: slow query log বা pg_stat_statements দিয়ে কোন কোয়েরি মোট সময় সবচেয়ে বেশি নিচ্ছে, তারপর সেটির EXPLAIN
১০ · মডিউল ৯ — বড় মাপের ডেটা, NoSQL আর ক্যাপস্টোন (১১টি প্রশ্ন)
শেষ মডিউলের প্রশ্নে বাছাইয়ের যুক্তিই আসল: CAP theorem কী বলে আর কী বলে না, shard key আর hot spot, consistent hashing, two-phase commit-এর দুর্বলতা, star schema, কোন কাজে কোন NoSQL (graph, document, key-value), Redis-এর atomic counter, আর vector search-এর cosine similarity ও approximate nearest neighbor. ক্যাপস্টোনের (পর্ব ৬২) নকশার সিদ্ধান্তগুলো এই প্রশ্নগুলোরই বাস্তব রূপ।
- পর্ব ৫৪ · Distributed database — partitioning, sharding, consistent hashing, 2PC, CAP আর PACELC
- পর্ব ৫৫ · Data warehouse — OLTP বনাম OLAP, star schema, fact আর dimension
- পর্ব ৫৬ · NoSQL, পর্ব ৫৭ · MongoDB আর পর্ব ৫৮ · Redis — কোন কাজে কোনটি, embed বনাম reference, INCR আর EXPIRE
- পর্ব ৫৯ · Graph, search আর time-series আর পর্ব ৬০ · Vector database — traversal, cosine, HNSW, recall
- পর্ব ৬১ · Cloud database আর পর্ব ৬২ · ক্যাপস্টোন — shared responsibility, পুরো নকশার সিদ্ধান্ত
(মাঝারি) CAP theorem-এর সবচেয়ে সঠিক ব্যাখ্যা কোনটি?
- যেকোনো সময় তিনটির যেকোনো দুটি বেছে নেওয়া যায়, যেমন “CA সিস্টেম”
- CAP-এর C আর ACID-এর C একই জিনিস
- network partition ঘটলে একটি distributed সিস্টেমকে consistency (linearizable) আর availability-র মধ্যে একটি বেছে নিতে হয়
- CAP বলে distributed database ধীর হতেই হবে
(মাঝারি) একটি অর্ডার-টেবিল order_time অনুযায়ী range sharding করা হলো (প্রতিটি shard একটি সময়ের পরিসর)। নতুন অর্ডারের লেখায় কী সমস্যা হবে?
- লেখাগুলো সব shard-এ সমানভাবে ছড়ায়
- সব নতুন লেখা শেষের shard-এ যায় — hot spot; বাকি shard প্রায় অলস
- range sharding-এ পরিসরের কোয়েরি অসম্ভব
- প্রতিটি লেখাকে সব shard-এ যেতে হয়
(কঠিন) key-কে key mod N দিয়ে shard-এ ভাগ করা হয়। N = 4 থেকে 5 করলে (key-গুলো 0, 1, 2, … সমানভাবে ছড়ানো) কত শতাংশ key তাদের shard বদলাবে?
- ২০%
- ২৫%
- ০% — পুরোনো key আগের জায়গাতেই থাকে
- ৮০%
-- 0 থেকে 999 পর্যন্ত ১,০০০টি key: mod 4 আর mod 5-এ একই shard কয়টির?
WITH RECURSIVE k(v) AS (
SELECT 0 UNION ALL SELECT v + 1 FROM k WHERE v < 999
)
SELECT COUNT(*) AS keys_total,
SUM(v % 4 = v % 5) AS same_shard
FROM k;ফল: 1000 | 200. ১,০০০টি key-র মাত্র ২০০টি (২০%) একই shard-এ থাকে, ৮০০টি (৮০%) সরতে হয়। একটি shard যোগ করতে প্রায় সব ডেটা নেটওয়ার্কে সরানো — এই খরচ এড়াতেই consistent hashing বা আগে থেকে অনেক ছোট ভাগ (যেমন Redis Cluster-এর 16,384 hash slot) বানিয়ে রাখা হয়।
(কঠিন) two-phase commit (2PC)-এর সবচেয়ে পরিচিত দুর্বলতা কোনটি?
- participant “prepared” (প্রস্তুত) ভোট দেওয়ার পর coordinator বন্ধ হয়ে গেলে participant নিজে commit বা abort ঠিক করতে পারে না — lock ধরে অপেক্ষা করে (blocking)
- 2PC atomicity দেয় না
- 2PC-তে একটিই network round trip লাগে
- participant যেকোনো সময় একতরফা abort করতে পারে, এমনকি prepared ভোটের পরেও
(সহজ) data warehouse-এর star schema-তে fact table-এ সাধারণত কী থাকে?
- শুধু বর্ণনামূলক লেখা, যেমন পণ্যের নাম আর বিভাগ
- সম্পূর্ণ normalized OLTP টেবিল
- পরিমাপযোগ্য সংখ্যা (measure, যেমন বিক্রির পরিমাণ, টাকা) আর dimension table-গুলোর foreign key
- শুধু তারিখের তালিকা
(মাঝারি) সামাজিক মাধ্যমের “বন্ধুর বন্ধু, যাঁকে আপনি চেনেন না” সুপারিশ — বহু স্তরের সম্পর্ক ঘুরে দেখার কাজে কোন ধরনের ডেটাবেস সবচেয়ে স্বাভাবিক?
- key-value store
- graph database (যেমন Neo4j)
- time-series database
- column store data warehouse
(মাঝারি) MongoDB-তে একটি blog post-এর মন্তব্য অসীমভাবে বাড়তে পারে (জনপ্রিয় post-এ লাখো)। কোন নকশা ভালো?
- মন্তব্যগুলো আলাদা collection-এ রেখে post_id দিয়ে reference করা
- সব মন্তব্য post document-এর ভেতরের array-তে embed করা
- প্রতিটি মন্তব্যে পুরো post-এর একটি কপি রাখা
- MongoDB-তে reference করা যায় না, embed করতেই হবে
(মাঝারি) Redis দিয়ে প্রতি মিনিটে প্রতি ব্যবহারকারী সর্বোচ্চ ১০০টি অনুরোধ (fixed window rate limit). সবচেয়ে প্রচলিত কৌশল কোনটি?
- অ্যাপে মান পড়ে (GET), এক বাড়িয়ে আবার লেখা (SET)
- প্রতিটি অনুরোধ relational টেবিলে একটি সারি হিসেবে লিখে প্রতিবার COUNT করা
INCRদিয়ে ব্যবহারকারী-আর-মিনিটভিত্তিক key বাড়ানো, প্রথমবারEXPIREবসানো, মান ১০০ ছাড়ালে অনুরোধ ফেরানো- Redis-এ ডেটা মেমোরিতে থাকে, তাই rate limiting-এ ব্যবহার করা যায় না
(মাঝারি) দুটি vector a = (1, 0) আর b = (1, 1)-এর cosine similarity কত?
- 1
- ≈ 0.707
- 0
- √2 ≈ 1.414
(কঠিন) vector database-এর HNSW বা IVF index সম্পর্কে কোনটি সত্য?
- HNSW সবসময় brute force-এর মতো হুবহু সঠিক ফল দেয়
- vector index B+ tree-র মতো বহু-মাত্রিক পরিসর ঠিকঠাক খুঁজে দেয়
- index থাকলে embedding মডেল বদলালেও পুরোনো vector দিয়ে চলে
- এগুলো approximate nearest neighbor (ANN) খোঁজে: অনেক দ্রুত, কিন্তু সবসময় আসল সবচেয়ে কাছের k-টি দেয় না — recall@k 1-এর কম হতে পারে; ef_search বা nprobe বাড়ালে recall বাড়ে, গতি কমে
(সহজ) managed cloud database (DBaaS, যেমন Amazon RDS বা Cloud SQL) ব্যবহার করলে সাধারণত কোন দায়িত্ব এখনো আপনার থাকে?
- ডেটা সেন্টারের হার্ডওয়্যার বদলানো
- operating system-এর নিরাপত্তা patch দেওয়া
- কে কোন ডেটা দেখবে (user, role, অধিকার), schema আর কোয়েরির মান, আর নেটওয়ার্কে কে পৌঁছাতে পারবে — এসব ঠিক রাখা
- কোনো দায়িত্বই থাকে না, সব provider-এর
AI-এর যুগে — AI দিয়ে আরও MCQ বানান, কিন্তু উত্তর SQL চালিয়ে যাচাই করুন
এই পাতার ১০৫টি প্রশ্ন শেষ হলে আরও অনুশীলন চাইবেন, আর AI চ্যাটবট মুহূর্তে শত শত MCQ বানিয়ে দিতে পারে। কিন্তু মনে রাখুন: DBMS-এর MCQ-তে AI প্রায়ই ভুল উত্তরকে “সঠিক” বলে চিহ্নিত করে, বা একই প্রশ্নে দুটি সঠিক অপশন রেখে দেয়। সবচেয়ে বেশি ভুল ঠিক সেই জায়গাগুলোতে, যেগুলো এই পাতার ফাঁদ: NULL-এর তুলনা, NOT IN, LEFT JOIN-এর পর COUNT, আর FD থেকে candidate key. AI প্রায়ই একটি key বাদ দেয়, আর তার ফলে normal form-এর উত্তরও ভুল হয়। আরেকটি সমস্যা: AI কোন DBMS-এর আচরণ বলছে, তা বলে না — MySQL-এর ||, SQLite-এর dynamic typing বা PostgreSQL-এর REPEATABLE READ-কে সবার আচরণ বলে চালিয়ে দেয়।
| AI-এর প্রচলিত ভুল | উদাহরণ | কীভাবে ধরবেন |
|---|---|---|
| ভুল উত্তর-চাবি | NULL-ওয়ালা কোয়েরির ফল NULL-কে সাধারণ মান ধরে গোনা | CREATE TABLE আর INSERT চেয়ে নিন, নিজে চালান |
| অসম্পূর্ণ key | দুটি candidate key-র একটি বাদ, ফলে 3NF-কে 2NF বলা | প্রতিটি attribute-সেটের closure ছোট স্ক্রিপ্টে বের করুন |
| DBMS না বলা | “|| string জোড়ে” — MySQL-এ ডিফল্টে নয় | প্রশ্নে কোন DBMS, তা লিখতে বলুন; ডকুমেন্টেশন মেলান |
| দুটি সঠিক অপশন | “RR non-repeatable read আটকায়” আর “SERIALIZABLE আটকায়” — প্রশ্নে “সবচেয়ে নিচের” না থাকলে দুটিই সত্য | প্রতিটি অপশন আলাদা করে সত্য/মিথ্যা যাচাই করুন |
| পুরোনো বা ভুল তথ্য | “primary key সবসময় clustered” | সংশ্লিষ্ট পর্ব আর DBMS-এর ডকুমেন্টেশনের সাথে মেলান |
| বানানো উৎস | “অমুক পরীক্ষায় এসেছিল” | উৎস দেখাতে না পারলে দাবিটি বাদ দিন |
নিচের প্রম্পটটি AI-কে প্রশ্ন বানাতে বলে, কিন্তু সাথে এমন তথ্যও চায়, যা দিয়ে আপনি উত্তর যাচাই করতে পারবেন। ফলের প্রতিটি প্রশ্নে চালানো যায় এমন SQL, আর তত্ত্বের প্রতিটি প্রশ্নে ধাপে ধাপে হিসাব চাওয়াই এখানে আসল কৌশল:
যাচাইয়ের চেকলিস্ট
কেন এই উত্তর? — কৌশল আর যে ধারণাগুলোতে সবচেয়ে বেশি ভুল হয়
প্রথমটি এই প্রশ্নব্যাংক দিয়ে কীভাবে রিভিশন করবেন তা নিয়ে; বাকি পাঁচটি ধারণা এত বেশি ভুল বোঝা হয় যে আলাদা ব্যাখ্যা দরকার। আগে নিজে ভাবুন — তারপর খুলে উত্তর দেখুন।
প্র ০১১০৫টি প্রশ্ন একবারে পড়ে মনে থাকে না। এই প্রশ্নব্যাংক দিয়ে কীভাবে রিভিশন করলে সবচেয়ে বেশি কাজে লাগে?
প্রশ্নব্যাংকের সবচেয়ে বড় অপব্যবহার হলো একটানা পড়ে যাওয়া — প্রশ্ন দেখা, উত্তর চাপা, “ও আচ্ছা” বলে এগিয়ে যাওয়া। শেখার গবেষণায় বারবার দেখা গেছে, মনে রাখতে সবচেয়ে কার্যকর দুটি অভ্যাস হলো নিজে থেকে মনে করার চেষ্টা (active recall) আর বিরতি দিয়ে ফিরে আসা (spaced repetition). নিচের পদ্ধতিটি দুটিকেই কাজে লাগায়:
- এক অংশ, পুরো মনোযোগ: একবারে একটি মডিউলের অংশ নিন। প্রতিটি প্রশ্নে চাপার আগে খাতায় নিজের উত্তর আর এক লাইনের কারণ লিখুন — “3NF, কারণ C → B-তে B prime”. কারণ লিখতে না পারলে আন্দাজটিকে ভুল হিসেবেই গুনুন, ঠিক হলেও।
- ভুলের খাতা: প্রতিটি ভুলের জন্য একটি লাইন — কোন নিয়মটি গুলিয়েছিলাম (“COUNT(col) NULL গোনে না”)। প্রশ্ন নয়, নিয়মটি লিখুন; পরীক্ষায় একই নিয়ম অন্য টেবিলে আসবে।
- এডিটরে নতুন প্রশ্ন: প্রতিটি লাইভ এডিটরে ডেটা বা শর্ত একটি জায়গায় বদলান — একটি NULL যোগ করুন, ON-এর শর্ত WHERE-এ নিন, RANK-এর জায়গায় DENSE_RANK — আর চালানোর আগে খাতায় নতুন ফল লিখুন। মুখস্থ উত্তর এখানে কাজ করে না, তাই এটিই সবচেয়ে শক্তিশালী অনুশীলন।
- পর্বে ফিরে যাওয়া: একটি অংশে তিনটির বেশি ভুল হলে সেই অংশের “যা ঝালিয়ে নেবেন” তালিকার পর্বগুলো আবার পড়ুন — বিশেষ করে সেখানকার ধাপে-ধাপে ডায়াগ্রাম।
- ফিরে আসার সময়সূচি: ভুলের খাতা দেখে ১ দিন, ৩ দিন আর ৭ দিন পরে শুধু ভুল প্রশ্নগুলো আবার করুন। পাতার প্রশ্নের ক্রম একই থাকে, তাই উত্তরের অবস্থান মুখস্থ হয়ে যাওয়ার ঝুঁকি আছে — অপশন পড়ার আগেই নিজের উত্তর বলুন।
- সময় ধরে পূর্ণ মহড়া: পরীক্ষার আগে সব অংশ থেকে মিশিয়ে ৩০টি প্রশ্ন ২৫ মিনিটে করুন। কোর্স হোমের মডিউল টেস্টও একই কাজে লাগে।
মূল উপলব্ধি: প্রশ্ন পড়া নয়, প্রশ্নের পেছনের নিয়ম মনে রাখাই লক্ষ্য — নিজে উত্তর আর কারণ লিখুন, এডিটরে বদলে পরীক্ষা করুন, আর বিরতি দিয়ে ফিরে আসুন।
প্র ০২NULL নিয়ে এত ফাঁদ কেন? NULL = NULL কেন TRUE নয়, আর বাস্তবে কোন কয়টি নিয়ম মানলেই নিরাপদ?
NULL কোনো মান নয় — “মান জানা নেই” বা “প্রযোজ্য নয়”-এর চিহ্ন। Fahim Karim-এর cgpa NULL মানে 0 নয়; মানে ফলটি এখনো জানা নেই। দুটি অজানা মান সমান কি না? জানা নেই। তাই SQL তুলনার ফলের জন্য তৃতীয় একটি মান রাখে — UNKNOWN. এটিই তিন-মানের যুক্তি: TRUE, FALSE, UNKNOWN. AND-এ একটি FALSE থাকলে ফল FALSE, OR-এ একটি TRUE থাকলে ফল TRUE; বাকি মিশ্রণে UNKNOWN. আর WHERE, ON, HAVING শুধু TRUE সারি রাখে — UNKNOWN বাদ পড়ে, FALSE-এর মতোই।
ইতিহাসটিও শিক্ষণীয়। E. F. Codd ১৯৭৯ সালের একটি প্রবন্ধে relational model-এ null-এর ধারণা বিস্তারিতভাবে প্রস্তাব করেন, আর পরে (১৯৯০ সালের RM/V2 বইয়ে) দুই রকম চিহ্নের প্রস্তাব দেন — “মান আছে কিন্তু জানা নেই” আর “প্রযোজ্যই নয়”। SQL একটিই NULL রাখে। C. J. Date-সহ অনেক তাত্ত্বিক বহু বছর ধরে যুক্তি দিয়েছেন যে NULL relational model-এর যুক্তিকে জটিল করে, আর ঠিক এই জটিলতাই পরীক্ষার ফাঁদ।
একটি অসংগতি মনে রাখুন: তুলনায় NULL = NULL UNKNOWN, কিন্তু পুনরাবৃত্তি সরাতে (DISTINCT, UNION, GROUP BY) দুটি NULL-কে একই দলে রাখা হয়। standard-এর ভাষায় দুটি NULL “not distinct”. এ কারণেই SQL:1999 আনে IS [NOT] DISTINCT FROM — যে তুলনা NULL-কে সাধারণ মানের মতো ধরে (SQLite-এ IS আর IS NOT একই কাজ করে)।
নিরাপদ থাকার ছয়টি নিয়ম: (১) NULL খুঁজতে IS NULL, কখনো = NULL নয়। (২) anti join-এ NOT IN নয়, NOT EXISTS. (৩) LEFT JOIN-এর পর গুনতে ডান টেবিলের NOT NULL কলাম — COUNT(*) নয়। (৪) ডান টেবিলের শর্ত ON-এ, যদি বাঁ দিকের সব সারি চান। (৫) <> আর NOT-এর শর্তে ভাবুন, NULL সারিগুলো আসবে কি না — চাইলে OR col IS NULL. (৬) AVG বা SUM-এর আগে ভাবুন, NULL মানে কি সত্যিই “বাদ দাও”, না 0 — দরকারে COALESCE.
মূল উপলব্ধি: NULL নিয়ে প্রতিটি প্রশ্নে নিজেকে একটি প্রশ্ন করুন — “এই সারিতে শর্তটি TRUE, FALSE, না UNKNOWN?” UNKNOWN মানেই বাদ।
প্র ০৩3NF আর BCNF-এর পার্থক্য ঠিক কোথায়? BCNF যদি বেশি কড়া হয়, তাহলে 3NF এখনো কেন শেখানো হয়?
দুটির সংজ্ঞা প্রায় একই, পার্থক্য একটি ছাড়ে। প্রতিটি নন-trivial FD X → A-র জন্য BCNF বলে: X superkey হতেই হবে। 3NF বলে: X superkey হোক, অথবা A কোনো candidate key-র অংশ (prime) হোক। অর্থাৎ 3NF একটি বিশেষ ক্ষেত্রে ছাড় দেয় — যখন একটি non-key attribute-সেট কোনো key-র অংশকে নির্ণয় করে।
এই ছাড়ের কারণ বোঝাতে পাঠ্যবইয়ের একটি পরিচিত উদাহরণ: ঠিকানার টেবিল (street, city, zip), যেখানে street, city → zip আর zip → city. key দুটি: (street, city) আর (street, zip). zip → city-তে zip superkey নয়, কিন্তু city prime — তাই 3NF খাটে, BCNF নয়। BCNF-এ ভাঙলে পাই (zip, city) আর (street, zip). lossless ঠিকই, কিন্তু street, city → zip আর কোনো একটি টেবিলের ভেতরে থাকে না — নিয়মটি রাখতে প্রতিটি INSERT-এ join করে পরীক্ষা করতে হবে। কোনো BCNF decomposition-ই এখানে দুটি FD রক্ষা করতে পারে না।
এটিই সাধারণ সত্য: 3NF-এ সবসময় এমন decomposition পাওয়া যায়, যা lossless আর dependency-preserving দুটোই (synthesis অ্যালগরিদম, ১৯৭০-এর দশকে Bernstein-এর কাজ থেকে)। BCNF-এ lossless নিশ্চিত, কিন্তু dependency preservation সবসময় নয়। তাই নকশায় প্রচলিত নীতি: BCNF-এর চেষ্টা করুন; dependency হারাতে হলে 3NF-এ থামুন।
ইতিহাসে, Codd ১৯৭১-৭২ সালে 2NF আর 3NF সংজ্ঞায়িত করেন; পরে ১৯৭৪ সালে Raymond Boyce আর Codd 3NF-এর এই ফাঁকটি বন্ধ করতে আরও কড়া রূপটি দেন — তাই নাম Boyce–Codd normal form. যে relation-এ candidate key একটিই, বা key-গুলো পরস্পর overlap করে না, সেখানে 3NF আর BCNF কার্যত একই — পার্থক্য ধরা পড়ে শুধু overlapping যৌগিক key থাকলে। MCQ-তে তাই “একাধিক key, আর একটি FD-র ডান দিক কোনো key-র অংশ” দেখলেই সতর্ক হন — সেটিই 3NF-কিন্তু-BCNF-নয়ের চিহ্ন।
মূল উপলব্ধি: BCNF = প্রতিটি নির্ণায়ক superkey. 3NF = তাই, অথবা ডান দিক prime. ছাড়টির দাম কিছু redundancy, আর লাভ সব FD টেবিলের ভেতরেই পরীক্ষা করতে পারা।
প্র ০৪conflict serializable নয়, অথচ view serializable — এমন schedule কীভাবে সম্ভব? বাস্তব DBMS কোনটি ব্যবহার করে?
দুটি schedule view equivalent হয়, যদি তিনটি জিনিস মেলে: প্রতিটি item-এর প্রাথমিক মান কে পড়ে, প্রতিটি read কার লেখা পড়ে, আর প্রতিটি item-এর শেষ write কার। conflict equivalence আরও কড়া: প্রতিটি conflict জোড়ার ক্রম মেলাতে হয়। ফারাকটি তৈরি করে blind write — আগে না পড়ে লেখা।
R1(A), W2(A), W1(A), W3(A) দেখুন। conflict graph-এ R1(A) … W2(A) থেকে T1 → T2, আর W2(A) … W1(A) থেকে T2 → T1 — চক্র, তাই conflict serializable নয়। কিন্তু view-এর তিন শর্ত দেখুন: T1 প্রাথমিক মান পড়ে, কেউ কারও লেখা পড়ে না, আর শেষ write T3-এর। serial T1, T2, T3-তেও ঠিক তাই। W2(A) আর W1(A)-র মান কেউ কখনো পড়েই না — T3 সব মুছে দেয়। তাই তাদের ক্রম ফলাফলে কোনো প্রভাব ফেলে না, যদিও conflict-এর নিয়মে ক্রমটি গুরুত্বপূর্ণ ধরা হয়। প্রমাণযোগ্য সত্য: প্রতিটি conflict serializable schedule view serializable; আর যে view serializable schedule conflict serializable নয়, তাতে blind write থাকতেই হবে।
তাহলে বাস্তব DBMS view serializability কেন ব্যবহার করে না? কারণ এটি পরীক্ষা করা NP-complete — Christos Papadimitriou ১৯৭৯ সালে তা প্রমাণ করেন। conflict serializability পরীক্ষা করা সহজ (precedence graph-এ চক্র খোঁজা, রৈখিক সময়), আর তার চেয়েও বড় কথা, তা আগেভাগে নিশ্চিত করা যায় — 2PL মানলেই schedule conflict serializable হয় (Eswaran, Gray, Lorie আর Traiger, ১৯৭৬)। আধুনিক পথটি আরেকটি: PostgreSQL ৯.১ (২০১১) থেকে SERIALIZABLE level চালায় Serializable Snapshot Isolation (Cahill, Röhm আর Fekete, ২০০৮) — snapshot-এর ওপর বিপজ্জনক read–write নির্ভরতার কাঠামো ধরে transaction বাতিল করে।
মূল উপলব্ধি: view serializability তত্ত্বে বড় শ্রেণি, কিন্তু পরীক্ষা করা কঠিন; conflict serializability ছোট শ্রেণি, কিন্তু সহজে নিশ্চিত করা যায় — তাই বাস্তবে সেটিই রাজত্ব করে। MCQ-তে blind write দেখলেই view serializability-র কথা ভাবুন।
প্র ০৫primary key, primary index আর clustered index — তিনটি কি একই? বিভিন্ন DBMS-এ বাস্তবে কী হয়?
তিনটি আলাদা স্তরের ধারণা। primary key একটি যৌক্তিক নিয়ম: এই কলাম(গুলো)-র মান অনন্য আর NULL নয়। clustered index একটি ভৌত বিন্যাস: টেবিলের সারিগুলো ডিস্কে index-এর key-র ক্রমে সাজানো, বা index-এর leaf-এই সারিগুলো বসানো। পাঠ্যবইয়ের primary index শব্দটি সাধারণত বোঝায় সাজানো ফাইলের search key-র ওপর index — যা প্রায়ই primary key, কিন্তু সবসময় নয়। সারিগুলো একটিই ক্রমে সাজানো যায়, তাই clustered index টেবিলে সর্বোচ্চ একটি; বাকিগুলো secondary (non-clustered).
বাস্তবে DBMS-ভেদে আলাদা: MySQL InnoDB-এ প্রতিটি টেবিল তার primary key অনুযায়ী clustered (PK না দিলে প্রথম NOT NULL UNIQUE index, নইলে একটি লুকানো row id). secondary index-এর leaf-এ সারির ঠিকানা নয়, PK-র মান থাকে — তাই বড় PK সব index বড় করে। SQL Server-এ PK ডিফল্টে clustered, তবে NONCLUSTERED লিখে বদলানো যায় আর অন্য কলামে clustered index দেওয়া যায়। PostgreSQL-এ টেবিল একটি heap — সারি যেখানে জায়গা পায় সেখানে বসে; PK-ও একটি আলাদা B-tree. CLUSTER কমান্ড একবার সাজিয়ে দেয়, কিন্তু পরের লেখায় ক্রম রক্ষা হয় না। Oracle-এ ডিফল্ট heap, চাইলে index-organized table. SQLite-এর সাধারণ টেবিল rowid অনুযায়ী একটি B-tree (INTEGER PRIMARY KEY লিখলে সেটিই rowid); WITHOUT ROWID টেবিল (২০১৩ সালের ৩.৮.২ সংস্করণ থেকে) PK অনুযায়ী clustered.
কেন এটি গুরুত্বপূর্ণ? clustered index-এ পরিসরের কোয়েরি (যেমন তারিখের পরিসর) পাশাপাশি page পড়ে — দ্রুত। আর InnoDB-তে এলোমেলো UUID-কে PK করলে প্রতিটি INSERT B-tree-র যেকোনো জায়গায় পড়ে — page split আর খণ্ডিত টেবিল; ক্রমবর্ধমান key এ কারণে প্রায়ই ভালো।
মূল উপলব্ধি: PK হলো “কী নিয়ম”, clustered index হলো “ডিস্কে কীভাবে সাজানো”। অনেক DBMS দুটি একসাথে জুড়ে দেয়, কিন্তু সংজ্ঞায় তারা আলাদা — MCQ-তে “primary key মানেই clustered” অপশনটি তাই সাধারণত ভুল।
প্র ০৬isolation level-এর টেবিল মুখস্থ করেছি, তবু PostgreSQL, MySQL আর Oracle-এর আচরণ মেলে না কেন? MCQ-তে কোনটি ধরব?
পাঠ্যবইয়ের টেবিলটি আসে SQL-92 standard থেকে, যা চারটি level-কে সংজ্ঞায়িত করে কোন anomaly নিষিদ্ধ তা দিয়ে: READ UNCOMMITTED-এ কিছুই নিষিদ্ধ নয়; READ COMMITTED-এ dirty read নিষিদ্ধ; REPEATABLE READ-এ non-repeatable read-ও; SERIALIZABLE-এ phantom-ও, আর ফল কোনো serial ক্রমের সমান। standard শুধু ন্যূনতম নিশ্চয়তা বলে — কোনো DBMS চাইলে বেশি দিতে পারে।
১৯৯৫ সালে Hal Berenson, Phil Bernstein, Jim Gray আর সহকর্মীরা “A Critique of ANSI SQL Isolation Levels” প্রবন্ধে দেখান যে এই anomaly-ভিত্তিক সংজ্ঞা অস্পষ্ট, আর এতে একটি গুরুত্বপূর্ণ level ধরা পড়ে না — snapshot isolation, যা dirty, non-repeatable আর phantom read তিনটিই আটকায়, তবু serializable নয়, কারণ write skew ঘটতে দেয়। এই ফাঁকেই বাস্তব DBMS-গুলোর ভিন্নতা: PostgreSQL-এর REPEATABLE READ আসলে snapshot isolation (তাই phantom-ও দেখায় না), আর ৯.১-এর আগে তার SERIALIZABLE-ও তাই ছিল। Oracle-এর “SERIALIZABLE” বহুদিন ধরে snapshot isolation-ই। MySQL InnoDB-র ডিফল্ট REPEATABLE READ: সাধারণ SELECT snapshot পড়ে, আর locking read-এ next-key lock phantom আটকায়। ডিফল্ট level-ও আলাদা — PostgreSQL, Oracle আর SQL Server-এ READ COMMITTED, InnoDB-তে REPEATABLE READ. SQLite-এ একসাথে একজনই লিখতে পারে, তাই তার আচরণ ডিফল্টে serializable.
MCQ-তে নিয়ম: DBMS-এর নাম না থাকলে standard-এর টেবিল ধরুন — “phantom আটকায় এমন সবচেয়ে নিচের level” = SERIALIZABLE. প্রশ্নে PostgreSQL বা MySQL-এর নাম থাকলে সেই DBMS-এর আচরণ। আর write skew-এর প্রশ্নে মনে রাখুন: snapshot-ভিত্তিক যেকোনো level, নাম যা-ই হোক, তা আটকায় না — লাগবে SSI, locking read (SELECT … FOR UPDATE), বা constraint দিয়ে সংঘাতটি দৃশ্যমান করা।
মূল উপলব্ধি: standard-এর টেবিল ন্যূনতম প্রতিশ্রুতি; প্রতিটি DBMS তার ওপর নিজের প্রকৌশল বসায়। প্রশ্নে DBMS-এর নাম দেখেই ঠিক করুন কোন টেবিল ধরবেন।
শেষ ধাপ — ক্রম সাজান আর স্কোর দেখুন
উপরের সব MCQ শেষ করলে নিচে আপনার মোট স্কোর দেখাবে — প্রথম চেষ্টায় কয়টি ঠিক হয়েছে।
ক্রমFD-র সেট দেওয়া আছে — relation সর্বোচ্চ কোন normal form-এ, তা বের করার ধাপগুলো আগে থেকে পরে সাজান (▲▼ চেপে সরান)
- attribute closure দিয়ে সব candidate key বের করা
- prime আর non-prime attribute চিহ্নিত করা
- non-prime-এর partial dependency খোঁজা (2NF)
- প্রতিটি FD-তে “বাঁ দিক superkey, নয়তো ডান দিক prime” যাচাই (3NF)
- প্রতিটি FD-র বাঁ দিক superkey কি না যাচাই (BCNF)
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব শব্দ এখানে একসাথে:
মনে রাখুন
- বাদ দিন, তারপর যাচাই করুন: প্রতিটি অপশনের পেছনের দাবি একটি নিয়ম বা ছোট উদাহরণ দিয়ে কাটুন; normal form-এর “সর্বোচ্চ” প্রশ্নে 2NF → 3NF → BCNF ক্রমে পরীক্ষা করুন।
- NULL মানে UNKNOWN:
= NULLকিছু দেয় না, NOT IN-এ একটি NULL সব থামায়, COUNT(col) আর AVG NULL বাদ দেয়, আর LEFT JOIN-এর পর WHERE NULL-সারি ছাঁটে। - তত্ত্বে পদ্ধতি: key-র জন্য closure, normal form-এর জন্য key থেকে শুরু, serializability-র জন্য item ধরে precedence graph, খরচের জন্য আগে সূত্র।
- সংজ্ঞার জোড়া আলাদা রাখুন: physical বনাম logical independence, primary key বনাম clustered index, conflict বনাম view, RPO বনাম RTO, replication বনাম backup.
- AI-এর MCQ যাচাই: ফলের প্রতিটি প্রশ্নের SQL নিজে চালান, প্রতিটি key নিজে বের করুন, আর DBMS-এর নাম ছাড়া আচরণের দাবি মেনে নেবেন না।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৬৫ · লিখিত ও মৌখিক (ভাইভা) প্রশ্নপরবর্তী পর্বঅপশন ছাড়া উত্তর লেখা — normalization, transaction আর আরও।
- পর্ব ৬৩ · SQL output predictionআগের পর্বকোয়েরির ফল হাতে বের করার আরও লম্বা অনুশীলন।
- ডেটাবেস (DBMS) ও SQL · কোর্স হোম৬৭টি পর্বপুরো কোর্সের রোডম্যাপ আর মডিউল টেস্ট।
- DSA · B-treeপাশের ট্র্যাকB+ tree-র উচ্চতা আর split-এর প্রশ্নের পেছনের ডেটা স্ট্রাকচার।
- Python · SQLite ডেটাবেসপাশের ট্র্যাকMCQ-র SQL উত্তর যাচাইয়ের ছোট স্ক্রিপ্ট লেখার জন্য।