šļø SQL vs NoSQL
SQL (Relational)
Structured data, ACID transactions
- ⢠PostgreSQL, MySQL, SQL Server
- ⢠Fixed schema
- ⢠Strong consistency
- ⢠Complex queries (JOINs)
- ⢠Vertical scaling
NoSQL
Flexible data, horizontal scaling
- ⢠MongoDB, Redis, Cassandra
- ⢠Flexible schema
- ⢠Eventual consistency
- ⢠Simple queries
- ⢠Horizontal scaling
š Database Normalization
1NF (First Normal Form)
⢠Atomic values (no arrays)
⢠Each column has unique name
⢠No repeating groups
2NF (Second Normal Form)
⢠Must be in 1NF
⢠No partial dependencies
⢠All non-key attributes depend on entire primary key
3NF (Third Normal Form)
⢠Must be in 2NF
⢠No transitive dependencies
⢠Non-key attributes depend only on primary key
š Relationships
-- One-to-Many (User has many Posts) CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) UNIQUE ); CREATE TABLE posts ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), title VARCHAR(200), content TEXT ); -- Many-to-Many (Students and Courses) CREATE TABLE students ( id SERIAL PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE courses ( id SERIAL PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE enrollments ( student_id INTEGER REFERENCES students(id), course_id INTEGER REFERENCES courses(id), enrolled_at TIMESTAMP DEFAULT NOW(), PRIMARY KEY (student_id, course_id) ); -- One-to-One (User and Profile) CREATE TABLE profiles ( id SERIAL PRIMARY KEY, user_id INTEGER UNIQUE REFERENCES users(id), bio TEXT, avatar_url VARCHAR(255) );
ā” Indexing
-- Create Index CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_posts_user_id ON posts(user_id); -- Composite Index CREATE INDEX idx_posts_user_date ON posts(user_id, created_at); -- Unique Index CREATE UNIQUE INDEX idx_users_email_unique ON users(email); -- When to Index: ā Foreign keys ā Columns in WHERE clauses ā Columns in ORDER BY ā Columns in JOIN conditions ā Small tables ā Columns with low cardinality ā Frequently updated columns
šÆ Query Optimization
-- ā Bad: SELECT *
SELECT * FROM users;
-- ā
Good: Select only needed columns
SELECT id, name, email FROM users;
-- ā Bad: N+1 Query Problem
for (const user of users) {
const posts = await db.query('SELECT * FROM posts WHERE user_id = ?', [user.id])
}
-- ā
Good: JOIN or IN clause
SELECT users.*, posts.*
FROM users
LEFT JOIN posts ON users.id = posts.user_id;
-- Use EXPLAIN to analyze queries
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
-- Pagination
SELECT * FROM posts
ORDER BY created_at DESC
LIMIT 20 OFFSET 0;
-- Better: Cursor-based pagination
SELECT * FROM posts
WHERE id < last_seen_id
ORDER BY id DESC
LIMIT 20;š Security
- Parameterized Queries: Prevent SQL injection
- Least Privilege: Minimal database permissions
- Encryption: Encrypt sensitive data at rest
- Backup: Regular automated backups
- Audit Logs: Track database changes
- Connection Pooling: Limit connections
š MongoDB Example
// Schema Design
const userSchema = new Schema({
name: String,
email: { type: String, unique: true, index: true },
posts: [{
title: String,
content: String,
createdAt: { type: Date, default: Date.now }
}]
})
// Embedded vs Referenced
// Embedded (1-to-few, data accessed together)
{
_id: ObjectId("..."),
name: "John",
address: {
street: "123 Main St",
city: "NYC"
}
}
// Referenced (1-to-many, independent access)
// User
{ _id: ObjectId("user1"), name: "John" }
// Posts
{ _id: ObjectId("post1"), userId: ObjectId("user1"), title: "..." }
{ _id: ObjectId("post2"), userId: ObjectId("user1"), title: "..." }
// Indexes
db.users.createIndex({ email: 1 })
db.posts.createIndex({ userId: 1, createdAt: -1 })š Design Checklist
- ā Choose SQL vs NoSQL based on requirements
- ā Normalize to 3NF (SQL)
- ā Define relationships clearly
- ā Add indexes on foreign keys
- ā Use parameterized queries
- ā Implement connection pooling
- ā Plan for scalability
- ā Set up backups
- ā Monitor query performance
- ā Document schema
šÆ Conclusion
Good database design is foundational to application performance and scalability. Choose the right database type, normalize appropriately, index strategically, and always prioritize security.
š Generate Database URLs
Need to create database connection strings? Use our Database URL Generator.
Generate Database URL ā