Databases and Data Persistence
Learn how Node.js applications communicate with databases, design data-access layers, handle MongoDB and SQL concepts, and manage transactions.
Database Connections
Node.js applications should manage database connections efficiently. Creating a new database connection for every request is usually expensive. Database clients commonly maintain a connection pool or reusable connection state.
Connection configuration should come from environment variables or secure configuration management.
import mongoose from 'mongoose';
await mongoose.connect(process.env.MONGODB_URI);
console.log('MongoDB connected');- Reuse database connections instead of reconnecting per request.
- Keep credentials outside source code.
- Handle connection failures and shutdowns explicitly.
Where should a production MongoDB connection string normally be stored?
MongoDB and Mongoose
MongoDB is a document-oriented database. Mongoose provides schemas, models, validation, middleware, and convenient querying on top of MongoDB.
A schema describes document structure and a model provides an interface for interacting with a MongoDB collection.
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true }
});
const User = mongoose.model('User', userSchema);
const users = await User.find({ name: /sur/i }).lean();
console.log(users);lean() returns plain objects instead of full Mongoose documents.- Mongoose schemas define application-level document rules.
- Indexes should support actual query patterns.
- Use
lean()when document methods and change tracking are unnecessary.
What does a Mongoose model primarily provide?
Transactions and Data Consistency
Some operations require multiple database changes to succeed or fail together. Database transactions provide atomicity for supported workloads.
Transactions should be used when consistency requirements justify their cost. They are not a substitute for good data modeling, validation, idempotency, and appropriate constraints.
Transactions can increase resource usage and contention. Use them when atomicity is genuinely required.
- Transactions provide atomicity across supported database operations.
- Use constraints and validation alongside transactions.
- Design operations to be idempotent where retries are possible.
What is a key benefit of a database transaction?