DBMS Concepts
15 Core Database Concepts — The foundation every backend engineer must know. Master these, and database questions become easy points.
ACID Properties
Core Most Asked 4 minACID is the gold standard for relational database transactions. When you transfer money between accounts, you absolutely need ACID — partial transfers or lost data is unacceptable.
| Property | What It Means | Real Example | How It's Implemented |
|---|---|---|---|
| Atomicity | Transaction is all-or-nothing | Bank transfer: debit AND credit happen together, or neither happens | Transaction logs, undo logs |
| Consistency | DB moves from one valid state to another | Account balance can't go negative if rules forbid it | Constraints, triggers, application logic |
| Isolation | Concurrent transactions don't affect each other | Two transfers happening simultaneously get correct totals | Locks, MVCC (Multi-Version Concurrency Control) |
| Durability | Committed data survives crashes | After "transfer successful," data persists even if power fails | Write-ahead logging (WAL), fsync |
Think of buying a house: Atomicity = money transfers AND ownership transfers, or deal is off. Consistency = you can't buy a house for negative money. Isolation = two people can't buy the same house simultaneously. Durability = once deed is signed, it's permanent record.
Key Interview Points
- Atomicity uses undo logs — if transaction fails midway, all changes are rolled back
- Durability uses redo logs (WAL) — writes are logged before applying, so recovery is possible
- Isolation has different levels — see Isolation Levels section
- NoSQL databases often sacrifice some ACID properties for performance (see BASE)
Competitive Edge
Know the difference between ACID (SQL) and BASE (NoSQL): BASE = Basically Available, Soft-state, Eventually consistent. NoSQL trades strict consistency for availability and partition tolerance. Mention this to show you understand the trade-offs.
Follow-up Questions
How does a database ensure atomicity after a crash?
Can you have ACID in distributed systems?
Normalization (1NF to BCNF)
Core Theory 5 minWhy normalize? Without it, you get anomalies:
- Update anomaly: Change data in one place, forget another copy
- Insert anomaly: Can't add data without unrelated data
- Delete anomaly: Deleting one thing accidentally removes other info
| StudentID | Name | Courses | Phones |
|---|---|---|---|
| 1 | Alice | Math, Physics | 111, 222 |
| 2 | Bob | Chemistry | 333, 444, 555 |
• Multi-valued columns (Courses, Phones)
• Can't query individual courses easily
• No atomic values
| StudentID | Name | Course | Phone |
|---|---|---|---|
| 1 | Alice | Math | 111 |
| 1 | Alice | Physics | 111 |
| 1 | Alice | Math | 222 |
| 2 | Bob | Chemistry | 333 |
• Name depends only on StudentID, not on full key (StudentID, Course)
• Partial dependency → violates 2NF
| StudentID | Name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| StudentID | CourseID | Grade |
|---|---|---|
| 1 | M101 | A |
| 1 | P201 | B |
| 2 | C301 | A |
• If we had ZipCode → City, that's a transitive dependency
• Non-key → Non-key violates 3NF
| StudentID | Name | ZipCode |
|---|---|---|
| 1 | Alice | 10001 |
| 2 | Bob | 90210 |
| ZipCode | City | State |
|---|---|---|
| 10001 | New York | NY |
| 90210 | Beverly Hills | CA |
"The key, the whole key, and nothing but the key"
• Most databases stop at 3NF ✓
| Student | Subject | Professor |
|---|---|---|
| Alice | DB | Dr. Smith |
| Bob | DB | Dr. Smith |
| Alice | OS | Dr. Jones |
| Normal Form | Rule | Simple Explanation | Example Violation |
|---|---|---|---|
| 1NF | Atomic values, no repeating groups | Each cell has ONE value. No arrays or lists. | Phone column with "123, 456, 789" |
| 2NF | 1NF + no partial dependencies | Every non-key column depends on the WHOLE primary key | Key: (StudentID, CourseID), but StudentName depends only on StudentID |
| 3NF | 2NF + no transitive dependencies | Non-key columns don't depend on other non-key columns | ZipCode → City (City depends on ZipCode, not on primary key) |
| BCNF | For every X→Y, X must be a superkey | Stricter 3NF — every determinant is a candidate key | Complex scenarios with overlapping candidate keys |
"The key, the whole key, and nothing but the key, so help me
Codd."
1NF = "The key" (must have a key, atomic values)
2NF = "The whole key" (depend on ALL of composite key)
3NF = "Nothing but the key" (no transitive deps through
non-keys)
Key Interview Points
- Most real-world databases aim for 3NF — good balance of normalization vs complexity
- BCNF is rarely needed — only when 3NF has specific edge cases with overlapping keys
- Higher normalization = more tables = more JOINs = potentially slower reads
- Know how to identify violations: "This column depends on X, not on the primary key"
Common Mistake
Don't say "higher normal form is always better." In practice, 3NF is usually sufficient. Over-normalizing creates too many joins and hurts read performance. Know when to stop.
Denormalization
Concept Practical 3 minNormalization optimizes for writes (no redundancy, easy updates). But in read-heavy systems like analytics dashboards or e-commerce product pages, JOINs across many tables are slow. Denormalization pre-computes and stores data together.
FROM Orders o
JOIN Customers c ON o.cust_id = c.id
JOIN Products p ON o.prod_id = p.id;
| id | cust_id | prod_id | qty |
|---|---|---|---|
| 1 | 10 | 50 | 2 |
| 2 | 11 | 50 | 1 |
| id | name | |
|---|---|---|
| 10 | Alice | [email protected] |
| 11 | Bob | [email protected] |
| id | title | price |
|---|---|---|
| 50 | Widget | $29 |
FROM Order_Details
WHERE id = 1;
| id | cust_name | cust_email | prod_title | prod_price | qty |
|---|---|---|---|---|---|
| 1 | Alice | [email protected] | Widget | $29 | 2 |
| 2 | Bob | [email protected] | Widget | $29 | 1 |
| Aspect | Normalized | Denormalized |
|---|---|---|
| Redundancy | Minimal | Intentional duplication |
| Read Performance | Slower (needs JOINs) | Faster (data together) |
| Write Performance | Faster (single update) | Slower (update multiple places) |
| Storage | Less | More |
| Data Consistency | Easier to maintain | Risk of inconsistency |
| Use Case | OLTP (transactions) | OLAP (analytics), caching |
When to Denormalize
- Read-heavy workloads: Analytics, reporting, dashboards
- Frequently accessed computed values: Store total instead of calculating
- Avoid expensive JOINs: Embed related data in same table
- Caching layer: Store pre-computed results
- Data warehouses: Star schema, fact tables with denormalized dimensions
Competitive Edge
Mention materialized views as a middle ground — they store query results but can be refreshed automatically. Also mention that NoSQL databases like MongoDB are often denormalized by design (embedding documents instead of referencing).
Primary Key vs Foreign Key
Core 3 min| Aspect | Primary Key | Foreign Key |
|---|---|---|
| Purpose | Uniquely identify rows | Create relationship between tables |
| Uniqueness | Must be unique | Can have duplicates |
| NULL allowed | No | Yes (optional relationship) |
| Count per table | Only 1 | Multiple allowed |
| Auto-creates index | Yes (clustered) | No (but recommended) |
| References | None | Must reference a primary/unique key |
Referential Integrity Actions
- CASCADE: Delete/update child rows when parent changes
- SET NULL: Set foreign key to NULL when parent deleted
- RESTRICT: Prevent delete if children exist (default)
- NO ACTION: Similar to RESTRICT, checked at end of transaction
Indexing
Core Performance 4 minSearch for "email_15" — see the difference
Without index: Full table scan — read EVERY row
to find matches. O(n).
With index: B+ tree lookup — jump directly to
relevant rows. O(log n).
When to Create Indexes
- Columns in WHERE clauses — frequently filtered columns
- JOIN columns — foreign keys used in joins
- ORDER BY columns — avoid sorting full result set
- High cardinality columns — many unique values (email, ID)
When NOT to Index
- Small tables — full scan is fast enough
- Frequently updated columns — index maintenance overhead
- Low cardinality — boolean columns (only 2 values) won't benefit much
- Columns rarely in queries — index unused but still maintained
Competitive Edge
Composite index order matters! Index on (A, B) helps queries on A, or (A AND B). But NOT queries on just B. This is the leftmost prefix rule. Also mention covering indexes — if all columns needed are in the index, the database doesn't need to read the actual table (index-only scan).
Clustered vs Non-Clustered Index
Concept Deep Dive 4 min| Aspect | Clustered Index | Non-Clustered Index |
|---|---|---|
| Physical order | Data rows sorted by index key | Separate structure, data unordered |
| Count per table | Only 1 | Multiple (up to 999 in SQL Server) |
| Leaf nodes contain | Actual data rows | Pointers to data rows |
| Range queries | Faster (data is contiguous) | Slower (need to follow pointers) |
| Insert performance | Slower (may need to reorder) | Faster |
| Default on | PRIMARY KEY | Other indexes |
✦ Clustered Index
✦ Non-Clustered Index
Clustered index: A phone book sorted by last
name. The data IS sorted — finding "Smith" is fast because all
Smiths are together.
Non-clustered index: A book's index at the
back. It tells you page numbers, but you still need to flip to
those pages. The pages themselves aren't sorted by the index.
Competitive Edge
In MySQL InnoDB, the primary key IS the clustered index. Non-clustered indexes store the primary key value (not row pointer). So if your primary key is a large UUID, ALL your indexes become larger. This is why auto-increment INT is often preferred for primary keys — smaller indexes, better performance.
B+ Trees
Concept Internals 4 minWhy B+ trees for databases?
- Disk-optimized: High fanout (many children) = fewer disk reads
- Range queries: Leaf nodes linked = easy sequential scan
- Balanced: All leaves at same depth = predictable performance
- Full nodes: Typically 70%+ full = space efficient
All data in leaf nodes • Leaves linked for range scans • O(log n) lookups
Internal nodes hold keys for navigation. Leaf nodes hold all data and are linked for sequential access.
B+ Tree vs B Tree
- B+ tree: Data ONLY in leaves, leaves linked. Better for range queries and disk I/O.
- B tree: Data in all nodes. Slightly faster single-key lookup, but worse for ranges.
- Databases use B+ trees because disk reads are expensive, and range queries are common.
Competitive Edge
B+ tree node size is typically one disk page (4KB-16KB). This means each node read = one disk I/O. A B+ tree with 1000 keys per node can index billions of rows with just 3-4 levels. Mentioning page size and fanout shows deep understanding.
Joins (All Types)
Core Most Asked 5 minKey Interview Points
- INNER JOIN is default when you just write JOIN
- LEFT JOIN is used to find "missing" records (customers with no orders)
- FULL OUTER JOIN not supported in MySQL — use UNION of LEFT and RIGHT
- CROSS JOIN is dangerous — 1000 × 1000 rows = 1 million result rows
- SELF JOIN needs aliases to distinguish the two "copies" of the table
Transactions
Core 3 minTransaction States
- Active: Transaction is executing operations
- Partially Committed: All operations done, waiting for final commit
- Committed: All changes are permanent
- Failed: Error occurred, cannot proceed
- Aborted: Rolled back, changes undone
Competitive Edge
Know about savepoints — you can partially rollback within a transaction. Also mention implicit vs explicit transactions: in autocommit mode (default in many DBs), each statement is its own transaction. For multi-statement operations, you need explicit BEGIN/COMMIT.
Locks (Shared/Exclusive)
Concept Concurrency 4 min| Lock Type | Also Called | Who Can Access | Used For |
|---|---|---|---|
| Shared (S) | Read Lock | Multiple readers, no writers | SELECT queries |
| Exclusive (X) | Write Lock | Only one holder, no other access | INSERT, UPDATE, DELETE |
| Lock Compatibility | Shared (S) | Exclusive (X) |
|---|---|---|
| Shared (S) | ✓ Compatible | ✗ Conflict |
| Exclusive (X) | ✗ Conflict | ✗ Conflict |
Lock Granularity
- Row-level: Lock specific rows. Most concurrent, most overhead. (InnoDB default)
- Page-level: Lock a page (group of rows). Middle ground.
- Table-level: Lock entire table. Least concurrent, least overhead. (MyISAM)
- Database-level: Lock entire database. Rare, used for maintenance.
Competitive Edge
Know about MVCC (Multi-Version Concurrency Control) — used by PostgreSQL and MySQL InnoDB. Instead of locking, readers see a snapshot of data at a point in time. Writers create new versions. Readers never block writers, writers never block readers. Much better concurrency than pure locking.
Deadlock
Concept Critical 4 minBoth transactions are stuck waiting for each other — neither can proceed.
Deadlock Handling
- Detection: Database periodically checks for cycles in wait-for graph. Kills one transaction (victim selection based on work done, priority, etc.)
- Prevention: Acquire all locks upfront, or always acquire in same order
- Timeout: If lock not acquired in X seconds, abort transaction
- Application handling: Catch deadlock error, retry transaction
Preventing Deadlocks in Your Code
- Lock ordering: Always acquire locks in the same order (e.g., by ID ascending)
- Keep transactions short: Less time holding locks = less chance of deadlock
- Avoid user input mid-transaction: Don't wait for user while holding locks
- Use lower isolation levels if possible: Fewer locks needed
Isolation Levels
Concept Tricky 5 min| Isolation Level | Dirty Read | Non-Repeatable Read | Phantom Read | Performance |
|---|---|---|---|---|
| Read Uncommitted | Possible | Possible | Possible | Fastest |
| Read Committed | Prevented | Possible | Possible | Fast |
| Repeatable Read | Prevented | Prevented | Possible* | Moderate |
| Serializable | Prevented | Prevented | Prevented | Slowest |
*MySQL InnoDB prevents phantom reads in Repeatable Read using gap locks.
Understanding the Anomalies
- Dirty Read: Reading uncommitted data from another transaction. If that transaction rolls back, you read garbage.
- Non-Repeatable Read: Read same row twice, get different values (another transaction committed an update).
- Phantom Read: Re-run a query, get new rows (another transaction inserted rows that match your WHERE clause).
SHOW VARIABLES LIKE 'transaction_isolation';
-- Set for session
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- Set for next transaction only
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Competitive Edge
Defaults: MySQL InnoDB = Repeatable Read. PostgreSQL = Read Committed. Know why PostgreSQL chose Read Committed: their MVCC implementation handles most anomalies efficiently at that level. Also mention Snapshot Isolation — used by PostgreSQL and Oracle, where each transaction sees a consistent snapshot of the database.
CAP Theorem
Concept Distributed Systems 4 minUnderstanding the Trade-offs
- CA (Consistency + Availability): Traditional single-node databases. No network partitions to worry about. (MySQL, PostgreSQL single node)
- CP (Consistency + Partition Tolerance): During partition, reject requests to maintain consistency. (MongoDB, HBase, Redis cluster)
- AP (Availability + Partition Tolerance): During partition, respond with possibly stale data. (Cassandra, DynamoDB, CouchDB)
Common Misconception
"You pick 2 and never get the third" — Not quite true. When there's no partition, you can have all three. The trade-off only matters DURING a network partition. Since partitions are rare but inevitable in distributed systems, P is usually non-negotiable, so the real choice is between C and A during failures.
Competitive Edge
Know about PACELC — an extension of CAP. If there's a Partition, choose A or C. Else (normal operation), choose Latency or Consistency. This better captures that systems make trade-offs even when running normally. Example: DynamoDB is PA/EL (chooses availability during partition, chooses low latency normally).
Sharding
Concept Scale 4 minSharding Strategies
- Range-based: Shard by value range (e.g., users A-M on shard 1, N-Z on shard 2). Easy range queries, but can cause hotspots.
- Hash-based: Hash the shard key (e.g., hash(user_id) mod N). Even distribution, but range queries hit all shards.
- Directory-based: Lookup table maps keys to shards. Flexible, but lookup table is a single point of failure.
- Geographic: Shard by location (e.g., US data on US shard). Good for latency, compliance.
Sharding Challenges
- Cross-shard queries: JOINs across shards are expensive (need to query all shards)
- Transactions: ACID across shards requires 2PC (slow) or eventual consistency
- Resharding: Adding/removing shards requires data migration
- Hotspots: Poor shard key choice leads to uneven load
- Complexity: Application must be shard-aware, or use middleware
Competitive Edge
Know Consistent Hashing — used by DynamoDB, Cassandra. When adding/removing nodes, only K/n keys need to move (K = total keys, n = nodes), not all of them. Also mention virtual nodes — each physical node owns multiple positions on the hash ring for better load distribution.
SQL vs NoSQL
Concept Decision Making 5 min| Aspect | SQL (Relational) | NoSQL |
|---|---|---|
| Data Model | Tables with rows and columns | Document, Key-Value, Column-family, Graph |
| Schema | Fixed schema, enforced | Flexible, schema-on-read |
| Query Language | SQL (standardized) | Varies by database |
| ACID | Full ACID support | Often BASE (eventual consistency) |
| Scaling | Vertical (scale up) | Horizontal (scale out) |
| JOINs | Powerful JOINs | Limited/no JOINs |
| Best For | Complex queries, transactions, relationships | High volume, simple access patterns, flexible data |
NoSQL Types
- Document: MongoDB, CouchDB. Store JSON-like documents. Good for content management, catalogs.
- Key-Value: Redis, DynamoDB. Simple get/set by key. Good for caching, sessions.
- Column-family: Cassandra, HBase. Columns grouped into families. Good for time-series, analytics.
- Graph: Neo4j, Amazon Neptune. Nodes and edges. Good for social networks, recommendations.
When to Choose What
- Choose SQL when: Complex relationships, need transactions, data integrity critical, complex queries/reporting
- Choose NoSQL when: Massive scale needed, flexible schema required, simple access patterns (key lookups), high write throughput
- Many systems use both: SQL for transactions, NoSQL for caching/analytics (polyglot persistence)
Common Interview Questions
Can NoSQL databases do transactions?
Is NoSQL always faster than SQL?
When would you migrate from SQL to NoSQL?
Competitive Edge
The line is blurring. PostgreSQL has JSONB for document storage. MySQL has JSON columns. MongoDB has JOINs ($lookup). CockroachDB is a distributed SQL database. Know that modern systems often combine approaches — use SQL for transactional data, Redis for caching, Elasticsearch for search, all in the same application.
Ready to test DBMS?
Practice the interview traps while the concepts are still fresh.