diff --git a/absolute-beginners/backend-beginner/caching/_category_.json b/absolute-beginners/backend-beginner/caching/_category_.json index efc8704..785a6eb 100644 --- a/absolute-beginners/backend-beginner/caching/_category_.json +++ b/absolute-beginners/backend-beginner/caching/_category_.json @@ -1,6 +1,6 @@ { "label": "Caching", - "position": 9, + "position": 7, "link": { "type": "generated-index", "description": "Master the art of high-speed data retrieval. Learn how to reduce database load and make your applications lightning-fast using Caching and Redis." diff --git a/absolute-beginners/backend-beginner/database/_category_.json b/absolute-beginners/backend-beginner/database/_category_.json new file mode 100644 index 0000000..7dfe209 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Database Foundations", + "position": 9, + "link": { + "type": "generated-index", + "description": "Master the heart of any application: the Database. Learn how to store, organize, and retrieve data efficiently using industry standards." + } +} \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/acid-properties.mdx b/absolute-beginners/backend-beginner/database/acid-properties.mdx new file mode 100644 index 0000000..a47248b --- /dev/null +++ b/absolute-beginners/backend-beginner/database/acid-properties.mdx @@ -0,0 +1,56 @@ +--- +sidebar_position: 9 +title: "ACID Properties" +sidebar_label: "9. ACID Properties" +description: "Learn the four key properties—Atomicity, Consistency, Isolation, and Durability—that guarantee database reliability." +--- + +When you are building an application like an E-commerce store or a Banking app, you cannot afford "glitches." If a user pays for a course but the database crashes halfway through, they might lose their money without getting the course. + +**ACID** is a set of four properties that guarantee database transactions are processed reliably. + +## 1. Atomicity (All or Nothing) + +Think of a transaction as an "Atom"—it cannot be split. Either the **entire** transaction succeeds, or the **entire** transaction fails. There is no "halfway." + +* **Real-World Example:** You transfer ₹500 to a friend. + 1. Money is deducted from your account. + 2. Money is added to your friend's account. +* **If Step 2 fails (network error):** Atomicity ensures that Step 1 is "rolled back" so you don't lose your money! + +## 2. Consistency (Following the Rules) + +Consistency ensures that a transaction only takes the database from one valid state to another. Any data written to the database must follow all defined rules (Constraints). + +* **Example:** If you have a rule that "Account Balance cannot be negative," and a transaction tries to withdraw more money than you have, the database will **reject** the transaction to stay "Consistent." + +## 3. Isolation (Work in Private) + +In a popular app like **CodeHarborHub**, thousands of people might be buying courses at the exact same time. **Isolation** ensures that concurrent transactions don't "trip over" each other. + +* **How it works:** Even if 100 people hit the "Buy" button at the same second, the database processes them in a way that feels like they happened one after another. This prevents "Double Spending" or incorrect inventory counts. + +## 4. Durability (Saved Forever) + +Once a transaction is "Committed" (finished successfully), it is permanent. Even if the power goes out or the server crashes one second later, the data is safe. + +* **How it works:** Databases use a **Transaction Log**. Before updating the main data, they write the change to a permanent log file on the hard drive. If the system crashes, it reads the log to recover the lost work. + +## ACID Summary Table + +| Property | Key Concept | Simple Goal | +| :--- | :--- | :--- | +| **Atomicity** | All or Nothing | Prevent partial updates. | +| **Consistency** | Validity | Prevent "illegal" data. | +| **Isolation** | Independence | Prevent data mix-ups. | +| **Durability** | Permanence | Prevent data loss after crashes. | + +## Summary Checklist +* [x] I understand that **Atomicity** means no partial transactions. +* [x] I know that **Consistency** keeps the data within the rules. +* [x] I understand that **Isolation** handles multiple users at once. +* [x] I know that **Durability** ensures data is saved to the disk forever. + +:::info The Trade-off +Relational databases (SQL) are famous for being strictly **ACID** compliant. Many NoSQL databases trade some ACID properties for extreme speed (often called **BASE**). At **CodeHarborHub**, we start with ACID because data safety is our #1 priority! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/database-migrations.mdx b/absolute-beginners/backend-beginner/database/database-migrations.mdx new file mode 100644 index 0000000..d1e34f7 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/database-migrations.mdx @@ -0,0 +1,65 @@ +--- +sidebar_position: 6 +title: "Database Migrations" +sidebar_label: "6. Database Migrations" +description: "Learn how to manage changes to your database schema safely and consistently across your entire team." +--- + +Imagine you are working in a team of 5 developers at **CodeHarborHub**. You decide to add a `profile_picture` column to the `Users` table. You run the SQL command on your local computer, and everything works. + +But when your teammate pulls your code, their app **crashes**. Why? Because their local database doesn't have that new column. **Migrations** solve this "It works on my machine" problem. + +## What is a Migration? + +A migration is a small file (usually JS, TS, or SQL) that describes a specific change to the database. These files are saved in your Git repository along with your code. + +Each migration file usually has two parts: +1. **Up:** The instructions to apply the change (e.g., `ADD COLUMN bio`). +2. **Down:** The instructions to undo the change (e.g., `DROP COLUMN bio`). + +## The Migration Workflow + +Instead of manually typing SQL in a terminal, a professional developer follows this cycle: + +1. **Create Migration:** You run a command to generate a new file. +2. **Write Logic:** You define the change (e.g., "Create a table called `Lessons`"). +3. **Run Migration:** The tool executes the SQL and updates your local DB. +4. **Commit to Git:** Your teammates pull the file and run it. **Now everyone is perfectly synced!** + +## Why use Migrations? + + + + You can see exactly who changed the database, when they changed it, and why. + + + If a database change breaks the app, you can "Rollback" to the previous version in seconds. + + + When you deploy your app to a server (like AWS or Vercel), the server can automatically update the database during the build process. + + + +## Example: A Migration File (Prisma) + +At **CodeHarborHub**, we often use **Prisma**. Here is what a small migration looks like in the background: + +```sql +-- Migration: Add bio to Users +-- UP +ALTER TABLE "Users" ADD COLUMN "bio" TEXT; + +-- DOWN +ALTER TABLE "Users" DROP COLUMN "bio"; +``` + +## Summary Checklist + + * [x] I understand that migrations are "Version Control" for the database. + * [x] I know that migration files should be saved in Git. + * [x] I understand the difference between **Up** (Apply) and **Down** (Undo). + * [x] I recognize that migrations prevent "schema mismatch" errors in teams. + +:::warning The Golden Rule +**Never** manually change your database structure in a production environment. Always use a migration. If you skip a migration, your code and your database will eventually "drift" apart, leading to nightmare bugs! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/indexes-performance.mdx b/absolute-beginners/backend-beginner/database/indexes-performance.mdx new file mode 100644 index 0000000..aeb2a21 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/indexes-performance.mdx @@ -0,0 +1,70 @@ +--- +sidebar_position: 7 +title: "Database Indexes & Performance" +sidebar_label: "7. Indexes & Performance" +description: "Learn how to make your database queries 100x faster by using Indexes and avoiding common performance traps." +--- + +As your app at **CodeHarborHub** grows from 10 users to 10,000, your database will naturally slow down. A query that took **5ms** might suddenly take **2 seconds**. **Indexing** is the primary way we fix this. + +## The "Book Index" Analogy + +Imagine you have a 500-page book on "Node.js." You want to find the chapter on "Middleware." + +1. **Without an Index (Full Table Scan):** You start at page 1 and flip through every single page until you find the word "Middleware." 🐢 (Very Slow) +2. **With an Index:** You flip to the back of the book, look up "M" for Middleware, see it's on page 245, and jump straight there. ⚡ (Very Fast) + +## How an Index Works + +When you create an index on a column (like `email`), the database creates a separate, hidden "mini-table" that is sorted alphabetically. + +Instead of looking through the main table, the database searches this sorted list first. Since it's sorted, it can use a **Binary Search** to find the data instantly. + +```sql +-- How to add an index in SQL +CREATE INDEX idx_user_email ON Users(email); +``` + +## The Trade-off: Read vs. Write + +Indexes aren't "free." Every time you add an index, you are making a trade-off. + +| Action | Impact with Index | Why? | +| :--- | :--- | :--- | +| **SELECT** (Read) | 100x Faster | The database jumps straight to the data. | +| **INSERT** (Write) | Slower | The DB must update the table **and** the index. | +| **STORAGE** | Increased | The index takes up extra space on the disk. | + +## When should you use an Index? + +Don't index every single column! At **CodeHarborHub**, follow these rules: + + + +1. **Primary Keys:** Most databases index these automatically. +2. **Foreign Keys:** Columns used in `JOIN` operations. +3. **Search Columns:** Columns used in `WHERE` clauses (e.g., `email`, `username`). + + +1. **Small Tables:** If a table has only 50 rows, an index is overkill. +2. **Frequently Changing Data:** Columns that get updated 100 times a second. +3. **Low Cardinality:** Columns with very few options (e.g., a `Gender` column with only 3 options). + + + +## Tools for Performance + +How do you know if your query is slow? Use the `EXPLAIN` command. + +```sql +EXPLAIN ANALYZE SELECT * FROM Users WHERE email = 'ajay@example.com'; +``` + +*This will tell you if the database used an index or if it had to read every single row.* + +## Summary Checklist + + * [x] I understand that an Index is a sorted pointer to data. + * [x] I know that Indexes make **Reads** faster but **Writes** slower. + * [x] I understand that `JOIN` columns and `WHERE` columns are the best candidates for indexing. + * [x] I know how to use `EXPLAIN` to check query performance. \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/intro-to-databases.mdx b/absolute-beginners/backend-beginner/database/intro-to-databases.mdx new file mode 100644 index 0000000..26fdd2c --- /dev/null +++ b/absolute-beginners/backend-beginner/database/intro-to-databases.mdx @@ -0,0 +1,67 @@ +--- +sidebar_position: 1 +title: "Introduction to Databases" +sidebar_label: "1. What is a Database?" +description: "Understand the core concept of databases and why they are the backbone of every modern application." +--- + +In the early days of computing, programmers saved data in simple text files. But imagine trying to find one specific user in a file containing 10 million names! It would be slow, prone to errors, and impossible for two people to edit at the same time. + +A **Database** is an organized collection of structured information, or data, typically stored electronically in a computer system. + +## The DBMS: The Librarian + +When we talk about "The Database," we usually mean the **Database Management System (DBMS)**. + +Think of the Database as a **Library** and the DBMS as the **Librarian**. You don't walk into the stacks and grab books yourself; you ask the Librarian (DBMS) to find, add, or update information for you. + +### Why do we need a DBMS? + +* **Massive Scale:** Handles millions of rows without breaking a sweat. +* **Concurrency:** Allows 1,000+ users to read and write data at the exact same millisecond. +* **Data Integrity:** Ensures that your "Age" column only contains numbers, not "Mango." +* **Security:** Controls exactly who can see or change specific pieces of data. + +## The 4 Core Operations (CRUD) + +No matter how complex an application like **CodeHarborHub** becomes, almost every interaction with a database boils down to these four actions: + +| Action | SQL Command | Real-World Example | +| :--- | :--- | :--- | +| **C**reate | `INSERT` | A new student signs up for a course. | +| **R**ead | `SELECT` | You view your dashboard to see your progress. | +| **U**pdate | `UPDATE` | You change your profile picture or password. | +| **D**elete | `DELETE` | You unsubscribe or remove a post. | + +## Database Categories + +Before you write your first line of code, you must choose the "Type" of database. At **CodeHarborHub**, we primarily focus on the first two: + + + + + ### Structured & Strict + Data is organized into tables (like Excel) with fixed columns. Great for complex relationships. + * **Examples:** PostgreSQL, MySQL, SQLite. + + + + + ### Flexible & Fast + Data is stored in "Documents" (like JSON). Great for rapidly changing data or massive real-time feeds. + * **Examples:** MongoDB, Cassandra, Firebase. + + + + +--- + +## Summary Checklist +* [x] I understand that a database is more than just a "file"; it's a managed system. +* [x] I know that the **DBMS** is the software that manages the data. +* [x] I can name the four **CRUD** operations. +* [x] I recognize the difference between **SQL** (Tables) and **NoSQL** (Documents). + +:::tip Career Insight +In your journey at **CodeHarborHub**, you will find that 90% of "Backend Development" is actually just moving data in and out of a database efficiently. Master the database, and you master the backend! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/n-plus-1-problem.mdx b/absolute-beginners/backend-beginner/database/n-plus-1-problem.mdx new file mode 100644 index 0000000..1899fac --- /dev/null +++ b/absolute-beginners/backend-beginner/database/n-plus-1-problem.mdx @@ -0,0 +1,88 @@ +--- +sidebar_position: 11 +title: "The N+1 Query Problem" +sidebar_label: "11. N+1 Problem" +description: "Learn how to identify and fix the N+1 query problem to prevent your database from slowing down as your data grows." +--- + +As a developer at **CodeHarborHub**, you want your app to be fast. However, many beginners accidentally write code that forces the database to do 100 times more work than necessary. This is known as the **N+1 Problem**. + +## 🧐 What is the N+1 Problem? + +This problem occurs when your application makes **one** initial query to fetch a list of items (N), and then makes **one additional query for each** item to fetch related data. + +### The "Grocery Store" Analogy +Imagine you need to buy 10 different items from the store: +* **The N+1 Way:** You drive to the store, buy milk, and drive home. Then you drive back, buy bread, and drive home. You repeat this **10 times**. (Exhausting!) +* **The Efficient Way:** You make a list of all 10 items, drive to the store **once**, buy everything, and drive home. (Fast!) + +## Seeing it in Code + +Imagine we want to display a list of 10 **Users** and their **Posts**. + +### The Bad Way (N+1) +If you use a loop to fetch related data, you create an N+1 disaster. + +```javascript +// 1 Query to get 10 users +const users = await prisma.user.findMany(); + +// 10 separate queries (one inside each loop) +for (const user of users) { + const posts = await prisma.post.findMany({ + where: { userId: user.id } + }); + console.log(`${user.name} has ${posts.length} posts.`); +} +// TOTAL QUERIES: 1 + 10 = 11 +```` + +If you had 1,000 users, your app would hit the database **1,001 times** just to load one page! + +## The Solution: Eager Loading + +Instead of fetching related data inside a loop, we tell the database to join the tables and give us everything in **one single trip**. + +### The Good Way (Eager Loading) + +In modern ORMs like **Prisma**, we use the `include` keyword. + +```javascript +// ONE SINGLE QUERY to get 10 users AND all their posts +const usersWithPosts = await prisma.user.findMany({ + include: { + posts: true, + }, +}); + +// Now the data is already in memory! No more DB hits. +usersWithPosts.forEach(user => { + console.log(`${user.name} has ${user.posts.length} posts.`); +}); +// TOTAL QUERIES: 1 +``` + +## Comparison: Why it matters + +| Feature | N+1 Strategy | Eager Loading (The Fix) | +| :--- | :--- | :--- | +| **Database Trips** | 1 + N (Many) | 1 (Single) | +| **Performance** | Slows down as data grows | Consistently fast | +| **Network Latency** | High (Multiple Roundtrips) | Low (One Roundtrip) | +| **Server Load** | Very High | Minimal | + +## How to Spot it? + +1. **Check your Logs:** If you see the same `SELECT` statement repeating 20 times in your console, you have an N+1 problem. +2. **Use Tools:** Tools like **Prisma Studio**, **Hibernate Profiler**, or even simple `console.log` can help you count your queries. + +## Summary Checklist + + * [x] I understand that N+1 means making a separate query for every item in a list. + * [x] I know that loops + database queries = **Performance Disaster**. + * [x] I understand that **Eager Loading** (Joins) is the primary solution. + * [x] I can identify N+1 problems by looking at my server logs. + +:::success You've Mastered the Foundations! +By understanding the N+1 problem, you've moved past "beginner" coding. You are now thinking about **Scalability** and **Efficiency**—the marks of a true Senior Backend Engineer at **CodeHarborHub**. +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/normalization.mdx b/absolute-beginners/backend-beginner/database/normalization.mdx new file mode 100644 index 0000000..dfbc1bb --- /dev/null +++ b/absolute-beginners/backend-beginner/database/normalization.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 5 +title: "Database Normalization" +sidebar_label: "5. Normalization" +description: "Learn how to organize your database tables to reduce redundancy and improve data integrity." +--- + +Imagine you have a spreadsheet where every time a student buys a course, you type their name, email, phone number, and address again. + +If that student changes their phone number, you have to find and update **10 different rows**. If you miss one, your data is inconsistent. **Normalization** is the cure for this "Data Mess." + +## 🧐 The Goal of Normalization + +1. **Eliminate Redundant Data:** Don't store the same info twice. +2. **Ensure Data Dependencies:** Only store related data together (e.g., don't put a "Course Price" in the "Student" table). +3. **Protect Data Integrity:** Make updates, deletions, and insertions easy and error-free. + +## The Three Normal Forms (1NF, 2NF, 3NF) + +Think of these as "Levels" of cleanliness for your database. Most professional apps at **CodeHarborHub** aim for **3rd Normal Form (3NF)**. + + + + + ### Rule: No Multi-Valued Attributes + Every cell must contain only **one** value. No lists or comma-separated strings! + + * **Bad:** `Courses: "React, Node, CSS"` + * **Good:** Three separate rows, one for each course. + + + + + ### Rule: Must be in 1NF + No Partial Dependencies + Every non-key column must depend on the **entire** Primary Key. If a table has a composite key (two IDs), don't store data that only relates to one of them. + + * **Action:** Move "Course Details" into a `Courses` table and "Student Details" into a `Students` table. + + + + + ### Rule: Must be in 2NF + No Transitive Dependencies + Non-key columns should not depend on other non-key columns. + + * **Example:** In a `Students` table, don't store `City` and `ZipCode` together if the `City` depends on the `ZipCode`. + * **Action:** Move `ZipCode` and `City` to a separate `Locations` table. + + + + +## The "Key" Oath + +To remember how 3NF works, database experts often use this famous quote: + +> "Every non-key attribute must provide a fact about **the key** (1NF), **the whole key** (2NF), and **nothing but the key** (3NF), so help me Codd." +> — *E.F. Codd (The inventor of the Relational Model)* + +## When to STOP Normalizing? + +While Normalization is great for data integrity, too much of it can make your queries slow because the computer has to "Join" 10 different tables just to show a user profile. + +In high-performance systems (like a massive "Search" feature), we sometimes **De-normalize** data (purposefully repeat it) to make reading faster. + +## Summary Checklist +* [x] I understand that Normalization reduces data redundancy. +* [x] I know that **1NF** means one value per cell. +* [x] I know that **2NF** and **3NF** are about splitting tables so data only lives where it belongs. +* [x] I understand that "The Key Oath" is the secret to 3NF. + +:::tip Real-World Tip +When you are just starting your project, **always normalize first**. It is much easier to "De-normalize" a clean database later than it is to fix a "Messy" database after it has 1,000 users! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/orms.mdx b/absolute-beginners/backend-beginner/database/orms.mdx new file mode 100644 index 0000000..7f7dd7f --- /dev/null +++ b/absolute-beginners/backend-beginner/database/orms.mdx @@ -0,0 +1,80 @@ +--- +sidebar_position: 8 +title: "Object-Relational Mapping (ORM)" +sidebar_label: "8. ORMs" +description: "Learn how to interact with your database using the programming language you already know." +--- + +Writing raw SQL inside your Node.js code can be messy. It’s hard to read, hard to debug, and dangerous if not handled correctly. An **ORM** is a library that acts as a translator between your **Object-Oriented Code** (JavaScript/TypeScript) and your **Relational Database** (SQL). + +## 🧐 The "Translator" Concept + +Imagine you speak English (JavaScript), but your database only speaks Spanish (SQL). You could learn Spanish, or you could hire a **Translator (ORM)**. + +1. **In JavaScript:** You think in terms of **Objects** and **Arrays**. +2. **In SQL:** The database thinks in terms of **Tables** and **Rows**. +3. **The ORM:** Maps your JS Object properties to your SQL Table columns automatically. + +## Raw SQL vs. ORM + +Let’s see how we find a user with the email `ajay@example.com`. + + + + + ```javascript + const query = "SELECT * FROM users WHERE email = 'ajay@example.com'"; + const user = await db.execute(query); + ``` + + * **Risk:** High chance of "SQL Injection" if you don't sanitize inputs. + * **Maintenance:** If you change a column name, you have to find and replace it in every string. + + + + +```javascript +const user = await prisma.user.findUnique({ + where: { email: 'ajay@example.com' } +}); +``` + + * **Safety:** Automatically protects against SQL injection. + * **IntelliSense:** Your editor (VS Code) will suggest column names as you type\! + + + + +## Why use an ORM at CodeHarborHub? + +1. **Database Agnostic:** Want to switch from MySQL to PostgreSQL? With an ORM, you usually only have to change one line of config, not rewrite your entire codebase. +2. **Migrations:** Most ORMs (like Prisma) handle your **Database Migrations** automatically. +3. **Type Safety:** If you use TypeScript, an ORM ensures you don't accidentally try to save a "String" into a "Number" column. +4. **Relationships:** Fetching a user and all their posts is as simple as adding `include: { posts: true }`. + +## Popular ORMs in the Ecosystem + +| ORM | Language | Style | +| :--- | :--- | :--- | +| **Prisma** | JS / TS | **Modern Choice.** Uses a schema file to generate a client. (Highly Recommended) | +| **Sequelize** | JS | **The Veteran.** Uses models and classes. Very stable. | +| **TypeORM** | TS | **The Java Style.** Uses decorators (`@Entity`, `@Column`). | +| **Mongoose** | JS / TS | **The NoSQL King.** Specifically for MongoDB. | + +## The "Performance" Warning + +While ORMs are amazing for developer productivity, they come with a small cost: + + * **Overhead:** They are slightly slower than raw SQL because of the translation layer. + * **Complex Queries:** For very advanced reports or data science, raw SQL is still better. + +## Summary Checklist + + * [x] I understand that an ORM maps Objects to Tables. + * [x] I know that ORMs provide better security and developer experience. + * [x] I can name at least two popular ORMs (Prisma, Sequelize). + * [x] I understand that ORMs make switching databases easier. + +:::tip Pro-Tip +At **CodeHarborHub**, we will be using **Prisma** for our practical projects. It is currently the most loved ORM in the industry because of its incredible developer tools and TypeScript support! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/primary-foreign-keys.mdx b/absolute-beginners/backend-beginner/database/primary-foreign-keys.mdx new file mode 100644 index 0000000..aace919 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/primary-foreign-keys.mdx @@ -0,0 +1,77 @@ +--- +sidebar_position: 4 +title: "Primary & Foreign Keys" +sidebar_label: "4. Keys & Relationships" +description: "Understand how to uniquely identify records and link different tables together using Primary and Foreign keys." +--- + +In a relational database, we don't store everything in one giant table. Instead, we split data into smaller, logical tables (like `Users`, `Courses`, and `Enrollments`). + +**Keys** are the unique identifiers that allow these tables to talk to each other. + +## 1. The Primary Key (PK) + +A **Primary Key** is a column (or group of columns) that uniquely identifies each row in a table. Think of it as the "Digital DNA" of a record. + +### The 3 Golden Rules of Primary Keys: +1. **Unique:** No two rows can have the same Primary Key. +2. **Not Null:** It can never be empty. Every record *must* have an ID. +3. **Immutable:** Once assigned, it should never change. + +* **Real-World Examples:** Your Aadhar Card Number, a Roll Number, or a random UUID (Universally Unique Identifier). + +## 2. The Foreign Key (FK) + +A **Foreign Key** is a column in one table that refers to the Primary Key of **another** table. This is how we create a "Relationship." + +### How it works: +Imagine you have a `Users` table and an `Orders` table. +* The `Users` table has a PK called `user_id`. +* The `Orders` table has its own PK, but it also has a column called `user_id`. +* This `user_id` in the `Orders` table is a **Foreign Key** pointing back to the `Users` table. + +## Visualizing the Connection + +Let's look at how **CodeHarborHub** might link a student to their enrolled courses: + +```mermaid +erDiagram + STUDENTS ||--o{ ENROLLMENTS : "has" + COURSES ||--o{ ENROLLMENTS : "includes" + + STUDENTS { + int id PK + string name + string email + } + + COURSES { + int id PK + string title + int price + } + + ENROLLMENTS { + int id PK + int student_id FK + int course_id FK + date enrolled_at + } +``` + +## Referential Integrity + +When you use Foreign Keys, the database enforces a rule called **Referential Integrity**. + +This means you cannot have an "Orphan" record. For example, you cannot create an `Order` for a `User` that doesn't exist in the `Users` table. The database will throw an error to protect your data! + +## Summary Checklist + + * [x] I know that a **Primary Key** uniquely identifies a single row. + * [x] I understand that a **Foreign Key** links two tables together. + * [x] I know that Primary Keys must be unique and cannot be null. + * [x] I understand that keys prevent "bad data" (orphaned records) from entering the system. + +:::tip Best Practice +Avoid using real data (like an Email or Phone Number) as a Primary Key. Instead, use an **Auto-Incrementing Integer** (`1, 2, 3...`) or a **UUID**. This ensures that even if a user changes their email, their ID remains the same\! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/relational-basics.mdx b/absolute-beginners/backend-beginner/database/relational-basics.mdx new file mode 100644 index 0000000..a25ad87 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/relational-basics.mdx @@ -0,0 +1,69 @@ +--- +sidebar_position: 3 +title: "Relational Database Basics" +sidebar_label: "3. Relational Basics" +description: "Learn the fundamental building blocks of a Relational Database—Tables, Rows, Columns, and Schema." +--- + +A **Relational Database Management System (RDBMS)** organizes data into one or more tables. These tables are linked to each other using common data, which is why we call them "Relational." + +## The Anatomy of a Table + +Every table in a database like **PostgreSQL** or **MySQL** follows a strict structure. Let’s look at a sample `Students` table: + +### 1. The Table (The Container) +A table is a collection of related data entries. In our case, the table is named `Students`. + +### 2. Columns / Fields (The Attributes) +Columns define **what** kind of data is stored. Each column has a specific **Data Type** (e.g., Integer, String, Date). +* *Example:* `first_name`, `email`, `enrollment_date`. + +### 3. Rows / Records (The Entries) +A row represents a single, complete unit of information. +* *Example:* One row contains all the info for a student named "Ajay." + +## The Schema (The Blueprint) + +Before you can add any data, you must define a **Schema**. This is a roadmap that tells the database exactly how many columns to have and what "rules" they must follow. + +```sql +-- Example Schema for a Students Table +CREATE TABLE Students ( + id INT PRIMARY KEY, + name VARCHAR(100), + email VARCHAR(100) UNIQUE, + joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +## Common Data Types + +When designing your tables at **CodeHarborHub**, you need to choose the right "bucket" for your data: + +| Data Type | Description | Use Case | +| :--- | :--- | :--- | +| **INT / INTEGER** | Whole numbers | IDs, Age, Quantity | +| **VARCHAR / TEXT** | Strings of characters | Names, Emails, Bios | +| **BOOLEAN** | True or False | `is_active`, `has_paid` | +| **DECIMAL / FLOAT**| Numbers with decimals | Prices, Ratings | +| **TIMESTAMP** | Date and Time | `created_at`, `updated_at` | + +## The Goal: Atomic Data + +In a good relational design, each piece of data should be **Atomic** (indivisible). + + * **Bad:** A column called `address` containing `"123 Street, Indore, MP, 452001"`. + * **Good:** Four separate columns: `street`, `city`, `state`, `zip_code`. + +*Why?* Because it's much easier to search for all students in "Indore" if the city has its own column! + +## Summary Checklist + + * [x] I know that a **Table** is a collection of Rows and Columns. + * [x] I understand that a **Row** is a single record. + * [x] I know that a **Column** defines the type of data (Integer, String, etc.). + * [x] I understand that the **Schema** is the blueprint for the database. + +:::info Pro-Tip +Always use **Snake Case** (`first_name`) or **Camel Case** (`firstName`) for your column names consistently. At **CodeHarborHub**, we recommend `snake_case` for SQL columns as it is the industry standard! +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/sql-vs-nosql.mdx b/absolute-beginners/backend-beginner/database/sql-vs-nosql.mdx new file mode 100644 index 0000000..c436692 --- /dev/null +++ b/absolute-beginners/backend-beginner/database/sql-vs-nosql.mdx @@ -0,0 +1,69 @@ +--- +sidebar_position: 2 +title: "SQL vs. NoSQL" +sidebar_label: "2. SQL vs. NoSQL" +description: "Compare Relational (SQL) and Non-Relational (NoSQL) databases to choose the best fit for your project." +--- + +One of the first major decisions you will make as a Backend Developer is deciding where to store your data. This choice affects how you write code, how your app scales, and how you handle changes in the future. + +## SQL (Relational Databases) + +SQL databases are like a **Spreadsheet**. They use structured tables with fixed rows and columns. Every piece of data must fit into a predefined "Schema" (blueprint). + +### Key Characteristics: +* **Relational:** Tables are linked using Keys (Primary and Foreign). +* **Predefined Schema:** You must define your columns and data types *before* you add data. +* **ACID Compliant:** High focus on data integrity and reliability. +* **Vertical Scaling:** To handle more traffic, you usually need a bigger, more powerful server. + +**Best For:** Complex queries, financial systems, and apps where data consistency is non-negotiable (like an E-commerce store). + +## NoSQL (Non-Relational Databases) + +NoSQL databases are like a **Folder of Documents**. They don't use tables; instead, they store data in flexible formats like JSON. + +### Key Characteristics: +* **Non-Relational:** Data is often "nested" inside a single document rather than linked across tables. +* **Dynamic Schema:** You can add new fields to a record without changing the whole database. +* **High Scalability:** Designed to be "Distributed." You can add 10 small servers instead of 1 giant one (**Horizontal Scaling**). +* **Speed:** Optimized for high-speed read/write operations for massive amounts of data. + +**Best For:** Real-time big data, content management (CMS), social media feeds, and rapid prototyping. + +## Head-to-Head Comparison + +| Feature | SQL (PostgreSQL, MySQL) | NoSQL (MongoDB, Redis) | +| :--- | :--- | :--- | +| **Data Model** | Tables / Rows | Documents / Key-Value | +| **Schema** | Fixed (Rigid) | Dynamic (Flexible) | +| **Scaling** | Vertical (Bigger Server) | Horizontal (More Servers) | +| **Joins** | Excellent (Native) | Poor (Manual or Nested) | +| **Consistency** | Strong (ACID) | Eventual (BASE) | + +## 🤔 Which one should you pick? + +At **CodeHarborHub**, we recommend following this simple rule of thumb: + + + + 1. Your data is highly structured (User -> Order -> Product). + 2. You need complex "Joins" to connect information. + 3. Data accuracy is more important than raw speed (e.g., Banking). + + + 1. Your data structure changes constantly. + 2. You are dealing with massive amounts of unstructured data (e.g., IoT logs). + 3. You need to scale your app across multiple global servers easily. + + + +## Summary Checklist +* [x] I understand that **SQL** uses tables and **NoSQL** uses documents. +* [x] I know that SQL is better for "Relationships" and NoSQL is better for "Flexibility." +* [x] I understand the difference between **Vertical** and **Horizontal** scaling. +* [x] I can choose the right database type based on project requirements. + +:::info Real-World Tip +Most modern "Unicorn" startups actually use **both**! They might use PostgreSQL (SQL) for their user accounts and payments, but use Redis (NoSQL) for their real-time chat and notifications. +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/database/transactions.mdx b/absolute-beginners/backend-beginner/database/transactions.mdx new file mode 100644 index 0000000..d0b903e --- /dev/null +++ b/absolute-beginners/backend-beginner/database/transactions.mdx @@ -0,0 +1,85 @@ +--- +sidebar_position: 10 +title: "Database Transactions" +sidebar_label: "10. Transactions" +description: "Learn how to group multiple SQL operations into a single, safe unit of work using Transactions." +--- + +A **Transaction** is a sequence of one or more SQL operations executed as a single unit. In a transaction, either **all** the changes are saved to the database, or **none** of them are. + +## The Classic Example: Bank Transfer + +Imagine a student at **CodeHarborHub** pays ₹1000 for a Premium Course. This requires two separate database updates: + +1. **Update 1:** Subtract ₹1000 from the Student's balance. +2. **Update 2:** Add ₹1000 to the Instructor's balance. + +**The Nightmare Scenario:** What if the server crashes *after* Update 1 but *before* Update 2? The student loses money, and the instructor gets nothing. + +## The 3 Key Commands + +To handle this, SQL provides three special commands to manage the lifecycle of a transaction: + +1. **`BEGIN` (or `START TRANSACTION`):** Tells the database, "Everything I do from now on is part of a single unit." +2. **`COMMIT`:** Tells the database, "Everything went perfectly. Save all these changes permanently." +3. **`ROLLBACK`:** Tells the database, "Something went wrong! Undo everything since the `BEGIN` command." + +## Writing a Transaction in SQL + +Here is how that bank transfer looks in raw SQL: + +```sql +BEGIN; + +-- Step 1: Deduct from Student +UPDATE accounts SET balance = balance - 1000 WHERE user_id = 'student_01'; + +-- Step 2: Add to Instructor +UPDATE accounts SET balance = balance + 1000 WHERE user_id = 'instructor_99'; + +-- If everything is okay: +COMMIT; + +-- IF SOMETHING FAILED: +-- ROLLBACK; +``` + +## Implementing Transactions in Node.js (Prisma) + +At **CodeHarborHub**, we use ORMs to make this even safer. In **Prisma**, we use the `$transaction` API: + +```javascript +const transferMoney = await prisma.$transaction(async (tx) => { + // 1. Deduct from sender + const sender = await tx.account.update({ + data: { balance: { decrement: 1000 } }, + where: { userId: 'student_01' }, + }); + + // 2. Add to receiver + const receiver = await tx.account.update({ + data: { balance: { increment: 1000 } }, + where: { userId: 'instructor_99' }, + }); + + // If any line fails, Prisma automatically rolls back both steps! + return { sender, receiver }; +}); +``` + +## When to use Transactions? + + * **Financial Transfers:** Payments, refunds, and balance updates. + * **Inventory Management:** Reducing stock when an order is placed. + * **Multi-Table Inserts:** Creating a `User` record and a `Profile` record at the same time. + +## Summary Checklist + + * [x] I understand that a Transaction is an "all or nothing" unit of work. + * [x] I know that **COMMIT** saves changes and **ROLLBACK** undoes them. + * [x] I can identify scenarios (like banking) where transactions are mandatory. + * [x] I know that modern ORMs like Prisma make transactions easier to write. + +:::warning Keep them Short! +Transactions "lock" the rows they are touching so other users can't mess with them. If you keep a transaction open for a long time (e.g., waiting for an external API), you might slow down your entire database! **Get in, do the work, and COMMIT immediately.** +::: \ No newline at end of file diff --git a/absolute-beginners/backend-beginner/relational-databases/_category_.json b/absolute-beginners/backend-beginner/relational-databases/_category_.json index d773b2a..7512ae5 100644 --- a/absolute-beginners/backend-beginner/relational-databases/_category_.json +++ b/absolute-beginners/backend-beginner/relational-databases/_category_.json @@ -1,6 +1,6 @@ { "label": "Relational Databases", - "position": 7, + "position": 6, "link": { "type": "generated-index", "description": "Learn how to store data in structured tables, use SQL to query information, and understand why RDBMS is the backbone of the banking and enterprise world." diff --git a/docusaurus.config.js b/docusaurus.config.js index fe9002d..bd20c7c 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -120,6 +120,7 @@ const config = { navbar: { title: "CodeHarborHub", + hideOnScroll: true, logo: { alt: "CodeHarborHub Logo", src: "img/nav-logo.jpg", @@ -186,6 +187,17 @@ const config = { }, ], }, + // { + // type: 'localeDropdown', + // position: 'left', + // dropdownItemsAfter: [ + // { + // to: 'https://my-site.com/help-us-translate', + // label: 'Help us translate', + // }, + // ], + // }, + // { // to: "https://codeharborhub.github.io/blog", // html: '📝 Blog',