ডাটাবেসে ডেটা ঢোকার সময় আমরা চাই যে কিছু নিয়ম মেনে চলুক – যেমন কোনো কলাম খালি রাখা যাবে না, বেতন শূন্য বা নেগেটিভ হতে পারবে না, কিংবা রোল নম্বর সবার আলাদা হবে। এই নিয়মগুলোকে কনস্ট্রেইন্ট (Constraints) বলে। কনস্ট্রেইন্ট টেবিলের কলাম বা পুরো টেবিলের উপর প্রয়োগ করা হয় এবং ডেটার সঠিকতা ও নির্ভরযোগ্যতা নিশ্চিত করে। SQLite-তে প্রধান পাঁচটি কনস্ট্রেইন্ট রয়েছে: NOT NULL, DEFAULT, UNIQUE, PRIMARY KEY, এবং CHECK। আজ আমরা প্রত্যেকটির কাজ, ব্যবহারের নিয়ম এবং বাস্তব উদাহরণ বিস্তারিত শিখব।
পূর্বপ্রস্তুতি:
- SQLite ইন্সটল করা থাকতে হবে (সিরিজের ৩য় পর্ব দেখুন)।
- আমরা একটি নতুন ডাটাবেস
constraints.dbব্যবহার করব, যাতে কনস্ট্রেইন্ট পরীক্ষা করা যায়। - কোনো অতিরিক্ত প্যাকেজ লাগবে না।
১. কনস্ট্রেইন্ট কী এবং প্রকারভেদ
কনস্ট্রেইন্ট হলো টেবিল তৈরির সময় কলামে দেওয়া কিছু শর্ত বা সীমাবদ্ধতা। এরা দুই ধরনের:
- কলাম লেভেল কনস্ট্রেইন্ট: শুধু একটি কলামের উপর প্রযোজ্য।
- টেবিল লেভেল কনস্ট্রেইন্ট: একাধিক কলামের সমন্বয়ে পুরো টেবিলের জন্য প্রযোজ্য (যেমন কম্পোজিট PRIMARY KEY)।
SQLite-র বহুল ব্যবহৃত কনস্ট্রেইন্টগুলো নিচে দেওয়া হলো।
২. NOT NULL কনস্ট্রেইন্ট
ডিফল্টভাবে যেকোনো কলামে NULL (অজানা/খালি) মান রাখা যায়। কিন্তু আমরা যদি চাই যে কোনোভাবেই একটি কলাম খালি রাখা যাবে না, তাহলে সেটিকে NOT NULL কনস্ট্রেইন্ট দিতে হবে।
সিনট্যাক্স:
sql
CREATE TABLE table_name ( column_name data_type NOT NULL, ... );
উদাহরণ: COMPANY টেবিলে ID, NAME, AGE কলামগুলোতে NOT NULL দিন।
sql
CREATE TABLE COMPANY ( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
এখন যদি আমরা INSERT INTO COMPANY (ID, NAME, AGE, SALARY) VALUES (1, NULL, 25, 10000); দেই, তাহলে এরর আসবে: NOT NULL constraint failed: COMPANY.NAME। কিন্তু ADDRESS বাদ দিলে সেটি NULL থাকবে, কারণ সেখানে NOT NULL দেওয়া হয়নি।
৩. DEFAULT কনস্ট্রেইন্ট
ইনসার্টের সময় কোনো কলামের মান দেওয়া না হলে, আমরা চাইলে একটি ডিফল্ট মান বসিয়ে দিতে পারি DEFAULT কনস্ট্রেইন্টের মাধ্যমে।
সিনট্যাক্স:
sql
CREATE TABLE table_name ( column_name data_type DEFAULT default_value, ... );
উদাহরণ: COMPANY টেবিলে SALARY কলামের ডিফল্ট 50000.00 রাখি।
sql
CREATE TABLE COMPANY ( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL DEFAULT 50000.00 );
এখন INSERT INTO COMPANY (ID, NAME, AGE) VALUES (1, 'Rahim', 30); দিলে SALARY কলামে 50000.00 বসে যাবে। কিন্তু যদি SALARY দেওয়া হয়, তাহলে প্রদত্ত মানই ব্যবহার হবে।
৪. UNIQUE কনস্ট্রেইন্ট
একটি কলামের সকল মান যাতে আলাদা (ডুপ্লিকেট নয়) হয়, তা নিশ্চিত করতে UNIQUE কনস্ট্রেইন্ট ব্যবহার করা হয়। একই টেবিলে একাধিক UNIQUE কলাম থাকতে পারে।
সিনট্যাক্স:
sql
CREATE TABLE table_name ( column_name data_type UNIQUE, ... );
উদাহরণ: AGE কলামে UNIQUE দিলে একই বয়স দুইবার বসবে না।
sql
CREATE TABLE COMPANY ( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL UNIQUE, ADDRESS CHAR(50), SALARY REAL DEFAULT 50000.00 );
এখন প্রথমে INSERT INTO COMPANY VALUES (1, 'Rahim', 25, 'Dhaka', 30000); সফল হবে। দ্বিতীয়বার INSERT INTO COMPANY VALUES (2, 'Karim', 25, 'CTG', 40000); দিলে UNIQUE constraint failed: COMPANY.AGE এরর আসবে।
মনে রাখবেন: UNIQUE কলামে একাধিক NULL থাকতে পারে (NULL একে অপরের সমান নয় বিবেচিত হয়)।
৫. PRIMARY KEY কনস্ট্রেইন্ট
PRIMARY KEY (প্রাইমারি কি) টেবিলের প্রতিটি রেকর্ডকে অনন্যভাবে শনাক্ত করে। এটি একই সাথে UNIQUE এবং NOT NULL-এর সমন্বয় (যদিও SQLite-তে ঐতিহাসিক কারণে প্রাইমারি কি NULL হতে পারে, কিন্তু এটি এড়িয়ে চলা উচিত)। একটি টেবিলে কেবলমাত্র একটি PRIMARY KEY থাকতে পারে, যা এক বা একাধিক কলামের সমন্বয়ে গঠিত হতে পারে (কম্পোজিট কি)।
সিনট্যাক্স:
sql
CREATE TABLE table_name ( column1 data_type PRIMARY KEY, ... ); -- অথবা টেবিল লেভেলে: CREATE TABLE table_name ( column1 data_type, column2 data_type, PRIMARY KEY (column1, column2) );
উদাহরণ ১ – একক প্রাইমারি কি:
sql
CREATE TABLE COMPANY ( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
এখানে ID হলো প্রাইমারি কি, যা স্বয়ংক্রিয়ভাবে UNIQUE ও NOT NULL হবে।
উদাহরণ ২ – কম্পোজিট প্রাইমারি কি:
sql
CREATE TABLE ORDER_ITEMS ( ORDER_ID INT, PRODUCT_ID INT, QUANTITY INT, PRIMARY KEY (ORDER_ID, PRODUCT_ID) );
এখানে ORDER_ID ও PRODUCT_ID-এর জুটি অনন্য হবে।
গুরুত্বপূর্ণ: যদি কলামটি INTEGER PRIMARY KEY হয়, তাহলে সেটি rowid-এর অ্যালিয়াস হিসেবে কাজ করে এবং ইনসার্টের সময় NULL দিলে স্বয়ংক্রিয়ভাবে ইউনিক পূর্ণসংখ্যা জেনারেট হয় (অটোইনক্রিমেন্টের মতো)।
৬. CHECK কনস্ট্রেইন্ট
CHECK কনস্ট্রেইন্ট দিয়ে আমরা কোনো কলামের মান একটি নির্দিষ্ট শর্ত পূরণ করছে কিনা তা নিশ্চিত করি। শর্তটি মিথ্যা হলে রেকর্ডটি গ্রহণ করা হবে না।
সিনট্যাক্স:
sql
CREATE TABLE table_name ( column_name data_type CHECK (condition), ... );
শর্তে কলামের নাম, অপারেটর ও লিটারেল মান ব্যবহার করা যায়।
উদাহরণ: বেতন কখনো শূন্য বা নেগেটিভ হতে পারবে না।
sql
CREATE TABLE COMPANY3 ( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL CHECK (SALARY > 0) );
INSERT INTO COMPANY3 VALUES (1, 'Rahim', 30, 'Dhaka', 0); দিলে CHECK constraint failed: COMPANY3 এরর আসবে।
একাধিক শর্তও দেওয়া যায়:
sql
CHECK (SALARY > 0 AND AGE >= 18)
৭. কনস্ট্রেইন্ট মুছে ফেলা (Dropping Constraints)
SQLite-র ALTER TABLE কমান্ড খুবই সীমিত। এটি কেবল টেবিলের নাম পরিবর্তন (RENAME TO) ও নতুন কলাম যোগ (ADD COLUMN) করতে পারে। আপনি কোনো কলাম ডিলিট করতে পারবেন না, কনস্ট্রেইন্ট পরিবর্তন বা মুছতে পারবেন না। একবার তৈরি কনস্ট্রেইন্ট থেকে মুক্তি পেতে চাইলে আপনাকে করতে হবে:
- নতুন টেবিল তৈরি (কাঙ্ক্ষিত কনস্ট্রেইন্টসহ)।
- পুরনো টেবিল থেকে ডেটা কপি (
INSERT INTO new_table SELECT ... FROM old_table)। - পুরনো টেবিল ড্রপ (
DROP TABLE old_table)। - নতুন টেবিলের নাম পরিবর্তন (
ALTER TABLE new_table RENAME TO old_table)।
এটি একটু জটিল, তাই টেবিল ডিজাইনের সময় কনস্ট্রেইন্ট সঠিকভাবে নির্ধারণ করা অত্যন্ত জরুরি।
৮. সম্পূর্ণ উদাহরণ: সব কনস্ট্রেইন্ট একসাথে
চলুন একটি EMPLOYEES টেবিল তৈরি করি যাতে সব কনস্ট্রেইন্টের ছোঁয়া থাকে।
sql
CREATE TABLE EMPLOYEES (
EMP_ID INTEGER PRIMARY KEY, -- প্রাইমারি কি (NOT NULL ও UNIQUE সমেত)
NAME TEXT NOT NULL, -- খালি নয়
EMAIL TEXT UNIQUE, -- সব ইমেইল আলাদা হতে হবে
AGE INTEGER CHECK (AGE >= 18), -- বয়স কমপক্ষে ১৮
JOIN_DATE TEXT DEFAULT (date('now')), -- আজকের তারিখ বসবে
SALARY REAL DEFAULT 20000.00 CHECK (SALARY > 0) -- ডিফল্ট 20000, শূন্য নয়
);
এবার কিছু ইনসার্ট টেস্ট করি:
sql
-- সঠিক ইনসার্ট
INSERT INTO EMPLOYEES (NAME, EMAIL, AGE, SALARY) VALUES ('Rahim', 'rahim@mail.com', 25, 30000);
-- DEFAULT চেক: JOIN_DATE আজকের তারিখ হবে, SALARY দেওয়া না থাকলে 20000
INSERT INTO EMPLOYEES (NAME, EMAIL, AGE) VALUES ('Karim', 'karim@mail.com', 30);
-- UNIQUE ভায়োলেশন:
INSERT INTO EMPLOYEES (NAME, EMAIL, AGE) VALUES ('Rahim 2', 'rahim@mail.com', 22);
-- ERROR: UNIQUE constraint failed: EMPLOYEES.EMAIL
-- CHECK ভায়োলেশন (বয়স ১৮-এর কম):
INSERT INTO EMPLOYEES (NAME, EMAIL, AGE) VALUES ('Child', 'child@mail.com', 15);
-- ERROR: CHECK constraint failed: EMPLOYEES
-- NOT NULL ভায়োলেশন:
INSERT INTO EMPLOYEES (EMAIL, AGE) VALUES ('noname@mail.com', 40);
-- ERROR: NOT NULL constraint failed: EMPLOYEES.NAME
৯. ডিরেক্টরি স্ট্রাকচার
আমরা constraints.db নামের ডাটাবেসে উপরের অনুশীলনগুলো করছি। ফোল্ডারে শুধু এই ফাইলটি থাকবে:
text
project-folder/ └── constraints.db
কোনো অতিরিক্ত প্যাকেজ প্রয়োজন নেই।
১০. গুরুত্বপূর্ণ টিপস
- PRIMARY KEY বাছাই: বেশিরভাগ টেবিলে একটি একক INTEGER PRIMARY KEY কলাম রাখাই উত্তম, যা ডেটা ম্যানিপুলেশন ও জয়েন সহজ করে।
- UNIQUE বনাম PRIMARY KEY: PRIMARY KEY স্বয়ংক্রিয়ভাবে UNIQUE হয়, কিন্তু UNIQUE কলাম NULL নিতে পারে। টেবিলে একাধিক UNIQUE কলাম থাকতে পারে।
- CHECK-এ সাবকোয়েরি নিষেধ: SQLite-তে CHECK কনস্ট্রেইন্টের ভেতর সাবকোয়েরি ব্যবহার করা যায় না। শুধুমাত্র কলামের মানের উপর শর্ত দেওয়া যায়।
- DEFAULT হিসেবে এক্সপ্রেশন: আপনি ডিফল্ট মান হিসেবে
(datetime('now'))বা(ABS(RANDOM() % 100))-এর মতো এক্সপ্রেশন দিতে পারেন (ব্র্যাকেটের ভেতরে)। - কনস্ট্রেইন্ট নেমিং: SQLite টেবিল তৈরির সময় কনস্ট্রেইন্টের নাম দেওয়া অপশনাল; না দিলে স্বয়ংক্রিয়ভাবে নাম তৈরি হয়। তবে বড় প্রজেক্টে নাম দিলে এরর বোঝা সহজ হয়।
১১. সম্পূর্ণ প্র্যাকটিস সেশন
টার্মিনালে constraints.db খুলে নিচের ধাপগুলো চালান:
sql
.headers on
.mode column
-- টেবিল তৈরি কনস্ট্রেইন্টসহ
CREATE TABLE STUDENTS (
ID INTEGER PRIMARY KEY,
NAME TEXT NOT NULL,
ROLL INTEGER UNIQUE,
AGE INTEGER CHECK (AGE BETWEEN 10 AND 100),
FEES REAL DEFAULT 5000.00 CHECK (FEES >= 0)
);
-- সঠিক ইনসার্ট
INSERT INTO STUDENTS (NAME, ROLL, AGE) VALUES ('Ashik', 1, 20);
INSERT INTO STUDENTS (NAME, ROLL, AGE, FEES) VALUES ('Bonna', 2, 22, 6000);
-- ভুল ইনসার্ট চেষ্টা
INSERT INTO STUDENTS (NAME, ROLL, AGE) VALUES ('Duplicate Roll', 1, 23); -- UNIQUE fail
INSERT INTO STUDENTS (NAME, ROLL, AGE) VALUES ('Young', 3, 5); -- CHECK fail
INSERT INTO STUDENTS (ROLL, AGE) VALUES (4, 25); -- NOT NULL fail (NAME missing)
-- সঠিক এন্ট্রিগুলো দেখুন
SELECT * FROM STUDENTS;
পরবর্তী পর্বে
আমরা শিখব SQLite Joins – বিভিন্ন টেবিলের মধ্যে সম্পর্ক তৈরি করে একত্রে ডেটা বের করার কৌশল।
লেখকের কথা: কনস্ট্রেইন্ট ব্যবহার করলে আপনার ডাটাবেস ডেটা দূষণ থেকে রক্ষা পায়। বাংলায় প্রযুক্তি শেখার এই সিরিজ আপনার কাজে লাগছে তো? পোস্টটি ভালো লাগলে শেয়ার করুন, এবং সিরিজের সব আপডেট পেতে ToLearnTeam.com ব্লগে সাবস্ক্রাইব করুন। আপনার মতামত বা প্রশ্ন জানাতে কমেন্ট করুন – আমরা উত্তর দিতে প্রস্তুত!
SQLite Full Course
- SQLite পরিচিতি ও ইন্সটলেশন গাইড – বাংলায় প্রথম ডাটাবেস তৈরি
- SQLite কী এবং কেন শিখবেন? সম্পূর্ণ ওভারভিউ ও কমান্ড ক্লাসিফিকেশন (DDL, DML, DQL)
- SQLite ইন্সটলেশন গাইড – Windows, Linux ও Mac-এ ধাপে ধাপে সেটআপ
- SQLite ডট কমান্ড (Dot Commands) – সম্পূর্ণ গাইড, আউটপুট ফরম্যাট ও sqlite_master
- SQLite সিনট্যাক্স (Syntax) – কেস সেনসিটিভিটি, কমেন্ট, সব কমান্ডের গঠন ও উদাহরণ
- SQLite ডেটা টাইপ (Data Type) – স্টোরেজ ক্লাস, টাইপ অ্যাফিনিটি, বুলিয়ান ও ডেট-টাইম
- SQLite ডেটাবেস তৈরি (Create Database) – ধাপে ধাপে গাইড, .dump এক্সপোর্ট ও রিস্টোর
- SQLite ATTACH DATABASE – একাধিক ডাটাবেস সংযুক্ত করার সম্পূর্ণ গাইড (বাংলা)
- SQLite DETACH DATABASE – সংযুক্ত ডাটাবেস বিচ্ছিন্ন করার পূর্ণাঙ্গ গাইড
- SQLite CREATE TABLE স্টেটমেন্ট – টেবিল তৈরি করার পূর্ণাঙ্গ গাইড (বাংলা)
- SQLite DROP TABLE স্টেটমেন্ট – টেবিল ডিলিট করার সম্পূর্ণ গাইড (বাংলা)
- SQLite INSERT INTO স্টেটমেন্ট – ডেটা ইনসার্ট করার সম্পূর্ণ গাইড (বাংলা)
- SQLite SELECT স্টেটমেন্ট – টেবিল থেকে ডেটা ফেচ করার সম্পূর্ণ গাইড (বাংলা)
- SQLite অপারেটর (Operators) – Arithmetic, Comparison, Logical, Bitwise (বাংলা টিউটোরিয়াল)
- SQLite এক্সপ্রেশন (Expressions) – বুলিয়ান, নিউমেরিক ও ডেট এক্সপ্রেশন (বাংলা টিউটোরিয়াল)
- SQLite AND ও OR অপারেটর – একাধিক শর্ত দিয়ে ডেটা ফিল্টার (বাংলা টিউটোরিয়াল)
- SQLite UPDATE Query – টেবিলের ডেটা পরিবর্তন করার সম্পূর্ণ গাইড (বাংলা)
- SQLite DELETE Query – টেবিল থেকে ডেটা মুছে ফেলার সম্পূর্ণ গাইড (বাংলা)
- SQLite LIKE Operator – প্যাটার্ন মিলিয়ে ডেটা খোঁজার সম্পূর্ণ গাইড (বাংলা)
- SQLite GLOB Operator – কেস-সেনসিটিভ প্যাটার্ন মিলিয়ে ডেটা খোঁজা (বাংলা)
- SQLite LIMIT Clause – ডেটা সীমিত করে আনার সম্পূর্ণ গাইড (বাংলা)
- SQLite ORDER BY ক্লজ – ডেটা সাজানোর সম্পূর্ণ গাইড (বাংলা)
- SQLite GROUP BY ক্লজ – ডেটা গ্রুপ করে বিশ্লেষণ করার সম্পূর্ণ গাইড (বাংলা)
- SQLite HAVING ক্লজ – গ্রুপের উপর শর্ত দিয়ে ডেটা ফিল্টার (বাংলা টিউটোরিয়াল)
- SQLite DISTINCT Keyword – ডুপ্লিকেট ডেটা বাদ দিয়ে ইউনিক ভ্যালু পাওয়া (বাংলা)
- SQLite PRAGMA কমান্ড – ডাটাবেস কনফিগারেশন ও সেটিংস (বাংলা টিউটোরিয়াল)
- SQLite Constraints – NOT NULL, DEFAULT, UNIQUE, PRIMARY KEY, CHECK (বাংলা টিউটোরিয়াল)
- SQLite JOINS – CROSS JOIN, INNER JOIN, LEFT OUTER JOIN (বাংলা টিউটোরিয়াল)
- SQLite UNION ও UNION ALL – একাধিক SELECT একত্রিত করার সম্পূর্ণ গাইড (বাংলা)
- SQLite NULL Values – NULL কী, IS NULL, IS NOT NULL (বাংলা টিউটোরিয়াল)
- SQLite ALIAS Syntax – টেবিল ও কলামের অস্থায়ী নাম (বাংলা টিউটোরিয়াল)
- SQLite Triggers – স্বয়ংক্রিয় ট্রিগার তৈরি, ব্যবহার ও মুছে ফেলা (বাংলা টিউটোরিয়াল)
- SQLite Indexes – CREATE, UNIQUE, COMPOSITE, DROP INDEX (বাংলা টিউটোরিয়াল)
- SQLite INDEXED BY Clause – নির্দিষ্ট ইনডেক্স ব্যবহার ও NOT INDEXED (বাংলা)
- SQLite ALTER TABLE Command – টেবিলের গঠন পরিবর্তন (বাংলা টিউটোরিয়াল)
- SQLite TRUNCATE TABLE Command – DELETE ও DROP দিয়ে টেবিল খালি করা (বাংলা)
- SQLite Views – ভার্চুয়াল টেবিল তৈরি, ব্যবহার ও ডিলিট (বাংলা টিউটোরিয়াল)
- SQLite Transactions – BEGIN, COMMIT, ROLLBACK ও ACID প্রপার্টি (বাংলা)
- SQLite Subqueries – SELECT, INSERT, UPDATE, DELETE-এ সাবকোয়েরি ব্যবহার (বাংলা টিউটোরিয়াল)
- SQLite AUTOINCREMENT – স্বয়ংক্রিয়ভাবে প্রাইমারি কি মান বৃদ্ধি (বাংলা টিউটোরিয়াল)
- SQLite SQL Injection – কী, কেন বিপজ্জনক ও প্রতিরোধের উপায় (বাংলা টিউটোরিয়াল)
- SQLite EXPLAIN ও EXPLAIN QUERY PLAN – কোয়েরি বিশ্লেষণ (বাংলা টিউটোরিয়াল)
- SQLite VACUUM – ডাটাবেস পরিষ্কার, স্পেস রিক্লেইম ও অটো-ভ্যাকুয়াম (বাংলা টিউটোরিয়াল)
- SQLite Date & Time ফাংশন – date(), time(), datetime(), julianday(), strftime() (বাংলা টিউটোরিয়াল)
- SQLite Useful Functions – COUNT, MAX, MIN, AVG, SUM, RANDOM, ABS, UPPER, LOWER, LENGTH (বাংলা টিউটোরিয়াল)
- SQLite C/C++ প্রোগ্রামিং – sqlite3_open, exec, close, callback (বাংলা টিউটোরিয়াল)
- SQLite PHP প্রোগ্রামিং – PHP-তে SQLite ডাটাবেস ব্যবহার (বাংলা টিউটোরিয়াল)
- SQLite Perl প্রোগ্রামিং – DBI/DBD::SQLite দিয়ে ডাটাবেস অপারেশন (বাংলা)
- SQLite Python প্রোগ্রামিং – sqlite3 মডিউল দিয়ে CRUD অপারেশন (বাংলা টিউটোরিয়াল)
- SQLite Quick Guide – বাংলায় পূর্ণাঙ্গ সংক্ষিপ্ত টিউটোরিয়াল (শেখার সহজ গাইড)
