Expert Talk Β· Dept. of CSE, LBS College of Engineering, Kasaragod
From Idea to App Build with AI
Databases, AI tools, and how real software gets built.
Vipindas K Β· Software Engineer, Hexeam Software Solutions
Classroom vs real project
You know the theory. Now the real questions.
In the classroom
In a real project
Define primary key and foreign key
What happens when a parent row is deleted?
Normalise this table to 3NF
When is it worth breaking the rule, and why?
What is an index?
Which column, and what does it cost?
Write the 4 ACID properties
Two users click Register at the same moment. Now what?
Draw a one-to-many ER diagram
One notifications table for 3 kinds of users?
SQL is the database language
SQL, MongoDB, Firebase or Redis: which, for my project?
Modern software workflow
How real software gets built
π‘
Idea
Who needs it, and why
ποΈ
Design
The data first, then screens
πΏ
Build
One Git branch per change
π
Review
Pull request and automatic tests
π
Deploy
Staging, then production
π
Monitor
Logs, feedback, improve
Why today goes deep on the database: code is easy to change. A live database full of real users' data isn't, so a bad design there costs the most.
And AI? It helps at every step, but the steps stay. Our live demo follows the same loop: spec, plan, build, check, deploy.
The next 75 minutes
Agenda
π Real projects along the way: attendance, online shop, ticket booking, wallet, canteen. Then: team habits, skills and opportunities.
01
πΊοΈ DB landscape
SQL, MongoDB, Firebase, Redis. Which one when?
02
π MySQL basics
Keys, indexes, normal forms.
03
π Relations
One-to-many, many-to-many, polymorphic.
04
π€ Joins
Row by row, so you never forget.
05
β‘ Same-time problems
Transactions, locks, two users, one ID.
06
π³ Trees
Closure table: insert and delete.
07
π Login
How it really works, in tables.
08
π€ AI + live reveal
Vibe coding, AI tools, which model. Then open the tool.
Live demo Β· kickoff
Let's give the AI a job: JoinLab
~/live-demo Β· claude
# the full spec is in CLAUDE.md$ claude --permission-mode plan
> Read CLAUDE.md and build JoinLab exactly as
specified. Plan first: the milestones only.
After I approve, do them in order, deploying
with bash deploy.sh at each milestone.
Keep it small. Don't ask me questions unless
something blocks you.
Theater: two tables stand apart, come together, and the join happens in front of you
Builder: make tables with a GUI, and see the SQL
Lab + Missions: real SQL, graded practice
Login (bonus): keep your own data, if time allows
Status: % and stuck warnings in the bottom panel β¬
The main four
Four databases to know first
π
SQL
Tables with strict columns and relations. The default for most apps.
MySQLPostgreSQLSQLite
π
MongoDB
JSON-like documents. Flexible shape, easy to spread across servers.
Document DB
π₯
Firebase
Google's cloud backend. Changes reach every phone in real time.
FirestoreRealtime DB
β‘
Redis
Lives in memory, extremely fast. Cache, OTP, sessions, queues.
Key-value
Same data, four shapes
One student, four ways to store
π§βπ Anjali Β· CSE Β· php, sql
π SQL: rows in tables
students departments
id | name | dept_id id | name
1 | Anjali | 1 β 1 | CSE
Relational protects correct data. Non-relational gives flexibility and easy scale.
Use cases
What would you pick?
Project
Pick
Why
College ERP, marks, fees
MySQL / PostgreSQL
Strong relations, correct data
Online payments
MySQL / PostgreSQL
Transactions keep money correct
Product catalogue, each item with different fields
MongoDB
Flexible document shape
Live chat or live score app
Firebase
Real-time sync, little backend code
OTP, cache, login sessions
Redis (alongside SQL)
Fast, expires by itself
Offline notes app on a phone
SQLite
A file on the device
Rule: start with one SQL database. Add others only for a real need.
Keys
The keys that hold data together
students
id
reg_no
name
dept_id
1
KSD22CS001
Anjali
1
2
KSD22CS002
Rahul
1
3
KSD22EC001
Fathima
2
departments
id
name
1
CSE
2
ECE
enrollments
student_id
course_id
1
5
1
7
Primary key: identifies each row. Unique, never NULL, one per table.
Unique key: no duplicates allowed, but not the row's main identity.
Foreign key: points to a primary key in another table. This is the link.
Composite key: two columns together are unique. Student 1 can't take course 5 twice.
Candidate key: any column that could be the primary key, like id or reg_no. You choose one.
Foreign keys protect data
The database says no
INSERT INTO students (name, dept_id) VALUES ('Arun', 99);
β ERROR: foreign key constraint fails. Department 99 doesn't exist.
π‘οΈ departments
id
name
1
CSE
2
ECE
And when you delete the CSE department, what happens to its students? You decide:
RESTRICT
Refuse the delete while students exist. The safe default.
CASCADE
Delete the students too. Good for order items; dangerous elsewhere.
AnjaliRahul
SET NULL
Keep the students, with dept_id = NULL. They're unassigned.
Indexing
Find one student among 10 lakh
π’ No index: full table scan
email
rahul@β¦
fathima@β¦
arjun@β¦
β¦ every row β¦
anjali@β¦ β found last
Rows checked: 0
π With an index: a sorted tree (B-tree)
Steps taken: 0
Worst case: every row gets checked.
Just a few steps, like the index at the back of a textbook.
CREATE INDEX idx_students_email ON students (email); -- one line, one column
Index trade-offs
Why not index every column?
β Index it when
Used in WHERE
Used in JOIN (foreign keys)
Used in ORDER BY
Many different values
β Disadvantages
INSERT and UPDATE get slower
Uses extra disk space
Too many confuse the design
π« Skip it when
Very small tables
Few values, like yes / no
Column rarely searched
-- Composite: order matters (leftmost first)CREATE INDEX idx ON students (dept_id, name);
WHERE dept_id = 1 AND name = 'Anjali'β used
WHERE name = 'Anjali'β not used
-- Is my query using the index?EXPLAIN SELECT * FROM students
WHERE email = 'anjali@β¦';
-- type: ALL = full scan (slow)-- type: ref = index used (fast)
π Real project Β· college attendance
One small feature, 12 lakh rows a year
π Rows in a year: 0
attendance
student_id
date
period
status
1
2026-11-05
1
P
2
2026-11-05
1
P
1
2026-11-05
2
P
3
2026-11-05
2
A
1
2026-11-06
1
A
2
2026-11-06
1
P
The maths: 1,000 students Γ 6 periods Γ 200 days.
The report: Anjali's attendance this semester. With no index, MySQL reads every row.
SELECT SUM(status='P') * 100 / COUNT(*) FROM attendance
WHERE student_id = 1AND date >= '2026-06-01';
The fix: a composite index. Now MySQL goes straight to Anjali's rows.
CREATE INDEX idx_student_date ON attendance (student_id, date);
Teacher taps Save twice?UNIQUE (student_id, date, period) refuses the copy.
Normal forms Β· 1NF
1NF: one value in each cell
β students
id
name
phones
1
Anjali
9876β¦, 9447β¦
2
Rahul
9995β¦
β
β students
id
name
1
Anjali
2
Rahul
β phones
student_id
phone
1
9876β¦
1
9447β¦
2
9995β¦
Problem: try finding βwho has 9447β¦β, or removing one number. You'd have to cut text apart.
Fix: a new table, with one row per phone.
Result: each cell holds one value, and each student can have any number of phones.
Normal forms Β· 2NF
2NF: depend on the whole key
β enrollments, key = (student_id, course_id)
student_id
course_id
student_name
grade
1
5
Anjali
A
1
7
Anjali
B
2
5
Rahul
A
β enrollments
student_id
course_id
grade
1
5
A
1
7
B
2
5
A
β students
id
name
1
Anjali
2
Rahul
Problem: the name depends only on student_id, part of the key. It repeats on every row.
Fix: move it to the students table. The grade needs both columns, so it stays.
Result: a name change touches one row, not hundreds.
One-to-one
Has one Β· belongs to
users
id
name
1
Anjali
2
Rahul
profiles
id
user_id FK + UNIQUE
photo
10
1
a.jpg
11
2
r.jpg
User has one profile. Read it from the users side.
Profile belongs to a user. Same link, read from the other side.
Where's the foreign key? Always on the βbelongs toβ table.
UNIQUE stops a second profile for the same user.
One-to-many Β· many-to-one
One line, two directions
departments (one)
id
name
1
CSE
2
ECE
students (many)
id
name
dept_id FK
1
Anjali
1
2
Rahul
1
3
Fathima
2
One-to-many: department has many students.
Many-to-one: each student belongs to one department.
Rule: the foreign key goes on the many side. You can't fit many ids in one cell (1NF!).
Many-to-many
A third table: the pivot
students
id
name
1
Anjali
2
Rahul
enrollments (pivot)
student_id
course_id
1
5
1
7
2
5
courses
id
title
5
DBMS
7
OS
A student takes many courses (DBMS and OS).
A course has many students (Anjali and Rahul take DBMS).
Bonus: the pivot can hold extra data, like grade or joined date.
Polymorphic Β· morph one / morph many
One table that points to many tables
students
id
name
1
Anjali
teachers
id
name
1
Dr. Nair
admins
id
name
4
Office
notifications
id
owner_type
owner_id
message
1
student
1
Fee due
2
teacher
1
Marks pending
3
admin
4
Server backup OK
Two columns do the work: which table (type) + which row (id). Student 1 and teacher 1 stay different.
Morph many: one student has many notifications. Morph one: one owner has one row, like a profile photo.
SELECT * FROM notifications WHERE owner_type = 'teacher'AND owner_id = 1;
The same pivot serves videos too. No second pivot table needed.
Morphed by many: the tag βdatabaseβ is used by posts and videos.
β οΈ Trade-off: owner_id can't be a real foreign key, so your code must keep it correct.
Joins Β· row by row
INNER JOIN: only matches survive
SELECT s.name, d.name FROM students s INNER JOIN departments d ON s.dept_id = d.id;
students
name
dept_id
Anjali
1
Rahul
1
Fathima
2
Arjun
3
Neha
2
Vishnu
NULL
departments
id
name
1
CSE
2
ECE
3
Mech
4
Civil
result: 5 rows
student
department
Anjali
CSE
Rahul
CSE
Fathima
ECE
Arjun
Mech
Neha
ECE
Vishnu: dept_id is NULL, so no partner. Dropped from the result.
Civil: no students point to it. It doesn't appear either.
Joins Β· keep the unmatched
LEFT Β· RIGHT Β· FULL
LEFT JOIN: 6 rows
All students. Vishnu stays, with department NULL.
Vishnu
NULL
RIGHT JOIN: 6 rows
All departments. Civil stays, with student NULL.
NULL
Civil
FULL JOIN: 7 rows
Everyone. MySQL has no FULL JOIN: combine LEFT and RIGHT with UNION.
-- A favourite interview question: students with no departmentSELECT s.name FROM students s LEFT JOIN departments d ON s.dept_id = d.id WHERE d.id IS NULL;
SELECT d.name, COUNT(s.id) AS total
FROM departments d
LEFT JOIN students s ON s.dept_id = d.id
GROUP BY d.id, d.name
HAVING total >= 2;
WHERE filters rows before grouping. HAVING filters groups after.
π The N+1 mistake
-- β 1 query, then 1 more per student
SELECT * FROM students;
SELECT * FROM departments WHERE id = ?;
-- β¦ 1000 students = 1001 queries-- β one JOIN gets it all at once
Works fast on your laptop, crawls with real data.
π Real project Β· online shop
The price went up. Did the old bill change?
users
id
name
1
Anjali
orders
id
user_id
501
1
order_items
order_id
product_id
qty
price
501
7
1
βΉ999
products
id
name
price
7
Earphones
βΉ999
SELECT p.name, oi.qty * p.priceoi.priceAS total
FROM order_items oi
JOIN products p ON p.id = oi.product_id
WHERE oi.order_id = 501;
π§Ύ Bill #501: βΉ999
The problem: Anjali paid βΉ999 in January. That old bill now says βΉ1,299.
The fix: copy the price into order_items at purchase.
Not a normalisation mistake: the price paid and today's price are two different facts. Do the same for the delivery address and tax.
Keep your data safe
SQL injection and backups
// β the input becomes part of the SQL
"SELECT * FROM users WHERE email = '" + email + "'"
email = ' OR 1=1 -- β returns every user!
// β prepared statement: input is only data
"SELECT * FROM users WHERE email = ?" + [email]
Back up every day, automatically
Test a restore: an untested backup is only a hope
Least privilege: the app's DB user can't drop tables
Procedural language
Code that lives inside the database
CREATE PROCEDURE enroll(IN s INT, IN c INT)
BEGINIF (SELECT COUNT(*) FROM enrollments
WHERE course_id = c) >= 60THENSIGNAL SQLSTATE'45000'SET MESSAGE_TEXT = 'Course is full';
END IF;
INSERT INTO enrollments VALUES (s, c);
END;
CALL enroll(1, 5); -- run it from any app
Stored procedure: a named program. Run it with CALL.
Function: returns a value, usable inside a SELECT.
Trigger: runs by itself on INSERT, UPDATE or DELETE. Good for audit logs.
Use sparingly: harder to test and review than normal app code.
Transaction
All steps succeed, or none do
Anjali
βΉ5000
β
Rahul
βΉ2000
START TRANSACTION;UPDATE accounts SET bal = bal - 1000 WHERE name = 'Anjali';β‘ power cut! β ROLLBACK-- try againUPDATE accounts SET bal = bal + 1000 WHERE name = 'Rahul';COMMIT; β saved for good
Crash halfway: the debit is undone. No money vanishes.
Atomic: all or nothing
Consistent: rules always hold
Isolated: others don't see half-done work
Durable: after COMMIT, it survives a crash
Locks
One biryani left, two students
π Biryani Β· stock = 1πππ
π User A
π User B
step 1
SELECT stock FROM menu_items WHERE id=1 FOR UPDATE π got it
step 2
Same query: β³ waitingβ¦
step 3
UPDATE menu_items SET stock = 0 WHERE id=1
step 4
COMMIT π released, ordered!
step 5
Reads stock = 0: βSold outβ
Shared lock: many can read, nobody writes.
Exclusive lock: one writer, others wait.
Row lock: only that row waits (InnoDB, needs an index).
Table lock: the whole table waits. Avoid it.
Deadlock: two users wait for each other, and MySQL cancels one. Always lock in the same order.
A real bug Β· race condition
Two users register at the same moment
π Anjali clicks Register
π Rahul clicks Register
10:00:00.01
SELECT MAX(reg_no) β 100
SELECT MAX(reg_no) β 100
10:00:00.02
100 + 1 = 101
100 + 1 = 101
10:00:00.03
INSERT reg_no 101 β
INSERT reg_no 101 π₯
ποΈ students Β· reg_no: 100, 101, 101 π₯
Both read before either one has saved.
Same maths, so the same number.
No UNIQUE: two students share one ID. With UNIQUE: Rahul gets an error.
On your laptop it never happens. On results day, it happens every minute.
The fix
Same moment, two different IDs
π’ counters.last_no = 100
π Anjali
π Rahul
Locks counter π reads 100
Waits for the lock β³
Saves 101, COMMIT π
Locks counter π reads 101
Saves 102, COMMIT π
START TRANSACTION;
SELECT last_no FROM counters WHERE name='reg'FOR UPDATE;
UPDATE counters SET last_no = last_no + 1WHERE name='reg';
INSERT INTO students (reg_no, name) VALUES (β¦);
COMMIT;
Plain ID: AUTO_INCREMENT. The database hands out unique numbers, with no code. Gaps can appear, and that's fine.
Formatted no. (KSD22CS101): counter row + lock, as here.
Fingerprint on the device. Server keeps a public key.
π‘οΈ
2FA
Password + a code from an authenticator app.
π’
SSO
One login for many apps.
ποΈ
API token
For mobile apps and other programs.
How a password login works
Sessions and cookies, in tables
π»Browseryou
email + passwordπͺ session idπͺ + next page
βοΈServeryour code
find userhash β
ποΈDatabaseusers, sessions
1. The form sends email + password over HTTPS
2. Compare with users.pass_hash (bcrypt), never plain text
3. Save a row in sessions, and send its id as a cookie (HttpOnly)
4. Every next request carries the cookie: βstill meβ
π Real project Β· canteen pre-order
From idea to tables
βStudents pre-order food from the canteen, pay online, and collect their order with a token.β
π€ users
id
name
phone
π³ payments
id
order_id
amount
idem_key
π orders
id
user_id
token_no
status
pickup_at
π§Ύ order_items
order_id
item_id
qty
price
π menu_items
id
name
price
stock
Only 50 biryani? Transaction, and lock the stock row.
Token number? Never MAX + 1. Use a counter row with a lock.
Pay tapped twice? UNIQUE idempotency key.
OTP login? Start in SQL. Add Redis only when you need it.
Starting your own project
Decide these before you code
Question
Usual answer
What's the data like?
Linked data β MySQL / PostgreSQL
Need live updates, no backend?
Firebase
Which language do I know?
PHP, JS, Python: the one you know is best
Framework?
Laravel, Express, Django: login and DB tools built in
Where will it run?
A small VPS, or a free tier to start
π€ Ask AI to think with you
I'm building a canteen pre-order app for
500 students. I know PHP. Suggest a database,
framework and tables. Explain why, list the
trade-offs, and don't write code yet.
AI proposes. You decide.
Industry best practices
Habits every team expects
πΏ Git and review
Every change on a branch, reviewed by someone before it merges.
π§ͺ Automatic tests
Checks run on every change, so old features don't silently break.
ποΈ Migrations
Database changes are versioned files, never manual edits on the server.
π Secrets
Passwords and keys live in .env, never in Git.
π§ Staging first
Try it on a copy. Never test on live data.
π Logs and backups
Know when it breaks, and test that the backup really restores.
π Real-world project experience
What real projects teach you
π Requirements change
Even after you've built it. Keep your design easy to change.
π Data grows
Fast with 100 rows can crawl with 10 lakh.
π You mostly read code
The job is understanding and changing code that already exists.
π Real users surprise you
Double taps, slow networks, input you never imagined.
π€ From my own work: a real story.
π€ Building with AI Β· vibe coding
Vibe coding: fast, until it isn't
π¬ Describe
prompt
π€ AI writes
code
βΆοΈ Run it
result
π£οΈ βFix thisβ
β Great for
Prototypes, demos, personal tools, and learning a new idea.
β οΈ Review every line
Login, payments, and anything holding real users' data.
AI often writes what we warned about today: MAX + 1 IDs, no UNIQUE, no index, input glued into SQL. Now you can catch them.
You own what you ship. JoinLab isn't pure vibes: it has a spec, a plan and automatic checks.
π€ Building with AI Β· major tools
Four types of AI tool
Type
Examples
Use it for
Watch out
π¬ Chat assistant
Claude, ChatGPT, Gemini
Think, plan, explain an error
Only knows what you paste in
βοΈ AI code editor
Cursor, GitHub Copilot, Windsurf
Autocomplete and edits as you code
Easy to accept without reading
π₯οΈ Terminal agent
Claude Code, Codex CLI, Gemini CLI
Plan, change many files, run tests
Needs a clear spec and permission limits
β‘ App builder
Lovable, Bolt, v0, Replit
A working prototype from a prompt
Check its database and login
Today's JoinLab is built by a terminal agent. Start with one chat tool and one coding tool. Names change; the four types don't.
π€ Building with AI Β· choosing a model
Pick the model by the job
π― What's the job?
π§ Most capable
Claude Opus tier. Slowest, highest cost. For decisions that are expensive to get wrong.
Plan the database
βοΈ Balanced
Claude Sonnet tier. Good speed and quality. Your default for coding.
Build the screens
β‘ Small and fast
Claude Haiku tier. Cheapest, fastest. For simple, repeated work.
Check the result
That's today's build: Opus plans, Sonnet builds, Haiku checks. OpenAI and Google offer similar tiers.
Ask: How hard is it? How many calls, at what cost? How fast must it reply? Is the data private? If it is, read the data terms or run an open model locally.
Test on your real task, starting cheap. Move up only if the results aren't good enough. Names and prices change every few months.
Live Β· built by an AI agent during this class
Meet JoinLab π
Watch joins happen, build tables with a GUI, write real SQL.
Theater: students LEFT JOIN departments
Lab: type your own query
Missions: can you finish all of them?
For aspiring software engineers
Skills and opportunities
π§± What companies look for
DBMS, OOP, data structures
One language and framework, properly
SQL and Git
Reading and debugging code
Clear communication
πͺ Where you can start
Backend, frontend, full stack, mobile
QA, DevOps, data
Product, service, startup
Internships, freelance, open source
π― Your next 6 months
Build one real project, end to end
Deploy it, and put the link on your resume
Keep the code on GitHub
Try one internship or open source fix
Your edge: AI makes typing code cheaper. Understanding the problem and the data gets more valuable.
Recap
From idea to app: take these home
Start with one SQL database; add others on real need
Keys link data; indexes make it fast, at a cost
Normalise so each fact lives in one place
Foreign key goes on the many side; many-to-many needs a pivot
Transactions and locks keep same-time users correct
Never calculate IDs yourself. Let the database do it
UNIQUE is your final safety; copy facts that must not change, like the price paid
Vibe code prototypes, but review login, money and data; pick the model by the job
π― This week
Finish all JoinLab missions
Design tables for your project
Practise joins until they feel easy
Put one project on GitHub
Thank you
Questions? π
Exams test what you remember. Real apps test what you understood.
Vipindas K Β· Software Engineer, Hexeam Software Solutions
vipindas.k@hexeam.in
Thanks to Reema K V (Faculty Coordinator), Sumayya Zakiya (Student Coordinator) and the Department of CSE, LBS College of Engineering, Kasaragod