ভূমিকা

এটি SQL ইন্টারভিউ প্রস্তুতির দ্বিতীয় পর্ব। এখানে আরও ১০টি গুরুত্বপূর্ণ SQL প্রশ্ন এবং বিস্তারিত উত্তর বাংলায় দেওয়া হয়েছে। এগুলো বিশেষভাবে senior-level Java developer ইন্টারভিউর জন্য প্রাসঙ্গিক।


১১. CTE (Common Table Expression) কী এবং কেন ব্যবহার করবেন?

উত্তর:

CTE হলো একটি named temporary result set যা WITH keyword দিয়ে তৈরি করা হয় এবং শুধুমাত্র সেই query-র মধ্যে ব্যবহারযোগ্য। এটি complex query-কে ছোট, পাঠযোগ্য অংশে ভাগ করতে সাহায্য করে।

CTE কেন ব্যবহার করবেন:

  • Code পাঠযোগ্যতা বাড়ায়
  • একই subquery বারবার লেখা এড়ানো যায়
  • Recursive query লেখা সম্ভব হয়
  • Debugging সহজ হয়
-- সাধারণ CTE উদাহরণ
WITH high_earners AS (
    SELECT emp_id, name, salary, dept_id
    FROM employees
    WHERE salary > 70000
),
dept_summary AS (
    SELECT dept_id, COUNT(*) AS high_earner_count, AVG(salary) AS avg_salary
    FROM high_earners
    GROUP BY dept_id
)
SELECT d.dept_name, ds.high_earner_count, ds.avg_salary
FROM dept_summary ds
JOIN departments d ON ds.dept_id = d.dept_id
ORDER BY ds.avg_salary DESC;

CTE বনাম Subquery:

  • CTE একবার define করে একাধিক জায়গায় reference করা যায়
  • Subquery প্রতিবার inline লিখতে হয়
  • CTE recursive হতে পারে, subquery পারে না

১২. SQL-এ View কী? View ব্যবহারের সুবিধা ও সীমাবদ্ধতা কী?

উত্তর:

View হলো একটি virtual table যা একটি SQL query-র উপর ভিত্তি করে তৈরি। এটি নিজে কোনো ডেটা store করে না, বরং query execute করার সময় data retrieve করে।

সুবিধা:

  • জটিল query পুনরায় ব্যবহারযোগ্য করে
  • Data security নিশ্চিত করে (sensitive column লুকানো যায়)
  • Business logic এক জায়গায় রাখা যায়
  • Backward compatibility বজায় রাখতে সাহায্য করে

সীমাবদ্ধতা:

  • Performance: প্রতিবার query execute করে (Materialized View ব্যতীত)
  • Updatable view-এ সীমাবদ্ধতা থাকে
  • Complex view debug করা কঠিন
-- View তৈরি
CREATE VIEW employee_details AS
SELECT
    e.emp_id,
    e.name,
    e.salary,
    d.dept_name,
    m.name AS manager_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
LEFT JOIN employees m ON e.manager_id = m.emp_id;

-- View ব্যবহার (সাধারণ টেবিলের মতো)
SELECT * FROM employee_details WHERE dept_name = 'Engineering';

-- View update (simple view-এ কাজ করে)
UPDATE employee_details SET salary = 80000 WHERE emp_id = 101;

-- View মুছে ফেলা
DROP VIEW employee_details;

১৩. SQL-এ Trigger কী এবং কখন ব্যবহার করবেন?

উত্তর:

Trigger হলো একটি stored procedure যা automatically execute হয় যখন কোনো নির্দিষ্ট event (INSERT, UPDATE, DELETE) ঘটে।

Trigger-এর ধরন:

  • BEFORE Trigger: Operation-এর আগে execute হয়
  • AFTER Trigger: Operation-এর পরে execute হয়
  • INSTEAD OF Trigger: View-এ operation-এর পরিবর্তে execute হয়
-- BEFORE INSERT Trigger: created_at স্বয়ংক্রিয়ভাবে set করা
CREATE TRIGGER set_created_at
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
    SET NEW.created_at = NOW();
    SET NEW.updated_at = NOW();
END;

-- AFTER UPDATE Trigger: Audit log রাখা
CREATE TABLE salary_audit (
    audit_id INT AUTO_INCREMENT PRIMARY KEY,
    emp_id INT,
    old_salary DECIMAL(10,2),
    new_salary DECIMAL(10,2),
    changed_at DATETIME,
    changed_by VARCHAR(100)
);

CREATE TRIGGER log_salary_change
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
    IF OLD.salary != NEW.salary THEN
        INSERT INTO salary_audit (emp_id, old_salary, new_salary, changed_at, changed_by)
        VALUES (NEW.emp_id, OLD.salary, NEW.salary, NOW(), USER());
    END IF;
END;

কখন Trigger ব্যবহার করবেন: Audit log, data validation, automatic timestamp, business rules enforce করতে।


১৪. SQL-এ Isolation Levels কী কী এবং কোনটি কখন ব্যবহার করবেন?

উত্তর:

Isolation Level নির্ধারণ করে যে concurrent transactions একে অপরের উপর কতটা প্রভাব ফেলতে পারবে।

চারটি Isolation Level (কম থেকে বেশি isolation):

Isolation Level Dirty Read Non-Repeatable Read Phantom Read
READ UNCOMMITTED সম্ভব সম্ভব সম্ভব
READ COMMITTED নেই সম্ভব সম্ভব
REPEATABLE READ নেই নেই সম্ভব
SERIALIZABLE নেই নেই নেই

সমস্যাগুলোর সংজ্ঞা:

  • Dirty Read: Commit না হওয়া data read করা
  • Non-Repeatable Read: একই transaction-এ একই row দুবার read করলে ভিন্ন result
  • Phantom Read: একই transaction-এ একই query দুবার চালালে ভিন্ন row set
-- Isolation level set করা (MySQL)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
SELECT * FROM accounts WHERE id = 1;
COMMIT;

-- Spring/Java-তে
-- @Transactional(isolation = Isolation.READ_COMMITTED)

ব্যবহারিক পরামর্শ: বেশিরভাগ ক্ষেত্রে READ COMMITTED যথেষ্ট। Financial transactions-এ SERIALIZABLE ব্যবহার করুন তবে performance cost মাথায় রাখুন।


১৫. SQL-এ EXISTS বনাম IN — কোনটি কখন ব্যবহার করবেন?

উত্তর:

IN: একটি static value list বা subquery-র result-এর সাথে match করে।

EXISTS: Subquery কোনো row return করে কিনা শুধু সেটা check করে (TRUE/FALSE)।

-- IN উদাহরণ
SELECT name FROM employees
WHERE dept_id IN (1, 3, 5);

-- IN with subquery
SELECT name FROM employees
WHERE dept_id IN (
    SELECT dept_id FROM departments WHERE location = 'Dhaka'
);

-- EXISTS উদাহরণ (বেশি efficient বড় dataset-এ)
SELECT name FROM employees e
WHERE EXISTS (
    SELECT 1 FROM departments d
    WHERE d.dept_id = e.dept_id
    AND d.location = 'Dhaka'
);

-- NOT EXISTS vs NOT IN পার্থক্য
-- NOT IN: subquery-তে NULL থাকলে সব row বাদ পড়ে!
SELECT name FROM employees
WHERE dept_id NOT IN (SELECT dept_id FROM departments WHERE location IS NULL);
-- ↑ এটি কোনো result নাও দিতে পারে যদি NULL থাকে

-- NOT EXISTS: NULL-safe
SELECT name FROM employees e
WHERE NOT EXISTS (
    SELECT 1 FROM departments d
    WHERE d.dept_id = e.dept_id AND d.location IS NULL
);

কখন কোনটি:

  • IN ভালো: ছোট static list বা ছোট subquery
  • EXISTS ভালো: বড় টেবিল, correlated subquery, NULL থাকতে পারে

১৬. Database Sharding এবং Partitioning-এর মধ্যে পার্থক্য কী?

উত্তর:

Partitioning হলো একটি টেবিলকে ভৌতিকভাবে একই database-এ একাধিক ভাগে ভাগ করা। Logical একটি টেবিল কিন্তু internally আলাদা partition-এ data store হয়।

Sharding হলো data একাধিক আলাদা database server-এ ভাগ করা। প্রতিটি shard একটি স্বাধীন database।

-- MySQL Table Partitioning উদাহরণ
CREATE TABLE orders (
    order_id   INT NOT NULL,
    order_date DATE NOT NULL,
    amount     DECIMAL(10,2),
    customer_id INT
)
PARTITION BY RANGE (YEAR(order_date)) (
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION p_future VALUES LESS THAN MAXVALUE
);

-- Partition pruning: শুধু ২০২৩ সালের data query
SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
-- MySQL স্বয়ংক্রিয়ভাবে শুধু p2023 partition scan করবে

-- Partition info দেখা
SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'orders';

Partitioning-এর ধরন:

  • RANGE: Date/number range অনুযায়ী
  • LIST: নির্দিষ্ট value-এর list অনুযায়ী
  • HASH: Hash function ব্যবহার করে সমানভাবে
  • KEY: Column value-এর key অনুযায়ী

১৭. SQL-এ GROUP BY ROLLUP এবং CUBE কী?

উত্তর:

ROLLUP subtotal এবং grand total সহ hierarchical summary তৈরি করে।

CUBE সব সম্ভাব্য combination-এর subtotal তৈরি করে।

-- Sample data: sales by year, region, product
-- ROLLUP উদাহরণ: region এবং year-এর subtotal
SELECT
    COALESCE(region, 'সব অঞ্চল')   AS অঞ্চল,
    COALESCE(CAST(year AS CHAR), 'সব বছর') AS বছর,
    SUM(sales_amount)               AS মোট_বিক্রয়
FROM sales
GROUP BY region, year WITH ROLLUP;

-- ফলাফল উদাহরণ:
-- Dhaka    | 2023 | 500000
-- Dhaka    | 2024 | 620000
-- Dhaka    | সব বছর | 1120000   ← subtotal for Dhaka
-- Chittagong | 2023 | 300000
-- Chittagong | সব বছর | 300000
-- সব অঞ্চল | সব বছর | 1420000  ← grand total

-- CUBE উদাহরণ (সব combination)
SELECT
    COALESCE(region, 'সব')   AS অঞ্চল,
    COALESCE(product, 'সব')  AS পণ্য,
    COALESCE(CAST(year AS CHAR), 'সব') AS বছর,
    SUM(sales_amount) AS মোট
FROM sales
GROUP BY region, product, year WITH CUBE;
-- CUBE সব সম্ভাব্য combination-এর জন্য subtotal দেয়

ব্যবহার: BI (Business Intelligence) dashboard, reporting query-তে ROLLUP/CUBE অত্যন্ত কার্যকর।


১৮. SQL-এ Full-Text Search কীভাবে কাজ করে?

উত্তর:

Full-Text Search হলো text data-র মধ্যে keyword search করার একটি বিশেষ mechanism যা LIKE '%keyword%' এর চেয়ে অনেক বেশি efficient।

-- Full-Text Index তৈরি
CREATE TABLE articles (
    article_id INT PRIMARY KEY AUTO_INCREMENT,
    title      VARCHAR(255),
    content    TEXT,
    FULLTEXT idx_search (title, content)
);

-- Natural Language Mode (default)
SELECT article_id, title,
       MATCH(title, content) AGAINST ('Java SQL optimization') AS relevance_score
FROM articles
WHERE MATCH(title, content) AGAINST ('Java SQL optimization')
ORDER BY relevance_score DESC;

-- Boolean Mode: advanced search
SELECT title
FROM articles
WHERE MATCH(title, content) AGAINST (
    '+Java +SQL -Python'   -- Java এবং SQL থাকতে হবে, Python থাকলে বাদ
    IN BOOLEAN MODE
);

-- Phrase search
SELECT title
FROM articles
WHERE MATCH(title, content) AGAINST (
    '"database optimization"'   -- exact phrase
    IN BOOLEAN MODE
);

LIKE বনাম FULLTEXT:

  • LIKE '%keyword%' index ব্যবহার করে না, slow
  • FULLTEXT inverted index ব্যবহার করে, fast এবং relevance scoring দেয়
  • বড় text data-তে সবসময় FULLTEXT ব্যবহার করুন

১৯. SQL-এ Materialized View কী এবং Regular View-এর সাথে পার্থক্য কী?

উত্তর:

Regular View কোনো data store করে না — query করলে প্রতিবার underlying টেবিল থেকে data নিয়ে আসে।

Materialized View query-র result physically store করে রাখে। নির্দিষ্ট সময় পরপর বা manually refresh করতে হয়।

-- PostgreSQL-এ Materialized View
CREATE MATERIALIZED VIEW monthly_sales_summary AS
SELECT
    DATE_TRUNC('month', order_date) AS month,
    customer_id,
    COUNT(order_id)                 AS order_count,
    SUM(total_amount)               AS total_spent
FROM orders
WHERE status = 'completed'
GROUP BY DATE_TRUNC('month', order_date), customer_id
WITH DATA;  -- এখনই populate করো

-- Index on Materialized View
CREATE INDEX idx_mv_month ON monthly_sales_summary(month);
CREATE INDEX idx_mv_customer ON monthly_sales_summary(customer_id);

-- Manual Refresh
REFRESH MATERIALIZED VIEW monthly_sales_summary;

-- Concurrent Refresh (lock ছাড়া, unique index দরকার)
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales_summary;

MySQL-এ Materialized View নেই, তাই সেখানে সাধারণত:

  • Summary টেবিল তৈরি করে Event Scheduler দিয়ে নিয়মিত populate করা হয়
  • অথবা application layer থেকে cache maintain করা হয়

কখন ব্যবহার করবেন: ভারী aggregation query যা বারবার চালাতে হয় কিন্তু real-time data দরকার নেই।


২০. SQL Performance Tuning-এ Execution Plan কীভাবে পড়বেন?

উত্তর:

EXPLAIN বা EXPLAIN ANALYZE command দিয়ে query-র execution plan দেখা যায় — database engine কীভাবে query execute করবে সেটা জানা যায়।

-- MySQL EXPLAIN
EXPLAIN SELECT e.name, d.dept_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE e.salary > 50000;

-- বিস্তারিত জানতে EXPLAIN ANALYZE (MySQL 8.0+)
EXPLAIN ANALYZE
SELECT e.name, d.dept_name, AVG(e.salary) OVER (PARTITION BY e.dept_id)
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE e.salary > 50000;

EXPLAIN Output-এর গুরুত্বপূর্ণ কলাম:

কলাম অর্থ ভালো/খারাপ
type Join type system > const > eq_ref > ref > range > index > ALL
key ব্যবহৃত index NULL হলে index নেই
rows আনুমানিক scan করা rows কম হলে ভালো
Extra অতিরিক্ত তথ্য "Using filesort" বা "Using temporary" খারাপ
-- সমস্যা চিহ্নিতকরণ ও সমাধান

-- ১. Full Table Scan (type = ALL) — খারাপ
EXPLAIN SELECT * FROM employees WHERE UPPER(name) = 'JOHN';
-- সমাধান: function ছাড়া index-friendly লিখুন
SELECT * FROM employees WHERE name = 'John';

-- ২. Filesort — ধীর
EXPLAIN SELECT * FROM employees ORDER BY salary DESC;
-- সমাধান: salary-তে index যোগ করুন
CREATE INDEX idx_salary ON employees(salary);

-- ৩. Using temporary — খারাপ
EXPLAIN SELECT dept_id, COUNT(*) FROM employees GROUP BY dept_id;
-- সমাধান: dept_id-এ index থাকলে temporary table দরকার হয় না

Performance Checklist:

  • type = ALL দেখলে index যোগ করুন
  • Extra = Using filesort দেখলে ORDER BY column-এ index দিন
  • rows সংখ্যা বেশি হলে WHERE clause review করুন
  • JOIN column-গুলোতে index আছে কিনা যাচাই করুন

উপসংহার

এই দ্বিতীয় পর্বে আমরা আরও advanced SQL বিষয়গুলো দেখলাম:

  • CTE: জটিল query সহজ ও পাঠযোগ্য করে
  • View ও Trigger: Database-level business logic
  • Isolation Level: Concurrency সমস্যা সমাধান
  • Partitioning: বড় টেবিলের performance উন্নয়ন
  • EXPLAIN: Query bottleneck চিহ্নিতকরণ

Senior Java developer হিসেবে শুধু query লেখা নয়, কেন এবং কীভাবে optimize করতে হয় সেটা বোঝাটা ইন্টারভিউতে আপনাকে আলাদা করবে।

Share