[{"data":1,"prerenderedAt":13421},["ShallowReactive",2],{"/post/dns-explained-how-domain-name-system-works":3,"related-/backend/dns-explained-how-domain-name-system-works":2459},{"id":4,"title":5,"author":6,"body":7,"date":2442,"description":2443,"draft":2444,"extension":2445,"guide":2446,"image":2447,"meta":2448,"navigation":1063,"path":2449,"seo":2450,"stem":2451,"tags":2452,"__hash__":2458},"blog/Backend/3.dns-explained-how-domain-name-system-works.md","DNS Explained: What Actually Happens Before Your Browser Loads a Page","Kashyap Kumar",{"type":8,"value":9,"toc":2380},"minimark",[10,24,27,32,46,52,55,61,65,72,75,103,106,110,113,120,126,136,139,209,218,222,225,231,236,246,249,253,256,259,263,272,276,282,286,293,299,305,308,311,315,321,324,333,347,353,367,370,376,380,383,386,390,393,408,430,439,442,446,449,618,621,625,634,640,643,649,653,656,662,674,679,694,699,703,706,712,722,726,729,732,738,744,750,756,762,766,769,775,778,782,788,794,797,801,804,810,814,821,827,830,835,846,851,862,865,870,874,877,883,887,890,894,897,906,912,916,923,926,1016,1019,1119,1123,1132,1138,1145,1149,1152,1157,1303,1309,1315,1321,1438,1441,1449,1510,1513,1521,1563,1567,1570,1654,1657,1661,1665,1668,1674,1681,1685,1688,1737,1740,1744,1747,1769,1772,1776,1779,1785,1791,1797,1803,1809,1813,1816,1822,1829,1833,1836,1840,1843,1846,1850,1853,1857,1860,1864,1867,1873,1876,1880,1883,1886,1892,1895,1944,1947,1951,1954,1960,1966,1969,2016,2020,2024,2041,2044,2048,2065,2068,2072,2075,2155,2158,2162,2165,2181,2188,2192,2252,2255,2259,2317,2320,2324,2327,2330,2376],[11,12,13,14,18,19,23],"p",{},"You type ",[15,16,17],"code",{},"github.com"," into your browser and press Enter. The page loads in under a second. But between that keypress and the first pixel appearing on your screen, something extraordinary happens that most people never think about. A system called ",[20,21,22],"strong",{},"DNS"," silently translates that human-readable name into a machine address, traverses a global hierarchy of servers, and returns an answer before you even notice.",[11,25,26],{},"This article explains every part of that process, from the very beginning.",[28,29,31],"h2",{"id":30},"what-is-dns","What is DNS?",[11,33,34,37,38,41,42,45],{},[20,35,36],{},"DNS stands for Domain Name System."," At its core, it is a global, distributed database that translates domain names (like ",[15,39,40],{},"google.com",") into IP addresses (like ",[15,43,44],{},"142.250.80.46",").",[11,47,48,49,51],{},"Why does this translation need to exist at all? Because computers on the internet communicate using IP addresses, not human-readable names. An IP address is the actual \"location\" of a server on the internet. But remembering ",[15,50,44],{}," every time you want to visit Google is not realistic for anyone.",[11,53,54],{},"So DNS acts as the internet's address book. You look up a name, and it returns the corresponding address.",[56,57,58],"blockquote",{},[11,59,60],{},"Think of DNS like the contacts app on your phone. When you tap \"Mom,\" your phone finds her phone number and dials it. You don't think about the number at all. DNS does the same thing: you type a name, it finds the corresponding IP address, and your browser connects to it.",[28,62,64],{"id":63},"the-problem-dns-was-built-to-solve","The Problem DNS Was Built to Solve",[11,66,67,68,71],{},"DNS was not always here. In the early days of the internet (ARPANET), there was a single text file called ",[15,69,70],{},"HOSTS.TXT"," that listed every computer on the network alongside its address. This file was maintained by hand at the Stanford Research Institute, and every connected computer would periodically download it.",[11,73,74],{},"When the network had a few hundred machines, this worked fine. But as the internet grew, the problems became serious:",[76,77,78,85,91,97],"ul",{},[79,80,81,84],"li",{},[20,82,83],{},"Scale:"," Thousands of new machines were being added constantly. One text file could not keep up.",[79,86,87,90],{},[20,88,89],{},"Inconsistency:"," Different computers downloaded the file at different times, so they had different data.",[79,92,93,96],{},[20,94,95],{},"Single point of failure:"," One file, one server, one catastrophic bottleneck for the entire network.",[79,98,99,102],{},[20,100,101],{},"No organisation:"," All names were flat. There was no concept of ownership or hierarchy.",[11,104,105],{},"In 1983, Paul Mockapetris designed DNS to replace this system. Instead of one flat file, DNS is a distributed, hierarchical, fault-tolerant database spanning thousands of servers across the globe.",[28,107,109],{"id":108},"the-domain-name-hierarchy","The Domain Name Hierarchy",[11,111,112],{},"Domain names have a tree structure, and you read them from right to left.",[11,114,115,116,119],{},"Take ",[15,117,118],{},"www.github.com."," (the trailing dot is almost always hidden, but it is always there):",[11,121,122],{},[123,124],"img",{"alt":109,"src":125},"/post-images/dns-explained-how-domain-name-system-works/domain-name-hierarchy-diagram.png",[127,128,133],"pre",{"className":129,"code":131,"language":132},[130],"language-text",".                       \u003C-- Root (the invisible dot at the very end)\n└── com                 \u003C-- Top-Level Domain (TLD)\n    └── github          \u003C-- Second-Level Domain (SLD)\n        └── www         \u003C-- Subdomain\n","text",[15,134,131],{"__ignoreMap":135},"",[11,137,138],{},"Each level of this hierarchy is owned and managed by a different organisation:",[76,140,141,151,179,191],{},[79,142,143,150],{},[20,144,145,146,149],{},"The root (",[15,147,148],{},".",")"," is managed by IANA (Internet Assigned Numbers Authority). There are 13 root server clusters, labeled A through M, distributed across hundreds of physical locations worldwide.",[79,152,153,156,157,160,161,160,164,167,168,171,172,175,176,178],{},[20,154,155],{},"Top-Level Domains (TLDs)"," like ",[15,158,159],{},".com",", ",[15,162,163],{},".org",[15,165,166],{},".net",", and country codes like ",[15,169,170],{},".uk"," or ",[15,173,174],{},".in"," are managed by registry operators. Verisign manages ",[15,177,159],{},", for example.",[79,180,181,156,184,187,188,190],{},[20,182,183],{},"Second-level domains",[15,185,186],{},"github"," in ",[15,189,17],{}," are registered by individuals and companies through domain registrars (Namecheap, GoDaddy, Cloudflare Registrar, etc.).",[79,192,193,156,196,160,199,160,202,160,205,208],{},[20,194,195],{},"Subdomains",[15,197,198],{},"www",[15,200,201],{},"api",[15,203,204],{},"mail",[15,206,207],{},"blog"," are created by the domain owner themselves in their DNS provider's control panel.",[56,210,211],{},[11,212,213,214,217],{},"That trailing dot in ",[15,215,216],{},"github.com."," represents the root of the DNS hierarchy. Your browser adds it automatically before sending a DNS query. It is always there even when invisible.",[28,219,221],{"id":220},"the-four-key-players-in-a-dns-query","The Four Key Players in a DNS Query",[11,223,224],{},"Before walking through a full DNS lookup, you need to understand the four main participants.",[11,226,227],{},[123,228],{"alt":229,"src":230},"The four key players in DNS resolution","/post-images/dns-explained-how-domain-name-system-works/dns-architecture-diagram.png",[232,233,235],"h3",{"id":234},"the-dns-recursor-recursive-resolver","The DNS Recursor (Recursive Resolver)",[11,237,238,239,242,243,148],{},"This is the first server your computer contacts when it needs to resolve a domain name. It is usually provided by your ISP, or by a public DNS service like Google's ",[15,240,241],{},"8.8.8.8"," or Cloudflare's ",[15,244,245],{},"1.1.1.1",[11,247,248],{},"The recursive resolver does the heavy lifting on your behalf. It contacts multiple servers, follows referrals, and eventually returns the final answer to your computer. Think of it as a librarian who goes through the entire library to find the book you need, rather than making you search yourself.",[232,250,252],{"id":251},"root-name-servers","Root Name Servers",[11,254,255],{},"There are 13 sets of root name servers (A through M). They do not know the IP address for your domain directly, but they know which servers are responsible for each TLD. They're like the index of a library that tells you which floor and section to visit.",[11,257,258],{},"The root server addresses are hardcoded into every DNS resolver software. They are the starting point for every uncached query.",[232,260,262],{"id":261},"tld-name-servers","TLD Name Servers",[11,264,265,266,268,269,271],{},"These servers know which authoritative name servers are responsible for specific domains within their TLD. The ",[15,267,159],{}," TLD server, for example, knows which name servers are authoritative for ",[15,270,17],{}," because GitHub's registrar told it when the domain was registered.",[232,273,275],{"id":274},"authoritative-name-servers","Authoritative Name Servers",[11,277,278,279,281],{},"This is the server that actually holds the DNS records for a domain. It is the final authority and gives the definitive answer: \"yes, ",[15,280,17],{}," is at this IP address.\" When you add DNS records in Cloudflare, Route 53, or any other DNS provider, you are updating the authoritative name server for your domain.",[28,283,285],{"id":284},"how-a-dns-lookup-actually-works","How a DNS Lookup Actually Works",[11,287,288,289,292],{},"Let's trace exactly what happens when you type ",[15,290,291],{},"www.github.com"," into your browser and press Enter.",[11,294,295],{},[123,296],{"alt":297,"src":298},"Full DNS lookup flow from browser to authoritative server","/post-images/dns-explained-how-domain-name-system-works/dns-lookup-flow-sequence-diagram.png",[127,300,303],{"className":301,"code":302,"language":132},[130],"Your Browser\n    │\n    ├─ Check 1: Browser DNS cache\n    │   (Did we look this up recently? Use the cached answer if TTL hasn't expired.)\n    │\n    ├─ Check 2: OS DNS cache + hosts file\n    │   (Does /etc/hosts have an entry? Did the OS already cache this?)\n    │\n    └─ Query: Ask the Recursive Resolver (e.g., 1.1.1.1)\n               │\n               ├─ Check 3: Resolver's own cache\n               │   (Has this resolver seen this query recently?)\n               │\n               ├─ Ask a Root Name Server\n               │   \"I need to resolve github.com. Help?\"\n               │   Root: \"I don't know the IP, but here are the .com TLD servers.\"\n               │\n               ├─ Ask the .com TLD Name Server\n               │   \"Who is authoritative for github.com?\"\n               │   TLD: \"Go ask ns1.p16.dynect.net\"\n               │\n               └─ Ask github.com's Authoritative Name Server\n                   \"What is the IP for www.github.com?\"\n                   Auth: \"It is 140.82.121.3\" (A record)\n                   │\n                   └─ Resolver returns 140.82.121.3 to your browser\n                       │\n                       └─ Browser connects to 140.82.121.3 over TCP/HTTPS\n                           Page loads.\n",[15,304,302],{"__ignoreMap":135},[11,306,307],{},"The entire process typically takes between 10 and 100 milliseconds. After this first lookup, the answer is cached at multiple levels, so future queries skip most of these steps and return almost instantly.",[11,309,310],{},"Let's look at each stage more carefully.",[232,312,314],{"id":313},"checking-local-caches-first","Checking Local Caches First",[11,316,317],{},[123,318],{"alt":319,"src":320},"DNS caching layers from browser to network","/post-images/dns-explained-how-domain-name-system-works/dns-caching-layers.png",[11,322,323],{},"Before any network request is made, your system checks several local caches in sequence:",[11,325,326,329,330,148],{},[20,327,328],{},"Browser cache:"," Chrome, Firefox, and other browsers maintain their own DNS cache. You can inspect Chrome's DNS cache at ",[15,331,332],{},"chrome://net-internals/#dns",[11,334,335,338,339,342,343,346],{},[20,336,337],{},"OS DNS cache:"," Your operating system caches DNS results separately. On Linux, this is typically handled by ",[15,340,341],{},"systemd-resolved",". On macOS, by ",[15,344,345],{},"mDNSResponder",". On Windows, by the DNS Client service.",[11,348,349,352],{},[20,350,351],{},"The hosts file:"," Before querying any DNS server, your OS reads a local text file:",[76,354,355,361],{},[79,356,357,358],{},"Linux/Mac: ",[15,359,360],{},"/etc/hosts",[79,362,363,364],{},"Windows: ",[15,365,366],{},"C:\\Windows\\System32\\drivers\\etc\\hosts",[11,368,369],{},"This file lets you manually map domain names to IP addresses. It predates DNS entirely and takes precedence over any DNS lookup for the entries it contains.",[127,371,374],{"className":372,"code":373,"language":132},[130],"# /etc/hosts example\n127.0.0.1     localhost\n::1           localhost\n\n# Point a custom local domain to your dev machine\n192.168.1.10  myapp.local\n192.168.1.10  api.myapp.local\n\n# Block a domain by pointing it to nothing\n127.0.0.1     ads.annoying-tracker.com\n",[15,375,373],{"__ignoreMap":135},[232,377,379],{"id":378},"contacting-the-recursive-resolver","Contacting the Recursive Resolver",[11,381,382],{},"If no local cache has the answer, your computer sends a DNS query to the recursive resolver configured on your system (received via DHCP when you connected to the network, or set manually).",[11,384,385],{},"The resolver is the workhorse of the entire system. It contacts all the other servers on your behalf and returns a final answer. Your computer never talks to root servers or authoritative servers directly.",[232,387,389],{"id":388},"the-resolution-chain","The Resolution Chain",[11,391,392],{},"If the resolver's own cache is also empty, it starts the chain of iterative queries:",[11,394,395,398,399,401,402,404,405,407],{},[20,396,397],{},"Asking a root server:"," The resolver contacts one of the 13 root server clusters and asks about ",[15,400,291],{},". The root server does not know the answer, but it knows who manages ",[15,403,159],{},". It responds with a list of ",[15,406,159],{}," TLD name server addresses.",[11,409,410,413,414,416,417,419,420,422,423,160,426,429],{},[20,411,412],{},"Asking the TLD server:"," The resolver asks the ",[15,415,159],{}," TLD server who is authoritative for ",[15,418,17],{},". The TLD server looks up its records and responds: \"The authoritative name servers for ",[15,421,17],{}," are ",[15,424,425],{},"ns1.p16.dynect.net",[15,427,428],{},"ns2.p16.dynect.net",", etc. Go ask them.\"",[11,431,432,435,436,438],{},[20,433,434],{},"Asking the authoritative server:"," The resolver contacts GitHub's authoritative name server and asks for the A record for ",[15,437,291],{},". The authoritative server has the actual DNS records and responds with the IP address.",[11,440,441],{},"The resolver caches this answer (for the duration of the TTL, covered below) and returns it to your computer. Your browser then opens a TCP connection to that IP and loads the page.",[28,443,445],{"id":444},"dns-record-types-the-different-kinds-of-answers","DNS Record Types: The Different Kinds of Answers",[11,447,448],{},"DNS is not just about IP addresses. There are many types of DNS records, each serving a different purpose. All of them are stored on authoritative name servers.",[450,451,452,468],"table",{},[453,454,455],"thead",{},[456,457,458,462,465],"tr",{},[459,460,461],"th",{},"Record Type",[459,463,464],{},"Purpose",[459,466,467],{},"Example Value",[469,470,471,487,502,516,531,546,561,574,588,603],"tbody",{},[456,472,473,479,482],{},[474,475,476],"td",{},[15,477,478],{},"A",[474,480,481],{},"Maps a hostname to an IPv4 address",[474,483,484],{},[15,485,486],{},"140.82.121.3",[456,488,489,494,497],{},[474,490,491],{},[15,492,493],{},"AAAA",[474,495,496],{},"Maps a hostname to an IPv6 address",[474,498,499],{},[15,500,501],{},"2606:50c0:8000::153",[456,503,504,509,512],{},[474,505,506],{},[15,507,508],{},"CNAME",[474,510,511],{},"Alias: points one name to another name",[474,513,514],{},[15,515,216],{},[456,517,518,523,526],{},[474,519,520],{},[15,521,522],{},"MX",[474,524,525],{},"Specifies mail servers for a domain",[474,527,528],{},[15,529,530],{},"10 aspmx.l.google.com.",[456,532,533,538,541],{},[474,534,535],{},[15,536,537],{},"TXT",[474,539,540],{},"Arbitrary text (SPF, DKIM, site verification)",[474,542,543],{},[15,544,545],{},"\"v=spf1 include:_spf.google.com ~all\"",[456,547,548,553,556],{},[474,549,550],{},[15,551,552],{},"NS",[474,554,555],{},"Delegates a zone to authoritative name servers",[474,557,558],{},[15,559,560],{},"ns1.p16.dynect.net.",[456,562,563,568,571],{},[474,564,565],{},[15,566,567],{},"SOA",[474,569,570],{},"Start of Authority: metadata about the zone",[474,572,573],{},"Serial, refresh, retry times",[456,575,576,581,584],{},[474,577,578],{},[15,579,580],{},"PTR",[474,582,583],{},"Reverse lookup: IP address to hostname",[474,585,586],{},[15,587,216],{},[456,589,590,595,598],{},[474,591,592],{},[15,593,594],{},"SRV",[474,596,597],{},"Service location: host and port for a service",[474,599,600],{},[15,601,602],{},"0 5 443 server.example.com.",[456,604,605,610,613],{},[474,606,607],{},[15,608,609],{},"CAA",[474,611,612],{},"Which Certificate Authorities can issue TLS certs",[474,614,615],{},[15,616,617],{},"\"0 issue letsencrypt.org\"",[11,619,620],{},"Let's walk through the most important ones.",[232,622,624],{"id":623},"a-and-aaaa-records","A and AAAA Records",[11,626,627,628,630,631,633],{},"These are the most fundamental record types. An ",[15,629,478],{}," record maps a domain to an IPv4 address. An ",[15,632,493],{}," record maps to an IPv6 address.",[127,635,638],{"className":636,"code":637,"language":132},[130],"; Format: name  TTL  class  type  value\ngithub.com.     60   IN     A     140.82.121.3\ngithub.com.     60   IN     AAAA  2606:50c0:8000::153\n",[15,639,637],{"__ignoreMap":135},[11,641,642],{},"A single domain can have multiple A records, each pointing to a different IP address. This is a simple form of load balancing: resolvers rotate through them, distributing traffic across multiple servers.",[127,644,647],{"className":645,"code":646,"language":132},[130],"; Multiple A records for round-robin load balancing\napp.example.com.  60  IN  A  10.0.0.1\napp.example.com.  60  IN  A  10.0.0.2\napp.example.com.  60  IN  A  10.0.0.3\n",[15,648,646],{"__ignoreMap":135},[232,650,652],{"id":651},"cname-records","CNAME Records",[11,654,655],{},"A CNAME (Canonical Name) record creates an alias from one domain name to another. Instead of pointing to an IP address, it points to a different domain name.",[127,657,660],{"className":658,"code":659,"language":132},[130],"www.github.com.    3600  IN  CNAME  github.com.\nblog.example.com.  3600  IN  CNAME  mysite.wordpress.com.\n",[15,661,659],{"__ignoreMap":135},[11,663,664,665,667,668,670,671,673],{},"When a resolver encounters a CNAME, it follows the chain: \"I was looking for ",[15,666,291],{},", but that's a CNAME pointing to ",[15,669,17],{},". Now let me look up ",[15,672,17],{},".\"",[11,675,676],{},[20,677,678],{},"Important CNAME limitations:",[76,680,681,688,691],{},[79,682,683,684,687],{},"You cannot put a CNAME on a bare/apex domain (",[15,685,686],{},"example.com",") if that domain has any other records. An apex domain with both a CNAME and an MX record would be invalid.",[79,689,690],{},"CNAMEs can only point to other domain names, never to IP addresses directly.",[79,692,693],{},"Long CNAME chains (pointing to another CNAME, pointing to another) add extra lookup steps.",[56,695,696],{},[11,697,698],{},"Many DNS providers offer \"ALIAS\" or \"ANAME\" records as a solution to the apex domain problem. They behave like CNAMEs but can sit at the root. Under the hood, the provider resolves the target and returns its IP directly.",[232,700,702],{"id":701},"mx-records","MX Records",[11,704,705],{},"MX (Mail Exchanger) records tell email servers where to deliver mail for a domain. Each record has a priority value: lower number means higher priority. If the highest-priority server is unavailable, the next one is tried.",[127,707,710],{"className":708,"code":709,"language":132},[130],"; Priority  Mail server\ngithub.com.  3600  IN  MX  1   aspmx.l.google.com.\ngithub.com.  3600  IN  MX  5   alt1.aspmx.l.google.com.\ngithub.com.  3600  IN  MX  10  alt2.aspmx.l.google.com.\n",[15,711,709],{"__ignoreMap":135},[11,713,714,715,718,719,721],{},"When someone sends an email to ",[15,716,717],{},"user@github.com",", their mail server looks up the MX records for ",[15,720,17],{}," and delivers the message to the highest-priority server that responds.",[232,723,725],{"id":724},"txt-records","TXT Records",[11,727,728],{},"TXT records store arbitrary text. They were originally for human-readable notes, but today they are critical for email authentication and domain ownership verification.",[11,730,731],{},"Common uses:",[11,733,734,737],{},[20,735,736],{},"SPF (Sender Policy Framework):"," Declares which servers are authorised to send email for your domain. Receiving mail servers check this before accepting messages.",[11,739,740,743],{},[20,741,742],{},"DKIM (DomainKeys Identified Mail):"," Publishes a public key used to verify that email signatures match, proving the email was not forged or altered.",[11,745,746,749],{},[20,747,748],{},"DMARC:"," Tells receiving servers what to do with messages that fail SPF or DKIM checks (reject them, quarantine them, or just report them).",[11,751,752,755],{},[20,753,754],{},"Domain verification:"," Services like Google Search Console ask you to add a TXT record to prove domain ownership before granting access.",[127,757,760],{"className":758,"code":759,"language":132},[130],"; SPF record\nexample.com.  IN  TXT  \"v=spf1 include:_spf.google.com include:sendgrid.net ~all\"\n\n; DKIM public key (partial for readability)\ngoogle._domainkey.example.com.  IN  TXT  \"v=DKIM1; k=rsa; p=MIGfMA0GCSq...\"\n\n; DMARC policy\n_dmarc.example.com.  IN  TXT  \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"\n\n; Google site verification\nexample.com.  IN  TXT  \"google-site-verification=abc123xyz...\"\n",[15,761,759],{"__ignoreMap":135},[232,763,765],{"id":764},"ns-records","NS Records",[11,767,768],{},"NS (Name Server) records declare which servers are authoritative for a domain. These are configured at your domain registrar and are what the TLD servers use to point resolvers toward your DNS provider.",[127,770,773],{"className":771,"code":772,"language":132},[130],"github.com.  IN  NS  ns1.p16.dynect.net.\ngithub.com.  IN  NS  ns2.p16.dynect.net.\ngithub.com.  IN  NS  ns3.p16.dynect.net.\ngithub.com.  IN  NS  ns4.p16.dynect.net.\n",[15,774,772],{"__ignoreMap":135},[11,776,777],{},"Domains always have at least two NS records for redundancy. If one authoritative name server is down, the others continue serving queries.",[232,779,781],{"id":780},"ptr-records","PTR Records",[11,783,784,785,148],{},"PTR records are the reverse of A records. Instead of mapping a name to an IP, they map an IP address back to a hostname. They live in a special domain called ",[15,786,787],{},"in-addr.arpa",[127,789,792],{"className":790,"code":791,"language":132},[130],"; Forward lookup\ngithub.com.                   A    140.82.121.3\n\n; Reverse lookup (note the IP is reversed)\n3.121.82.140.in-addr.arpa.    PTR  github.com.\n",[15,793,791],{"__ignoreMap":135},[11,795,796],{},"PTR records are particularly important for email. Mail servers frequently check that the sending IP address has a matching PTR record pointing back to a legitimate hostname. Missing or mismatched PTR records are a common cause of email being flagged as spam.",[232,798,800],{"id":799},"soa-record","SOA Record",[11,802,803],{},"Every DNS zone has exactly one SOA (Start of Authority) record. It contains metadata that controls how the zone behaves.",[127,805,808],{"className":806,"code":807,"language":132},[130],"github.com.  IN  SOA  ns1.p16.dynect.net. admin.github.com. (\n    2024040101  ; Serial: incremented whenever the zone changes\n    3600        ; Refresh: how often secondary servers check for updates (seconds)\n    900         ; Retry: wait before retrying after a failed refresh\n    604800      ; Expire: how long secondaries keep data if primary is unreachable\n    300         ; Minimum TTL: default for negative caching (NXDOMAIN responses)\n)\n",[15,809,807],{"__ignoreMap":135},[28,811,813],{"id":812},"ttl-how-dns-caching-works","TTL: How DNS Caching Works",[11,815,816,817,820],{},"Every DNS record has a ",[20,818,819],{},"TTL (Time to Live)",", measured in seconds. This tells resolvers and clients how long they are allowed to cache the record before fetching a fresh copy.",[127,822,825],{"className":823,"code":824,"language":132},[130],"; TTL of 300 seconds (5 minutes)\ngithub.com.  300  IN  A  140.82.121.3\n             ^^^\n             This is the TTL\n",[15,826,824],{"__ignoreMap":135},[11,828,829],{},"When a resolver caches this record, it starts a countdown timer. After 300 seconds, it discards the cached answer and fetches a fresh one on the next query.",[11,831,832],{},[20,833,834],{},"Lower TTL (60 to 300 seconds):",[76,836,837,840,843],{},[79,838,839],{},"DNS changes propagate faster across the internet",[79,841,842],{},"Higher query load on your DNS servers (cache expires more often)",[79,844,845],{},"Useful before making infrastructure changes",[11,847,848],{},[20,849,850],{},"Higher TTL (3600 to 86400 seconds):",[76,852,853,856,859],{},[79,854,855],{},"Fewer queries to your DNS servers",[79,857,858],{},"Faster responses for end users (more cache hits)",[79,860,861],{},"But changes are slow to propagate: old values persist until every cache expires",[11,863,864],{},"When you change a DNS record, the internet does not instantly update. Old cached values continue serving the previous answer until their TTL expires. This is what people call \"DNS propagation time.\"",[56,866,867],{},[11,868,869],{},"Before making a major DNS change (like migrating to a new server), lower your TTL to 300 seconds at least a day in advance. Once your change is live and confirmed working, raise it back to a higher value.",[28,871,873],{"id":872},"recursive-vs-iterative-queries","Recursive vs. Iterative Queries",[11,875,876],{},"DNS supports two different querying modes that work at different levels of the system.",[11,878,879],{},[123,880],{"alt":881,"src":882},"Recursive query versus iterative query side by side","/post-images/dns-explained-how-domain-name-system-works/recursive-vs-iterative-dns.png",[232,884,886],{"id":885},"recursive-queries","Recursive Queries",[11,888,889],{},"In a recursive query, you ask for a complete final answer and the server does all the work for you. Your computer sends recursive queries to its configured resolver. The resolver takes full responsibility for finding the answer, however many steps that requires.",[232,891,893],{"id":892},"iterative-queries","Iterative Queries",[11,895,896],{},"In an iterative query, the server you ask does not go fetch the answer for you. Instead, it gives you a referral: \"I don't know, but try asking this other server.\" You do the next step yourself.",[11,898,899,900,902,903,905],{},"When your recursive resolver talks to root servers and TLD servers, it uses iterative queries. The root server does not resolve ",[15,901,17],{}," for the resolver. It just says \"try the ",[15,904,159],{}," TLD servers\" and the resolver makes that next request itself.",[127,907,910],{"className":908,"code":909,"language":132},[130],"Recursive (your computer to resolver):\n  Computer:  \"What is the IP for github.com? Find out completely.\"\n  Resolver:  \"140.82.121.3\" (does all internal work, returns final answer)\n\nIterative (resolver talking to root/TLD/authoritative):\n  Resolver:  \"What is the IP for github.com?\"\n  Root:      \"I don't know. Try ns.verisign-tld.com for .com\"\n\n  Resolver:  \"What is the IP for github.com?\"\n  TLD:       \"I don't know. Try ns1.p16.dynect.net for github.com\"\n\n  Resolver:  \"What is the IP for www.github.com?\"\n  Auth:      \"It's 140.82.121.3\"\n\n  Resolver returns 140.82.121.3 to your computer.\n",[15,911,909],{"__ignoreMap":135},[28,913,915],{"id":914},"how-your-computer-knows-which-resolver-to-use","How Your Computer Knows Which Resolver to Use",[11,917,918,919,922],{},"When you connect to a network, your device receives DNS resolver addresses via ",[20,920,921],{},"DHCP"," alongside your IP address, default gateway, and subnet mask. Your ISP's resolver is typically assigned this way.",[11,924,925],{},"You can override this in your OS network settings or on your router. Popular public resolvers:",[450,927,928,944],{},[453,929,930],{},[456,931,932,935,938,941],{},[459,933,934],{},"Provider",[459,936,937],{},"IPv4 Primary",[459,939,940],{},"IPv4 Secondary",[459,942,943],{},"Characteristic",[469,945,946,963,980,998],{},[456,947,948,951,955,960],{},[474,949,950],{},"Cloudflare",[474,952,953],{},[15,954,245],{},[474,956,957],{},[15,958,959],{},"1.0.0.1",[474,961,962],{},"Privacy-focused, consistently fast",[456,964,965,968,972,977],{},[474,966,967],{},"Google",[474,969,970],{},[15,971,241],{},[474,973,974],{},[15,975,976],{},"8.8.4.4",[474,978,979],{},"Reliable, widely trusted",[456,981,982,985,990,995],{},[474,983,984],{},"Quad9",[474,986,987],{},[15,988,989],{},"9.9.9.9",[474,991,992],{},[15,993,994],{},"149.112.112.112",[474,996,997],{},"Blocks known malicious domains",[456,999,1000,1003,1008,1013],{},[474,1001,1002],{},"OpenDNS",[474,1004,1005],{},[15,1006,1007],{},"208.67.222.222",[474,1009,1010],{},[15,1011,1012],{},"208.67.220.220",[474,1014,1015],{},"Customisable, parental controls",[11,1017,1018],{},"To check which resolver your system is currently using:",[127,1020,1024],{"className":1021,"code":1022,"language":1023,"meta":135,"style":135},"language-bash shiki shiki-themes github-dark","# Linux (most systems)\ncat /etc/resolv.conf\n# nameserver 1.1.1.1\n# nameserver 8.8.8.8\n\n# macOS\nscutil --dns | grep nameserver\n\n# Windows\nipconfig /all | findstr \"DNS Servers\"\n","bash",[15,1025,1026,1035,1046,1052,1058,1065,1071,1091,1096,1102],{"__ignoreMap":135},[1027,1028,1031],"span",{"class":1029,"line":1030},"line",1,[1027,1032,1034],{"class":1033},"sAwPA","# Linux (most systems)\n",[1027,1036,1038,1042],{"class":1029,"line":1037},2,[1027,1039,1041],{"class":1040},"svObZ","cat",[1027,1043,1045],{"class":1044},"sU2Wk"," /etc/resolv.conf\n",[1027,1047,1049],{"class":1029,"line":1048},3,[1027,1050,1051],{"class":1033},"# nameserver 1.1.1.1\n",[1027,1053,1055],{"class":1029,"line":1054},4,[1027,1056,1057],{"class":1033},"# nameserver 8.8.8.8\n",[1027,1059,1061],{"class":1029,"line":1060},5,[1027,1062,1064],{"emptyLinePlaceholder":1063},true,"\n",[1027,1066,1068],{"class":1029,"line":1067},6,[1027,1069,1070],{"class":1033},"# macOS\n",[1027,1072,1074,1077,1081,1085,1088],{"class":1029,"line":1073},7,[1027,1075,1076],{"class":1040},"scutil",[1027,1078,1080],{"class":1079},"sDLfK"," --dns",[1027,1082,1084],{"class":1083},"snl16"," |",[1027,1086,1087],{"class":1040}," grep",[1027,1089,1090],{"class":1044}," nameserver\n",[1027,1092,1094],{"class":1029,"line":1093},8,[1027,1095,1064],{"emptyLinePlaceholder":1063},[1027,1097,1099],{"class":1029,"line":1098},9,[1027,1100,1101],{"class":1033},"# Windows\n",[1027,1103,1105,1108,1111,1113,1116],{"class":1029,"line":1104},10,[1027,1106,1107],{"class":1040},"ipconfig",[1027,1109,1110],{"class":1044}," /all",[1027,1112,1084],{"class":1083},[1027,1114,1115],{"class":1040}," findstr",[1027,1117,1118],{"class":1044}," \"DNS Servers\"\n",[28,1120,1122],{"id":1121},"the-hosts-file-dns-before-dns","The hosts File: DNS Before DNS",[11,1124,1125,1126,1128,1129,1131],{},"The ",[15,1127,360],{}," file (or ",[15,1130,366],{}," on Windows) is a simple text file that maps hostnames to IP addresses. It is read before any DNS query is made, so entries in this file always override DNS.",[127,1133,1136],{"className":1134,"code":1135,"language":132},[130],"# /etc/hosts\n127.0.0.1     localhost\n::1           localhost ip6-localhost\n\n# Local development: custom domain pointing to your machine\n127.0.0.1     myapp.local\n127.0.0.1     api.myapp.local\n127.0.0.1     admin.myapp.local\n\n# Override a real domain for testing (dangerous: use carefully)\n192.168.1.50  staging.example.com\n",[15,1137,1135],{"__ignoreMap":135},[11,1139,1140,1141,1144],{},"The hosts file is useful for local development (no need for a local DNS server), testing staging environments, and blocking domains by pointing them to ",[15,1142,1143],{},"127.0.0.1"," (the machine itself, which has no web server on the expected port).",[28,1146,1148],{"id":1147},"dns-tools-every-developer-should-know","DNS Tools Every Developer Should Know",[232,1150,1151],{"id":1151},"dig",[11,1153,1154,1156],{},[15,1155,1151],{}," (Domain Information Groper) is the most powerful DNS debugging tool. It shows you exactly what DNS servers return, including raw record data and query timing.",[127,1158,1160],{"className":1021,"code":1159,"language":1023,"meta":135,"style":135},"# Basic A record lookup\ndig github.com\n\n# Query a specific record type\ndig github.com MX\ndig github.com TXT\ndig github.com NS\ndig github.com AAAA\n\n# Query a specific DNS server directly\ndig @1.1.1.1 github.com\n\n# See the full resolution chain (root, TLD, authoritative)\ndig +trace github.com\n\n# Short output: just the answer\ndig +short github.com\n\n# Reverse lookup (IP to hostname)\ndig -x 140.82.121.3\n",[15,1161,1162,1167,1174,1178,1183,1193,1202,1211,1220,1224,1229,1239,1244,1250,1260,1265,1271,1281,1286,1292],{"__ignoreMap":135},[1027,1163,1164],{"class":1029,"line":1030},[1027,1165,1166],{"class":1033},"# Basic A record lookup\n",[1027,1168,1169,1171],{"class":1029,"line":1037},[1027,1170,1151],{"class":1040},[1027,1172,1173],{"class":1044}," github.com\n",[1027,1175,1176],{"class":1029,"line":1048},[1027,1177,1064],{"emptyLinePlaceholder":1063},[1027,1179,1180],{"class":1029,"line":1054},[1027,1181,1182],{"class":1033},"# Query a specific record type\n",[1027,1184,1185,1187,1190],{"class":1029,"line":1060},[1027,1186,1151],{"class":1040},[1027,1188,1189],{"class":1044}," github.com",[1027,1191,1192],{"class":1044}," MX\n",[1027,1194,1195,1197,1199],{"class":1029,"line":1067},[1027,1196,1151],{"class":1040},[1027,1198,1189],{"class":1044},[1027,1200,1201],{"class":1044}," TXT\n",[1027,1203,1204,1206,1208],{"class":1029,"line":1073},[1027,1205,1151],{"class":1040},[1027,1207,1189],{"class":1044},[1027,1209,1210],{"class":1044}," NS\n",[1027,1212,1213,1215,1217],{"class":1029,"line":1093},[1027,1214,1151],{"class":1040},[1027,1216,1189],{"class":1044},[1027,1218,1219],{"class":1044}," AAAA\n",[1027,1221,1222],{"class":1029,"line":1098},[1027,1223,1064],{"emptyLinePlaceholder":1063},[1027,1225,1226],{"class":1029,"line":1104},[1027,1227,1228],{"class":1033},"# Query a specific DNS server directly\n",[1027,1230,1232,1234,1237],{"class":1029,"line":1231},11,[1027,1233,1151],{"class":1040},[1027,1235,1236],{"class":1044}," @1.1.1.1",[1027,1238,1173],{"class":1044},[1027,1240,1242],{"class":1029,"line":1241},12,[1027,1243,1064],{"emptyLinePlaceholder":1063},[1027,1245,1247],{"class":1029,"line":1246},13,[1027,1248,1249],{"class":1033},"# See the full resolution chain (root, TLD, authoritative)\n",[1027,1251,1253,1255,1258],{"class":1029,"line":1252},14,[1027,1254,1151],{"class":1040},[1027,1256,1257],{"class":1044}," +trace",[1027,1259,1173],{"class":1044},[1027,1261,1263],{"class":1029,"line":1262},15,[1027,1264,1064],{"emptyLinePlaceholder":1063},[1027,1266,1268],{"class":1029,"line":1267},16,[1027,1269,1270],{"class":1033},"# Short output: just the answer\n",[1027,1272,1274,1276,1279],{"class":1029,"line":1273},17,[1027,1275,1151],{"class":1040},[1027,1277,1278],{"class":1044}," +short",[1027,1280,1173],{"class":1044},[1027,1282,1284],{"class":1029,"line":1283},18,[1027,1285,1064],{"emptyLinePlaceholder":1063},[1027,1287,1289],{"class":1029,"line":1288},19,[1027,1290,1291],{"class":1033},"# Reverse lookup (IP to hostname)\n",[1027,1293,1295,1297,1300],{"class":1029,"line":1294},20,[1027,1296,1151],{"class":1040},[1027,1298,1299],{"class":1079}," -x",[1027,1301,1302],{"class":1079}," 140.82.121.3\n",[11,1304,1305,1306,1308],{},"A typical ",[15,1307,1151],{}," response:",[127,1310,1313],{"className":1311,"code":1312,"language":132},[130],"; \u003C\u003C>> DiG 9.18.0 \u003C\u003C>> github.com\n;; QUESTION SECTION:\n;github.com.                  IN  A\n\n;; ANSWER SECTION:\ngithub.com.        60  IN  A  140.82.121.3\n\n;; Query time: 12 msec\n;; SERVER: 1.1.1.1#53(1.1.1.1)\n;; WHEN: Sun Apr 27 10:30:00 UTC 2026\n;; MSG SIZE rcvd: 55\n",[15,1314,1312],{"__ignoreMap":135},[11,1316,1125,1317,1320],{},[15,1318,1319],{},"+trace"," flag is the most valuable for debugging. It walks through every step of the resolution chain from root to authoritative:",[127,1322,1324],{"className":1021,"code":1323,"language":1023,"meta":135,"style":135},"dig +trace www.example.com\n\n# Output shows (abbreviated):\n.               518400  IN  NS  a.root-servers.net.\n# (13 root server entries)\n\ncom.            172800  IN  NS  a.gtld-servers.net.\n# (TLD servers for .com)\n\nexample.com.    172800  IN  NS  a.iana-servers.net.\n# (Authoritative servers for example.com)\n\nwww.example.com.  86400  IN  A  93.184.216.34\n# (Final answer from the authoritative server)\n",[15,1325,1326,1335,1339,1344,1360,1365,1369,1384,1389,1393,1408,1413,1417,1433],{"__ignoreMap":135},[1027,1327,1328,1330,1332],{"class":1029,"line":1030},[1027,1329,1151],{"class":1040},[1027,1331,1257],{"class":1044},[1027,1333,1334],{"class":1044}," www.example.com\n",[1027,1336,1337],{"class":1029,"line":1037},[1027,1338,1064],{"emptyLinePlaceholder":1063},[1027,1340,1341],{"class":1029,"line":1048},[1027,1342,1343],{"class":1033},"# Output shows (abbreviated):\n",[1027,1345,1346,1348,1351,1354,1357],{"class":1029,"line":1054},[1027,1347,148],{"class":1079},[1027,1349,1350],{"class":1079},"               518400",[1027,1352,1353],{"class":1044},"  IN",[1027,1355,1356],{"class":1044},"  NS",[1027,1358,1359],{"class":1044},"  a.root-servers.net.\n",[1027,1361,1362],{"class":1029,"line":1060},[1027,1363,1364],{"class":1033},"# (13 root server entries)\n",[1027,1366,1367],{"class":1029,"line":1067},[1027,1368,1064],{"emptyLinePlaceholder":1063},[1027,1370,1371,1374,1377,1379,1381],{"class":1029,"line":1073},[1027,1372,1373],{"class":1040},"com.",[1027,1375,1376],{"class":1079},"            172800",[1027,1378,1353],{"class":1044},[1027,1380,1356],{"class":1044},[1027,1382,1383],{"class":1044},"  a.gtld-servers.net.\n",[1027,1385,1386],{"class":1029,"line":1093},[1027,1387,1388],{"class":1033},"# (TLD servers for .com)\n",[1027,1390,1391],{"class":1029,"line":1098},[1027,1392,1064],{"emptyLinePlaceholder":1063},[1027,1394,1395,1398,1401,1403,1405],{"class":1029,"line":1104},[1027,1396,1397],{"class":1040},"example.com.",[1027,1399,1400],{"class":1079},"    172800",[1027,1402,1353],{"class":1044},[1027,1404,1356],{"class":1044},[1027,1406,1407],{"class":1044},"  a.iana-servers.net.\n",[1027,1409,1410],{"class":1029,"line":1231},[1027,1411,1412],{"class":1033},"# (Authoritative servers for example.com)\n",[1027,1414,1415],{"class":1029,"line":1241},[1027,1416,1064],{"emptyLinePlaceholder":1063},[1027,1418,1419,1422,1425,1427,1430],{"class":1029,"line":1246},[1027,1420,1421],{"class":1040},"www.example.com.",[1027,1423,1424],{"class":1079},"  86400",[1027,1426,1353],{"class":1044},[1027,1428,1429],{"class":1044},"  A",[1027,1431,1432],{"class":1079},"  93.184.216.34\n",[1027,1434,1435],{"class":1029,"line":1252},[1027,1436,1437],{"class":1033},"# (Final answer from the authoritative server)\n",[232,1439,1440],{"id":1440},"nslookup",[11,1442,1443,1445,1446,1448],{},[15,1444,1440],{}," is older but available on all platforms, including Windows, where ",[15,1447,1151],{}," is not installed by default.",[127,1450,1452],{"className":1021,"code":1451,"language":1023,"meta":135,"style":135},"# Basic lookup\nnslookup github.com\n\n# Query a specific type\nnslookup -type=MX github.com\nnslookup -type=TXT github.com\n\n# Query a specific server\nnslookup github.com 8.8.8.8\n",[15,1453,1454,1459,1465,1469,1474,1483,1492,1496,1501],{"__ignoreMap":135},[1027,1455,1456],{"class":1029,"line":1030},[1027,1457,1458],{"class":1033},"# Basic lookup\n",[1027,1460,1461,1463],{"class":1029,"line":1037},[1027,1462,1440],{"class":1040},[1027,1464,1173],{"class":1044},[1027,1466,1467],{"class":1029,"line":1048},[1027,1468,1064],{"emptyLinePlaceholder":1063},[1027,1470,1471],{"class":1029,"line":1054},[1027,1472,1473],{"class":1033},"# Query a specific type\n",[1027,1475,1476,1478,1481],{"class":1029,"line":1060},[1027,1477,1440],{"class":1040},[1027,1479,1480],{"class":1079}," -type=MX",[1027,1482,1173],{"class":1044},[1027,1484,1485,1487,1490],{"class":1029,"line":1067},[1027,1486,1440],{"class":1040},[1027,1488,1489],{"class":1079}," -type=TXT",[1027,1491,1173],{"class":1044},[1027,1493,1494],{"class":1029,"line":1073},[1027,1495,1064],{"emptyLinePlaceholder":1063},[1027,1497,1498],{"class":1029,"line":1093},[1027,1499,1500],{"class":1033},"# Query a specific server\n",[1027,1502,1503,1505,1507],{"class":1029,"line":1098},[1027,1504,1440],{"class":1040},[1027,1506,1189],{"class":1044},[1027,1508,1509],{"class":1079}," 8.8.8.8\n",[232,1511,1512],{"id":1512},"host",[11,1514,1515,1517,1518,1520],{},[15,1516,1512],{}," is a simple, readable alternative to ",[15,1519,1151],{}," for quick lookups:",[127,1522,1524],{"className":1021,"code":1523,"language":1023,"meta":135,"style":135},"host github.com\n# github.com has address 140.82.121.3\n# github.com has IPv6 address 2606:50c0:8000::153\n# github.com mail is handled by 1 aspmx.l.google.com.\n\nhost -t TXT github.com\n",[15,1525,1526,1532,1537,1542,1547,1551],{"__ignoreMap":135},[1027,1527,1528,1530],{"class":1029,"line":1030},[1027,1529,1512],{"class":1040},[1027,1531,1173],{"class":1044},[1027,1533,1534],{"class":1029,"line":1037},[1027,1535,1536],{"class":1033},"# github.com has address 140.82.121.3\n",[1027,1538,1539],{"class":1029,"line":1048},[1027,1540,1541],{"class":1033},"# github.com has IPv6 address 2606:50c0:8000::153\n",[1027,1543,1544],{"class":1029,"line":1054},[1027,1545,1546],{"class":1033},"# github.com mail is handled by 1 aspmx.l.google.com.\n",[1027,1548,1549],{"class":1029,"line":1060},[1027,1550,1064],{"emptyLinePlaceholder":1063},[1027,1552,1553,1555,1558,1561],{"class":1029,"line":1067},[1027,1554,1512],{"class":1040},[1027,1556,1557],{"class":1079}," -t",[1027,1559,1560],{"class":1044}," TXT",[1027,1562,1173],{"class":1044},[232,1564,1566],{"id":1565},"flushing-your-dns-cache","Flushing Your DNS Cache",[11,1568,1569],{},"When you change a DNS record and need to see the new value immediately without waiting for TTL to expire, flush your local cache:",[127,1571,1573],{"className":1021,"code":1572,"language":1023,"meta":135,"style":135},"# Linux (systemd-resolved)\nsudo resolvectl flush-caches\n# or\nsudo systemd-resolve --flush-caches\n\n# macOS\nsudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder\n\n# Windows\nipconfig /flushdns\n",[15,1574,1575,1580,1591,1596,1606,1610,1614,1639,1643,1647],{"__ignoreMap":135},[1027,1576,1577],{"class":1029,"line":1030},[1027,1578,1579],{"class":1033},"# Linux (systemd-resolved)\n",[1027,1581,1582,1585,1588],{"class":1029,"line":1037},[1027,1583,1584],{"class":1040},"sudo",[1027,1586,1587],{"class":1044}," resolvectl",[1027,1589,1590],{"class":1044}," flush-caches\n",[1027,1592,1593],{"class":1029,"line":1048},[1027,1594,1595],{"class":1033},"# or\n",[1027,1597,1598,1600,1603],{"class":1029,"line":1054},[1027,1599,1584],{"class":1040},[1027,1601,1602],{"class":1044}," systemd-resolve",[1027,1604,1605],{"class":1079}," --flush-caches\n",[1027,1607,1608],{"class":1029,"line":1060},[1027,1609,1064],{"emptyLinePlaceholder":1063},[1027,1611,1612],{"class":1029,"line":1067},[1027,1613,1070],{"class":1033},[1027,1615,1616,1618,1621,1624,1628,1630,1633,1636],{"class":1029,"line":1073},[1027,1617,1584],{"class":1040},[1027,1619,1620],{"class":1044}," dscacheutil",[1027,1622,1623],{"class":1079}," -flushcache",[1027,1625,1627],{"class":1626},"s95oV"," && ",[1027,1629,1584],{"class":1040},[1027,1631,1632],{"class":1044}," killall",[1027,1634,1635],{"class":1079}," -HUP",[1027,1637,1638],{"class":1044}," mDNSResponder\n",[1027,1640,1641],{"class":1029,"line":1093},[1027,1642,1064],{"emptyLinePlaceholder":1063},[1027,1644,1645],{"class":1029,"line":1098},[1027,1646,1101],{"class":1033},[1027,1648,1649,1651],{"class":1029,"line":1104},[1027,1650,1107],{"class":1040},[1027,1652,1653],{"class":1044}," /flushdns\n",[11,1655,1656],{},"After flushing, the next DNS query for that domain will go out to the network rather than returning a cached response.",[28,1658,1660],{"id":1659},"dns-in-practice-real-world-scenarios","DNS in Practice: Real-World Scenarios",[232,1662,1664],{"id":1663},"local-development-with-custom-domains","Local Development with Custom Domains",[11,1666,1667],{},"The hosts file is the fastest way to set up a local domain for development:",[127,1669,1672],{"className":1670,"code":1671,"language":132},[130],"# /etc/hosts\n127.0.0.1   myapp.local\n127.0.0.1   api.myapp.local\n127.0.0.1   auth.myapp.local\n",[15,1673,1671],{"__ignoreMap":135},[11,1675,1676,1677,1680],{},"Now ",[15,1678,1679],{},"http://myapp.local"," resolves to your machine without any DNS server. Your browser, curl, and all other tools will use this mapping automatically.",[232,1682,1684],{"id":1683},"testing-dns-changes-before-they-propagate","Testing DNS Changes Before They Propagate",[11,1686,1687],{},"After making a DNS change, you can verify it was saved correctly by querying the authoritative server directly, before the change has propagated to public resolvers:",[127,1689,1691],{"className":1021,"code":1690,"language":1023,"meta":135,"style":135},"# Find the authoritative name server for your domain\ndig NS example.com +short\n# Returns: ns1.your-dns-provider.com.\n\n# Now query that server directly for the record you just changed\ndig @ns1.your-dns-provider.com example.com A\n",[15,1692,1693,1698,1711,1716,1720,1725],{"__ignoreMap":135},[1027,1694,1695],{"class":1029,"line":1030},[1027,1696,1697],{"class":1033},"# Find the authoritative name server for your domain\n",[1027,1699,1700,1702,1705,1708],{"class":1029,"line":1037},[1027,1701,1151],{"class":1040},[1027,1703,1704],{"class":1044}," NS",[1027,1706,1707],{"class":1044}," example.com",[1027,1709,1710],{"class":1044}," +short\n",[1027,1712,1713],{"class":1029,"line":1048},[1027,1714,1715],{"class":1033},"# Returns: ns1.your-dns-provider.com.\n",[1027,1717,1718],{"class":1029,"line":1054},[1027,1719,1064],{"emptyLinePlaceholder":1063},[1027,1721,1722],{"class":1029,"line":1060},[1027,1723,1724],{"class":1033},"# Now query that server directly for the record you just changed\n",[1027,1726,1727,1729,1732,1734],{"class":1029,"line":1067},[1027,1728,1151],{"class":1040},[1027,1730,1731],{"class":1044}," @ns1.your-dns-provider.com",[1027,1733,1707],{"class":1044},[1027,1735,1736],{"class":1044}," A\n",[11,1738,1739],{},"If this returns the new value, your change was saved. Public resolvers will see it after the old TTL expires.",[232,1741,1743],{"id":1742},"setting-up-dns-for-a-new-domain","Setting Up DNS for a New Domain",[11,1745,1746],{},"When you register a domain and want to use Cloudflare for DNS:",[1748,1749,1750,1753,1763,1766],"ol",{},[79,1751,1752],{},"Add the domain in Cloudflare's dashboard. Cloudflare scans your current DNS records.",[79,1754,1755,1756,1759,1760,45],{},"Cloudflare gives you two NS records (like ",[15,1757,1758],{},"ns1.cloudflare.com"," and ",[15,1761,1762],{},"ns2.cloudflare.com",[79,1764,1765],{},"Log in to your domain registrar and update the NS records to Cloudflare's values.",[79,1767,1768],{},"DNS propagation begins: resolver caches start expiring worldwide, gradually switching to Cloudflare as the authority.",[11,1770,1771],{},"During propagation (which takes a few hours to complete globally), some users see old DNS data and others see new. This is normal and unavoidable due to TTL-based caching.",[232,1773,1775],{"id":1774},"dns-load-balancing","DNS Load Balancing",[11,1777,1778],{},"DNS can distribute traffic across multiple servers without a dedicated hardware load balancer.",[11,1780,1781,1784],{},[20,1782,1783],{},"Round-robin DNS:"," Give one domain multiple A records. Resolvers rotate through them, spreading queries across servers.",[127,1786,1789],{"className":1787,"code":1788,"language":132},[130],"; Traffic distributed across three servers\napp.example.com.  60  IN  A  10.0.0.1\napp.example.com.  60  IN  A  10.0.0.2\napp.example.com.  60  IN  A  10.0.0.3\n",[15,1790,1788],{"__ignoreMap":135},[11,1792,1793,1796],{},[20,1794,1795],{},"Weighted routing:"," With providers like AWS Route 53 or Cloudflare Load Balancing, you can send a specific percentage of traffic to each server. For example: 90% to the primary server, 10% to a canary.",[11,1798,1799,1802],{},[20,1800,1801],{},"Geo-routing:"," Return different A records based on the user's geographic location. Users in Europe get your European server. Users in Asia get your Asia-Pacific server. This reduces latency without any application-level changes.",[11,1804,1805,1808],{},[20,1806,1807],{},"Failover:"," Configure health checks alongside DNS. When a server fails a health check, the DNS provider automatically stops returning its IP address. Traffic shifts to healthy servers within the TTL window.",[232,1810,1812],{"id":1811},"subdomain-delegation","Subdomain Delegation",[11,1814,1815],{},"You can delegate a subdomain to a completely different set of authoritative name servers. This is used by large organisations to give different teams independent control over their DNS zones.",[127,1817,1820],{"className":1818,"code":1819,"language":132},[130],"; Main company domain at the primary DNS provider\nexample.com.      NS  ns1.main-dns.com.\n\n; dev.example.com delegated to the dev team's DNS provider\ndev.example.com.  NS  ns1.dev-team-dns.com.\ndev.example.com.  NS  ns2.dev-team-dns.com.\n",[15,1821,1819],{"__ignoreMap":135},[11,1823,1824,1825,1828],{},"After this delegation, the dev team controls all records under ",[15,1826,1827],{},"dev.example.com"," completely independently. They can add, change, or delete records without touching the main domain's DNS.",[28,1830,1832],{"id":1831},"dns-security-what-can-go-wrong","DNS Security: What Can Go Wrong",[11,1834,1835],{},"DNS was designed in 1983, when the internet was a cooperative research network and security threats were not a primary concern. Several attack types exploit the trust model that DNS was built on.",[232,1837,1839],{"id":1838},"dns-cache-poisoning-spoofing","DNS Cache Poisoning (Spoofing)",[11,1841,1842],{},"An attacker floods a recursive resolver with forged DNS responses. If a forged response arrives before the legitimate one, the resolver caches the fake record. All users of that resolver then get the wrong IP address for the target domain, potentially being redirected to a malicious server without any visible warning.",[11,1844,1845],{},"The classic exploit sends thousands of forged responses while the resolver is still waiting for a legitimate reply, gambling on one of them matching the query's transaction ID before the real response arrives.",[232,1847,1849],{"id":1848},"dns-hijacking","DNS Hijacking",[11,1851,1852],{},"An attacker takes control of a router, resolver, or even the domain's registrar account and changes DNS records at the source. Unlike cache poisoning (which injects false data into caches), hijacking modifies the actual authoritative data. Victims are redirected to fake sites at the DNS level, making the attack very difficult for end users to detect.",[232,1854,1856],{"id":1855},"dns-amplification","DNS Amplification",[11,1858,1859],{},"Attackers exploit publicly open DNS resolvers to amplify DDoS attacks. They send small DNS queries (30 to 40 bytes) with the victim's IP address forged as the source. The resolver sends its large response (up to 3,000 bytes) to the victim. The query-to-response size ratio can be 50 to 100 times, dramatically amplifying the attack bandwidth.",[232,1861,1863],{"id":1862},"dns-tunneling-exfiltration","DNS Tunneling / Exfiltration",[11,1865,1866],{},"Because DNS traffic almost never gets blocked by firewalls, attackers use it as a covert data channel. Sensitive data is encoded into DNS query names, which are sent to an authoritative server the attacker controls. The attacker's server logs every incoming query name and decodes the exfiltrated data.",[127,1868,1871],{"className":1869,"code":1870,"language":132},[130],"; Data encoded as base64 in a subdomain label\ndGhpcyBpcyBzdG9sZW4gZGF0YQ.attacker-controlled.com.\n",[15,1872,1870],{"__ignoreMap":135},[11,1874,1875],{},"Detecting this requires monitoring DNS query volumes and looking for unusually long or high-entropy subdomains.",[28,1877,1879],{"id":1878},"dnssec-adding-cryptographic-trust-to-dns","DNSSEC: Adding Cryptographic Trust to DNS",[11,1881,1882],{},"DNSSEC (DNS Security Extensions) addresses the core vulnerability in plain DNS: you have no way to verify that a response actually came from the authoritative server and was not modified in transit.",[11,1884,1885],{},"DNSSEC adds digital signatures to DNS records. Resolvers that support DNSSEC can verify the full chain of signatures from the root zone down to the specific record they queried.",[127,1887,1890],{"className":1888,"code":1889,"language":132},[130],"Root zone signs the TLD zone's key\n        ↓\nTLD zone signs the domain's zone key (DS record)\n        ↓\nDomain's zone key signs individual records (RRSIG records)\n        ↓\nResolver validates the entire chain, top to bottom\n        ↓\nIf any signature is invalid or missing, the query fails\n",[15,1891,1889],{"__ignoreMap":135},[11,1893,1894],{},"The trust anchor for this entire chain is the root zone's key. ICANN publishes it, and it is hardcoded into resolver software. A response cannot be forged without breaking the cryptographic chain.",[127,1896,1898],{"className":1021,"code":1897,"language":1023,"meta":135,"style":135},"# Check if a domain has DNSSEC configured\ndig github.com DNSKEY\ndig github.com DS\n\n# Verify the DNSSEC chain with a validating resolver\ndig +dnssec github.com @1.1.1.1\n",[15,1899,1900,1905,1914,1923,1927,1932],{"__ignoreMap":135},[1027,1901,1902],{"class":1029,"line":1030},[1027,1903,1904],{"class":1033},"# Check if a domain has DNSSEC configured\n",[1027,1906,1907,1909,1911],{"class":1029,"line":1037},[1027,1908,1151],{"class":1040},[1027,1910,1189],{"class":1044},[1027,1912,1913],{"class":1044}," DNSKEY\n",[1027,1915,1916,1918,1920],{"class":1029,"line":1048},[1027,1917,1151],{"class":1040},[1027,1919,1189],{"class":1044},[1027,1921,1922],{"class":1044}," DS\n",[1027,1924,1925],{"class":1029,"line":1054},[1027,1926,1064],{"emptyLinePlaceholder":1063},[1027,1928,1929],{"class":1029,"line":1060},[1027,1930,1931],{"class":1033},"# Verify the DNSSEC chain with a validating resolver\n",[1027,1933,1934,1936,1939,1941],{"class":1029,"line":1067},[1027,1935,1151],{"class":1040},[1027,1937,1938],{"class":1044}," +dnssec",[1027,1940,1189],{"class":1044},[1027,1942,1943],{"class":1044}," @1.1.1.1\n",[11,1945,1946],{},"DNSSEC has one important limitation: it proves records were not tampered with in transit, but it does not hide what you are looking up. The question \"what is the IP for github.com?\" is still plaintext on the wire.",[28,1948,1950],{"id":1949},"dns-over-https-and-dns-over-tls","DNS over HTTPS and DNS over TLS",[11,1952,1953],{},"Standard DNS queries travel as plaintext over UDP port 53. Anyone between you and the resolver (your ISP, the coffee shop WiFi operator, or a compromised router) can see exactly which domains you are querying. This is a significant privacy issue.",[11,1955,1956,1959],{},[20,1957,1958],{},"DNS over TLS (DoT)"," encrypts DNS queries using TLS, running on port 853. It provides confidentiality between you and the resolver, preventing passive observers from seeing your query names.",[11,1961,1962,1965],{},[20,1963,1964],{},"DNS over HTTPS (DoH)"," wraps DNS queries inside regular HTTPS traffic on port 443. Because it looks identical to normal web traffic, network observers cannot selectively block or monitor DNS. Modern browsers (Chrome, Firefox, Edge) support DoH natively and can be configured to use it.",[11,1967,1968],{},"Both protect against passive eavesdropping on the network between you and the resolver. Neither hides your queries from the resolver itself: Cloudflare, Google, or whichever provider you use still sees every domain you look up.",[127,1970,1972],{"className":1021,"code":1971,"language":1023,"meta":135,"style":135},"# Query using DoH with curl\ncurl -H 'accept: application/dns-json' \\\n     'https://cloudflare-dns.com/dns-query?name=github.com&type=A'\n\n# Query using DoH with dig (newer versions)\ndig @https://cloudflare-dns.com/dns-query github.com\n",[15,1973,1974,1979,1993,1998,2002,2007],{"__ignoreMap":135},[1027,1975,1976],{"class":1029,"line":1030},[1027,1977,1978],{"class":1033},"# Query using DoH with curl\n",[1027,1980,1981,1984,1987,1990],{"class":1029,"line":1037},[1027,1982,1983],{"class":1040},"curl",[1027,1985,1986],{"class":1079}," -H",[1027,1988,1989],{"class":1044}," 'accept: application/dns-json'",[1027,1991,1992],{"class":1079}," \\\n",[1027,1994,1995],{"class":1029,"line":1048},[1027,1996,1997],{"class":1044},"     'https://cloudflare-dns.com/dns-query?name=github.com&type=A'\n",[1027,1999,2000],{"class":1029,"line":1054},[1027,2001,1064],{"emptyLinePlaceholder":1063},[1027,2003,2004],{"class":1029,"line":1060},[1027,2005,2006],{"class":1033},"# Query using DoH with dig (newer versions)\n",[1027,2008,2009,2011,2014],{"class":1029,"line":1067},[1027,2010,1151],{"class":1040},[1027,2012,2013],{"class":1044}," @https://cloudflare-dns.com/dns-query",[1027,2015,1173],{"class":1044},[28,2017,2019],{"id":2018},"common-dns-problems-and-how-to-debug-them","Common DNS Problems and How to Debug Them",[232,2021,2023],{"id":2022},"nxdomain-domain-does-not-exist","NXDOMAIN: Domain Does Not Exist",[127,2025,2027],{"className":1021,"code":2026,"language":1023,"meta":135,"style":135},"dig nonexistent.example.com\n# status: NXDOMAIN\n",[15,2028,2029,2036],{"__ignoreMap":135},[1027,2030,2031,2033],{"class":1029,"line":1030},[1027,2032,1151],{"class":1040},[1027,2034,2035],{"class":1044}," nonexistent.example.com\n",[1027,2037,2038],{"class":1029,"line":1037},[1027,2039,2040],{"class":1033},"# status: NXDOMAIN\n",[11,2042,2043],{},"The authoritative server says this domain definitely does not exist. Common causes: typo in the domain name, the DNS record has not been created yet, or the domain has expired.",[232,2045,2047],{"id":2046},"servfail-server-failure","SERVFAIL: Server Failure",[127,2049,2051],{"className":1021,"code":2050,"language":1023,"meta":135,"style":135},"dig example.com\n# status: SERVFAIL\n",[15,2052,2053,2060],{"__ignoreMap":135},[1027,2054,2055,2057],{"class":1029,"line":1030},[1027,2056,1151],{"class":1040},[1027,2058,2059],{"class":1044}," example.com\n",[1027,2061,2062],{"class":1029,"line":1037},[1027,2063,2064],{"class":1033},"# status: SERVFAIL\n",[11,2066,2067],{},"The resolver encountered an error while trying to resolve the query. Frequent causes: DNSSEC validation failure (the signature does not match), misconfigured authoritative servers, or a broken NS delegation (the TLD points to a name server that does not respond).",[232,2069,2071],{"id":2070},"stale-cache-seeing-old-dns-after-a-change","Stale Cache: Seeing Old DNS After a Change",[11,2073,2074],{},"If you made a DNS change but the new value is not showing up:",[127,2076,2078],{"className":1021,"code":2077,"language":1023,"meta":135,"style":135},"# Check what different resolvers currently have cached\ndig @8.8.8.8 example.com    # Google's resolver\ndig @1.1.1.1 example.com    # Cloudflare's resolver\ndig @9.9.9.9 example.com    # Quad9\n\n# Check what the authoritative server says directly (bypasses all caches)\ndig NS example.com +short\n# Returns the authoritative NS, e.g.: ns1.your-provider.com.\ndig @ns1.your-provider.com example.com A\n",[15,2079,2080,2085,2097,2108,2120,2124,2129,2139,2144],{"__ignoreMap":135},[1027,2081,2082],{"class":1029,"line":1030},[1027,2083,2084],{"class":1033},"# Check what different resolvers currently have cached\n",[1027,2086,2087,2089,2092,2094],{"class":1029,"line":1037},[1027,2088,1151],{"class":1040},[1027,2090,2091],{"class":1044}," @8.8.8.8",[1027,2093,1707],{"class":1044},[1027,2095,2096],{"class":1033},"    # Google's resolver\n",[1027,2098,2099,2101,2103,2105],{"class":1029,"line":1048},[1027,2100,1151],{"class":1040},[1027,2102,1236],{"class":1044},[1027,2104,1707],{"class":1044},[1027,2106,2107],{"class":1033},"    # Cloudflare's resolver\n",[1027,2109,2110,2112,2115,2117],{"class":1029,"line":1054},[1027,2111,1151],{"class":1040},[1027,2113,2114],{"class":1044}," @9.9.9.9",[1027,2116,1707],{"class":1044},[1027,2118,2119],{"class":1033},"    # Quad9\n",[1027,2121,2122],{"class":1029,"line":1060},[1027,2123,1064],{"emptyLinePlaceholder":1063},[1027,2125,2126],{"class":1029,"line":1067},[1027,2127,2128],{"class":1033},"# Check what the authoritative server says directly (bypasses all caches)\n",[1027,2130,2131,2133,2135,2137],{"class":1029,"line":1073},[1027,2132,1151],{"class":1040},[1027,2134,1704],{"class":1044},[1027,2136,1707],{"class":1044},[1027,2138,1710],{"class":1044},[1027,2140,2141],{"class":1029,"line":1093},[1027,2142,2143],{"class":1033},"# Returns the authoritative NS, e.g.: ns1.your-provider.com.\n",[1027,2145,2146,2148,2151,2153],{"class":1029,"line":1098},[1027,2147,1151],{"class":1040},[1027,2149,2150],{"class":1044}," @ns1.your-provider.com",[1027,2152,1707],{"class":1044},[1027,2154,1736],{"class":1044},[11,2156,2157],{},"If the authoritative server returns the new value but public resolvers still return the old one, you are simply waiting for the old TTL to expire across the globe. You cannot speed this up for external resolvers, but you can flush your own local cache.",[232,2159,2161],{"id":2160},"slow-dns-resolution","Slow DNS Resolution",[11,2163,2164],{},"Run a trace with timing to find the slow step:",[127,2166,2168],{"className":1021,"code":2167,"language":1023,"meta":135,"style":135},"dig +trace +stats example.com\n",[15,2169,2170],{"__ignoreMap":135},[1027,2171,2172,2174,2176,2179],{"class":1029,"line":1030},[1027,2173,1151],{"class":1040},[1027,2175,1257],{"class":1044},[1027,2177,2178],{"class":1044}," +stats",[1027,2180,2059],{"class":1044},[11,2182,2183,2184,2187],{},"Look at the ",[15,2185,2186],{},"Query time"," line after each step. If the authoritative query is slow, the problem is with your DNS provider's infrastructure. If all steps are slow, try using a geographically closer resolver.",[232,2189,2191],{"id":2190},"email-delivery-problems","Email Delivery Problems",[127,2193,2195],{"className":1021,"code":2194,"language":1023,"meta":135,"style":135},"# Check that MX records exist\ndig example.com MX\n\n# Verify SPF record is present\ndig example.com TXT | grep spf\n\n# Check PTR record for your mail server's IP\ndig -x YOUR_MAIL_SERVER_IP\n",[15,2196,2197,2202,2210,2214,2219,2234,2238,2243],{"__ignoreMap":135},[1027,2198,2199],{"class":1029,"line":1030},[1027,2200,2201],{"class":1033},"# Check that MX records exist\n",[1027,2203,2204,2206,2208],{"class":1029,"line":1037},[1027,2205,1151],{"class":1040},[1027,2207,1707],{"class":1044},[1027,2209,1192],{"class":1044},[1027,2211,2212],{"class":1029,"line":1048},[1027,2213,1064],{"emptyLinePlaceholder":1063},[1027,2215,2216],{"class":1029,"line":1054},[1027,2217,2218],{"class":1033},"# Verify SPF record is present\n",[1027,2220,2221,2223,2225,2227,2229,2231],{"class":1029,"line":1060},[1027,2222,1151],{"class":1040},[1027,2224,1707],{"class":1044},[1027,2226,1560],{"class":1044},[1027,2228,1084],{"class":1083},[1027,2230,1087],{"class":1040},[1027,2232,2233],{"class":1044}," spf\n",[1027,2235,2236],{"class":1029,"line":1067},[1027,2237,1064],{"emptyLinePlaceholder":1063},[1027,2239,2240],{"class":1029,"line":1073},[1027,2241,2242],{"class":1033},"# Check PTR record for your mail server's IP\n",[1027,2244,2245,2247,2249],{"class":1029,"line":1093},[1027,2246,1151],{"class":1040},[1027,2248,1299],{"class":1079},[1027,2250,2251],{"class":1044}," YOUR_MAIL_SERVER_IP\n",[11,2253,2254],{},"Missing PTR records are one of the most common causes of email being flagged as spam or rejected outright.",[28,2256,2258],{"id":2257},"a-quick-reference-dns-ports-and-protocols","A Quick Reference: DNS Ports and Protocols",[450,2260,2261,2274],{},[453,2262,2263],{},[456,2264,2265,2268,2271],{},[459,2266,2267],{},"Protocol",[459,2269,2270],{},"Port",[459,2272,2273],{},"Notes",[469,2275,2276,2287,2297,2307],{},[456,2277,2278,2281,2284],{},[474,2279,2280],{},"DNS (UDP)",[474,2282,2283],{},"53",[474,2285,2286],{},"Standard queries (fast, no connection overhead)",[456,2288,2289,2292,2294],{},[474,2290,2291],{},"DNS (TCP)",[474,2293,2283],{},[474,2295,2296],{},"Large responses over 512 bytes, zone transfers",[456,2298,2299,2301,2304],{},[474,2300,1958],{},[474,2302,2303],{},"853",[474,2305,2306],{},"Encrypted DNS",[456,2308,2309,2311,2314],{},[474,2310,1964],{},[474,2312,2313],{},"443",[474,2315,2316],{},"Encrypted DNS via HTTPS (looks like web traffic)",[11,2318,2319],{},"DNS uses UDP by default for speed (no handshake, no connection state). TCP is used when a response is too large for a single UDP packet, and for zone transfers (copying an entire DNS zone from a primary to a secondary name server).",[28,2321,2323],{"id":2322},"summary","Summary",[11,2325,2326],{},"DNS is one of the most fundamental pieces of infrastructure on the internet and almost completely invisible when it is working correctly.",[11,2328,2329],{},"Here is what you now know:",[76,2331,2332,2335,2338,2361,2364,2370,2373],{},[79,2333,2334],{},"DNS translates domain names to IP addresses through a global, distributed, hierarchical system.",[79,2336,2337],{},"A full DNS lookup flows through four types of servers: recursive resolver, root name servers, TLD name servers, and authoritative name servers.",[79,2339,2340,2341,1759,2343,2345,2346,2348,2349,2351,2352,2354,2355,2357,2358,2360],{},"DNS has many record types: ",[15,2342,478],{},[15,2344,493],{}," for IP addresses, ",[15,2347,508],{}," for aliases, ",[15,2350,522],{}," for email routing, ",[15,2353,537],{}," for email authentication and verification, ",[15,2356,552],{}," for delegation, ",[15,2359,580],{}," for reverse lookups, and more.",[79,2362,2363],{},"TTL controls how long records are cached. Lower TTL means faster propagation but more load on your DNS servers.",[79,2365,2366,2369],{},[15,2367,2368],{},"dig +trace"," is your best debugging tool. It shows the full resolution chain from root to authoritative server, with query times at each step.",[79,2371,2372],{},"DNS was not designed with security in mind. DNSSEC adds cryptographic integrity. DoH and DoT add privacy against eavesdropping.",[79,2374,2375],{},"The hosts file is simple, powerful, and useful for local development. It always takes precedence over DNS.",[2377,2378,2379],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}",{"title":135,"searchDepth":1037,"depth":1037,"links":2381},[2382,2383,2384,2385,2391,2396,2405,2406,2410,2411,2412,2418,2425,2431,2432,2433,2440,2441],{"id":30,"depth":1037,"text":31},{"id":63,"depth":1037,"text":64},{"id":108,"depth":1037,"text":109},{"id":220,"depth":1037,"text":221,"children":2386},[2387,2388,2389,2390],{"id":234,"depth":1048,"text":235},{"id":251,"depth":1048,"text":252},{"id":261,"depth":1048,"text":262},{"id":274,"depth":1048,"text":275},{"id":284,"depth":1037,"text":285,"children":2392},[2393,2394,2395],{"id":313,"depth":1048,"text":314},{"id":378,"depth":1048,"text":379},{"id":388,"depth":1048,"text":389},{"id":444,"depth":1037,"text":445,"children":2397},[2398,2399,2400,2401,2402,2403,2404],{"id":623,"depth":1048,"text":624},{"id":651,"depth":1048,"text":652},{"id":701,"depth":1048,"text":702},{"id":724,"depth":1048,"text":725},{"id":764,"depth":1048,"text":765},{"id":780,"depth":1048,"text":781},{"id":799,"depth":1048,"text":800},{"id":812,"depth":1037,"text":813},{"id":872,"depth":1037,"text":873,"children":2407},[2408,2409],{"id":885,"depth":1048,"text":886},{"id":892,"depth":1048,"text":893},{"id":914,"depth":1037,"text":915},{"id":1121,"depth":1037,"text":1122},{"id":1147,"depth":1037,"text":1148,"children":2413},[2414,2415,2416,2417],{"id":1151,"depth":1048,"text":1151},{"id":1440,"depth":1048,"text":1440},{"id":1512,"depth":1048,"text":1512},{"id":1565,"depth":1048,"text":1566},{"id":1659,"depth":1037,"text":1660,"children":2419},[2420,2421,2422,2423,2424],{"id":1663,"depth":1048,"text":1664},{"id":1683,"depth":1048,"text":1684},{"id":1742,"depth":1048,"text":1743},{"id":1774,"depth":1048,"text":1775},{"id":1811,"depth":1048,"text":1812},{"id":1831,"depth":1037,"text":1832,"children":2426},[2427,2428,2429,2430],{"id":1838,"depth":1048,"text":1839},{"id":1848,"depth":1048,"text":1849},{"id":1855,"depth":1048,"text":1856},{"id":1862,"depth":1048,"text":1863},{"id":1878,"depth":1037,"text":1879},{"id":1949,"depth":1037,"text":1950},{"id":2018,"depth":1037,"text":2019,"children":2434},[2435,2436,2437,2438,2439],{"id":2022,"depth":1048,"text":2023},{"id":2046,"depth":1048,"text":2047},{"id":2070,"depth":1048,"text":2071},{"id":2160,"depth":1048,"text":2161},{"id":2190,"depth":1048,"text":2191},{"id":2257,"depth":1037,"text":2258},{"id":2322,"depth":1037,"text":2323},"2026-04-27","Every website visit starts with a DNS lookup you never see. This guide breaks down exactly how DNS works, from root servers to your browser, with diagrams and real examples for beginners and experienced developers alike.",false,"md",null,"dns-explained-how-domain-name-system-works.png",{},"/backend/dns-explained-how-domain-name-system-works",{"title":5,"description":2443},"Backend/3.dns-explained-how-domain-name-system-works",[22,2453,2454,2455,2456,2457],"Networking","Web Development","Backend","Infrastructure","Domain Names","4VFkEeH3deLD-hhWTmh4VmeJio3W5o4tTYEXEMia_W4",[2460,4250,11449,12806],{"id":4,"title":5,"author":6,"body":2461,"date":2442,"description":2443,"draft":2444,"extension":2445,"guide":2446,"image":2447,"meta":4247,"navigation":1063,"path":2449,"seo":4248,"stem":2451,"tags":4249,"__hash__":2458},{"type":8,"value":2462,"toc":4185},[2463,2469,2471,2473,2481,2485,2487,2491,2493,2497,2499,2517,2519,2521,2523,2527,2531,2536,2538,2582,2588,2590,2592,2596,2598,2604,2606,2608,2610,2612,2614,2620,2622,2626,2628,2632,2636,2641,2643,2645,2647,2651,2653,2659,2667,2671,2681,2683,2688,2690,2692,2694,2696,2698,2708,2722,2728,2730,2732,2734,2866,2868,2870,2876,2881,2883,2888,2890,2892,2897,2905,2909,2919,2923,2925,2927,2932,2938,2940,2942,2944,2948,2952,2956,2960,2965,2967,2969,2974,2976,2978,2982,2987,2989,2991,2993,2998,3000,3004,3009,3011,3015,3023,3027,3035,3037,3041,3043,3045,3049,3051,3053,3055,3057,3063,3068,3070,3074,3076,3148,3150,3212,3214,3220,3225,3229,3231,3233,3237,3355,3359,3364,3368,3464,3466,3472,3526,3528,3534,3570,3572,3574,3642,3644,3646,3648,3650,3655,3659,3661,3663,3703,3705,3707,3709,3723,3725,3727,3729,3733,3738,3742,3746,3750,3752,3754,3759,3763,3765,3767,3769,3771,3773,3775,3777,3779,3781,3783,3785,3790,3792,3794,3796,3798,3803,3805,3847,3849,3851,3853,3857,3861,3863,3901,3903,3905,3919,3921,3923,3937,3939,3941,3943,4013,4015,4017,4019,4033,4037,4039,4093,4095,4097,4143,4145,4147,4149,4151,4183],[11,2464,13,2465,18,2467,23],{},[15,2466,17],{},[20,2468,22],{},[11,2470,26],{},[28,2472,31],{"id":30},[11,2474,2475,37,2477,41,2479,45],{},[20,2476,36],{},[15,2478,40],{},[15,2480,44],{},[11,2482,48,2483,51],{},[15,2484,44],{},[11,2486,54],{},[56,2488,2489],{},[11,2490,60],{},[28,2492,64],{"id":63},[11,2494,67,2495,71],{},[15,2496,70],{},[11,2498,74],{},[76,2500,2501,2505,2509,2513],{},[79,2502,2503,84],{},[20,2504,83],{},[79,2506,2507,90],{},[20,2508,89],{},[79,2510,2511,96],{},[20,2512,95],{},[79,2514,2515,102],{},[20,2516,101],{},[11,2518,105],{},[28,2520,109],{"id":108},[11,2522,112],{},[11,2524,115,2525,119],{},[15,2526,118],{},[11,2528,2529],{},[123,2530],{"alt":109,"src":125},[127,2532,2534],{"className":2533,"code":131,"language":132},[130],[15,2535,131],{"__ignoreMap":135},[11,2537,138],{},[76,2539,2540,2546,2562,2570],{},[79,2541,2542,150],{},[20,2543,145,2544,149],{},[15,2545,148],{},[79,2547,2548,156,2550,160,2552,160,2554,167,2556,171,2558,175,2560,178],{},[20,2549,155],{},[15,2551,159],{},[15,2553,163],{},[15,2555,166],{},[15,2557,170],{},[15,2559,174],{},[15,2561,159],{},[79,2563,2564,156,2566,187,2568,190],{},[20,2565,183],{},[15,2567,186],{},[15,2569,17],{},[79,2571,2572,156,2574,160,2576,160,2578,160,2580,208],{},[20,2573,195],{},[15,2575,198],{},[15,2577,201],{},[15,2579,204],{},[15,2581,207],{},[56,2583,2584],{},[11,2585,213,2586,217],{},[15,2587,216],{},[28,2589,221],{"id":220},[11,2591,224],{},[11,2593,2594],{},[123,2595],{"alt":229,"src":230},[232,2597,235],{"id":234},[11,2599,238,2600,242,2602,148],{},[15,2601,241],{},[15,2603,245],{},[11,2605,248],{},[232,2607,252],{"id":251},[11,2609,255],{},[11,2611,258],{},[232,2613,262],{"id":261},[11,2615,265,2616,268,2618,271],{},[15,2617,159],{},[15,2619,17],{},[232,2621,275],{"id":274},[11,2623,278,2624,281],{},[15,2625,17],{},[28,2627,285],{"id":284},[11,2629,288,2630,292],{},[15,2631,291],{},[11,2633,2634],{},[123,2635],{"alt":297,"src":298},[127,2637,2639],{"className":2638,"code":302,"language":132},[130],[15,2640,302],{"__ignoreMap":135},[11,2642,307],{},[11,2644,310],{},[232,2646,314],{"id":313},[11,2648,2649],{},[123,2650],{"alt":319,"src":320},[11,2652,323],{},[11,2654,2655,329,2657,148],{},[20,2656,328],{},[15,2658,332],{},[11,2660,2661,338,2663,342,2665,346],{},[20,2662,337],{},[15,2664,341],{},[15,2666,345],{},[11,2668,2669,352],{},[20,2670,351],{},[76,2672,2673,2677],{},[79,2674,357,2675],{},[15,2676,360],{},[79,2678,363,2679],{},[15,2680,366],{},[11,2682,369],{},[127,2684,2686],{"className":2685,"code":373,"language":132},[130],[15,2687,373],{"__ignoreMap":135},[232,2689,379],{"id":378},[11,2691,382],{},[11,2693,385],{},[232,2695,389],{"id":388},[11,2697,392],{},[11,2699,2700,398,2702,401,2704,404,2706,407],{},[20,2701,397],{},[15,2703,291],{},[15,2705,159],{},[15,2707,159],{},[11,2709,2710,413,2712,416,2714,419,2716,422,2718,160,2720,429],{},[20,2711,412],{},[15,2713,159],{},[15,2715,17],{},[15,2717,17],{},[15,2719,425],{},[15,2721,428],{},[11,2723,2724,435,2726,438],{},[20,2725,434],{},[15,2727,291],{},[11,2729,441],{},[28,2731,445],{"id":444},[11,2733,448],{},[450,2735,2736,2746],{},[453,2737,2738],{},[456,2739,2740,2742,2744],{},[459,2741,461],{},[459,2743,464],{},[459,2745,467],{},[469,2747,2748,2760,2772,2784,2796,2808,2820,2830,2842,2854],{},[456,2749,2750,2754,2756],{},[474,2751,2752],{},[15,2753,478],{},[474,2755,481],{},[474,2757,2758],{},[15,2759,486],{},[456,2761,2762,2766,2768],{},[474,2763,2764],{},[15,2765,493],{},[474,2767,496],{},[474,2769,2770],{},[15,2771,501],{},[456,2773,2774,2778,2780],{},[474,2775,2776],{},[15,2777,508],{},[474,2779,511],{},[474,2781,2782],{},[15,2783,216],{},[456,2785,2786,2790,2792],{},[474,2787,2788],{},[15,2789,522],{},[474,2791,525],{},[474,2793,2794],{},[15,2795,530],{},[456,2797,2798,2802,2804],{},[474,2799,2800],{},[15,2801,537],{},[474,2803,540],{},[474,2805,2806],{},[15,2807,545],{},[456,2809,2810,2814,2816],{},[474,2811,2812],{},[15,2813,552],{},[474,2815,555],{},[474,2817,2818],{},[15,2819,560],{},[456,2821,2822,2826,2828],{},[474,2823,2824],{},[15,2825,567],{},[474,2827,570],{},[474,2829,573],{},[456,2831,2832,2836,2838],{},[474,2833,2834],{},[15,2835,580],{},[474,2837,583],{},[474,2839,2840],{},[15,2841,216],{},[456,2843,2844,2848,2850],{},[474,2845,2846],{},[15,2847,594],{},[474,2849,597],{},[474,2851,2852],{},[15,2853,602],{},[456,2855,2856,2860,2862],{},[474,2857,2858],{},[15,2859,609],{},[474,2861,612],{},[474,2863,2864],{},[15,2865,617],{},[11,2867,620],{},[232,2869,624],{"id":623},[11,2871,627,2872,630,2874,633],{},[15,2873,478],{},[15,2875,493],{},[127,2877,2879],{"className":2878,"code":637,"language":132},[130],[15,2880,637],{"__ignoreMap":135},[11,2882,642],{},[127,2884,2886],{"className":2885,"code":646,"language":132},[130],[15,2887,646],{"__ignoreMap":135},[232,2889,652],{"id":651},[11,2891,655],{},[127,2893,2895],{"className":2894,"code":659,"language":132},[130],[15,2896,659],{"__ignoreMap":135},[11,2898,664,2899,667,2901,670,2903,673],{},[15,2900,291],{},[15,2902,17],{},[15,2904,17],{},[11,2906,2907],{},[20,2908,678],{},[76,2910,2911,2915,2917],{},[79,2912,683,2913,687],{},[15,2914,686],{},[79,2916,690],{},[79,2918,693],{},[56,2920,2921],{},[11,2922,698],{},[232,2924,702],{"id":701},[11,2926,705],{},[127,2928,2930],{"className":2929,"code":709,"language":132},[130],[15,2931,709],{"__ignoreMap":135},[11,2933,714,2934,718,2936,721],{},[15,2935,717],{},[15,2937,17],{},[232,2939,725],{"id":724},[11,2941,728],{},[11,2943,731],{},[11,2945,2946,737],{},[20,2947,736],{},[11,2949,2950,743],{},[20,2951,742],{},[11,2953,2954,749],{},[20,2955,748],{},[11,2957,2958,755],{},[20,2959,754],{},[127,2961,2963],{"className":2962,"code":759,"language":132},[130],[15,2964,759],{"__ignoreMap":135},[232,2966,765],{"id":764},[11,2968,768],{},[127,2970,2972],{"className":2971,"code":772,"language":132},[130],[15,2973,772],{"__ignoreMap":135},[11,2975,777],{},[232,2977,781],{"id":780},[11,2979,784,2980,148],{},[15,2981,787],{},[127,2983,2985],{"className":2984,"code":791,"language":132},[130],[15,2986,791],{"__ignoreMap":135},[11,2988,796],{},[232,2990,800],{"id":799},[11,2992,803],{},[127,2994,2996],{"className":2995,"code":807,"language":132},[130],[15,2997,807],{"__ignoreMap":135},[28,2999,813],{"id":812},[11,3001,816,3002,820],{},[20,3003,819],{},[127,3005,3007],{"className":3006,"code":824,"language":132},[130],[15,3008,824],{"__ignoreMap":135},[11,3010,829],{},[11,3012,3013],{},[20,3014,834],{},[76,3016,3017,3019,3021],{},[79,3018,839],{},[79,3020,842],{},[79,3022,845],{},[11,3024,3025],{},[20,3026,850],{},[76,3028,3029,3031,3033],{},[79,3030,855],{},[79,3032,858],{},[79,3034,861],{},[11,3036,864],{},[56,3038,3039],{},[11,3040,869],{},[28,3042,873],{"id":872},[11,3044,876],{},[11,3046,3047],{},[123,3048],{"alt":881,"src":882},[232,3050,886],{"id":885},[11,3052,889],{},[232,3054,893],{"id":892},[11,3056,896],{},[11,3058,899,3059,902,3061,905],{},[15,3060,17],{},[15,3062,159],{},[127,3064,3066],{"className":3065,"code":909,"language":132},[130],[15,3067,909],{"__ignoreMap":135},[28,3069,915],{"id":914},[11,3071,918,3072,922],{},[20,3073,921],{},[11,3075,925],{},[450,3077,3078,3090],{},[453,3079,3080],{},[456,3081,3082,3084,3086,3088],{},[459,3083,934],{},[459,3085,937],{},[459,3087,940],{},[459,3089,943],{},[469,3091,3092,3106,3120,3134],{},[456,3093,3094,3096,3100,3104],{},[474,3095,950],{},[474,3097,3098],{},[15,3099,245],{},[474,3101,3102],{},[15,3103,959],{},[474,3105,962],{},[456,3107,3108,3110,3114,3118],{},[474,3109,967],{},[474,3111,3112],{},[15,3113,241],{},[474,3115,3116],{},[15,3117,976],{},[474,3119,979],{},[456,3121,3122,3124,3128,3132],{},[474,3123,984],{},[474,3125,3126],{},[15,3127,989],{},[474,3129,3130],{},[15,3131,994],{},[474,3133,997],{},[456,3135,3136,3138,3142,3146],{},[474,3137,1002],{},[474,3139,3140],{},[15,3141,1007],{},[474,3143,3144],{},[15,3145,1012],{},[474,3147,1015],{},[11,3149,1018],{},[127,3151,3152],{"className":1021,"code":1022,"language":1023,"meta":135,"style":135},[15,3153,3154,3158,3164,3168,3172,3176,3180,3192,3196,3200],{"__ignoreMap":135},[1027,3155,3156],{"class":1029,"line":1030},[1027,3157,1034],{"class":1033},[1027,3159,3160,3162],{"class":1029,"line":1037},[1027,3161,1041],{"class":1040},[1027,3163,1045],{"class":1044},[1027,3165,3166],{"class":1029,"line":1048},[1027,3167,1051],{"class":1033},[1027,3169,3170],{"class":1029,"line":1054},[1027,3171,1057],{"class":1033},[1027,3173,3174],{"class":1029,"line":1060},[1027,3175,1064],{"emptyLinePlaceholder":1063},[1027,3177,3178],{"class":1029,"line":1067},[1027,3179,1070],{"class":1033},[1027,3181,3182,3184,3186,3188,3190],{"class":1029,"line":1073},[1027,3183,1076],{"class":1040},[1027,3185,1080],{"class":1079},[1027,3187,1084],{"class":1083},[1027,3189,1087],{"class":1040},[1027,3191,1090],{"class":1044},[1027,3193,3194],{"class":1029,"line":1093},[1027,3195,1064],{"emptyLinePlaceholder":1063},[1027,3197,3198],{"class":1029,"line":1098},[1027,3199,1101],{"class":1033},[1027,3201,3202,3204,3206,3208,3210],{"class":1029,"line":1104},[1027,3203,1107],{"class":1040},[1027,3205,1110],{"class":1044},[1027,3207,1084],{"class":1083},[1027,3209,1115],{"class":1040},[1027,3211,1118],{"class":1044},[28,3213,1122],{"id":1121},[11,3215,1125,3216,1128,3218,1131],{},[15,3217,360],{},[15,3219,366],{},[127,3221,3223],{"className":3222,"code":1135,"language":132},[130],[15,3224,1135],{"__ignoreMap":135},[11,3226,1140,3227,1144],{},[15,3228,1143],{},[28,3230,1148],{"id":1147},[232,3232,1151],{"id":1151},[11,3234,3235,1156],{},[15,3236,1151],{},[127,3238,3239],{"className":1021,"code":1159,"language":1023,"meta":135,"style":135},[15,3240,3241,3245,3251,3255,3259,3267,3275,3283,3291,3295,3299,3307,3311,3315,3323,3327,3331,3339,3343,3347],{"__ignoreMap":135},[1027,3242,3243],{"class":1029,"line":1030},[1027,3244,1166],{"class":1033},[1027,3246,3247,3249],{"class":1029,"line":1037},[1027,3248,1151],{"class":1040},[1027,3250,1173],{"class":1044},[1027,3252,3253],{"class":1029,"line":1048},[1027,3254,1064],{"emptyLinePlaceholder":1063},[1027,3256,3257],{"class":1029,"line":1054},[1027,3258,1182],{"class":1033},[1027,3260,3261,3263,3265],{"class":1029,"line":1060},[1027,3262,1151],{"class":1040},[1027,3264,1189],{"class":1044},[1027,3266,1192],{"class":1044},[1027,3268,3269,3271,3273],{"class":1029,"line":1067},[1027,3270,1151],{"class":1040},[1027,3272,1189],{"class":1044},[1027,3274,1201],{"class":1044},[1027,3276,3277,3279,3281],{"class":1029,"line":1073},[1027,3278,1151],{"class":1040},[1027,3280,1189],{"class":1044},[1027,3282,1210],{"class":1044},[1027,3284,3285,3287,3289],{"class":1029,"line":1093},[1027,3286,1151],{"class":1040},[1027,3288,1189],{"class":1044},[1027,3290,1219],{"class":1044},[1027,3292,3293],{"class":1029,"line":1098},[1027,3294,1064],{"emptyLinePlaceholder":1063},[1027,3296,3297],{"class":1029,"line":1104},[1027,3298,1228],{"class":1033},[1027,3300,3301,3303,3305],{"class":1029,"line":1231},[1027,3302,1151],{"class":1040},[1027,3304,1236],{"class":1044},[1027,3306,1173],{"class":1044},[1027,3308,3309],{"class":1029,"line":1241},[1027,3310,1064],{"emptyLinePlaceholder":1063},[1027,3312,3313],{"class":1029,"line":1246},[1027,3314,1249],{"class":1033},[1027,3316,3317,3319,3321],{"class":1029,"line":1252},[1027,3318,1151],{"class":1040},[1027,3320,1257],{"class":1044},[1027,3322,1173],{"class":1044},[1027,3324,3325],{"class":1029,"line":1262},[1027,3326,1064],{"emptyLinePlaceholder":1063},[1027,3328,3329],{"class":1029,"line":1267},[1027,3330,1270],{"class":1033},[1027,3332,3333,3335,3337],{"class":1029,"line":1273},[1027,3334,1151],{"class":1040},[1027,3336,1278],{"class":1044},[1027,3338,1173],{"class":1044},[1027,3340,3341],{"class":1029,"line":1283},[1027,3342,1064],{"emptyLinePlaceholder":1063},[1027,3344,3345],{"class":1029,"line":1288},[1027,3346,1291],{"class":1033},[1027,3348,3349,3351,3353],{"class":1029,"line":1294},[1027,3350,1151],{"class":1040},[1027,3352,1299],{"class":1079},[1027,3354,1302],{"class":1079},[11,3356,1305,3357,1308],{},[15,3358,1151],{},[127,3360,3362],{"className":3361,"code":1312,"language":132},[130],[15,3363,1312],{"__ignoreMap":135},[11,3365,1125,3366,1320],{},[15,3367,1319],{},[127,3369,3370],{"className":1021,"code":1323,"language":1023,"meta":135,"style":135},[15,3371,3372,3380,3384,3388,3400,3404,3408,3420,3424,3428,3440,3444,3448,3460],{"__ignoreMap":135},[1027,3373,3374,3376,3378],{"class":1029,"line":1030},[1027,3375,1151],{"class":1040},[1027,3377,1257],{"class":1044},[1027,3379,1334],{"class":1044},[1027,3381,3382],{"class":1029,"line":1037},[1027,3383,1064],{"emptyLinePlaceholder":1063},[1027,3385,3386],{"class":1029,"line":1048},[1027,3387,1343],{"class":1033},[1027,3389,3390,3392,3394,3396,3398],{"class":1029,"line":1054},[1027,3391,148],{"class":1079},[1027,3393,1350],{"class":1079},[1027,3395,1353],{"class":1044},[1027,3397,1356],{"class":1044},[1027,3399,1359],{"class":1044},[1027,3401,3402],{"class":1029,"line":1060},[1027,3403,1364],{"class":1033},[1027,3405,3406],{"class":1029,"line":1067},[1027,3407,1064],{"emptyLinePlaceholder":1063},[1027,3409,3410,3412,3414,3416,3418],{"class":1029,"line":1073},[1027,3411,1373],{"class":1040},[1027,3413,1376],{"class":1079},[1027,3415,1353],{"class":1044},[1027,3417,1356],{"class":1044},[1027,3419,1383],{"class":1044},[1027,3421,3422],{"class":1029,"line":1093},[1027,3423,1388],{"class":1033},[1027,3425,3426],{"class":1029,"line":1098},[1027,3427,1064],{"emptyLinePlaceholder":1063},[1027,3429,3430,3432,3434,3436,3438],{"class":1029,"line":1104},[1027,3431,1397],{"class":1040},[1027,3433,1400],{"class":1079},[1027,3435,1353],{"class":1044},[1027,3437,1356],{"class":1044},[1027,3439,1407],{"class":1044},[1027,3441,3442],{"class":1029,"line":1231},[1027,3443,1412],{"class":1033},[1027,3445,3446],{"class":1029,"line":1241},[1027,3447,1064],{"emptyLinePlaceholder":1063},[1027,3449,3450,3452,3454,3456,3458],{"class":1029,"line":1246},[1027,3451,1421],{"class":1040},[1027,3453,1424],{"class":1079},[1027,3455,1353],{"class":1044},[1027,3457,1429],{"class":1044},[1027,3459,1432],{"class":1079},[1027,3461,3462],{"class":1029,"line":1252},[1027,3463,1437],{"class":1033},[232,3465,1440],{"id":1440},[11,3467,3468,1445,3470,1448],{},[15,3469,1440],{},[15,3471,1151],{},[127,3473,3474],{"className":1021,"code":1451,"language":1023,"meta":135,"style":135},[15,3475,3476,3480,3486,3490,3494,3502,3510,3514,3518],{"__ignoreMap":135},[1027,3477,3478],{"class":1029,"line":1030},[1027,3479,1458],{"class":1033},[1027,3481,3482,3484],{"class":1029,"line":1037},[1027,3483,1440],{"class":1040},[1027,3485,1173],{"class":1044},[1027,3487,3488],{"class":1029,"line":1048},[1027,3489,1064],{"emptyLinePlaceholder":1063},[1027,3491,3492],{"class":1029,"line":1054},[1027,3493,1473],{"class":1033},[1027,3495,3496,3498,3500],{"class":1029,"line":1060},[1027,3497,1440],{"class":1040},[1027,3499,1480],{"class":1079},[1027,3501,1173],{"class":1044},[1027,3503,3504,3506,3508],{"class":1029,"line":1067},[1027,3505,1440],{"class":1040},[1027,3507,1489],{"class":1079},[1027,3509,1173],{"class":1044},[1027,3511,3512],{"class":1029,"line":1073},[1027,3513,1064],{"emptyLinePlaceholder":1063},[1027,3515,3516],{"class":1029,"line":1093},[1027,3517,1500],{"class":1033},[1027,3519,3520,3522,3524],{"class":1029,"line":1098},[1027,3521,1440],{"class":1040},[1027,3523,1189],{"class":1044},[1027,3525,1509],{"class":1079},[232,3527,1512],{"id":1512},[11,3529,3530,1517,3532,1520],{},[15,3531,1512],{},[15,3533,1151],{},[127,3535,3536],{"className":1021,"code":1523,"language":1023,"meta":135,"style":135},[15,3537,3538,3544,3548,3552,3556,3560],{"__ignoreMap":135},[1027,3539,3540,3542],{"class":1029,"line":1030},[1027,3541,1512],{"class":1040},[1027,3543,1173],{"class":1044},[1027,3545,3546],{"class":1029,"line":1037},[1027,3547,1536],{"class":1033},[1027,3549,3550],{"class":1029,"line":1048},[1027,3551,1541],{"class":1033},[1027,3553,3554],{"class":1029,"line":1054},[1027,3555,1546],{"class":1033},[1027,3557,3558],{"class":1029,"line":1060},[1027,3559,1064],{"emptyLinePlaceholder":1063},[1027,3561,3562,3564,3566,3568],{"class":1029,"line":1067},[1027,3563,1512],{"class":1040},[1027,3565,1557],{"class":1079},[1027,3567,1560],{"class":1044},[1027,3569,1173],{"class":1044},[232,3571,1566],{"id":1565},[11,3573,1569],{},[127,3575,3576],{"className":1021,"code":1572,"language":1023,"meta":135,"style":135},[15,3577,3578,3582,3590,3594,3602,3606,3610,3628,3632,3636],{"__ignoreMap":135},[1027,3579,3580],{"class":1029,"line":1030},[1027,3581,1579],{"class":1033},[1027,3583,3584,3586,3588],{"class":1029,"line":1037},[1027,3585,1584],{"class":1040},[1027,3587,1587],{"class":1044},[1027,3589,1590],{"class":1044},[1027,3591,3592],{"class":1029,"line":1048},[1027,3593,1595],{"class":1033},[1027,3595,3596,3598,3600],{"class":1029,"line":1054},[1027,3597,1584],{"class":1040},[1027,3599,1602],{"class":1044},[1027,3601,1605],{"class":1079},[1027,3603,3604],{"class":1029,"line":1060},[1027,3605,1064],{"emptyLinePlaceholder":1063},[1027,3607,3608],{"class":1029,"line":1067},[1027,3609,1070],{"class":1033},[1027,3611,3612,3614,3616,3618,3620,3622,3624,3626],{"class":1029,"line":1073},[1027,3613,1584],{"class":1040},[1027,3615,1620],{"class":1044},[1027,3617,1623],{"class":1079},[1027,3619,1627],{"class":1626},[1027,3621,1584],{"class":1040},[1027,3623,1632],{"class":1044},[1027,3625,1635],{"class":1079},[1027,3627,1638],{"class":1044},[1027,3629,3630],{"class":1029,"line":1093},[1027,3631,1064],{"emptyLinePlaceholder":1063},[1027,3633,3634],{"class":1029,"line":1098},[1027,3635,1101],{"class":1033},[1027,3637,3638,3640],{"class":1029,"line":1104},[1027,3639,1107],{"class":1040},[1027,3641,1653],{"class":1044},[11,3643,1656],{},[28,3645,1660],{"id":1659},[232,3647,1664],{"id":1663},[11,3649,1667],{},[127,3651,3653],{"className":3652,"code":1671,"language":132},[130],[15,3654,1671],{"__ignoreMap":135},[11,3656,1676,3657,1680],{},[15,3658,1679],{},[232,3660,1684],{"id":1683},[11,3662,1687],{},[127,3664,3665],{"className":1021,"code":1690,"language":1023,"meta":135,"style":135},[15,3666,3667,3671,3681,3685,3689,3693],{"__ignoreMap":135},[1027,3668,3669],{"class":1029,"line":1030},[1027,3670,1697],{"class":1033},[1027,3672,3673,3675,3677,3679],{"class":1029,"line":1037},[1027,3674,1151],{"class":1040},[1027,3676,1704],{"class":1044},[1027,3678,1707],{"class":1044},[1027,3680,1710],{"class":1044},[1027,3682,3683],{"class":1029,"line":1048},[1027,3684,1715],{"class":1033},[1027,3686,3687],{"class":1029,"line":1054},[1027,3688,1064],{"emptyLinePlaceholder":1063},[1027,3690,3691],{"class":1029,"line":1060},[1027,3692,1724],{"class":1033},[1027,3694,3695,3697,3699,3701],{"class":1029,"line":1067},[1027,3696,1151],{"class":1040},[1027,3698,1731],{"class":1044},[1027,3700,1707],{"class":1044},[1027,3702,1736],{"class":1044},[11,3704,1739],{},[232,3706,1743],{"id":1742},[11,3708,1746],{},[1748,3710,3711,3713,3719,3721],{},[79,3712,1752],{},[79,3714,1755,3715,1759,3717,45],{},[15,3716,1758],{},[15,3718,1762],{},[79,3720,1765],{},[79,3722,1768],{},[11,3724,1771],{},[232,3726,1775],{"id":1774},[11,3728,1778],{},[11,3730,3731,1784],{},[20,3732,1783],{},[127,3734,3736],{"className":3735,"code":1788,"language":132},[130],[15,3737,1788],{"__ignoreMap":135},[11,3739,3740,1796],{},[20,3741,1795],{},[11,3743,3744,1802],{},[20,3745,1801],{},[11,3747,3748,1808],{},[20,3749,1807],{},[232,3751,1812],{"id":1811},[11,3753,1815],{},[127,3755,3757],{"className":3756,"code":1819,"language":132},[130],[15,3758,1819],{"__ignoreMap":135},[11,3760,1824,3761,1828],{},[15,3762,1827],{},[28,3764,1832],{"id":1831},[11,3766,1835],{},[232,3768,1839],{"id":1838},[11,3770,1842],{},[11,3772,1845],{},[232,3774,1849],{"id":1848},[11,3776,1852],{},[232,3778,1856],{"id":1855},[11,3780,1859],{},[232,3782,1863],{"id":1862},[11,3784,1866],{},[127,3786,3788],{"className":3787,"code":1870,"language":132},[130],[15,3789,1870],{"__ignoreMap":135},[11,3791,1875],{},[28,3793,1879],{"id":1878},[11,3795,1882],{},[11,3797,1885],{},[127,3799,3801],{"className":3800,"code":1889,"language":132},[130],[15,3802,1889],{"__ignoreMap":135},[11,3804,1894],{},[127,3806,3807],{"className":1021,"code":1897,"language":1023,"meta":135,"style":135},[15,3808,3809,3813,3821,3829,3833,3837],{"__ignoreMap":135},[1027,3810,3811],{"class":1029,"line":1030},[1027,3812,1904],{"class":1033},[1027,3814,3815,3817,3819],{"class":1029,"line":1037},[1027,3816,1151],{"class":1040},[1027,3818,1189],{"class":1044},[1027,3820,1913],{"class":1044},[1027,3822,3823,3825,3827],{"class":1029,"line":1048},[1027,3824,1151],{"class":1040},[1027,3826,1189],{"class":1044},[1027,3828,1922],{"class":1044},[1027,3830,3831],{"class":1029,"line":1054},[1027,3832,1064],{"emptyLinePlaceholder":1063},[1027,3834,3835],{"class":1029,"line":1060},[1027,3836,1931],{"class":1033},[1027,3838,3839,3841,3843,3845],{"class":1029,"line":1067},[1027,3840,1151],{"class":1040},[1027,3842,1938],{"class":1044},[1027,3844,1189],{"class":1044},[1027,3846,1943],{"class":1044},[11,3848,1946],{},[28,3850,1950],{"id":1949},[11,3852,1953],{},[11,3854,3855,1959],{},[20,3856,1958],{},[11,3858,3859,1965],{},[20,3860,1964],{},[11,3862,1968],{},[127,3864,3865],{"className":1021,"code":1971,"language":1023,"meta":135,"style":135},[15,3866,3867,3871,3881,3885,3889,3893],{"__ignoreMap":135},[1027,3868,3869],{"class":1029,"line":1030},[1027,3870,1978],{"class":1033},[1027,3872,3873,3875,3877,3879],{"class":1029,"line":1037},[1027,3874,1983],{"class":1040},[1027,3876,1986],{"class":1079},[1027,3878,1989],{"class":1044},[1027,3880,1992],{"class":1079},[1027,3882,3883],{"class":1029,"line":1048},[1027,3884,1997],{"class":1044},[1027,3886,3887],{"class":1029,"line":1054},[1027,3888,1064],{"emptyLinePlaceholder":1063},[1027,3890,3891],{"class":1029,"line":1060},[1027,3892,2006],{"class":1033},[1027,3894,3895,3897,3899],{"class":1029,"line":1067},[1027,3896,1151],{"class":1040},[1027,3898,2013],{"class":1044},[1027,3900,1173],{"class":1044},[28,3902,2019],{"id":2018},[232,3904,2023],{"id":2022},[127,3906,3907],{"className":1021,"code":2026,"language":1023,"meta":135,"style":135},[15,3908,3909,3915],{"__ignoreMap":135},[1027,3910,3911,3913],{"class":1029,"line":1030},[1027,3912,1151],{"class":1040},[1027,3914,2035],{"class":1044},[1027,3916,3917],{"class":1029,"line":1037},[1027,3918,2040],{"class":1033},[11,3920,2043],{},[232,3922,2047],{"id":2046},[127,3924,3925],{"className":1021,"code":2050,"language":1023,"meta":135,"style":135},[15,3926,3927,3933],{"__ignoreMap":135},[1027,3928,3929,3931],{"class":1029,"line":1030},[1027,3930,1151],{"class":1040},[1027,3932,2059],{"class":1044},[1027,3934,3935],{"class":1029,"line":1037},[1027,3936,2064],{"class":1033},[11,3938,2067],{},[232,3940,2071],{"id":2070},[11,3942,2074],{},[127,3944,3945],{"className":1021,"code":2077,"language":1023,"meta":135,"style":135},[15,3946,3947,3951,3961,3971,3981,3985,3989,3999,4003],{"__ignoreMap":135},[1027,3948,3949],{"class":1029,"line":1030},[1027,3950,2084],{"class":1033},[1027,3952,3953,3955,3957,3959],{"class":1029,"line":1037},[1027,3954,1151],{"class":1040},[1027,3956,2091],{"class":1044},[1027,3958,1707],{"class":1044},[1027,3960,2096],{"class":1033},[1027,3962,3963,3965,3967,3969],{"class":1029,"line":1048},[1027,3964,1151],{"class":1040},[1027,3966,1236],{"class":1044},[1027,3968,1707],{"class":1044},[1027,3970,2107],{"class":1033},[1027,3972,3973,3975,3977,3979],{"class":1029,"line":1054},[1027,3974,1151],{"class":1040},[1027,3976,2114],{"class":1044},[1027,3978,1707],{"class":1044},[1027,3980,2119],{"class":1033},[1027,3982,3983],{"class":1029,"line":1060},[1027,3984,1064],{"emptyLinePlaceholder":1063},[1027,3986,3987],{"class":1029,"line":1067},[1027,3988,2128],{"class":1033},[1027,3990,3991,3993,3995,3997],{"class":1029,"line":1073},[1027,3992,1151],{"class":1040},[1027,3994,1704],{"class":1044},[1027,3996,1707],{"class":1044},[1027,3998,1710],{"class":1044},[1027,4000,4001],{"class":1029,"line":1093},[1027,4002,2143],{"class":1033},[1027,4004,4005,4007,4009,4011],{"class":1029,"line":1098},[1027,4006,1151],{"class":1040},[1027,4008,2150],{"class":1044},[1027,4010,1707],{"class":1044},[1027,4012,1736],{"class":1044},[11,4014,2157],{},[232,4016,2161],{"id":2160},[11,4018,2164],{},[127,4020,4021],{"className":1021,"code":2167,"language":1023,"meta":135,"style":135},[15,4022,4023],{"__ignoreMap":135},[1027,4024,4025,4027,4029,4031],{"class":1029,"line":1030},[1027,4026,1151],{"class":1040},[1027,4028,1257],{"class":1044},[1027,4030,2178],{"class":1044},[1027,4032,2059],{"class":1044},[11,4034,2183,4035,2187],{},[15,4036,2186],{},[232,4038,2191],{"id":2190},[127,4040,4041],{"className":1021,"code":2194,"language":1023,"meta":135,"style":135},[15,4042,4043,4047,4055,4059,4063,4077,4081,4085],{"__ignoreMap":135},[1027,4044,4045],{"class":1029,"line":1030},[1027,4046,2201],{"class":1033},[1027,4048,4049,4051,4053],{"class":1029,"line":1037},[1027,4050,1151],{"class":1040},[1027,4052,1707],{"class":1044},[1027,4054,1192],{"class":1044},[1027,4056,4057],{"class":1029,"line":1048},[1027,4058,1064],{"emptyLinePlaceholder":1063},[1027,4060,4061],{"class":1029,"line":1054},[1027,4062,2218],{"class":1033},[1027,4064,4065,4067,4069,4071,4073,4075],{"class":1029,"line":1060},[1027,4066,1151],{"class":1040},[1027,4068,1707],{"class":1044},[1027,4070,1560],{"class":1044},[1027,4072,1084],{"class":1083},[1027,4074,1087],{"class":1040},[1027,4076,2233],{"class":1044},[1027,4078,4079],{"class":1029,"line":1067},[1027,4080,1064],{"emptyLinePlaceholder":1063},[1027,4082,4083],{"class":1029,"line":1073},[1027,4084,2242],{"class":1033},[1027,4086,4087,4089,4091],{"class":1029,"line":1093},[1027,4088,1151],{"class":1040},[1027,4090,1299],{"class":1079},[1027,4092,2251],{"class":1044},[11,4094,2254],{},[28,4096,2258],{"id":2257},[450,4098,4099,4109],{},[453,4100,4101],{},[456,4102,4103,4105,4107],{},[459,4104,2267],{},[459,4106,2270],{},[459,4108,2273],{},[469,4110,4111,4119,4127,4135],{},[456,4112,4113,4115,4117],{},[474,4114,2280],{},[474,4116,2283],{},[474,4118,2286],{},[456,4120,4121,4123,4125],{},[474,4122,2291],{},[474,4124,2283],{},[474,4126,2296],{},[456,4128,4129,4131,4133],{},[474,4130,1958],{},[474,4132,2303],{},[474,4134,2306],{},[456,4136,4137,4139,4141],{},[474,4138,1964],{},[474,4140,2313],{},[474,4142,2316],{},[11,4144,2319],{},[28,4146,2323],{"id":2322},[11,4148,2326],{},[11,4150,2329],{},[76,4152,4153,4155,4157,4173,4175,4179,4181],{},[79,4154,2334],{},[79,4156,2337],{},[79,4158,2340,4159,1759,4161,2345,4163,2348,4165,2351,4167,2354,4169,2357,4171,2360],{},[15,4160,478],{},[15,4162,493],{},[15,4164,508],{},[15,4166,522],{},[15,4168,537],{},[15,4170,552],{},[15,4172,580],{},[79,4174,2363],{},[79,4176,4177,2369],{},[15,4178,2368],{},[79,4180,2372],{},[79,4182,2375],{},[2377,4184,2379],{},{"title":135,"searchDepth":1037,"depth":1037,"links":4186},[4187,4188,4189,4190,4196,4201,4210,4211,4215,4216,4217,4223,4230,4236,4237,4238,4245,4246],{"id":30,"depth":1037,"text":31},{"id":63,"depth":1037,"text":64},{"id":108,"depth":1037,"text":109},{"id":220,"depth":1037,"text":221,"children":4191},[4192,4193,4194,4195],{"id":234,"depth":1048,"text":235},{"id":251,"depth":1048,"text":252},{"id":261,"depth":1048,"text":262},{"id":274,"depth":1048,"text":275},{"id":284,"depth":1037,"text":285,"children":4197},[4198,4199,4200],{"id":313,"depth":1048,"text":314},{"id":378,"depth":1048,"text":379},{"id":388,"depth":1048,"text":389},{"id":444,"depth":1037,"text":445,"children":4202},[4203,4204,4205,4206,4207,4208,4209],{"id":623,"depth":1048,"text":624},{"id":651,"depth":1048,"text":652},{"id":701,"depth":1048,"text":702},{"id":724,"depth":1048,"text":725},{"id":764,"depth":1048,"text":765},{"id":780,"depth":1048,"text":781},{"id":799,"depth":1048,"text":800},{"id":812,"depth":1037,"text":813},{"id":872,"depth":1037,"text":873,"children":4212},[4213,4214],{"id":885,"depth":1048,"text":886},{"id":892,"depth":1048,"text":893},{"id":914,"depth":1037,"text":915},{"id":1121,"depth":1037,"text":1122},{"id":1147,"depth":1037,"text":1148,"children":4218},[4219,4220,4221,4222],{"id":1151,"depth":1048,"text":1151},{"id":1440,"depth":1048,"text":1440},{"id":1512,"depth":1048,"text":1512},{"id":1565,"depth":1048,"text":1566},{"id":1659,"depth":1037,"text":1660,"children":4224},[4225,4226,4227,4228,4229],{"id":1663,"depth":1048,"text":1664},{"id":1683,"depth":1048,"text":1684},{"id":1742,"depth":1048,"text":1743},{"id":1774,"depth":1048,"text":1775},{"id":1811,"depth":1048,"text":1812},{"id":1831,"depth":1037,"text":1832,"children":4231},[4232,4233,4234,4235],{"id":1838,"depth":1048,"text":1839},{"id":1848,"depth":1048,"text":1849},{"id":1855,"depth":1048,"text":1856},{"id":1862,"depth":1048,"text":1863},{"id":1878,"depth":1037,"text":1879},{"id":1949,"depth":1037,"text":1950},{"id":2018,"depth":1037,"text":2019,"children":4239},[4240,4241,4242,4243,4244],{"id":2022,"depth":1048,"text":2023},{"id":2046,"depth":1048,"text":2047},{"id":2070,"depth":1048,"text":2071},{"id":2160,"depth":1048,"text":2161},{"id":2190,"depth":1048,"text":2191},{"id":2257,"depth":1037,"text":2258},{"id":2322,"depth":1037,"text":2323},{},{"title":5,"description":2443},[22,2453,2454,2455,2456,2457],{"id":4251,"title":4252,"author":6,"body":4253,"date":11439,"description":11440,"draft":2444,"extension":2445,"guide":2446,"image":11441,"meta":11442,"navigation":1063,"path":11443,"seo":11444,"stem":11445,"tags":11446,"__hash__":11448},"blog/Backend/2.sql-made-dead-simple-rdbms-guide.md","SQL Made Dead Simple (The Only RDBMS Guide You Need)",{"type":8,"value":4254,"toc":11390},[4255,4259,4277,4292,4296,4302,4305,4331,4342,4354,4357,4361,4365,4370,4431,4435,4442,4456,4461,4524,4535,4539,4544,4550,4586,4590,4597,4602,4612,4615,4685,4689,4702,4771,4791,4795,4880,4884,4895,4901,4905,4908,4921,4927,4931,4938,4949,4955,4959,4966,4985,5038,5042,5053,5214,5233,5237,5254,5257,5305,5322,5389,5391,5395,5400,5531,5535,5539,5662,5666,5783,5787,5823,5836,5840,5843,5987,5990,6082,6085,6142,6165,6169,6178,6305,6309,6444,6446,6450,6454,6460,6841,6845,7000,7004,7014,7120,7255,7260,7266,7270,7290,7403,7416,7420,7431,7437,7450,7454,7468,7471,7491,7497,7501,7507,7603,7612,7616,7623,7701,7709,7713,7716,7720,7727,7787,7791,7798,7843,7847,8003,8007,8013,8181,8183,8187,8197,8270,8402,8407,8487,8494,8496,8500,8516,8520,8523,8529,8534,8549,8553,8557,8569,8655,8659,8674,8678,8694,8737,8753,8755,8759,8773,8776,8866,8871,8891,8896,8915,8933,8935,8939,8949,8953,9055,9061,9065,9071,9143,9224,9226,9230,9240,9468,9473,9499,9501,9505,9515,9519,9525,9936,9940,10328,10332,10988,10990,10994,11001,11157,11159,11163,11167,11276,11280,11342,11346,11371,11373,11381,11384,11387],[28,4256,4258],{"id":4257},"_1-overview","1. Overview",[11,4260,4261,4262,4266,4267,4269,4270,4273,4274,148],{},"Every app you use daily — Instagram, Zomato, Google Pay, your college's exam\nportal — stores its data ",[4263,4264,4265],"em",{},"somewhere",". That ",[4263,4268,4265],{}," is almost always a\n",[20,4271,4272],{},"database",", and the most widely used kind of database in the world is the\n",[20,4275,4276],{},"Relational Database",[11,4278,4279,4280,4283,4284,4287,4288,4291],{},"A ",[20,4281,4282],{},"Relational Database Management System (RDBMS)"," is software that lets you\nstore, organize, and retrieve structured data using a language called ",[20,4285,4286],{},"SQL\n(Structured Query Language)",". SQL has been the industry standard since the\n1970s, and despite decades of new technology, it remains one of the most\nin-demand skills for any software engineer, data analyst, or backend developer.\nWhether you want to ",[20,4289,4290],{},"learn SQL from scratch"," or sharpen your existing skills,\nunderstanding RDBMS concepts deeply is a must.",[232,4293,4295],{"id":4294},"real-world-example-an-e-commerce-platform","Real-World Example: An E-Commerce Platform",[11,4297,4298],{},[123,4299],{"alt":4300,"src":4301},"E-Commerce ER Diagram","/post-images/sql-made-dead-simple-rdbms-guide/ecommerce-er-diagram.png",[11,4303,4304],{},"Imagine you are building something like Amazon. You need to keep track of:",[76,4306,4307,4313,4319,4325],{},[79,4308,4309,4312],{},[20,4310,4311],{},"Customers"," — who they are, their email, their address",[79,4314,4315,4318],{},[20,4316,4317],{},"Products"," — names, prices, stock counts",[79,4320,4321,4324],{},[20,4322,4323],{},"Orders"," — which customer bought which product, when, and for how much",[79,4326,4327,4330],{},[20,4328,4329],{},"Payments"," — transaction IDs, payment method, status",[11,4332,4333,4334,4337,4338,4341],{},"All of this data is ",[4263,4335,4336],{},"related"," to each other. An order belongs to a customer.\nAn order contains products. A payment belongs to an order. The ",[20,4339,4340],{},"relational\ndatabase"," model gives us a clean, structured, and efficient way to represent\nthese connections — and SQL gives us the power to query across all of them\ninstantly.",[56,4343,4344],{},[11,4345,4346,4349,4350,4353],{},[20,4347,4348],{},"Why SQL still matters in 2026:"," Despite the rise of NoSQL databases like\nMongoDB, the vast majority of production systems still rely on relational\ndatabases (PostgreSQL, MySQL, SQLite, Oracle, SQL Server). When comparing\n",[20,4351,4352],{},"RDBMS vs NoSQL",", the relational model wins for structured, transactional\ndata. Understanding SQL deeply makes you a far more capable engineer,\nregardless of your specialization.",[4355,4356],"hr",{},[28,4358,4360],{"id":4359},"_2-foundational-concepts","2. Foundational Concepts",[232,4362,4364],{"id":4363},"_21-what-is-a-database","2.1 What is a Database?",[11,4366,4279,4367,4369],{},[20,4368,4272],{}," is an organized collection of structured data stored\nelectronically. Think of it like a digital filing cabinet — but one that can\nfind any document in milliseconds, even if there are a billion of them.",[450,4371,4372,4385],{},[453,4373,4374],{},[456,4375,4376,4379,4382],{},[459,4377,4378],{},"Analogy",[459,4380,4381],{},"Real World",[459,4383,4384],{},"Database World",[469,4386,4387,4398,4409,4420],{},[456,4388,4389,4392,4395],{},[474,4390,4391],{},"Filing Cabinet",[474,4393,4394],{},"Physical storage room",[474,4396,4397],{},"Database",[456,4399,4400,4403,4406],{},[474,4401,4402],{},"File Folder",[474,4404,4405],{},"A category of documents",[474,4407,4408],{},"Table",[456,4410,4411,4414,4417],{},[474,4412,4413],{},"One Document",[474,4415,4416],{},"A single record",[474,4418,4419],{},"Row (tuple)",[456,4421,4422,4425,4428],{},[474,4423,4424],{},"A field on the document",[474,4426,4427],{},"One piece of info",[474,4429,4430],{},"Column (attribute)",[232,4432,4434],{"id":4433},"_22-what-is-an-rdbms","2.2 What is an RDBMS?",[11,4436,4437,4438,4441],{},"An ",[20,4439,4440],{},"RDBMS"," (Relational Database Management System) is the software engine\nthat manages the database. It handles:",[76,4443,4444,4447,4450,4453],{},[79,4445,4446],{},"Storing data safely to disk",[79,4448,4449],{},"Letting multiple users read/write simultaneously without corruption",[79,4451,4452],{},"Enforcing rules (e.g., \"every order must have a valid customer\")",[79,4454,4455],{},"Executing SQL queries with high performance",[11,4457,4458],{},[20,4459,4460],{},"Popular RDBMS options:",[450,4462,4463,4472],{},[453,4464,4465],{},[456,4466,4467,4469],{},[459,4468,4440],{},[459,4470,4471],{},"Best Known For",[469,4473,4474,4484,4494,4504,4514],{},[456,4475,4476,4481],{},[474,4477,4478],{},[20,4479,4480],{},"PostgreSQL",[474,4482,4483],{},"Open-source, feature-rich, industry favourite",[456,4485,4486,4491],{},[474,4487,4488],{},[20,4489,4490],{},"MySQL / MariaDB",[474,4492,4493],{},"Web applications (LAMP stack)",[456,4495,4496,4501],{},[474,4497,4498],{},[20,4499,4500],{},"SQLite",[474,4502,4503],{},"Lightweight, embedded (used in Android, iOS)",[456,4505,4506,4511],{},[474,4507,4508],{},[20,4509,4510],{},"Oracle DB",[474,4512,4513],{},"Enterprise, banking systems",[456,4515,4516,4521],{},[474,4517,4518],{},[20,4519,4520],{},"Microsoft SQL Server",[474,4522,4523],{},"Windows/enterprise ecosystems",[56,4525,4526],{},[11,4527,4528,4529,4531,4532,4534],{},"For learning, ",[20,4530,4500],{}," is recommended because it requires zero setup.\nFor production projects, use ",[20,4533,4480],{},". Both are covered in this\ncomplete SQL guide.",[232,4536,4538],{"id":4537},"_23-tables-rows-and-columns","2.3 Tables, Rows, and Columns",[11,4540,4279,4541,4543],{},[20,4542,450],{}," is the fundamental unit of storage in a relational database. It\nlooks exactly like a spreadsheet grid.",[127,4545,4548],{"className":4546,"code":4547,"language":132},[130],"Table: students\n+------------+------------------+-----+--------+\n| student_id | name             | age | grade  |\n+------------+------------------+-----+--------+\n|     1      | Priya Sharma     |  20 |  A     |\n|     2      | Rahul Das        |  21 |  B+    |\n|     3      | Aisha Khan       |  19 |  A+    |\n+------------+------------------+-----+--------+\n",[15,4549,4547],{"__ignoreMap":135},[76,4551,4552,4563,4576],{},[79,4553,4554,4555,4558,4559,4562],{},"Each ",[20,4556,4557],{},"column"," represents one ",[4263,4560,4561],{},"attribute"," or property (name, age, grade).",[79,4564,4554,4565,4568,4569,171,4572,4575],{},[20,4566,4567],{},"row"," (also called a ",[20,4570,4571],{},"record",[20,4573,4574],{},"tuple",") represents one complete\nentity — in this case, one student.",[79,4577,1125,4578,4581,4582,4585],{},[20,4579,4580],{},"schema"," is the blueprint of the table — its column names and their\ndata types. Good ",[20,4583,4584],{},"database schema design"," is the cornerstone of a\nwell-structured application.",[232,4587,4589],{"id":4588},"_24-keys-the-identity-system","2.4 Keys — The Identity System",[11,4591,4592,4593,4596],{},"This is one of the most important concepts in all of RDBMS. Understanding the\ndifference between a ",[20,4594,4595],{},"primary key vs foreign key"," is fundamental to relational\ndatabase design.",[4598,4599,4601],"h4",{"id":4600},"primary-key-pk","Primary Key (PK)",[11,4603,4279,4604,4607,4608,4611],{},[20,4605,4606],{},"Primary Key"," is a column (or combination of columns) that ",[20,4609,4610],{},"uniquely\nidentifies each row"," in a table. No two rows can have the same primary key\nvalue, and it can never be NULL.",[11,4613,4614],{},"Think of it like an Aadhaar number — every citizen has one, it's unique, and\nit never changes.",[127,4616,4620],{"className":4617,"code":4618,"language":4619,"meta":135,"style":135},"language-sql shiki shiki-themes github-dark","-- student_id is the Primary Key\nCREATE TABLE students (\n    student_id INT PRIMARY KEY,\n    name       VARCHAR(100),\n    age        INT\n);\n","sql",[15,4621,4622,4627,4641,4655,4672,4680],{"__ignoreMap":135},[1027,4623,4624],{"class":1029,"line":1030},[1027,4625,4626],{"class":1033},"-- student_id is the Primary Key\n",[1027,4628,4629,4632,4635,4638],{"class":1029,"line":1037},[1027,4630,4631],{"class":1083},"CREATE",[1027,4633,4634],{"class":1083}," TABLE",[1027,4636,4637],{"class":1040}," students",[1027,4639,4640],{"class":1626}," (\n",[1027,4642,4643,4646,4649,4652],{"class":1029,"line":1048},[1027,4644,4645],{"class":1626},"    student_id ",[1027,4647,4648],{"class":1083},"INT",[1027,4650,4651],{"class":1083}," PRIMARY KEY",[1027,4653,4654],{"class":1626},",\n",[1027,4656,4657,4660,4663,4666,4669],{"class":1029,"line":1054},[1027,4658,4659],{"class":1083},"    name",[1027,4661,4662],{"class":1083},"       VARCHAR",[1027,4664,4665],{"class":1626},"(",[1027,4667,4668],{"class":1079},"100",[1027,4670,4671],{"class":1626},"),\n",[1027,4673,4674,4677],{"class":1029,"line":1060},[1027,4675,4676],{"class":1626},"    age        ",[1027,4678,4679],{"class":1083},"INT\n",[1027,4681,4682],{"class":1029,"line":1067},[1027,4683,4684],{"class":1626},");\n",[4598,4686,4688],{"id":4687},"foreign-key-fk","Foreign Key (FK)",[11,4690,4279,4691,4694,4695,4698,4699,4701],{},[20,4692,4693],{},"Foreign Key"," is a column in one table that ",[4263,4696,4697],{},"references"," the Primary Key\nof another table. This is how relationships between tables are enforced.\nThe ",[20,4700,4595],{}," distinction is what makes the \"relational\"\nin RDBMS meaningful.",[127,4703,4705],{"className":4617,"code":4704,"language":4619,"meta":135,"style":135},"-- course_id in enrollments REFERENCES the courses table\nCREATE TABLE enrollments (\n    enrollment_id INT PRIMARY KEY,\n    student_id    INT REFERENCES students(student_id),\n    course_id     INT REFERENCES courses(course_id),\n    enrolled_on   DATE\n);\n",[15,4706,4707,4712,4723,4734,4747,4759,4767],{"__ignoreMap":135},[1027,4708,4709],{"class":1029,"line":1030},[1027,4710,4711],{"class":1033},"-- course_id in enrollments REFERENCES the courses table\n",[1027,4713,4714,4716,4718,4721],{"class":1029,"line":1037},[1027,4715,4631],{"class":1083},[1027,4717,4634],{"class":1083},[1027,4719,4720],{"class":1040}," enrollments",[1027,4722,4640],{"class":1626},[1027,4724,4725,4728,4730,4732],{"class":1029,"line":1048},[1027,4726,4727],{"class":1626},"    enrollment_id ",[1027,4729,4648],{"class":1083},[1027,4731,4651],{"class":1083},[1027,4733,4654],{"class":1626},[1027,4735,4736,4739,4741,4744],{"class":1029,"line":1054},[1027,4737,4738],{"class":1626},"    student_id    ",[1027,4740,4648],{"class":1083},[1027,4742,4743],{"class":1083}," REFERENCES",[1027,4745,4746],{"class":1626}," students(student_id),\n",[1027,4748,4749,4752,4754,4756],{"class":1029,"line":1060},[1027,4750,4751],{"class":1626},"    course_id     ",[1027,4753,4648],{"class":1083},[1027,4755,4743],{"class":1083},[1027,4757,4758],{"class":1626}," courses(course_id),\n",[1027,4760,4761,4764],{"class":1029,"line":1067},[1027,4762,4763],{"class":1626},"    enrolled_on   ",[1027,4765,4766],{"class":1083},"DATE\n",[1027,4768,4769],{"class":1029,"line":1073},[1027,4770,4684],{"class":1626},[56,4772,4773],{},[11,4774,4775,4778,4779,4782,4783,4786,4787,4790],{},[20,4776,4777],{},"Analogy:"," If ",[15,4780,4781],{},"students"," is a list of employees and ",[15,4784,4785],{},"enrollments"," is a\nlist of projects, then the foreign key is like writing an employee's badge\nnumber on the project sheet — it ",[4263,4788,4789],{},"links"," back to the actual person.",[4598,4792,4794],{"id":4793},"candidate-key-composite-key-surrogate-key","Candidate Key, Composite Key, Surrogate Key",[450,4796,4797,4810],{},[453,4798,4799],{},[456,4800,4801,4804,4807],{},[459,4802,4803],{},"Key Type",[459,4805,4806],{},"Definition",[459,4808,4809],{},"Example",[469,4811,4812,4834,4850,4865],{},[456,4813,4814,4819,4826],{},[474,4815,4816],{},[20,4817,4818],{},"Candidate Key",[474,4820,4821,4822,4825],{},"Any column that ",[4263,4823,4824],{},"could"," be a PK",[474,4827,4828,171,4831],{},[15,4829,4830],{},"email",[15,4832,4833],{},"student_id",[456,4835,4836,4841,4844],{},[474,4837,4838],{},[20,4839,4840],{},"Composite Key",[474,4842,4843],{},"PK made of two or more columns",[474,4845,4846,4849],{},[15,4847,4848],{},"(student_id, course_id)"," together",[456,4851,4852,4857,4860],{},[474,4853,4854],{},[20,4855,4856],{},"Surrogate Key",[474,4858,4859],{},"An artificial PK (like an auto-increment ID)",[474,4861,4862],{},[15,4863,4864],{},"id SERIAL",[456,4866,4867,4872,4875],{},[474,4868,4869],{},[20,4870,4871],{},"Natural Key",[474,4873,4874],{},"A PK from real-world data",[474,4876,4877],{},[15,4878,4879],{},"PAN_number",[232,4881,4883],{"id":4882},"_25-relationships-between-tables","2.5 Relationships Between Tables",[11,4885,4886,4887,4890,4891,4894],{},"The \"relational\" in RDBMS refers to the ",[4263,4888,4889],{},"relationships"," between tables, which is a central part of ",[20,4892,4893],{},"entity relationship"," modelling. There are three fundamental types:",[11,4896,4897],{},[123,4898],{"alt":4899,"src":4900},"Database Relationship Types","/post-images/sql-made-dead-simple-rdbms-guide/database-relationship-types.png",[4598,4902,4904],{"id":4903},"one-to-one-11","One-to-One (1:1)",[11,4906,4907],{},"One row in Table A corresponds to exactly one row in Table B.",[11,4909,4910,4913,4914,4917,4918,148],{},[20,4911,4912],{},"Example:"," One ",[15,4915,4916],{},"user"," has exactly one ",[15,4919,4920],{},"user_profile",[127,4922,4925],{"className":4923,"code":4924,"language":132},[130],"users             user_profiles\n+----+--------+   +----+---------+-----------+\n| id | name   |   | id | user_id | bio       |\n+----+--------+   +----+---------+-----------+\n|  1 | Rahul  |   |  1 |    1    | Developer |\n|  2 | Priya  |   |  2 |    2    | Designer  |\n+----+--------+   +----+---------+-----------+\n",[15,4926,4924],{"__ignoreMap":135},[4598,4928,4930],{"id":4929},"one-to-many-1n-most-common","One-to-Many (1:N) ← Most Common",[11,4932,4933,4934,4937],{},"One row in Table A corresponds to ",[4263,4935,4936],{},"many"," rows in Table B.",[11,4939,4940,4913,4942,4945,4946,148],{},[20,4941,4912],{},[15,4943,4944],{},"customer"," can place many ",[15,4947,4948],{},"orders",[127,4950,4953],{"className":4951,"code":4952,"language":132},[130],"customers                orders\n+----+--------+          +----+-------------+----------+\n| id | name   |          | id | customer_id | amount   |\n+----+--------+          +----+-------------+----------+\n|  1 | Rahul  |          |  1 |      1      | ₹500     |\n|  2 | Priya  |          |  2 |      1      | ₹1200    |\n+----+--------+          |  3 |      2      | ₹800     |\n                         +----+-------------+----------+\n",[15,4954,4952],{"__ignoreMap":135},[4598,4956,4958],{"id":4957},"many-to-many-mn","Many-to-Many (M:N)",[11,4960,4961,4962,4965],{},"Many rows in Table A correspond to many rows in Table B. This requires a\n",[20,4963,4964],{},"junction table"," (also called a bridge or pivot table) in the middle.",[11,4967,4968,4970,4971,4974,4975,4978,4979,4982,4983,148],{},[20,4969,4912],{}," A ",[15,4972,4973],{},"student"," can enroll in many ",[15,4976,4977],{},"courses",", and a ",[15,4980,4981],{},"course"," can have many ",[15,4984,4781],{},[127,4986,4988],{"className":4617,"code":4987,"language":4619,"meta":135,"style":135},"CREATE TABLE enrollments (\n    student_id INT REFERENCES students(id),\n    course_id  INT REFERENCES courses(id),\n    PRIMARY KEY (student_id, course_id)   -- Composite PK\n);\n",[15,4989,4990,5000,5011,5023,5034],{"__ignoreMap":135},[1027,4991,4992,4994,4996,4998],{"class":1029,"line":1030},[1027,4993,4631],{"class":1083},[1027,4995,4634],{"class":1083},[1027,4997,4720],{"class":1040},[1027,4999,4640],{"class":1626},[1027,5001,5002,5004,5006,5008],{"class":1029,"line":1037},[1027,5003,4645],{"class":1626},[1027,5005,4648],{"class":1083},[1027,5007,4743],{"class":1083},[1027,5009,5010],{"class":1626}," students(id),\n",[1027,5012,5013,5016,5018,5020],{"class":1029,"line":1048},[1027,5014,5015],{"class":1626},"    course_id  ",[1027,5017,4648],{"class":1083},[1027,5019,4743],{"class":1083},[1027,5021,5022],{"class":1626}," courses(id),\n",[1027,5024,5025,5028,5031],{"class":1029,"line":1054},[1027,5026,5027],{"class":1083},"    PRIMARY KEY",[1027,5029,5030],{"class":1626}," (student_id, course_id)   ",[1027,5032,5033],{"class":1033},"-- Composite PK\n",[1027,5035,5036],{"class":1029,"line":1060},[1027,5037,4684],{"class":1626},[232,5039,5041],{"id":5040},"_26-data-types","2.6 Data Types",[11,5043,5044,5045,5048,5049,5052],{},"Every column has a ",[20,5046,5047],{},"data type"," that restricts what kind of data it can hold.\nChoosing the right ",[20,5050,5051],{},"data types in SQL"," is crucial for data integrity and\nstorage efficiency.",[450,5054,5055,5068],{},[453,5056,5057],{},[456,5058,5059,5062,5065],{},[459,5060,5061],{},"Category",[459,5063,5064],{},"Common Types",[459,5066,5067],{},"Example Values",[469,5069,5070,5098,5124,5150,5170,5196],{},[456,5071,5072,5077,5087],{},[474,5073,5074],{},[20,5075,5076],{},"Integer",[474,5078,5079,160,5081,160,5084],{},[15,5080,4648],{},[15,5082,5083],{},"BIGINT",[15,5085,5086],{},"SMALLINT",[474,5088,5089,160,5092,160,5095],{},[15,5090,5091],{},"1",[15,5093,5094],{},"99",[15,5096,5097],{},"1000000",[456,5099,5100,5105,5116],{},[474,5101,5102],{},[20,5103,5104],{},"Decimal",[474,5106,5107,160,5110,160,5113],{},[15,5108,5109],{},"DECIMAL(p,s)",[15,5111,5112],{},"NUMERIC",[15,5114,5115],{},"FLOAT",[474,5117,5118,160,5121],{},[15,5119,5120],{},"9.99",[15,5122,5123],{},"3.14159",[456,5125,5126,5131,5142],{},[474,5127,5128],{},[20,5129,5130],{},"Text",[474,5132,5133,160,5136,160,5139],{},[15,5134,5135],{},"VARCHAR(n)",[15,5137,5138],{},"TEXT",[15,5140,5141],{},"CHAR(n)",[474,5143,5144,160,5147],{},[15,5145,5146],{},"'Rahul'",[15,5148,5149],{},"'Hello World'",[456,5151,5152,5157,5162],{},[474,5153,5154],{},[20,5155,5156],{},"Boolean",[474,5158,5159],{},[15,5160,5161],{},"BOOLEAN",[474,5163,5164,160,5167],{},[15,5165,5166],{},"TRUE",[15,5168,5169],{},"FALSE",[456,5171,5172,5177,5188],{},[474,5173,5174],{},[20,5175,5176],{},"Date/Time",[474,5178,5179,160,5182,160,5185],{},[15,5180,5181],{},"DATE",[15,5183,5184],{},"TIME",[15,5186,5187],{},"TIMESTAMP",[474,5189,5190,160,5193],{},[15,5191,5192],{},"2024-01-15",[15,5194,5195],{},"09:30:00",[456,5197,5198,5203,5211],{},[474,5199,5200],{},[20,5201,5202],{},"Binary",[474,5204,5205,160,5208],{},[15,5206,5207],{},"BYTEA",[15,5209,5210],{},"BLOB",[474,5212,5213],{},"Image files, PDFs",[56,5215,5216],{},[11,5217,5218,5226,5227,5229,5230,5232],{},[20,5219,5220,5222,5223,5225],{},[15,5221,5135],{}," vs ",[15,5224,5138],{},":"," Use ",[15,5228,5135],{}," when you know the max length\n(e.g., a phone number is always ≤15 chars). Use ",[15,5231,5138],{}," for open-ended\nstrings like comments or descriptions.",[232,5234,5236],{"id":5235},"_27-null-the-absence-of-a-value","2.7 NULL — The Absence of a Value",[11,5238,5239,5242,5243,5246,5247,5250,5251,5253],{},[15,5240,5241],{},"NULL"," in SQL means ",[20,5244,5245],{},"the value is unknown or does not exist",". It is ",[4263,5248,5249],{},"not","\nzero, it is ",[4263,5252,5249],{}," an empty string — it is the complete absence of a value.",[11,5255,5256],{},"This is a frequent source of confusion for beginners learning SQL.",[127,5258,5260],{"className":4617,"code":5259,"language":4619,"meta":135,"style":135},"-- These are all DIFFERENT:\nage = 0        -- The person is 0 years old\nage = ''       -- Invalid for INT; for text, it's an empty string\nage = NULL     -- We simply don't know the person's age\n",[15,5261,5262,5267,5281,5293],{"__ignoreMap":135},[1027,5263,5264],{"class":1029,"line":1030},[1027,5265,5266],{"class":1033},"-- These are all DIFFERENT:\n",[1027,5268,5269,5272,5275,5278],{"class":1029,"line":1037},[1027,5270,5271],{"class":1626},"age ",[1027,5273,5274],{"class":1083},"=",[1027,5276,5277],{"class":1079}," 0",[1027,5279,5280],{"class":1033},"        -- The person is 0 years old\n",[1027,5282,5283,5285,5287,5290],{"class":1029,"line":1048},[1027,5284,5271],{"class":1626},[1027,5286,5274],{"class":1083},[1027,5288,5289],{"class":1044}," ''",[1027,5291,5292],{"class":1033},"       -- Invalid for INT; for text, it's an empty string\n",[1027,5294,5295,5297,5299,5302],{"class":1029,"line":1054},[1027,5296,5271],{"class":1626},[1027,5298,5274],{"class":1083},[1027,5300,5301],{"class":1083}," NULL",[1027,5303,5304],{"class":1033},"     -- We simply don't know the person's age\n",[56,5306,5307],{},[11,5308,5309,5312,5313,5315,5316,171,5319,148],{},[20,5310,5311],{},"Critical Rule:"," You cannot compare NULL using ",[15,5314,5274],{},". You must use\n",[15,5317,5318],{},"IS NULL",[15,5320,5321],{},"IS NOT NULL",[127,5323,5325],{"className":4617,"code":5324,"language":4619,"meta":135,"style":135},"-- WRONG — this will never return results even if age is NULL\nSELECT * FROM students WHERE age = NULL;\n\n-- CORRECT\nSELECT * FROM students WHERE age IS NULL;\n",[15,5326,5327,5332,5359,5363,5368],{"__ignoreMap":135},[1027,5328,5329],{"class":1029,"line":1030},[1027,5330,5331],{"class":1033},"-- WRONG — this will never return results even if age is NULL\n",[1027,5333,5334,5337,5340,5343,5346,5349,5352,5354,5356],{"class":1029,"line":1037},[1027,5335,5336],{"class":1083},"SELECT",[1027,5338,5339],{"class":1083}," *",[1027,5341,5342],{"class":1083}," FROM",[1027,5344,5345],{"class":1626}," students ",[1027,5347,5348],{"class":1083},"WHERE",[1027,5350,5351],{"class":1626}," age ",[1027,5353,5274],{"class":1083},[1027,5355,5301],{"class":1083},[1027,5357,5358],{"class":1626},";\n",[1027,5360,5361],{"class":1029,"line":1048},[1027,5362,1064],{"emptyLinePlaceholder":1063},[1027,5364,5365],{"class":1029,"line":1054},[1027,5366,5367],{"class":1033},"-- CORRECT\n",[1027,5369,5370,5372,5374,5376,5378,5380,5382,5385,5387],{"class":1029,"line":1060},[1027,5371,5336],{"class":1083},[1027,5373,5339],{"class":1083},[1027,5375,5342],{"class":1083},[1027,5377,5345],{"class":1626},[1027,5379,5348],{"class":1083},[1027,5381,5351],{"class":1626},[1027,5383,5384],{"class":1083},"IS",[1027,5386,5301],{"class":1083},[1027,5388,5358],{"class":1626},[4355,5390],{},[28,5392,5394],{"id":5393},"_3-sql-the-language-of-databases","3. SQL — The Language of Databases",[11,5396,5397,5398,5225],{},"SQL (pronounced \"sequel\" or \"S-Q-L\") is divided into sub-languages based on\nwhat they do. This is essential knowledge when you ",[20,5399,4290],{},[450,5401,5402,5417],{},[453,5403,5404],{},[456,5405,5406,5409,5412,5414],{},[459,5407,5408],{},"Sub-language",[459,5410,5411],{},"Full Name",[459,5413,464],{},[459,5415,5416],{},"Commands",[469,5418,5419,5445,5469,5486,5507],{},[456,5420,5421,5426,5429,5432],{},[474,5422,5423],{},[20,5424,5425],{},"DDL",[474,5427,5428],{},"Data Definition Language",[474,5430,5431],{},"Define/modify structure",[474,5433,5434,160,5436,160,5439,160,5442],{},[15,5435,4631],{},[15,5437,5438],{},"ALTER",[15,5440,5441],{},"DROP",[15,5443,5444],{},"TRUNCATE",[456,5446,5447,5452,5455,5458],{},[474,5448,5449],{},[20,5450,5451],{},"DML",[474,5453,5454],{},"Data Manipulation Language",[474,5456,5457],{},"Add/change/delete data",[474,5459,5460,160,5463,160,5466],{},[15,5461,5462],{},"INSERT",[15,5464,5465],{},"UPDATE",[15,5467,5468],{},"DELETE",[456,5470,5471,5476,5479,5482],{},[474,5472,5473],{},[20,5474,5475],{},"DQL",[474,5477,5478],{},"Data Query Language",[474,5480,5481],{},"Read/fetch data",[474,5483,5484],{},[15,5485,5336],{},[456,5487,5488,5493,5496,5499],{},[474,5489,5490],{},[20,5491,5492],{},"DCL",[474,5494,5495],{},"Data Control Language",[474,5497,5498],{},"Manage permissions",[474,5500,5501,160,5504],{},[15,5502,5503],{},"GRANT",[15,5505,5506],{},"REVOKE",[456,5508,5509,5514,5517,5520],{},[474,5510,5511],{},[20,5512,5513],{},"TCL",[474,5515,5516],{},"Transaction Control Language",[474,5518,5519],{},"Manage transactions",[474,5521,5522,160,5525,160,5528],{},[15,5523,5524],{},"COMMIT",[15,5526,5527],{},"ROLLBACK",[15,5529,5530],{},"SAVEPOINT",[232,5532,5534],{"id":5533},"_31-ddl-defining-structure","3.1 DDL — Defining Structure",[4598,5536,5538],{"id":5537},"create-table","CREATE TABLE",[127,5540,5542],{"className":4617,"code":5541,"language":4619,"meta":135,"style":135},"CREATE TABLE products (\n    product_id   SERIAL PRIMARY KEY,       -- auto-incrementing ID\n    name         VARCHAR(200) NOT NULL,\n    description  TEXT,\n    price        DECIMAL(10, 2) NOT NULL,  -- up to 10 digits, 2 decimal places\n    stock_count  INT DEFAULT 0,\n    created_at   TIMESTAMP DEFAULT NOW()\n);\n",[15,5543,5544,5555,5571,5591,5601,5629,5643,5658],{"__ignoreMap":135},[1027,5545,5546,5548,5550,5553],{"class":1029,"line":1030},[1027,5547,4631],{"class":1083},[1027,5549,4634],{"class":1083},[1027,5551,5552],{"class":1040}," products",[1027,5554,4640],{"class":1626},[1027,5556,5557,5560,5563,5565,5568],{"class":1029,"line":1037},[1027,5558,5559],{"class":1626},"    product_id   ",[1027,5561,5562],{"class":1083},"SERIAL",[1027,5564,4651],{"class":1083},[1027,5566,5567],{"class":1626},",       ",[1027,5569,5570],{"class":1033},"-- auto-incrementing ID\n",[1027,5572,5573,5575,5578,5580,5583,5586,5589],{"class":1029,"line":1048},[1027,5574,4659],{"class":1083},[1027,5576,5577],{"class":1083},"         VARCHAR",[1027,5579,4665],{"class":1626},[1027,5581,5582],{"class":1079},"200",[1027,5584,5585],{"class":1626},") ",[1027,5587,5588],{"class":1083},"NOT NULL",[1027,5590,4654],{"class":1626},[1027,5592,5593,5596,5599],{"class":1029,"line":1054},[1027,5594,5595],{"class":1083},"    description",[1027,5597,5598],{"class":1083},"  TEXT",[1027,5600,4654],{"class":1626},[1027,5602,5603,5606,5609,5611,5614,5616,5619,5621,5623,5626],{"class":1029,"line":1060},[1027,5604,5605],{"class":1626},"    price        ",[1027,5607,5608],{"class":1083},"DECIMAL",[1027,5610,4665],{"class":1626},[1027,5612,5613],{"class":1079},"10",[1027,5615,160],{"class":1626},[1027,5617,5618],{"class":1079},"2",[1027,5620,5585],{"class":1626},[1027,5622,5588],{"class":1083},[1027,5624,5625],{"class":1626},",  ",[1027,5627,5628],{"class":1033},"-- up to 10 digits, 2 decimal places\n",[1027,5630,5631,5634,5636,5639,5641],{"class":1029,"line":1067},[1027,5632,5633],{"class":1626},"    stock_count  ",[1027,5635,4648],{"class":1083},[1027,5637,5638],{"class":1083}," DEFAULT",[1027,5640,5277],{"class":1079},[1027,5642,4654],{"class":1626},[1027,5644,5645,5648,5650,5652,5655],{"class":1029,"line":1073},[1027,5646,5647],{"class":1626},"    created_at   ",[1027,5649,5187],{"class":1083},[1027,5651,5638],{"class":1083},[1027,5653,5654],{"class":1083}," NOW",[1027,5656,5657],{"class":1626},"()\n",[1027,5659,5660],{"class":1029,"line":1093},[1027,5661,4684],{"class":1626},[4598,5663,5665],{"id":5664},"alter-table","ALTER TABLE",[127,5667,5669],{"className":4617,"code":5668,"language":4619,"meta":135,"style":135},"-- Add a new column\nALTER TABLE products ADD COLUMN category VARCHAR(100);\n\n-- Change a column's data type\nALTER TABLE products ALTER COLUMN name TYPE TEXT;\n\n-- Rename a column\nALTER TABLE products RENAME COLUMN stock_count TO quantity;\n\n-- Drop a column\nALTER TABLE products DROP COLUMN description;\n",[15,5670,5671,5676,5700,5704,5709,5733,5737,5742,5757,5761,5766],{"__ignoreMap":135},[1027,5672,5673],{"class":1029,"line":1030},[1027,5674,5675],{"class":1033},"-- Add a new column\n",[1027,5677,5678,5680,5682,5685,5688,5691,5694,5696,5698],{"class":1029,"line":1037},[1027,5679,5438],{"class":1083},[1027,5681,4634],{"class":1083},[1027,5683,5684],{"class":1626}," products ",[1027,5686,5687],{"class":1083},"ADD",[1027,5689,5690],{"class":1626}," COLUMN category ",[1027,5692,5693],{"class":1083},"VARCHAR",[1027,5695,4665],{"class":1626},[1027,5697,4668],{"class":1079},[1027,5699,4684],{"class":1626},[1027,5701,5702],{"class":1029,"line":1048},[1027,5703,1064],{"emptyLinePlaceholder":1063},[1027,5705,5706],{"class":1029,"line":1054},[1027,5707,5708],{"class":1033},"-- Change a column's data type\n",[1027,5710,5711,5713,5715,5717,5719,5722,5725,5728,5731],{"class":1029,"line":1060},[1027,5712,5438],{"class":1083},[1027,5714,4634],{"class":1083},[1027,5716,5684],{"class":1626},[1027,5718,5438],{"class":1083},[1027,5720,5721],{"class":1626}," COLUMN ",[1027,5723,5724],{"class":1083},"name",[1027,5726,5727],{"class":1083}," TYPE",[1027,5729,5730],{"class":1083}," TEXT",[1027,5732,5358],{"class":1626},[1027,5734,5735],{"class":1029,"line":1067},[1027,5736,1064],{"emptyLinePlaceholder":1063},[1027,5738,5739],{"class":1029,"line":1073},[1027,5740,5741],{"class":1033},"-- Rename a column\n",[1027,5743,5744,5746,5748,5751,5754],{"class":1029,"line":1093},[1027,5745,5438],{"class":1083},[1027,5747,4634],{"class":1083},[1027,5749,5750],{"class":1626}," products RENAME COLUMN stock_count ",[1027,5752,5753],{"class":1083},"TO",[1027,5755,5756],{"class":1626}," quantity;\n",[1027,5758,5759],{"class":1029,"line":1098},[1027,5760,1064],{"emptyLinePlaceholder":1063},[1027,5762,5763],{"class":1029,"line":1104},[1027,5764,5765],{"class":1033},"-- Drop a column\n",[1027,5767,5768,5770,5772,5774,5776,5778,5781],{"class":1029,"line":1231},[1027,5769,5438],{"class":1083},[1027,5771,4634],{"class":1083},[1027,5773,5684],{"class":1626},[1027,5775,5441],{"class":1083},[1027,5777,5721],{"class":1626},[1027,5779,5780],{"class":1083},"description",[1027,5782,5358],{"class":1626},[4598,5784,5786],{"id":5785},"drop-truncate","DROP & TRUNCATE",[127,5788,5790],{"className":4617,"code":5789,"language":4619,"meta":135,"style":135},"-- Deletes the entire table structure AND all data (irreversible)\nDROP TABLE products;\n\n-- Deletes ALL data inside the table, but keeps the structure\nTRUNCATE TABLE products;\n",[15,5791,5792,5797,5806,5810,5815],{"__ignoreMap":135},[1027,5793,5794],{"class":1029,"line":1030},[1027,5795,5796],{"class":1033},"-- Deletes the entire table structure AND all data (irreversible)\n",[1027,5798,5799,5801,5803],{"class":1029,"line":1037},[1027,5800,5441],{"class":1083},[1027,5802,4634],{"class":1083},[1027,5804,5805],{"class":1626}," products;\n",[1027,5807,5808],{"class":1029,"line":1048},[1027,5809,1064],{"emptyLinePlaceholder":1063},[1027,5811,5812],{"class":1029,"line":1054},[1027,5813,5814],{"class":1033},"-- Deletes ALL data inside the table, but keeps the structure\n",[1027,5816,5817,5819,5821],{"class":1029,"line":1060},[1027,5818,5444],{"class":1083},[1027,5820,4634],{"class":1083},[1027,5822,5805],{"class":1626},[56,5824,5825],{},[11,5826,5827,5830,5831,1759,5833,5835],{},[20,5828,5829],{},"Warning:"," ",[15,5832,5441],{},[15,5834,5444],{}," are dangerous. Always double-check before\nrunning them, especially in production.",[232,5837,5839],{"id":5838},"_32-dml-manipulating-data","3.2 DML — Manipulating Data",[4598,5841,5462],{"id":5842},"insert",[127,5844,5846],{"className":4617,"code":5845,"language":4619,"meta":135,"style":135},"-- Insert one row\nINSERT INTO products (name, price, stock_count)\nVALUES ('Mechanical Keyboard', 3499.00, 50);\n\n-- Insert multiple rows at once\nINSERT INTO products (name, price, stock_count) VALUES\n    ('Wireless Mouse', 999.00, 120),\n    ('USB-C Hub', 1499.00, 75),\n    ('Laptop Stand', 2199.00, 30);\n",[15,5847,5848,5853,5866,5894,5898,5903,5917,5941,5964],{"__ignoreMap":135},[1027,5849,5850],{"class":1029,"line":1030},[1027,5851,5852],{"class":1033},"-- Insert one row\n",[1027,5854,5855,5858,5861,5863],{"class":1029,"line":1037},[1027,5856,5857],{"class":1083},"INSERT INTO",[1027,5859,5860],{"class":1626}," products (",[1027,5862,5724],{"class":1083},[1027,5864,5865],{"class":1626},", price, stock_count)\n",[1027,5867,5868,5871,5874,5877,5879,5882,5884,5887,5889,5892],{"class":1029,"line":1048},[1027,5869,5870],{"class":1083},"VALUES",[1027,5872,5873],{"class":1626}," (",[1027,5875,5876],{"class":1044},"'Mechanical Keyboard'",[1027,5878,160],{"class":1626},[1027,5880,5881],{"class":1079},"3499",[1027,5883,148],{"class":1626},[1027,5885,5886],{"class":1079},"00",[1027,5888,160],{"class":1626},[1027,5890,5891],{"class":1079},"50",[1027,5893,4684],{"class":1626},[1027,5895,5896],{"class":1029,"line":1054},[1027,5897,1064],{"emptyLinePlaceholder":1063},[1027,5899,5900],{"class":1029,"line":1060},[1027,5901,5902],{"class":1033},"-- Insert multiple rows at once\n",[1027,5904,5905,5907,5909,5911,5914],{"class":1029,"line":1067},[1027,5906,5857],{"class":1083},[1027,5908,5860],{"class":1626},[1027,5910,5724],{"class":1083},[1027,5912,5913],{"class":1626},", price, stock_count) ",[1027,5915,5916],{"class":1083},"VALUES\n",[1027,5918,5919,5922,5925,5927,5930,5932,5934,5936,5939],{"class":1029,"line":1073},[1027,5920,5921],{"class":1626},"    (",[1027,5923,5924],{"class":1044},"'Wireless Mouse'",[1027,5926,160],{"class":1626},[1027,5928,5929],{"class":1079},"999",[1027,5931,148],{"class":1626},[1027,5933,5886],{"class":1079},[1027,5935,160],{"class":1626},[1027,5937,5938],{"class":1079},"120",[1027,5940,4671],{"class":1626},[1027,5942,5943,5945,5948,5950,5953,5955,5957,5959,5962],{"class":1029,"line":1093},[1027,5944,5921],{"class":1626},[1027,5946,5947],{"class":1044},"'USB-C Hub'",[1027,5949,160],{"class":1626},[1027,5951,5952],{"class":1079},"1499",[1027,5954,148],{"class":1626},[1027,5956,5886],{"class":1079},[1027,5958,160],{"class":1626},[1027,5960,5961],{"class":1079},"75",[1027,5963,4671],{"class":1626},[1027,5965,5966,5968,5971,5973,5976,5978,5980,5982,5985],{"class":1029,"line":1098},[1027,5967,5921],{"class":1626},[1027,5969,5970],{"class":1044},"'Laptop Stand'",[1027,5972,160],{"class":1626},[1027,5974,5975],{"class":1079},"2199",[1027,5977,148],{"class":1626},[1027,5979,5886],{"class":1079},[1027,5981,160],{"class":1626},[1027,5983,5984],{"class":1079},"30",[1027,5986,4684],{"class":1626},[4598,5988,5465],{"id":5989},"update",[127,5991,5993],{"className":4617,"code":5992,"language":4619,"meta":135,"style":135},"-- ALWAYS use WHERE with UPDATE, or you'll update every single row!\nUPDATE products\nSET price = 3199.00, stock_count = 45\nWHERE product_id = 1;\n\n-- Increase all prices by 10%\nUPDATE products\nSET price = price * 1.10;\n",[15,5994,5995,6000,6007,6032,6046,6050,6055,6061],{"__ignoreMap":135},[1027,5996,5997],{"class":1029,"line":1030},[1027,5998,5999],{"class":1033},"-- ALWAYS use WHERE with UPDATE, or you'll update every single row!\n",[1027,6001,6002,6004],{"class":1029,"line":1037},[1027,6003,5465],{"class":1083},[1027,6005,6006],{"class":1626}," products\n",[1027,6008,6009,6012,6015,6017,6020,6022,6024,6027,6029],{"class":1029,"line":1048},[1027,6010,6011],{"class":1083},"SET",[1027,6013,6014],{"class":1626}," price ",[1027,6016,5274],{"class":1083},[1027,6018,6019],{"class":1079}," 3199",[1027,6021,148],{"class":1626},[1027,6023,5886],{"class":1079},[1027,6025,6026],{"class":1626},", stock_count ",[1027,6028,5274],{"class":1083},[1027,6030,6031],{"class":1079}," 45\n",[1027,6033,6034,6036,6039,6041,6044],{"class":1029,"line":1054},[1027,6035,5348],{"class":1083},[1027,6037,6038],{"class":1626}," product_id ",[1027,6040,5274],{"class":1083},[1027,6042,6043],{"class":1079}," 1",[1027,6045,5358],{"class":1626},[1027,6047,6048],{"class":1029,"line":1060},[1027,6049,1064],{"emptyLinePlaceholder":1063},[1027,6051,6052],{"class":1029,"line":1067},[1027,6053,6054],{"class":1033},"-- Increase all prices by 10%\n",[1027,6056,6057,6059],{"class":1029,"line":1073},[1027,6058,5465],{"class":1083},[1027,6060,6006],{"class":1626},[1027,6062,6063,6065,6067,6069,6071,6074,6076,6078,6080],{"class":1029,"line":1093},[1027,6064,6011],{"class":1083},[1027,6066,6014],{"class":1626},[1027,6068,5274],{"class":1083},[1027,6070,6014],{"class":1626},[1027,6072,6073],{"class":1083},"*",[1027,6075,6043],{"class":1079},[1027,6077,148],{"class":1626},[1027,6079,5613],{"class":1079},[1027,6081,5358],{"class":1626},[4598,6083,5468],{"id":6084},"delete",[127,6086,6088],{"className":4617,"code":6087,"language":4619,"meta":135,"style":135},"-- Delete a specific row\nDELETE FROM products WHERE product_id = 3;\n\n-- Delete all products that are out of stock\nDELETE FROM products WHERE stock_count = 0;\n",[15,6089,6090,6095,6114,6118,6123],{"__ignoreMap":135},[1027,6091,6092],{"class":1029,"line":1030},[1027,6093,6094],{"class":1033},"-- Delete a specific row\n",[1027,6096,6097,6099,6101,6103,6105,6107,6109,6112],{"class":1029,"line":1037},[1027,6098,5468],{"class":1083},[1027,6100,5342],{"class":1083},[1027,6102,5684],{"class":1626},[1027,6104,5348],{"class":1083},[1027,6106,6038],{"class":1626},[1027,6108,5274],{"class":1083},[1027,6110,6111],{"class":1079}," 3",[1027,6113,5358],{"class":1626},[1027,6115,6116],{"class":1029,"line":1048},[1027,6117,1064],{"emptyLinePlaceholder":1063},[1027,6119,6120],{"class":1029,"line":1054},[1027,6121,6122],{"class":1033},"-- Delete all products that are out of stock\n",[1027,6124,6125,6127,6129,6131,6133,6136,6138,6140],{"class":1029,"line":1060},[1027,6126,5468],{"class":1083},[1027,6128,5342],{"class":1083},[1027,6130,5684],{"class":1626},[1027,6132,5348],{"class":1083},[1027,6134,6135],{"class":1626}," stock_count ",[1027,6137,5274],{"class":1083},[1027,6139,5277],{"class":1079},[1027,6141,5358],{"class":1626},[56,6143,6144],{},[11,6145,6146,6149,6150,6152,6153,171,6155,6157,6158,6160,6161,6164],{},[20,6147,6148],{},"Golden Rule of DML:"," Always write your ",[15,6151,5348],{}," clause first in your head\nbefore writing ",[15,6154,5465],{},[15,6156,5468],{},". A missing ",[15,6159,5348],{}," clause affects\n",[4263,6162,6163],{},"every row"," in the table.",[232,6166,6168],{"id":6167},"_33-dql-querying-data","3.3 DQL — Querying Data",[11,6170,6171,6173,6174,6177],{},[15,6172,5336],{}," is the most important and most used SQL command. Knowing ",[20,6175,6176],{},"how to\nwrite SQL queries step by step"," starts here.",[127,6179,6181],{"className":4617,"code":6180,"language":4619,"meta":135,"style":135},"-- Basic syntax\nSELECT column1, column2, ...\nFROM   table_name\nWHERE  condition\nORDER BY column ASC|DESC\nLIMIT  n;\n\n-- Select all columns (use sparingly in production)\nSELECT * FROM products;\n\n-- Select specific columns with an alias\nSELECT\n    name        AS product_name,\n    price       AS selling_price,\n    stock_count AS qty_available\nFROM products;\n",[15,6182,6183,6188,6195,6203,6210,6227,6235,6239,6244,6254,6258,6263,6268,6278,6289,6299],{"__ignoreMap":135},[1027,6184,6185],{"class":1029,"line":1030},[1027,6186,6187],{"class":1033},"-- Basic syntax\n",[1027,6189,6190,6192],{"class":1029,"line":1037},[1027,6191,5336],{"class":1083},[1027,6193,6194],{"class":1626}," column1, column2, ...\n",[1027,6196,6197,6200],{"class":1029,"line":1048},[1027,6198,6199],{"class":1083},"FROM",[1027,6201,6202],{"class":1626},"   table_name\n",[1027,6204,6205,6207],{"class":1029,"line":1054},[1027,6206,5348],{"class":1083},[1027,6208,6209],{"class":1626},"  condition\n",[1027,6211,6212,6215,6218,6221,6224],{"class":1029,"line":1060},[1027,6213,6214],{"class":1083},"ORDER BY",[1027,6216,6217],{"class":1626}," column ",[1027,6219,6220],{"class":1083},"ASC",[1027,6222,6223],{"class":1626},"|",[1027,6225,6226],{"class":1083},"DESC\n",[1027,6228,6229,6232],{"class":1029,"line":1067},[1027,6230,6231],{"class":1083},"LIMIT",[1027,6233,6234],{"class":1626},"  n;\n",[1027,6236,6237],{"class":1029,"line":1073},[1027,6238,1064],{"emptyLinePlaceholder":1063},[1027,6240,6241],{"class":1029,"line":1093},[1027,6242,6243],{"class":1033},"-- Select all columns (use sparingly in production)\n",[1027,6245,6246,6248,6250,6252],{"class":1029,"line":1098},[1027,6247,5336],{"class":1083},[1027,6249,5339],{"class":1083},[1027,6251,5342],{"class":1083},[1027,6253,5805],{"class":1626},[1027,6255,6256],{"class":1029,"line":1104},[1027,6257,1064],{"emptyLinePlaceholder":1063},[1027,6259,6260],{"class":1029,"line":1231},[1027,6261,6262],{"class":1033},"-- Select specific columns with an alias\n",[1027,6264,6265],{"class":1029,"line":1241},[1027,6266,6267],{"class":1083},"SELECT\n",[1027,6269,6270,6272,6275],{"class":1029,"line":1246},[1027,6271,4659],{"class":1083},[1027,6273,6274],{"class":1083},"        AS",[1027,6276,6277],{"class":1626}," product_name,\n",[1027,6279,6280,6283,6286],{"class":1029,"line":1252},[1027,6281,6282],{"class":1626},"    price       ",[1027,6284,6285],{"class":1083},"AS",[1027,6287,6288],{"class":1626}," selling_price,\n",[1027,6290,6291,6294,6296],{"class":1029,"line":1262},[1027,6292,6293],{"class":1626},"    stock_count ",[1027,6295,6285],{"class":1083},[1027,6297,6298],{"class":1626}," qty_available\n",[1027,6300,6301,6303],{"class":1029,"line":1267},[1027,6302,6199],{"class":1083},[1027,6304,5805],{"class":1626},[232,6306,6308],{"id":6307},"_34-dcl-tcl-control-transactions","3.4 DCL & TCL — Control & Transactions",[127,6310,6312],{"className":4617,"code":6311,"language":4619,"meta":135,"style":135},"-- DCL: Grant read access to a user\nGRANT SELECT ON products TO 'readonly_user';\n\n-- TCL: Transaction block\nBEGIN;\n    UPDATE accounts SET balance = balance - 500 WHERE id = 1;\n    UPDATE accounts SET balance = balance + 500 WHERE id = 2;\nCOMMIT;  -- Make it permanent\n\n-- If something goes wrong, undo everything\nROLLBACK;\n",[15,6313,6314,6319,6338,6342,6347,6354,6389,6419,6429,6433,6438],{"__ignoreMap":135},[1027,6315,6316],{"class":1029,"line":1030},[1027,6317,6318],{"class":1033},"-- DCL: Grant read access to a user\n",[1027,6320,6321,6323,6326,6329,6331,6333,6336],{"class":1029,"line":1037},[1027,6322,5503],{"class":1083},[1027,6324,6325],{"class":1083}," SELECT",[1027,6327,6328],{"class":1083}," ON",[1027,6330,5684],{"class":1626},[1027,6332,5753],{"class":1083},[1027,6334,6335],{"class":1044}," 'readonly_user'",[1027,6337,5358],{"class":1626},[1027,6339,6340],{"class":1029,"line":1048},[1027,6341,1064],{"emptyLinePlaceholder":1063},[1027,6343,6344],{"class":1029,"line":1054},[1027,6345,6346],{"class":1033},"-- TCL: Transaction block\n",[1027,6348,6349,6352],{"class":1029,"line":1060},[1027,6350,6351],{"class":1083},"BEGIN",[1027,6353,5358],{"class":1626},[1027,6355,6356,6359,6362,6364,6367,6369,6371,6374,6377,6380,6383,6385,6387],{"class":1029,"line":1067},[1027,6357,6358],{"class":1083},"    UPDATE",[1027,6360,6361],{"class":1626}," accounts ",[1027,6363,6011],{"class":1083},[1027,6365,6366],{"class":1626}," balance ",[1027,6368,5274],{"class":1083},[1027,6370,6366],{"class":1626},[1027,6372,6373],{"class":1083},"-",[1027,6375,6376],{"class":1079}," 500",[1027,6378,6379],{"class":1083}," WHERE",[1027,6381,6382],{"class":1626}," id ",[1027,6384,5274],{"class":1083},[1027,6386,6043],{"class":1079},[1027,6388,5358],{"class":1626},[1027,6390,6391,6393,6395,6397,6399,6401,6403,6406,6408,6410,6412,6414,6417],{"class":1029,"line":1073},[1027,6392,6358],{"class":1083},[1027,6394,6361],{"class":1626},[1027,6396,6011],{"class":1083},[1027,6398,6366],{"class":1626},[1027,6400,5274],{"class":1083},[1027,6402,6366],{"class":1626},[1027,6404,6405],{"class":1083},"+",[1027,6407,6376],{"class":1079},[1027,6409,6379],{"class":1083},[1027,6411,6382],{"class":1626},[1027,6413,5274],{"class":1083},[1027,6415,6416],{"class":1079}," 2",[1027,6418,5358],{"class":1626},[1027,6420,6421,6423,6426],{"class":1029,"line":1093},[1027,6422,5524],{"class":1083},[1027,6424,6425],{"class":1626},";  ",[1027,6427,6428],{"class":1033},"-- Make it permanent\n",[1027,6430,6431],{"class":1029,"line":1098},[1027,6432,1064],{"emptyLinePlaceholder":1063},[1027,6434,6435],{"class":1029,"line":1104},[1027,6436,6437],{"class":1033},"-- If something goes wrong, undo everything\n",[1027,6439,6440,6442],{"class":1029,"line":1231},[1027,6441,5527],{"class":1083},[1027,6443,5358],{"class":1626},[4355,6445],{},[28,6447,6449],{"id":6448},"_4-querying-in-depth","4. Querying in Depth",[232,6451,6453],{"id":6452},"_41-filtering-with-where","4.1 Filtering with WHERE",[11,6455,1125,6456,6459],{},[20,6457,6458],{},"SQL WHERE clause"," filters which rows are returned. It's one of the most\nfrequently used tools when writing SQL queries.",[127,6461,6463],{"className":4617,"code":6462,"language":4619,"meta":135,"style":135},"-- Comparison operators\nSELECT * FROM products WHERE price > 1000;\nSELECT * FROM products WHERE stock_count = 0;\nSELECT * FROM products WHERE name != 'USB-C Hub';\n\n-- Range\nSELECT * FROM products WHERE price BETWEEN 500 AND 2000;\n\n-- Pattern matching (% = any sequence of chars, _ = exactly one char)\nSELECT * FROM products WHERE name LIKE 'Wire%';    -- starts with \"Wire\"\nSELECT * FROM products WHERE name LIKE '%Mouse%';  -- contains \"Mouse\"\nSELECT * FROM products WHERE name LIKE 'M____';    -- \"M\" + exactly 4 chars\n\n-- Match against a list\nSELECT * FROM products WHERE category IN ('Electronics', 'Accessories');\n\n-- NULL check\nSELECT * FROM products WHERE category IS NULL;\n\n-- Combining conditions\nSELECT * FROM products\nWHERE price \u003C 2000 AND stock_count > 10;\n\nSELECT * FROM products\nWHERE category = 'Electronics' OR price \u003C 500;\n\n-- NOT operator\nSELECT * FROM products WHERE NOT (price > 3000);\n",[15,6464,6465,6470,6492,6512,6535,6539,6544,6571,6575,6580,6606,6630,6654,6658,6663,6693,6697,6702,6722,6726,6731,6742,6765,6770,6781,6804,6809,6815],{"__ignoreMap":135},[1027,6466,6467],{"class":1029,"line":1030},[1027,6468,6469],{"class":1033},"-- Comparison operators\n",[1027,6471,6472,6474,6476,6478,6480,6482,6484,6487,6490],{"class":1029,"line":1037},[1027,6473,5336],{"class":1083},[1027,6475,5339],{"class":1083},[1027,6477,5342],{"class":1083},[1027,6479,5684],{"class":1626},[1027,6481,5348],{"class":1083},[1027,6483,6014],{"class":1626},[1027,6485,6486],{"class":1083},">",[1027,6488,6489],{"class":1079}," 1000",[1027,6491,5358],{"class":1626},[1027,6493,6494,6496,6498,6500,6502,6504,6506,6508,6510],{"class":1029,"line":1048},[1027,6495,5336],{"class":1083},[1027,6497,5339],{"class":1083},[1027,6499,5342],{"class":1083},[1027,6501,5684],{"class":1626},[1027,6503,5348],{"class":1083},[1027,6505,6135],{"class":1626},[1027,6507,5274],{"class":1083},[1027,6509,5277],{"class":1079},[1027,6511,5358],{"class":1626},[1027,6513,6514,6516,6518,6520,6522,6524,6527,6530,6533],{"class":1029,"line":1054},[1027,6515,5336],{"class":1083},[1027,6517,5339],{"class":1083},[1027,6519,5342],{"class":1083},[1027,6521,5684],{"class":1626},[1027,6523,5348],{"class":1083},[1027,6525,6526],{"class":1083}," name",[1027,6528,6529],{"class":1083}," !=",[1027,6531,6532],{"class":1044}," 'USB-C Hub'",[1027,6534,5358],{"class":1626},[1027,6536,6537],{"class":1029,"line":1060},[1027,6538,1064],{"emptyLinePlaceholder":1063},[1027,6540,6541],{"class":1029,"line":1067},[1027,6542,6543],{"class":1033},"-- Range\n",[1027,6545,6546,6548,6550,6552,6554,6556,6558,6561,6563,6566,6569],{"class":1029,"line":1073},[1027,6547,5336],{"class":1083},[1027,6549,5339],{"class":1083},[1027,6551,5342],{"class":1083},[1027,6553,5684],{"class":1626},[1027,6555,5348],{"class":1083},[1027,6557,6014],{"class":1626},[1027,6559,6560],{"class":1083},"BETWEEN",[1027,6562,6376],{"class":1079},[1027,6564,6565],{"class":1083}," AND",[1027,6567,6568],{"class":1079}," 2000",[1027,6570,5358],{"class":1626},[1027,6572,6573],{"class":1029,"line":1093},[1027,6574,1064],{"emptyLinePlaceholder":1063},[1027,6576,6577],{"class":1029,"line":1098},[1027,6578,6579],{"class":1033},"-- Pattern matching (% = any sequence of chars, _ = exactly one char)\n",[1027,6581,6582,6584,6586,6588,6590,6592,6594,6597,6600,6603],{"class":1029,"line":1104},[1027,6583,5336],{"class":1083},[1027,6585,5339],{"class":1083},[1027,6587,5342],{"class":1083},[1027,6589,5684],{"class":1626},[1027,6591,5348],{"class":1083},[1027,6593,6526],{"class":1083},[1027,6595,6596],{"class":1083}," LIKE",[1027,6598,6599],{"class":1044}," 'Wire%'",[1027,6601,6602],{"class":1626},";    ",[1027,6604,6605],{"class":1033},"-- starts with \"Wire\"\n",[1027,6607,6608,6610,6612,6614,6616,6618,6620,6622,6625,6627],{"class":1029,"line":1231},[1027,6609,5336],{"class":1083},[1027,6611,5339],{"class":1083},[1027,6613,5342],{"class":1083},[1027,6615,5684],{"class":1626},[1027,6617,5348],{"class":1083},[1027,6619,6526],{"class":1083},[1027,6621,6596],{"class":1083},[1027,6623,6624],{"class":1044}," '%Mouse%'",[1027,6626,6425],{"class":1626},[1027,6628,6629],{"class":1033},"-- contains \"Mouse\"\n",[1027,6631,6632,6634,6636,6638,6640,6642,6644,6646,6649,6651],{"class":1029,"line":1241},[1027,6633,5336],{"class":1083},[1027,6635,5339],{"class":1083},[1027,6637,5342],{"class":1083},[1027,6639,5684],{"class":1626},[1027,6641,5348],{"class":1083},[1027,6643,6526],{"class":1083},[1027,6645,6596],{"class":1083},[1027,6647,6648],{"class":1044}," 'M____'",[1027,6650,6602],{"class":1626},[1027,6652,6653],{"class":1033},"-- \"M\" + exactly 4 chars\n",[1027,6655,6656],{"class":1029,"line":1246},[1027,6657,1064],{"emptyLinePlaceholder":1063},[1027,6659,6660],{"class":1029,"line":1252},[1027,6661,6662],{"class":1033},"-- Match against a list\n",[1027,6664,6665,6667,6669,6671,6673,6675,6678,6681,6683,6686,6688,6691],{"class":1029,"line":1262},[1027,6666,5336],{"class":1083},[1027,6668,5339],{"class":1083},[1027,6670,5342],{"class":1083},[1027,6672,5684],{"class":1626},[1027,6674,5348],{"class":1083},[1027,6676,6677],{"class":1626}," category ",[1027,6679,6680],{"class":1083},"IN",[1027,6682,5873],{"class":1626},[1027,6684,6685],{"class":1044},"'Electronics'",[1027,6687,160],{"class":1626},[1027,6689,6690],{"class":1044},"'Accessories'",[1027,6692,4684],{"class":1626},[1027,6694,6695],{"class":1029,"line":1267},[1027,6696,1064],{"emptyLinePlaceholder":1063},[1027,6698,6699],{"class":1029,"line":1273},[1027,6700,6701],{"class":1033},"-- NULL check\n",[1027,6703,6704,6706,6708,6710,6712,6714,6716,6718,6720],{"class":1029,"line":1283},[1027,6705,5336],{"class":1083},[1027,6707,5339],{"class":1083},[1027,6709,5342],{"class":1083},[1027,6711,5684],{"class":1626},[1027,6713,5348],{"class":1083},[1027,6715,6677],{"class":1626},[1027,6717,5384],{"class":1083},[1027,6719,5301],{"class":1083},[1027,6721,5358],{"class":1626},[1027,6723,6724],{"class":1029,"line":1288},[1027,6725,1064],{"emptyLinePlaceholder":1063},[1027,6727,6728],{"class":1029,"line":1294},[1027,6729,6730],{"class":1033},"-- Combining conditions\n",[1027,6732,6734,6736,6738,6740],{"class":1029,"line":6733},21,[1027,6735,5336],{"class":1083},[1027,6737,5339],{"class":1083},[1027,6739,5342],{"class":1083},[1027,6741,6006],{"class":1626},[1027,6743,6745,6747,6749,6752,6754,6756,6758,6760,6763],{"class":1029,"line":6744},22,[1027,6746,5348],{"class":1083},[1027,6748,6014],{"class":1626},[1027,6750,6751],{"class":1083},"\u003C",[1027,6753,6568],{"class":1079},[1027,6755,6565],{"class":1083},[1027,6757,6135],{"class":1626},[1027,6759,6486],{"class":1083},[1027,6761,6762],{"class":1079}," 10",[1027,6764,5358],{"class":1626},[1027,6766,6768],{"class":1029,"line":6767},23,[1027,6769,1064],{"emptyLinePlaceholder":1063},[1027,6771,6773,6775,6777,6779],{"class":1029,"line":6772},24,[1027,6774,5336],{"class":1083},[1027,6776,5339],{"class":1083},[1027,6778,5342],{"class":1083},[1027,6780,6006],{"class":1626},[1027,6782,6784,6786,6788,6790,6793,6796,6798,6800,6802],{"class":1029,"line":6783},25,[1027,6785,5348],{"class":1083},[1027,6787,6677],{"class":1626},[1027,6789,5274],{"class":1083},[1027,6791,6792],{"class":1044}," 'Electronics'",[1027,6794,6795],{"class":1083}," OR",[1027,6797,6014],{"class":1626},[1027,6799,6751],{"class":1083},[1027,6801,6376],{"class":1079},[1027,6803,5358],{"class":1626},[1027,6805,6807],{"class":1029,"line":6806},26,[1027,6808,1064],{"emptyLinePlaceholder":1063},[1027,6810,6812],{"class":1029,"line":6811},27,[1027,6813,6814],{"class":1033},"-- NOT operator\n",[1027,6816,6818,6820,6822,6824,6826,6828,6831,6834,6836,6839],{"class":1029,"line":6817},28,[1027,6819,5336],{"class":1083},[1027,6821,5339],{"class":1083},[1027,6823,5342],{"class":1083},[1027,6825,5684],{"class":1626},[1027,6827,5348],{"class":1083},[1027,6829,6830],{"class":1083}," NOT",[1027,6832,6833],{"class":1626}," (price ",[1027,6835,6486],{"class":1083},[1027,6837,6838],{"class":1079}," 3000",[1027,6840,4684],{"class":1626},[232,6842,6844],{"id":6843},"_42-sorting-with-order-by","4.2 Sorting with ORDER BY",[127,6846,6848],{"className":4617,"code":6847,"language":4619,"meta":135,"style":135},"-- Ascending (default)\nSELECT * FROM products ORDER BY price ASC;\n\n-- Descending\nSELECT * FROM products ORDER BY price DESC;\n\n-- Sort by multiple columns\nSELECT * FROM products ORDER BY category ASC, price DESC;\n\n-- Limit results (great for pagination)\nSELECT * FROM products ORDER BY price DESC LIMIT 5;\n\n-- Pagination: skip the first 10 rows, get the next 10\nSELECT * FROM products ORDER BY product_id LIMIT 10 OFFSET 10;\n",[15,6849,6850,6855,6873,6877,6882,6901,6905,6910,6933,6937,6942,6966,6970,6975],{"__ignoreMap":135},[1027,6851,6852],{"class":1029,"line":1030},[1027,6853,6854],{"class":1033},"-- Ascending (default)\n",[1027,6856,6857,6859,6861,6863,6865,6867,6869,6871],{"class":1029,"line":1037},[1027,6858,5336],{"class":1083},[1027,6860,5339],{"class":1083},[1027,6862,5342],{"class":1083},[1027,6864,5684],{"class":1626},[1027,6866,6214],{"class":1083},[1027,6868,6014],{"class":1626},[1027,6870,6220],{"class":1083},[1027,6872,5358],{"class":1626},[1027,6874,6875],{"class":1029,"line":1048},[1027,6876,1064],{"emptyLinePlaceholder":1063},[1027,6878,6879],{"class":1029,"line":1054},[1027,6880,6881],{"class":1033},"-- Descending\n",[1027,6883,6884,6886,6888,6890,6892,6894,6896,6899],{"class":1029,"line":1060},[1027,6885,5336],{"class":1083},[1027,6887,5339],{"class":1083},[1027,6889,5342],{"class":1083},[1027,6891,5684],{"class":1626},[1027,6893,6214],{"class":1083},[1027,6895,6014],{"class":1626},[1027,6897,6898],{"class":1083},"DESC",[1027,6900,5358],{"class":1626},[1027,6902,6903],{"class":1029,"line":1067},[1027,6904,1064],{"emptyLinePlaceholder":1063},[1027,6906,6907],{"class":1029,"line":1073},[1027,6908,6909],{"class":1033},"-- Sort by multiple columns\n",[1027,6911,6912,6914,6916,6918,6920,6922,6924,6926,6929,6931],{"class":1029,"line":1093},[1027,6913,5336],{"class":1083},[1027,6915,5339],{"class":1083},[1027,6917,5342],{"class":1083},[1027,6919,5684],{"class":1626},[1027,6921,6214],{"class":1083},[1027,6923,6677],{"class":1626},[1027,6925,6220],{"class":1083},[1027,6927,6928],{"class":1626},", price ",[1027,6930,6898],{"class":1083},[1027,6932,5358],{"class":1626},[1027,6934,6935],{"class":1029,"line":1098},[1027,6936,1064],{"emptyLinePlaceholder":1063},[1027,6938,6939],{"class":1029,"line":1104},[1027,6940,6941],{"class":1033},"-- Limit results (great for pagination)\n",[1027,6943,6944,6946,6948,6950,6952,6954,6956,6958,6961,6964],{"class":1029,"line":1231},[1027,6945,5336],{"class":1083},[1027,6947,5339],{"class":1083},[1027,6949,5342],{"class":1083},[1027,6951,5684],{"class":1626},[1027,6953,6214],{"class":1083},[1027,6955,6014],{"class":1626},[1027,6957,6898],{"class":1083},[1027,6959,6960],{"class":1083}," LIMIT",[1027,6962,6963],{"class":1079}," 5",[1027,6965,5358],{"class":1626},[1027,6967,6968],{"class":1029,"line":1241},[1027,6969,1064],{"emptyLinePlaceholder":1063},[1027,6971,6972],{"class":1029,"line":1246},[1027,6973,6974],{"class":1033},"-- Pagination: skip the first 10 rows, get the next 10\n",[1027,6976,6977,6979,6981,6983,6985,6987,6989,6991,6993,6996,6998],{"class":1029,"line":1252},[1027,6978,5336],{"class":1083},[1027,6980,5339],{"class":1083},[1027,6982,5342],{"class":1083},[1027,6984,5684],{"class":1626},[1027,6986,6214],{"class":1083},[1027,6988,6038],{"class":1626},[1027,6990,6231],{"class":1083},[1027,6992,6762],{"class":1079},[1027,6994,6995],{"class":1626}," OFFSET ",[1027,6997,5613],{"class":1079},[1027,6999,5358],{"class":1626},[232,7001,7003],{"id":7002},"_43-aggregate-functions-group-by","4.3 Aggregate Functions & GROUP BY",[11,7005,7006,7009,7010,7013],{},[20,7007,7008],{},"SQL aggregate functions"," calculate a ",[4263,7011,7012],{},"single result"," from a set of rows.\nThey are essential for reporting, analytics, and summarizing structured data.",[450,7015,7016,7028],{},[453,7017,7018],{},[456,7019,7020,7023,7026],{},[459,7021,7022],{},"Function",[459,7024,7025],{},"Description",[459,7027,4809],{},[469,7029,7030,7048,7066,7084,7102],{},[456,7031,7032,7037,7040],{},[474,7033,7034],{},[15,7035,7036],{},"COUNT(*)",[474,7038,7039],{},"Number of rows",[474,7041,7042,7044,7045],{},[15,7043,7036],{}," → ",[15,7046,7047],{},"4",[456,7049,7050,7055,7058],{},[474,7051,7052],{},[15,7053,7054],{},"SUM(col)",[474,7056,7057],{},"Total of a numeric column",[474,7059,7060,7044,7063],{},[15,7061,7062],{},"SUM(price)",[15,7064,7065],{},"8196.00",[456,7067,7068,7073,7076],{},[474,7069,7070],{},[15,7071,7072],{},"AVG(col)",[474,7074,7075],{},"Average value",[474,7077,7078,7044,7081],{},[15,7079,7080],{},"AVG(price)",[15,7082,7083],{},"2049.00",[456,7085,7086,7091,7094],{},[474,7087,7088],{},[15,7089,7090],{},"MIN(col)",[474,7092,7093],{},"Smallest value",[474,7095,7096,7044,7099],{},[15,7097,7098],{},"MIN(price)",[15,7100,7101],{},"999.00",[456,7103,7104,7109,7112],{},[474,7105,7106],{},[15,7107,7108],{},"MAX(col)",[474,7110,7111],{},"Largest value",[474,7113,7114,7044,7117],{},[15,7115,7116],{},"MAX(price)",[15,7118,7119],{},"3499.00",[127,7121,7123],{"className":4617,"code":7122,"language":4619,"meta":135,"style":135},"-- How many products do we have?\nSELECT COUNT(*) AS total_products FROM products;\n\n-- What is the average price?\nSELECT AVG(price) AS avg_price FROM products;\n\n-- Aggregation per group using GROUP BY\nSELECT\n    category,\n    COUNT(*)       AS num_products,\n    AVG(price)     AS avg_price,\n    SUM(stock_count) AS total_stock\nFROM products\nGROUP BY category;\n",[15,7124,7125,7130,7152,7156,7161,7180,7184,7189,7193,7198,7215,7228,7241,7247],{"__ignoreMap":135},[1027,7126,7127],{"class":1029,"line":1030},[1027,7128,7129],{"class":1033},"-- How many products do we have?\n",[1027,7131,7132,7134,7137,7139,7141,7143,7145,7148,7150],{"class":1029,"line":1037},[1027,7133,5336],{"class":1083},[1027,7135,7136],{"class":1079}," COUNT",[1027,7138,4665],{"class":1626},[1027,7140,6073],{"class":1083},[1027,7142,5585],{"class":1626},[1027,7144,6285],{"class":1083},[1027,7146,7147],{"class":1626}," total_products ",[1027,7149,6199],{"class":1083},[1027,7151,5805],{"class":1626},[1027,7153,7154],{"class":1029,"line":1048},[1027,7155,1064],{"emptyLinePlaceholder":1063},[1027,7157,7158],{"class":1029,"line":1054},[1027,7159,7160],{"class":1033},"-- What is the average price?\n",[1027,7162,7163,7165,7168,7171,7173,7176,7178],{"class":1029,"line":1060},[1027,7164,5336],{"class":1083},[1027,7166,7167],{"class":1079}," AVG",[1027,7169,7170],{"class":1626},"(price) ",[1027,7172,6285],{"class":1083},[1027,7174,7175],{"class":1626}," avg_price ",[1027,7177,6199],{"class":1083},[1027,7179,5805],{"class":1626},[1027,7181,7182],{"class":1029,"line":1067},[1027,7183,1064],{"emptyLinePlaceholder":1063},[1027,7185,7186],{"class":1029,"line":1073},[1027,7187,7188],{"class":1033},"-- Aggregation per group using GROUP BY\n",[1027,7190,7191],{"class":1029,"line":1093},[1027,7192,6267],{"class":1083},[1027,7194,7195],{"class":1029,"line":1098},[1027,7196,7197],{"class":1626},"    category,\n",[1027,7199,7200,7203,7205,7207,7210,7212],{"class":1029,"line":1104},[1027,7201,7202],{"class":1079},"    COUNT",[1027,7204,4665],{"class":1626},[1027,7206,6073],{"class":1083},[1027,7208,7209],{"class":1626},")       ",[1027,7211,6285],{"class":1083},[1027,7213,7214],{"class":1626}," num_products,\n",[1027,7216,7217,7220,7223,7225],{"class":1029,"line":1231},[1027,7218,7219],{"class":1079},"    AVG",[1027,7221,7222],{"class":1626},"(price)     ",[1027,7224,6285],{"class":1083},[1027,7226,7227],{"class":1626}," avg_price,\n",[1027,7229,7230,7233,7236,7238],{"class":1029,"line":1241},[1027,7231,7232],{"class":1079},"    SUM",[1027,7234,7235],{"class":1626},"(stock_count) ",[1027,7237,6285],{"class":1083},[1027,7239,7240],{"class":1626}," total_stock\n",[1027,7242,7243,7245],{"class":1029,"line":1246},[1027,7244,6199],{"class":1083},[1027,7246,6006],{"class":1626},[1027,7248,7249,7252],{"class":1029,"line":1252},[1027,7250,7251],{"class":1083},"GROUP BY",[1027,7253,7254],{"class":1626}," category;\n",[11,7256,7257],{},[20,7258,7259],{},"Output:",[127,7261,7264],{"className":7262,"code":7263,"language":132},[130],"category      | num_products | avg_price | total_stock\n--------------+--------------+-----------+-------------\nElectronics   |      3       |  2332.33  |     275\nAccessories   |      1       |   999.00  |     120\n",[15,7265,7263],{"__ignoreMap":135},[4598,7267,7269],{"id":7268},"having-filtering-groups","HAVING — Filtering Groups",[11,7271,7272,7274,7275,7278,7279,7274,7282,7285,7286,7289],{},[15,7273,5348],{}," filters ",[4263,7276,7277],{},"rows"," before grouping. ",[15,7280,7281],{},"HAVING",[4263,7283,7284],{},"groups"," after\naggregation. Understanding ",[20,7287,7288],{},"SQL GROUP BY and HAVING explained with examples","\nis key to writing analytical queries.",[127,7291,7293],{"className":4617,"code":7292,"language":4619,"meta":135,"style":135},"-- Only show categories that have more than 2 products\nSELECT category, COUNT(*) AS num_products\nFROM products\nGROUP BY category\nHAVING COUNT(*) > 2;\n\n-- Categories where the average price exceeds ₹2000\nSELECT category, AVG(price) AS avg_price\nFROM products\nGROUP BY category\nHAVING AVG(price) > 2000;\n",[15,7294,7295,7300,7321,7327,7334,7352,7356,7361,7377,7383,7389],{"__ignoreMap":135},[1027,7296,7297],{"class":1029,"line":1030},[1027,7298,7299],{"class":1033},"-- Only show categories that have more than 2 products\n",[1027,7301,7302,7304,7307,7310,7312,7314,7316,7318],{"class":1029,"line":1037},[1027,7303,5336],{"class":1083},[1027,7305,7306],{"class":1626}," category, ",[1027,7308,7309],{"class":1079},"COUNT",[1027,7311,4665],{"class":1626},[1027,7313,6073],{"class":1083},[1027,7315,5585],{"class":1626},[1027,7317,6285],{"class":1083},[1027,7319,7320],{"class":1626}," num_products\n",[1027,7322,7323,7325],{"class":1029,"line":1048},[1027,7324,6199],{"class":1083},[1027,7326,6006],{"class":1626},[1027,7328,7329,7331],{"class":1029,"line":1054},[1027,7330,7251],{"class":1083},[1027,7332,7333],{"class":1626}," category\n",[1027,7335,7336,7338,7340,7342,7344,7346,7348,7350],{"class":1029,"line":1060},[1027,7337,7281],{"class":1083},[1027,7339,7136],{"class":1079},[1027,7341,4665],{"class":1626},[1027,7343,6073],{"class":1083},[1027,7345,5585],{"class":1626},[1027,7347,6486],{"class":1083},[1027,7349,6416],{"class":1079},[1027,7351,5358],{"class":1626},[1027,7353,7354],{"class":1029,"line":1067},[1027,7355,1064],{"emptyLinePlaceholder":1063},[1027,7357,7358],{"class":1029,"line":1073},[1027,7359,7360],{"class":1033},"-- Categories where the average price exceeds ₹2000\n",[1027,7362,7363,7365,7367,7370,7372,7374],{"class":1029,"line":1093},[1027,7364,5336],{"class":1083},[1027,7366,7306],{"class":1626},[1027,7368,7369],{"class":1079},"AVG",[1027,7371,7170],{"class":1626},[1027,7373,6285],{"class":1083},[1027,7375,7376],{"class":1626}," avg_price\n",[1027,7378,7379,7381],{"class":1029,"line":1098},[1027,7380,6199],{"class":1083},[1027,7382,6006],{"class":1626},[1027,7384,7385,7387],{"class":1029,"line":1104},[1027,7386,7251],{"class":1083},[1027,7388,7333],{"class":1626},[1027,7390,7391,7393,7395,7397,7399,7401],{"class":1029,"line":1231},[1027,7392,7281],{"class":1083},[1027,7394,7167],{"class":1079},[1027,7396,7170],{"class":1626},[1027,7398,6486],{"class":1083},[1027,7400,6568],{"class":1079},[1027,7402,5358],{"class":1626},[56,7404,7405],{},[11,7406,7407,5830,7410,7412,7413,7415],{},[20,7408,7409],{},"Memory trick:",[15,7411,5348],{}," is for rows, ",[15,7414,7281],{}," is for groups.",[4598,7417,7419],{"id":7418},"the-logical-order-of-sql-clauses","The Logical Order of SQL Clauses",[11,7421,7422,7423,7426,7427,7430],{},"SQL clauses are ",[4263,7424,7425],{},"written"," in one order but ",[4263,7428,7429],{},"executed"," in another:",[127,7432,7435],{"className":7433,"code":7434,"language":132},[130],"Written Order:             Execution Order:\n1. SELECT                  1. FROM\n2. FROM                    2. WHERE\n3. WHERE                   3. GROUP BY\n4. GROUP BY                4. HAVING\n5. HAVING                  5. SELECT\n6. ORDER BY                6. ORDER BY\n7. LIMIT                   7. LIMIT\n",[15,7436,7434],{"__ignoreMap":135},[11,7438,7439,7440,7443,7444,7446,7447,7449],{},"Understanding execution order explains ",[4263,7441,7442],{},"why"," you can't use a ",[15,7445,5336],{}," alias\nin a ",[15,7448,5348],{}," clause — the alias hasn't been created yet at that point.",[232,7451,7453],{"id":7452},"_44-joins-combining-tables","4.4 JOINs — Combining Tables",[11,7455,7456,7459,7460,7463,7464,7467],{},[20,7457,7458],{},"SQL JOIN types explained"," — JOINs are the most powerful feature in SQL.\nThey let you query ",[4263,7461,7462],{},"multiple tables at once"," by linking them through their\nrelated keys. Knowing the ",[20,7465,7466],{},"difference between INNER JOIN and LEFT JOIN"," is one of the most practical skills in relational databases.",[11,7469,7470],{},"Let's use a concrete example:",[127,7472,7474],{"className":4617,"code":7473,"language":4619,"meta":135,"style":135},"-- Our tables:\n-- customers(id, name, email)\n-- orders(id, customer_id, total_amount, order_date, status)\n",[15,7475,7476,7481,7486],{"__ignoreMap":135},[1027,7477,7478],{"class":1029,"line":1030},[1027,7479,7480],{"class":1033},"-- Our tables:\n",[1027,7482,7483],{"class":1029,"line":1037},[1027,7484,7485],{"class":1033},"-- customers(id, name, email)\n",[1027,7487,7488],{"class":1029,"line":1048},[1027,7489,7490],{"class":1033},"-- orders(id, customer_id, total_amount, order_date, status)\n",[11,7492,7493],{},[123,7494],{"alt":7495,"src":7496},"SQL JOINs Venn Diagram","/post-images/sql-made-dead-simple-rdbms-guide/sql-joins-venn-diagram.png",[4598,7498,7500],{"id":7499},"inner-join","INNER JOIN",[11,7502,7503,7504,148],{},"Returns only the rows where there is a ",[20,7505,7506],{},"match in both tables",[127,7508,7510],{"className":4617,"code":7509,"language":4619,"meta":135,"style":135},"SELECT\n    c.name        AS customer_name,\n    o.id          AS order_id,\n    o.total_amount,\n    o.order_date\nFROM customers c\nINNER JOIN orders o ON c.id = o.customer_id;\n",[15,7511,7512,7516,7530,7546,7557,7566,7573],{"__ignoreMap":135},[1027,7513,7514],{"class":1029,"line":1030},[1027,7515,6267],{"class":1083},[1027,7517,7518,7521,7523,7525,7527],{"class":1029,"line":1037},[1027,7519,7520],{"class":1079},"    c",[1027,7522,148],{"class":1626},[1027,7524,5724],{"class":1079},[1027,7526,6274],{"class":1083},[1027,7528,7529],{"class":1626}," customer_name,\n",[1027,7531,7532,7535,7537,7540,7543],{"class":1029,"line":1048},[1027,7533,7534],{"class":1079},"    o",[1027,7536,148],{"class":1626},[1027,7538,7539],{"class":1079},"id",[1027,7541,7542],{"class":1083},"          AS",[1027,7544,7545],{"class":1626}," order_id,\n",[1027,7547,7548,7550,7552,7555],{"class":1029,"line":1054},[1027,7549,7534],{"class":1079},[1027,7551,148],{"class":1626},[1027,7553,7554],{"class":1079},"total_amount",[1027,7556,4654],{"class":1626},[1027,7558,7559,7561,7563],{"class":1029,"line":1060},[1027,7560,7534],{"class":1079},[1027,7562,148],{"class":1626},[1027,7564,7565],{"class":1079},"order_date\n",[1027,7567,7568,7570],{"class":1029,"line":1067},[1027,7569,6199],{"class":1083},[1027,7571,7572],{"class":1626}," customers c\n",[1027,7574,7575,7577,7580,7583,7586,7588,7590,7593,7596,7598,7601],{"class":1029,"line":1073},[1027,7576,7500],{"class":1083},[1027,7578,7579],{"class":1626}," orders o ",[1027,7581,7582],{"class":1083},"ON",[1027,7584,7585],{"class":1079}," c",[1027,7587,148],{"class":1626},[1027,7589,7539],{"class":1079},[1027,7591,7592],{"class":1083}," =",[1027,7594,7595],{"class":1079}," o",[1027,7597,148],{"class":1626},[1027,7599,7600],{"class":1079},"customer_id",[1027,7602,5358],{"class":1626},[56,7604,7605],{},[11,7606,7607,7608,7611],{},"Customers who have never placed an order will ",[20,7609,7610],{},"NOT"," appear here.",[4598,7613,7615],{"id":7614},"left-join-left-outer-join","LEFT JOIN (LEFT OUTER JOIN)",[11,7617,7618,7619,7622],{},"Returns ",[20,7620,7621],{},"all rows from the left table",", and matched rows from the right.\nIf there is no match, the right side columns return NULL.",[127,7624,7626],{"className":4617,"code":7625,"language":4619,"meta":135,"style":135},"-- All customers, even those with no orders\nSELECT\n    c.name        AS customer_name,\n    o.id          AS order_id,\n    o.total_amount\nFROM customers c\nLEFT JOIN orders o ON c.id = o.customer_id;\n",[15,7627,7628,7633,7637,7649,7661,7670,7676],{"__ignoreMap":135},[1027,7629,7630],{"class":1029,"line":1030},[1027,7631,7632],{"class":1033},"-- All customers, even those with no orders\n",[1027,7634,7635],{"class":1029,"line":1037},[1027,7636,6267],{"class":1083},[1027,7638,7639,7641,7643,7645,7647],{"class":1029,"line":1048},[1027,7640,7520],{"class":1079},[1027,7642,148],{"class":1626},[1027,7644,5724],{"class":1079},[1027,7646,6274],{"class":1083},[1027,7648,7529],{"class":1626},[1027,7650,7651,7653,7655,7657,7659],{"class":1029,"line":1054},[1027,7652,7534],{"class":1079},[1027,7654,148],{"class":1626},[1027,7656,7539],{"class":1079},[1027,7658,7542],{"class":1083},[1027,7660,7545],{"class":1626},[1027,7662,7663,7665,7667],{"class":1029,"line":1060},[1027,7664,7534],{"class":1079},[1027,7666,148],{"class":1626},[1027,7668,7669],{"class":1079},"total_amount\n",[1027,7671,7672,7674],{"class":1029,"line":1067},[1027,7673,6199],{"class":1083},[1027,7675,7572],{"class":1626},[1027,7677,7678,7681,7683,7685,7687,7689,7691,7693,7695,7697,7699],{"class":1029,"line":1073},[1027,7679,7680],{"class":1083},"LEFT JOIN",[1027,7682,7579],{"class":1626},[1027,7684,7582],{"class":1083},[1027,7686,7585],{"class":1079},[1027,7688,148],{"class":1626},[1027,7690,7539],{"class":1079},[1027,7692,7592],{"class":1083},[1027,7694,7595],{"class":1079},[1027,7696,148],{"class":1626},[1027,7698,7600],{"class":1079},[1027,7700,5358],{"class":1626},[56,7702,7703],{},[11,7704,7705,7706,148],{},"A customer with no orders will show up with ",[15,7707,7708],{},"order_id = NULL",[4598,7710,7712],{"id":7711},"right-join-right-outer-join","RIGHT JOIN (RIGHT OUTER JOIN)",[11,7714,7715],{},"The mirror of LEFT JOIN — all rows from the right table, matched rows from\nthe left. (Less common; usually rewritten as a LEFT JOIN for clarity.)",[4598,7717,7719],{"id":7718},"full-outer-join","FULL OUTER JOIN",[11,7721,7722,7723,7726],{},"Returns all rows from ",[20,7724,7725],{},"both"," tables. NULLs fill in where there is no match\non either side.",[127,7728,7730],{"className":4617,"code":7729,"language":4619,"meta":135,"style":135},"SELECT c.name, o.id AS order_id\nFROM customers c\nFULL OUTER JOIN orders o ON c.id = o.customer_id;\n",[15,7731,7732,7757,7763],{"__ignoreMap":135},[1027,7733,7734,7736,7738,7740,7742,7744,7747,7749,7751,7754],{"class":1029,"line":1030},[1027,7735,5336],{"class":1083},[1027,7737,7585],{"class":1079},[1027,7739,148],{"class":1626},[1027,7741,5724],{"class":1079},[1027,7743,160],{"class":1626},[1027,7745,7746],{"class":1079},"o",[1027,7748,148],{"class":1626},[1027,7750,7539],{"class":1079},[1027,7752,7753],{"class":1083}," AS",[1027,7755,7756],{"class":1626}," order_id\n",[1027,7758,7759,7761],{"class":1029,"line":1037},[1027,7760,6199],{"class":1083},[1027,7762,7572],{"class":1626},[1027,7764,7765,7767,7769,7771,7773,7775,7777,7779,7781,7783,7785],{"class":1029,"line":1048},[1027,7766,7719],{"class":1083},[1027,7768,7579],{"class":1626},[1027,7770,7582],{"class":1083},[1027,7772,7585],{"class":1079},[1027,7774,148],{"class":1626},[1027,7776,7539],{"class":1079},[1027,7778,7592],{"class":1083},[1027,7780,7595],{"class":1079},[1027,7782,148],{"class":1626},[1027,7784,7600],{"class":1079},[1027,7786,5358],{"class":1626},[4598,7788,7790],{"id":7789},"cross-join","CROSS JOIN",[11,7792,7793,7794,7797],{},"Returns the ",[20,7795,7796],{},"Cartesian product"," — every row in Table A combined with every\nrow in Table B. Use with extreme caution (1000 rows × 1000 rows = 1,000,000\nresult rows).",[127,7799,7801],{"className":4617,"code":7800,"language":4619,"meta":135,"style":135},"-- Every possible pairing of colors and sizes\nSELECT colors.name, sizes.label\nFROM colors\nCROSS JOIN sizes;\n",[15,7802,7803,7808,7829,7836],{"__ignoreMap":135},[1027,7804,7805],{"class":1029,"line":1030},[1027,7806,7807],{"class":1033},"-- Every possible pairing of colors and sizes\n",[1027,7809,7810,7812,7815,7817,7819,7821,7824,7826],{"class":1029,"line":1037},[1027,7811,5336],{"class":1083},[1027,7813,7814],{"class":1079}," colors",[1027,7816,148],{"class":1626},[1027,7818,5724],{"class":1079},[1027,7820,160],{"class":1626},[1027,7822,7823],{"class":1079},"sizes",[1027,7825,148],{"class":1626},[1027,7827,7828],{"class":1079},"label\n",[1027,7830,7831,7833],{"class":1029,"line":1048},[1027,7832,6199],{"class":1083},[1027,7834,7835],{"class":1626}," colors\n",[1027,7837,7838,7840],{"class":1029,"line":1054},[1027,7839,7790],{"class":1083},[1027,7841,7842],{"class":1626}," sizes;\n",[4598,7844,7846],{"id":7845},"join-with-multiple-tables","JOIN with Multiple Tables",[127,7848,7850],{"className":4617,"code":7849,"language":4619,"meta":135,"style":135},"SELECT\n    c.name          AS customer,\n    p.name          AS product,\n    oi.quantity,\n    oi.unit_price\nFROM customers c\nJOIN orders    o  ON c.id    = o.customer_id\nJOIN order_items oi ON o.id = oi.order_id\nJOIN products  p  ON p.id   = oi.product_id\nWHERE c.id = 5;\n",[15,7851,7852,7856,7869,7883,7895,7904,7910,7936,7961,7987],{"__ignoreMap":135},[1027,7853,7854],{"class":1029,"line":1030},[1027,7855,6267],{"class":1083},[1027,7857,7858,7860,7862,7864,7866],{"class":1029,"line":1037},[1027,7859,7520],{"class":1079},[1027,7861,148],{"class":1626},[1027,7863,5724],{"class":1079},[1027,7865,7542],{"class":1083},[1027,7867,7868],{"class":1626}," customer,\n",[1027,7870,7871,7874,7876,7878,7880],{"class":1029,"line":1048},[1027,7872,7873],{"class":1079},"    p",[1027,7875,148],{"class":1626},[1027,7877,5724],{"class":1079},[1027,7879,7542],{"class":1083},[1027,7881,7882],{"class":1626}," product,\n",[1027,7884,7885,7888,7890,7893],{"class":1029,"line":1054},[1027,7886,7887],{"class":1079},"    oi",[1027,7889,148],{"class":1626},[1027,7891,7892],{"class":1079},"quantity",[1027,7894,4654],{"class":1626},[1027,7896,7897,7899,7901],{"class":1029,"line":1060},[1027,7898,7887],{"class":1079},[1027,7900,148],{"class":1626},[1027,7902,7903],{"class":1079},"unit_price\n",[1027,7905,7906,7908],{"class":1029,"line":1067},[1027,7907,6199],{"class":1083},[1027,7909,7572],{"class":1626},[1027,7911,7912,7915,7918,7920,7922,7924,7926,7929,7931,7933],{"class":1029,"line":1073},[1027,7913,7914],{"class":1083},"JOIN",[1027,7916,7917],{"class":1626}," orders    o  ",[1027,7919,7582],{"class":1083},[1027,7921,7585],{"class":1079},[1027,7923,148],{"class":1626},[1027,7925,7539],{"class":1079},[1027,7927,7928],{"class":1083},"    =",[1027,7930,7595],{"class":1079},[1027,7932,148],{"class":1626},[1027,7934,7935],{"class":1079},"customer_id\n",[1027,7937,7938,7940,7943,7945,7947,7949,7951,7953,7956,7958],{"class":1029,"line":1093},[1027,7939,7914],{"class":1083},[1027,7941,7942],{"class":1626}," order_items oi ",[1027,7944,7582],{"class":1083},[1027,7946,7595],{"class":1079},[1027,7948,148],{"class":1626},[1027,7950,7539],{"class":1079},[1027,7952,7592],{"class":1083},[1027,7954,7955],{"class":1079}," oi",[1027,7957,148],{"class":1626},[1027,7959,7960],{"class":1079},"order_id\n",[1027,7962,7963,7965,7968,7970,7973,7975,7977,7980,7982,7984],{"class":1029,"line":1098},[1027,7964,7914],{"class":1083},[1027,7966,7967],{"class":1626}," products  p  ",[1027,7969,7582],{"class":1083},[1027,7971,7972],{"class":1079}," p",[1027,7974,148],{"class":1626},[1027,7976,7539],{"class":1079},[1027,7978,7979],{"class":1083},"   =",[1027,7981,7955],{"class":1079},[1027,7983,148],{"class":1626},[1027,7985,7986],{"class":1079},"product_id\n",[1027,7988,7989,7991,7993,7995,7997,7999,8001],{"class":1029,"line":1104},[1027,7990,5348],{"class":1083},[1027,7992,7585],{"class":1079},[1027,7994,148],{"class":1626},[1027,7996,7539],{"class":1079},[1027,7998,7592],{"class":1083},[1027,8000,6963],{"class":1079},[1027,8002,5358],{"class":1626},[232,8004,8006],{"id":8005},"_45-subqueries","4.5 Subqueries",[11,8008,4279,8009,8012],{},[20,8010,8011],{},"subquery"," is a query nested inside another query. The inner query runs\nfirst, and its result is used by the outer query.",[127,8014,8016],{"className":4617,"code":8015,"language":4619,"meta":135,"style":135},"-- Find all customers who have placed at least one order\nSELECT name FROM customers\nWHERE id IN (\n    SELECT DISTINCT customer_id FROM orders\n);\n\n-- Find products that cost more than the average price\nSELECT name, price FROM products\nWHERE price > (\n    SELECT AVG(price) FROM products\n);\n\n-- Subquery in FROM clause (derived table)\nSELECT category, avg_price\nFROM (\n    SELECT category, AVG(price) AS avg_price\n    FROM products\n    GROUP BY category\n) AS category_summary\nWHERE avg_price > 1500;\n",[15,8017,8018,8023,8034,8044,8057,8061,8065,8070,8082,8092,8105,8109,8113,8118,8125,8131,8145,8152,8159,8168],{"__ignoreMap":135},[1027,8019,8020],{"class":1029,"line":1030},[1027,8021,8022],{"class":1033},"-- Find all customers who have placed at least one order\n",[1027,8024,8025,8027,8029,8031],{"class":1029,"line":1037},[1027,8026,5336],{"class":1083},[1027,8028,6526],{"class":1083},[1027,8030,5342],{"class":1083},[1027,8032,8033],{"class":1626}," customers\n",[1027,8035,8036,8038,8040,8042],{"class":1029,"line":1048},[1027,8037,5348],{"class":1083},[1027,8039,6382],{"class":1626},[1027,8041,6680],{"class":1083},[1027,8043,4640],{"class":1626},[1027,8045,8046,8049,8052,8054],{"class":1029,"line":1054},[1027,8047,8048],{"class":1083},"    SELECT DISTINCT",[1027,8050,8051],{"class":1626}," customer_id ",[1027,8053,6199],{"class":1083},[1027,8055,8056],{"class":1626}," orders\n",[1027,8058,8059],{"class":1029,"line":1060},[1027,8060,4684],{"class":1626},[1027,8062,8063],{"class":1029,"line":1067},[1027,8064,1064],{"emptyLinePlaceholder":1063},[1027,8066,8067],{"class":1029,"line":1073},[1027,8068,8069],{"class":1033},"-- Find products that cost more than the average price\n",[1027,8071,8072,8074,8076,8078,8080],{"class":1029,"line":1093},[1027,8073,5336],{"class":1083},[1027,8075,6526],{"class":1083},[1027,8077,6928],{"class":1626},[1027,8079,6199],{"class":1083},[1027,8081,6006],{"class":1626},[1027,8083,8084,8086,8088,8090],{"class":1029,"line":1098},[1027,8085,5348],{"class":1083},[1027,8087,6014],{"class":1626},[1027,8089,6486],{"class":1083},[1027,8091,4640],{"class":1626},[1027,8093,8094,8097,8099,8101,8103],{"class":1029,"line":1104},[1027,8095,8096],{"class":1083},"    SELECT",[1027,8098,7167],{"class":1079},[1027,8100,7170],{"class":1626},[1027,8102,6199],{"class":1083},[1027,8104,6006],{"class":1626},[1027,8106,8107],{"class":1029,"line":1231},[1027,8108,4684],{"class":1626},[1027,8110,8111],{"class":1029,"line":1241},[1027,8112,1064],{"emptyLinePlaceholder":1063},[1027,8114,8115],{"class":1029,"line":1246},[1027,8116,8117],{"class":1033},"-- Subquery in FROM clause (derived table)\n",[1027,8119,8120,8122],{"class":1029,"line":1252},[1027,8121,5336],{"class":1083},[1027,8123,8124],{"class":1626}," category, avg_price\n",[1027,8126,8127,8129],{"class":1029,"line":1262},[1027,8128,6199],{"class":1083},[1027,8130,4640],{"class":1626},[1027,8132,8133,8135,8137,8139,8141,8143],{"class":1029,"line":1267},[1027,8134,8096],{"class":1083},[1027,8136,7306],{"class":1626},[1027,8138,7369],{"class":1079},[1027,8140,7170],{"class":1626},[1027,8142,6285],{"class":1083},[1027,8144,7376],{"class":1626},[1027,8146,8147,8150],{"class":1029,"line":1273},[1027,8148,8149],{"class":1083},"    FROM",[1027,8151,6006],{"class":1626},[1027,8153,8154,8157],{"class":1029,"line":1283},[1027,8155,8156],{"class":1083},"    GROUP BY",[1027,8158,7333],{"class":1626},[1027,8160,8161,8163,8165],{"class":1029,"line":1288},[1027,8162,5585],{"class":1626},[1027,8164,6285],{"class":1083},[1027,8166,8167],{"class":1626}," category_summary\n",[1027,8169,8170,8172,8174,8176,8179],{"class":1029,"line":1294},[1027,8171,5348],{"class":1083},[1027,8173,7175],{"class":1626},[1027,8175,6486],{"class":1083},[1027,8177,8178],{"class":1079}," 1500",[1027,8180,5358],{"class":1626},[4355,8182],{},[28,8184,8186],{"id":8185},"_5-constraints-enforcing-rules","5. Constraints — Enforcing Rules",[11,8188,8189,8192,8193,8196],{},[20,8190,8191],{},"SQL constraints"," are rules applied to columns that the database enforces\nautomatically. They are a core part of maintaining ",[20,8194,8195],{},"data integrity"," and\nprevent bad data from ever entering your database.",[450,8198,8199,8209],{},[453,8200,8201],{},[456,8202,8203,8206],{},[459,8204,8205],{},"Constraint",[459,8207,8208],{},"What It Does",[469,8210,8211,8221,8231,8240,8250,8260],{},[456,8212,8213,8218],{},[474,8214,8215],{},[15,8216,8217],{},"PRIMARY KEY",[474,8219,8220],{},"Unique + NOT NULL. Uniquely identifies each row.",[456,8222,8223,8228],{},[474,8224,8225],{},[15,8226,8227],{},"FOREIGN KEY",[474,8229,8230],{},"Value must exist in the referenced table.",[456,8232,8233,8237],{},[474,8234,8235],{},[15,8236,5588],{},[474,8238,8239],{},"Column cannot be empty.",[456,8241,8242,8247],{},[474,8243,8244],{},[15,8245,8246],{},"UNIQUE",[474,8248,8249],{},"All values in the column must be different.",[456,8251,8252,8257],{},[474,8253,8254],{},[15,8255,8256],{},"DEFAULT",[474,8258,8259],{},"Provides a default value if none is given.",[456,8261,8262,8267],{},[474,8263,8264],{},[15,8265,8266],{},"CHECK",[474,8268,8269],{},"Value must satisfy a custom boolean expression.",[127,8271,8273],{"className":4617,"code":8272,"language":4619,"meta":135,"style":135},"CREATE TABLE employees (\n    id         SERIAL PRIMARY KEY,\n    email      VARCHAR(255) NOT NULL UNIQUE,\n    name       VARCHAR(100) NOT NULL,\n    salary     DECIMAL(10,2) CHECK (salary > 0),\n    department VARCHAR(50) DEFAULT 'General',\n    manager_id INT REFERENCES employees(id)    -- Self-referencing FK\n);\n",[15,8274,8275,8286,8297,8318,8334,8363,8383,8398],{"__ignoreMap":135},[1027,8276,8277,8279,8281,8284],{"class":1029,"line":1030},[1027,8278,4631],{"class":1083},[1027,8280,4634],{"class":1083},[1027,8282,8283],{"class":1040}," employees",[1027,8285,4640],{"class":1626},[1027,8287,8288,8291,8293,8295],{"class":1029,"line":1037},[1027,8289,8290],{"class":1626},"    id         ",[1027,8292,5562],{"class":1083},[1027,8294,4651],{"class":1083},[1027,8296,4654],{"class":1626},[1027,8298,8299,8302,8304,8306,8309,8311,8313,8316],{"class":1029,"line":1048},[1027,8300,8301],{"class":1626},"    email      ",[1027,8303,5693],{"class":1083},[1027,8305,4665],{"class":1626},[1027,8307,8308],{"class":1079},"255",[1027,8310,5585],{"class":1626},[1027,8312,5588],{"class":1083},[1027,8314,8315],{"class":1083}," UNIQUE",[1027,8317,4654],{"class":1626},[1027,8319,8320,8322,8324,8326,8328,8330,8332],{"class":1029,"line":1054},[1027,8321,4659],{"class":1083},[1027,8323,4662],{"class":1083},[1027,8325,4665],{"class":1626},[1027,8327,4668],{"class":1079},[1027,8329,5585],{"class":1626},[1027,8331,5588],{"class":1083},[1027,8333,4654],{"class":1626},[1027,8335,8336,8339,8341,8343,8345,8348,8350,8352,8354,8357,8359,8361],{"class":1029,"line":1060},[1027,8337,8338],{"class":1626},"    salary     ",[1027,8340,5608],{"class":1083},[1027,8342,4665],{"class":1626},[1027,8344,5613],{"class":1079},[1027,8346,8347],{"class":1626},",",[1027,8349,5618],{"class":1079},[1027,8351,5585],{"class":1626},[1027,8353,8266],{"class":1083},[1027,8355,8356],{"class":1626}," (salary ",[1027,8358,6486],{"class":1083},[1027,8360,5277],{"class":1079},[1027,8362,4671],{"class":1626},[1027,8364,8365,8368,8370,8372,8374,8376,8378,8381],{"class":1029,"line":1067},[1027,8366,8367],{"class":1626},"    department ",[1027,8369,5693],{"class":1083},[1027,8371,4665],{"class":1626},[1027,8373,5891],{"class":1079},[1027,8375,5585],{"class":1626},[1027,8377,8256],{"class":1083},[1027,8379,8380],{"class":1044}," 'General'",[1027,8382,4654],{"class":1626},[1027,8384,8385,8388,8390,8392,8395],{"class":1029,"line":1073},[1027,8386,8387],{"class":1626},"    manager_id ",[1027,8389,4648],{"class":1083},[1027,8391,4743],{"class":1083},[1027,8393,8394],{"class":1626}," employees(id)    ",[1027,8396,8397],{"class":1033},"-- Self-referencing FK\n",[1027,8399,8400],{"class":1029,"line":1093},[1027,8401,4684],{"class":1626},[11,8403,8404],{},[20,8405,8406],{},"What happens when a constraint is violated?",[127,8408,8410],{"className":4617,"code":8409,"language":4619,"meta":135,"style":135},"-- This will FAIL with an error because email must be unique\nINSERT INTO employees (email, name, salary)\nVALUES ('dev@example.com', 'Rahul', 50000);\n\nINSERT INTO employees (email, name, salary)\nVALUES ('dev@example.com', 'Priya', 60000);  -- ERROR: duplicate key value\n",[15,8411,8412,8417,8429,8449,8453,8463],{"__ignoreMap":135},[1027,8413,8414],{"class":1029,"line":1030},[1027,8415,8416],{"class":1033},"-- This will FAIL with an error because email must be unique\n",[1027,8418,8419,8421,8424,8426],{"class":1029,"line":1037},[1027,8420,5857],{"class":1083},[1027,8422,8423],{"class":1626}," employees (email, ",[1027,8425,5724],{"class":1083},[1027,8427,8428],{"class":1626},", salary)\n",[1027,8430,8431,8433,8435,8438,8440,8442,8444,8447],{"class":1029,"line":1048},[1027,8432,5870],{"class":1083},[1027,8434,5873],{"class":1626},[1027,8436,8437],{"class":1044},"'dev@example.com'",[1027,8439,160],{"class":1626},[1027,8441,5146],{"class":1044},[1027,8443,160],{"class":1626},[1027,8445,8446],{"class":1079},"50000",[1027,8448,4684],{"class":1626},[1027,8450,8451],{"class":1029,"line":1054},[1027,8452,1064],{"emptyLinePlaceholder":1063},[1027,8454,8455,8457,8459,8461],{"class":1029,"line":1060},[1027,8456,5857],{"class":1083},[1027,8458,8423],{"class":1626},[1027,8460,5724],{"class":1083},[1027,8462,8428],{"class":1626},[1027,8464,8465,8467,8469,8471,8473,8476,8478,8481,8484],{"class":1029,"line":1067},[1027,8466,5870],{"class":1083},[1027,8468,5873],{"class":1626},[1027,8470,8437],{"class":1044},[1027,8472,160],{"class":1626},[1027,8474,8475],{"class":1044},"'Priya'",[1027,8477,160],{"class":1626},[1027,8479,8480],{"class":1079},"60000",[1027,8482,8483],{"class":1626},");  ",[1027,8485,8486],{"class":1033},"-- ERROR: duplicate key value\n",[11,8488,8489,8490,8493],{},"The database rejects the second insert automatically. You don't need to write\nany application-level code to check for this — the database handles ",[20,8491,8492],{},"data\nintegrity"," natively.",[4355,8495],{},[28,8497,8499],{"id":8498},"_6-normalization-designing-clean-databases","6. Normalization — Designing Clean Databases",[11,8501,8502,8505,8506,8509,8510,8512,8513,148],{},[20,8503,8504],{},"Database normalization explained:"," Normalization is the process of organizing\na database to reduce ",[20,8507,8508],{},"data redundancy"," (storing the same data in multiple\nplaces) and improve ",[20,8511,8195],{},". It is a foundational step when you\n",[20,8514,8515],{},"design a relational database from scratch",[232,8517,8519],{"id":8518},"the-problem-un-normalized-data","The Problem: Un-normalized Data",[11,8521,8522],{},"Imagine storing all order data in one flat table:",[127,8524,8527],{"className":8525,"code":8526,"language":132},[130],"+----------+----------+-------------------+----------+----------+-------+\n| order_id | cust_name| cust_email        | product  | category | price |\n+----------+----------+-------------------+----------+----------+-------+\n|    1     | Rahul    | rahul@example.com | Keyboard | Electronics | 3499|\n|    2     | Rahul    | rahul@example.com | Mouse    | Electronics | 999 |\n|    3     | Priya    | priya@example.com | Hub      | Electronics | 1499|\n+----------+----------+-------------------+----------+----------+-------+\n",[15,8528,8526],{"__ignoreMap":135},[11,8530,8531],{},[20,8532,8533],{},"Problems:",[76,8535,8536,8543,8546],{},[79,8537,8538,8539,8542],{},"Rahul's email is repeated — if he changes it, you must update ",[4263,8540,8541],{},"every"," row",[79,8544,8545],{},"Deleting all of Priya's orders accidentally deletes her customer record too",[79,8547,8548],{},"Inserting a new customer requires placing a dummy order",[232,8550,8552],{"id":8551},"normal-forms","Normal Forms",[4598,8554,8556],{"id":8555},"first-normal-form-1nf","First Normal Form (1NF)",[76,8558,8559,8566],{},[79,8560,8561,8562,8565],{},"Every column contains ",[20,8563,8564],{},"atomic (indivisible) values"," — no lists or sets\nin a single cell",[79,8567,8568],{},"Each row is unique",[127,8570,8572],{"className":4617,"code":8571,"language":4619,"meta":135,"style":135},"-- VIOLATION of 1NF: storing multiple values in one column\n| order_id | products                          |\n|----------|-----------------------------------|\n|    1     | 'Keyboard, Mouse, USB Hub'        | ← BAD\n\n-- CORRECT 1NF: one value per cell, one row per item\n| order_id | product   |\n|----------|-----------|\n|    1     | Keyboard  |\n|    1     | Mouse     |\n|    1     | USB Hub   |\n",[15,8573,8574,8579,8584,8591,8607,8611,8616,8621,8628,8637,8646],{"__ignoreMap":135},[1027,8575,8576],{"class":1029,"line":1030},[1027,8577,8578],{"class":1033},"-- VIOLATION of 1NF: storing multiple values in one column\n",[1027,8580,8581],{"class":1029,"line":1037},[1027,8582,8583],{"class":1626},"| order_id | products                          |\n",[1027,8585,8586,8588],{"class":1029,"line":1048},[1027,8587,6223],{"class":1626},[1027,8589,8590],{"class":1033},"----------|-----------------------------------|\n",[1027,8592,8593,8596,8598,8601,8604],{"class":1029,"line":1054},[1027,8594,8595],{"class":1626},"|    ",[1027,8597,5091],{"class":1079},[1027,8599,8600],{"class":1626},"     | ",[1027,8602,8603],{"class":1044},"'Keyboard, Mouse, USB Hub'",[1027,8605,8606],{"class":1626},"        | ← BAD\n",[1027,8608,8609],{"class":1029,"line":1060},[1027,8610,1064],{"emptyLinePlaceholder":1063},[1027,8612,8613],{"class":1029,"line":1067},[1027,8614,8615],{"class":1033},"-- CORRECT 1NF: one value per cell, one row per item\n",[1027,8617,8618],{"class":1029,"line":1073},[1027,8619,8620],{"class":1626},"| order_id | product   |\n",[1027,8622,8623,8625],{"class":1029,"line":1093},[1027,8624,6223],{"class":1626},[1027,8626,8627],{"class":1033},"----------|-----------|\n",[1027,8629,8630,8632,8634],{"class":1029,"line":1098},[1027,8631,8595],{"class":1626},[1027,8633,5091],{"class":1079},[1027,8635,8636],{"class":1626},"     | Keyboard  |\n",[1027,8638,8639,8641,8643],{"class":1029,"line":1104},[1027,8640,8595],{"class":1626},[1027,8642,5091],{"class":1079},[1027,8644,8645],{"class":1626},"     | Mouse     |\n",[1027,8647,8648,8650,8652],{"class":1029,"line":1231},[1027,8649,8595],{"class":1626},[1027,8651,5091],{"class":1079},[1027,8653,8654],{"class":1626},"     | USB Hub   |\n",[4598,8656,8658],{"id":8657},"second-normal-form-2nf","Second Normal Form (2NF)",[76,8660,8661,8664,8671],{},[79,8662,8663],{},"Must be in 1NF",[79,8665,8666,8667,8670],{},"Every non-key column must depend on the ",[20,8668,8669],{},"entire"," primary key (no partial\ndependencies)",[79,8672,8673],{},"Only relevant when the primary key is composite",[4598,8675,8677],{"id":8676},"third-normal-form-3nf","Third Normal Form (3NF)",[76,8679,8680,8683],{},[79,8681,8682],{},"Must be in 2NF",[79,8684,8685,8686,8689,8690,8693],{},"No ",[20,8687,8688],{},"transitive dependencies"," — non-key columns must depend ",[4263,8691,8692],{},"only"," on the\nprimary key, not on other non-key columns",[127,8695,8697],{"className":4617,"code":8696,"language":4619,"meta":135,"style":135},"-- VIOLATION: category_description depends on category, not on product_id\nproducts(product_id, name, category, category_description)\n\n-- CORRECT 3NF: split into two tables\nproducts(product_id, name, category_id)\ncategories(category_id, category_name, category_description)\n",[15,8698,8699,8704,8714,8718,8723,8732],{"__ignoreMap":135},[1027,8700,8701],{"class":1029,"line":1030},[1027,8702,8703],{"class":1033},"-- VIOLATION: category_description depends on category, not on product_id\n",[1027,8705,8706,8709,8711],{"class":1029,"line":1037},[1027,8707,8708],{"class":1626},"products(product_id, ",[1027,8710,5724],{"class":1083},[1027,8712,8713],{"class":1626},", category, category_description)\n",[1027,8715,8716],{"class":1029,"line":1048},[1027,8717,1064],{"emptyLinePlaceholder":1063},[1027,8719,8720],{"class":1029,"line":1054},[1027,8721,8722],{"class":1033},"-- CORRECT 3NF: split into two tables\n",[1027,8724,8725,8727,8729],{"class":1029,"line":1060},[1027,8726,8708],{"class":1626},[1027,8728,5724],{"class":1083},[1027,8730,8731],{"class":1626},", category_id)\n",[1027,8733,8734],{"class":1029,"line":1067},[1027,8735,8736],{"class":1626},"categories(category_id, category_name, category_description)\n",[56,8738,8739],{},[11,8740,8741,8744,8745,8748,8749,8752],{},[20,8742,8743],{},"Practical advice:"," Aim for 3NF in most projects. ",[20,8746,8747],{},"How normalization works\nin databases"," is about finding the right balance — over-normalizing can\nsometimes hurt query performance (too many JOINs). Real-world systems\noccasionally ",[4263,8750,8751],{},"deliberately"," denormalize for performance.",[4355,8754],{},[28,8756,8758],{"id":8757},"_7-indexes-making-queries-fast","7. Indexes — Making Queries Fast",[11,8760,8761,8764,8765,8768,8769,8772],{},[20,8762,8763],{},"Database indexes explained:"," An index is a separate data structure (usually\na B-Tree) that the database builds to make searching faster. Without an index,\nthe database does a ",[20,8766,8767],{},"full table scan"," — it reads every single row to find a\nmatch. ",[20,8770,8771],{},"Query optimization"," in SQL largely comes down to strategic use of\nindexes.",[11,8774,8775],{},"Think of it like a book's index at the back — instead of reading all 500 pages\nto find \"Binary Search,\" you look it up in the index and jump directly to\npage 312.",[127,8777,8779],{"className":4617,"code":8778,"language":4619,"meta":135,"style":135},"-- Create an index on the email column (often searched)\nCREATE INDEX idx_customers_email ON customers(email);\n\n-- Create a composite index (for queries that filter on both columns)\nCREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);\n\n-- Unique index (also enforces uniqueness like a UNIQUE constraint)\nCREATE UNIQUE INDEX idx_products_sku ON products(sku);\n\n-- Drop an index\nDROP INDEX idx_customers_email;\n",[15,8780,8781,8786,8801,8805,8810,8824,8828,8833,8848,8852,8857],{"__ignoreMap":135},[1027,8782,8783],{"class":1029,"line":1030},[1027,8784,8785],{"class":1033},"-- Create an index on the email column (often searched)\n",[1027,8787,8788,8790,8793,8796,8798],{"class":1029,"line":1037},[1027,8789,4631],{"class":1083},[1027,8791,8792],{"class":1083}," INDEX",[1027,8794,8795],{"class":1040}," idx_customers_email",[1027,8797,6328],{"class":1083},[1027,8799,8800],{"class":1626}," customers(email);\n",[1027,8802,8803],{"class":1029,"line":1048},[1027,8804,1064],{"emptyLinePlaceholder":1063},[1027,8806,8807],{"class":1029,"line":1054},[1027,8808,8809],{"class":1033},"-- Create a composite index (for queries that filter on both columns)\n",[1027,8811,8812,8814,8816,8819,8821],{"class":1029,"line":1060},[1027,8813,4631],{"class":1083},[1027,8815,8792],{"class":1083},[1027,8817,8818],{"class":1040}," idx_orders_customer_date",[1027,8820,6328],{"class":1083},[1027,8822,8823],{"class":1626}," orders(customer_id, order_date);\n",[1027,8825,8826],{"class":1029,"line":1067},[1027,8827,1064],{"emptyLinePlaceholder":1063},[1027,8829,8830],{"class":1029,"line":1073},[1027,8831,8832],{"class":1033},"-- Unique index (also enforces uniqueness like a UNIQUE constraint)\n",[1027,8834,8835,8837,8840,8843,8845],{"class":1029,"line":1093},[1027,8836,4631],{"class":1083},[1027,8838,8839],{"class":1083}," UNIQUE INDEX",[1027,8841,8842],{"class":1040}," idx_products_sku",[1027,8844,6328],{"class":1083},[1027,8846,8847],{"class":1626}," products(sku);\n",[1027,8849,8850],{"class":1029,"line":1098},[1027,8851,1064],{"emptyLinePlaceholder":1063},[1027,8853,8854],{"class":1029,"line":1104},[1027,8855,8856],{"class":1033},"-- Drop an index\n",[1027,8858,8859,8861,8863],{"class":1029,"line":1231},[1027,8860,5441],{"class":1083},[1027,8862,8792],{"class":1083},[1027,8864,8865],{"class":1626}," idx_customers_email;\n",[11,8867,8868],{},[20,8869,8870],{},"When to add an index:",[76,8872,8873,8885,8888],{},[79,8874,8875,8876,160,8878,8881,8882,8884],{},"Columns frequently used in ",[15,8877,5348],{},[15,8879,8880],{},"JOIN ON",", or ",[15,8883,6214],{}," clauses",[79,8886,8887],{},"Foreign key columns (most RDBMS recommend this)",[79,8889,8890],{},"Columns with high cardinality (many distinct values)",[11,8892,8893],{},[20,8894,8895],{},"When NOT to add an index:",[76,8897,8898,8901,8904],{},[79,8899,8900],{},"Small tables (full scan is fast enough)",[79,8902,8903],{},"Columns rarely used in queries",[79,8905,8906,8907,8909,8910,8909,8912,8914],{},"Tables with very frequent ",[15,8908,5462],{},"/",[15,8911,5465],{},[15,8913,5468],{}," (indexes slow down writes)",[56,8916,8917],{},[11,8918,8919,8922,8923,171,8926,8929,8930,148],{},[20,8920,8921],{},"Rule of thumb:"," Add indexes based on actual query patterns, not\npreemptively on every column. Use ",[15,8924,8925],{},"EXPLAIN",[15,8927,8928],{},"EXPLAIN ANALYZE"," to see\nhow the database is executing a query — this is your primary tool for\n",[20,8931,8932],{},"query optimization",[4355,8934],{},[28,8936,8938],{"id":8937},"_8-transactions-acid-properties","8. Transactions & ACID Properties",[11,8940,4279,8941,8944,8945,8948],{},[20,8942,8943],{},"transaction"," is a sequence of SQL operations treated as a ",[20,8946,8947],{},"single unit\nof work"," — either all of them succeed, or none of them do.",[232,8950,8952],{"id":8951},"the-classic-bank-transfer-example","The Classic Bank Transfer Example",[127,8954,8956],{"className":4617,"code":8955,"language":4619,"meta":135,"style":135},"BEGIN;  -- Start the transaction\n\n    -- Step 1: Deduct money from Rahul's account\n    UPDATE accounts SET balance = balance - 1000 WHERE id = 1;\n\n    -- Step 2: Add money to Priya's account\n    UPDATE accounts SET balance = balance + 1000 WHERE id = 2;\n\nCOMMIT; -- Only now are changes written permanently\n",[15,8957,8958,8967,8971,8976,9004,9008,9013,9041,9045],{"__ignoreMap":135},[1027,8959,8960,8962,8964],{"class":1029,"line":1030},[1027,8961,6351],{"class":1083},[1027,8963,6425],{"class":1626},[1027,8965,8966],{"class":1033},"-- Start the transaction\n",[1027,8968,8969],{"class":1029,"line":1037},[1027,8970,1064],{"emptyLinePlaceholder":1063},[1027,8972,8973],{"class":1029,"line":1048},[1027,8974,8975],{"class":1033},"    -- Step 1: Deduct money from Rahul's account\n",[1027,8977,8978,8980,8982,8984,8986,8988,8990,8992,8994,8996,8998,9000,9002],{"class":1029,"line":1054},[1027,8979,6358],{"class":1083},[1027,8981,6361],{"class":1626},[1027,8983,6011],{"class":1083},[1027,8985,6366],{"class":1626},[1027,8987,5274],{"class":1083},[1027,8989,6366],{"class":1626},[1027,8991,6373],{"class":1083},[1027,8993,6489],{"class":1079},[1027,8995,6379],{"class":1083},[1027,8997,6382],{"class":1626},[1027,8999,5274],{"class":1083},[1027,9001,6043],{"class":1079},[1027,9003,5358],{"class":1626},[1027,9005,9006],{"class":1029,"line":1060},[1027,9007,1064],{"emptyLinePlaceholder":1063},[1027,9009,9010],{"class":1029,"line":1067},[1027,9011,9012],{"class":1033},"    -- Step 2: Add money to Priya's account\n",[1027,9014,9015,9017,9019,9021,9023,9025,9027,9029,9031,9033,9035,9037,9039],{"class":1029,"line":1073},[1027,9016,6358],{"class":1083},[1027,9018,6361],{"class":1626},[1027,9020,6011],{"class":1083},[1027,9022,6366],{"class":1626},[1027,9024,5274],{"class":1083},[1027,9026,6366],{"class":1626},[1027,9028,6405],{"class":1083},[1027,9030,6489],{"class":1079},[1027,9032,6379],{"class":1083},[1027,9034,6382],{"class":1626},[1027,9036,5274],{"class":1083},[1027,9038,6416],{"class":1079},[1027,9040,5358],{"class":1626},[1027,9042,9043],{"class":1029,"line":1093},[1027,9044,1064],{"emptyLinePlaceholder":1063},[1027,9046,9047,9049,9052],{"class":1029,"line":1098},[1027,9048,5524],{"class":1083},[1027,9050,9051],{"class":1626},"; ",[1027,9053,9054],{"class":1033},"-- Only now are changes written permanently\n",[11,9056,9057,9058,9060],{},"If the database crashes between Step 1 and Step 2, the ",[15,9059,5527],{}," happens\nautomatically — Rahul's money is returned. You never lose money in the void.",[232,9062,9064],{"id":9063},"acid-properties-in-sql","ACID Properties in SQL",[11,9066,9067,9070],{},[20,9068,9069],{},"ACID properties"," are the set of guarantees every proper RDBMS provides for\ntransactions. For anyone learning SQL for computer science students or backend\ndevelopment, this is non-negotiable knowledge:",[450,9072,9073,9086],{},[453,9074,9075],{},[456,9076,9077,9080,9083],{},[459,9078,9079],{},"Property",[459,9081,9082],{},"What It Means",[459,9084,9085],{},"Real-World Analogy",[469,9087,9088,9101,9115,9129],{},[456,9089,9090,9095,9098],{},[474,9091,9092,9094],{},[20,9093,478],{},"tomicity",[474,9096,9097],{},"All operations succeed, or none do",[474,9099,9100],{},"A flight booking — you either get the seat AND pay, or neither happens",[456,9102,9103,9109,9112],{},[474,9104,9105,9108],{},[20,9106,9107],{},"C","onsistency",[474,9110,9111],{},"The database moves from one valid state to another",[474,9113,9114],{},"A bank's total money never changes from a transfer",[456,9116,9117,9123,9126],{},[474,9118,9119,9122],{},[20,9120,9121],{},"I","solation",[474,9124,9125],{},"Concurrent transactions don't interfere with each other",[474,9127,9128],{},"Two cashiers at a bank can serve customers simultaneously without error",[456,9130,9131,9137,9140],{},[474,9132,9133,9136],{},[20,9134,9135],{},"D","urability",[474,9138,9139],{},"Once committed, changes survive crashes",[474,9141,9142],{},"A receipt means the transaction is permanent",[127,9144,9146],{"className":4617,"code":9145,"language":4619,"meta":135,"style":135},"-- Savepoints allow partial rollbacks within a transaction\nBEGIN;\n    INSERT INTO orders (...) VALUES (...);\n    SAVEPOINT order_created;\n\n    INSERT INTO payments (...) VALUES (...);\n    -- Something went wrong with payment:\n    ROLLBACK TO SAVEPOINT order_created;  -- Undo only the payment insert\n\nCOMMIT;  -- The order insert still gets committed\n",[15,9147,9148,9153,9159,9172,9177,9181,9192,9197,9211,9215],{"__ignoreMap":135},[1027,9149,9150],{"class":1029,"line":1030},[1027,9151,9152],{"class":1033},"-- Savepoints allow partial rollbacks within a transaction\n",[1027,9154,9155,9157],{"class":1029,"line":1037},[1027,9156,6351],{"class":1083},[1027,9158,5358],{"class":1626},[1027,9160,9161,9164,9167,9169],{"class":1029,"line":1048},[1027,9162,9163],{"class":1083},"    INSERT INTO",[1027,9165,9166],{"class":1626}," orders (...) ",[1027,9168,5870],{"class":1083},[1027,9170,9171],{"class":1626}," (...);\n",[1027,9173,9174],{"class":1029,"line":1054},[1027,9175,9176],{"class":1626},"    SAVEPOINT order_created;\n",[1027,9178,9179],{"class":1029,"line":1060},[1027,9180,1064],{"emptyLinePlaceholder":1063},[1027,9182,9183,9185,9188,9190],{"class":1029,"line":1067},[1027,9184,9163],{"class":1083},[1027,9186,9187],{"class":1626}," payments (...) ",[1027,9189,5870],{"class":1083},[1027,9191,9171],{"class":1626},[1027,9193,9194],{"class":1029,"line":1073},[1027,9195,9196],{"class":1033},"    -- Something went wrong with payment:\n",[1027,9198,9199,9202,9205,9208],{"class":1029,"line":1093},[1027,9200,9201],{"class":1083},"    ROLLBACK",[1027,9203,9204],{"class":1083}," TO",[1027,9206,9207],{"class":1626}," SAVEPOINT order_created;  ",[1027,9209,9210],{"class":1033},"-- Undo only the payment insert\n",[1027,9212,9213],{"class":1029,"line":1098},[1027,9214,1064],{"emptyLinePlaceholder":1063},[1027,9216,9217,9219,9221],{"class":1029,"line":1104},[1027,9218,5524],{"class":1083},[1027,9220,6425],{"class":1626},[1027,9222,9223],{"class":1033},"-- The order insert still gets committed\n",[4355,9225],{},[28,9227,9229],{"id":9228},"_9-views","9. Views",[11,9231,4279,9232,9235,9236,9239],{},[20,9233,9234],{},"view"," is a saved SQL query that you can treat like a virtual table. The\nview itself stores no data — it executes the underlying query every time you\nselect from it. Views are an elegant tool for simplifying complex ",[20,9237,9238],{},"database\nmanagement system"," operations.",[127,9241,9243],{"className":4617,"code":9242,"language":4619,"meta":135,"style":135},"-- Create a view for frequently needed customer order summary\nCREATE VIEW customer_order_summary AS\nSELECT\n    c.id,\n    c.name,\n    c.email,\n    COUNT(o.id)       AS total_orders,\n    SUM(o.total_amount) AS lifetime_value\nFROM customers c\nLEFT JOIN orders o ON c.id = o.customer_id\nGROUP BY c.id, c.name, c.email;\n\n-- Now use it just like a regular table\nSELECT * FROM customer_order_summary WHERE lifetime_value > 10000;\nSELECT name, total_orders FROM customer_order_summary ORDER BY total_orders DESC LIMIT 10;\n\n-- Drop a view\nDROP VIEW customer_order_summary;\n",[15,9244,9245,9250,9263,9267,9277,9287,9297,9316,9335,9341,9363,9392,9396,9401,9424,9450,9454,9459],{"__ignoreMap":135},[1027,9246,9247],{"class":1029,"line":1030},[1027,9248,9249],{"class":1033},"-- Create a view for frequently needed customer order summary\n",[1027,9251,9252,9254,9257,9260],{"class":1029,"line":1037},[1027,9253,4631],{"class":1083},[1027,9255,9256],{"class":1083}," VIEW",[1027,9258,9259],{"class":1040}," customer_order_summary",[1027,9261,9262],{"class":1083}," AS\n",[1027,9264,9265],{"class":1029,"line":1048},[1027,9266,6267],{"class":1083},[1027,9268,9269,9271,9273,9275],{"class":1029,"line":1054},[1027,9270,7520],{"class":1079},[1027,9272,148],{"class":1626},[1027,9274,7539],{"class":1079},[1027,9276,4654],{"class":1626},[1027,9278,9279,9281,9283,9285],{"class":1029,"line":1060},[1027,9280,7520],{"class":1079},[1027,9282,148],{"class":1626},[1027,9284,5724],{"class":1079},[1027,9286,4654],{"class":1626},[1027,9288,9289,9291,9293,9295],{"class":1029,"line":1067},[1027,9290,7520],{"class":1079},[1027,9292,148],{"class":1626},[1027,9294,4830],{"class":1079},[1027,9296,4654],{"class":1626},[1027,9298,9299,9301,9303,9305,9307,9309,9311,9313],{"class":1029,"line":1073},[1027,9300,7202],{"class":1079},[1027,9302,4665],{"class":1626},[1027,9304,7746],{"class":1079},[1027,9306,148],{"class":1626},[1027,9308,7539],{"class":1079},[1027,9310,7209],{"class":1626},[1027,9312,6285],{"class":1083},[1027,9314,9315],{"class":1626}," total_orders,\n",[1027,9317,9318,9320,9322,9324,9326,9328,9330,9332],{"class":1029,"line":1093},[1027,9319,7232],{"class":1079},[1027,9321,4665],{"class":1626},[1027,9323,7746],{"class":1079},[1027,9325,148],{"class":1626},[1027,9327,7554],{"class":1079},[1027,9329,5585],{"class":1626},[1027,9331,6285],{"class":1083},[1027,9333,9334],{"class":1626}," lifetime_value\n",[1027,9336,9337,9339],{"class":1029,"line":1098},[1027,9338,6199],{"class":1083},[1027,9340,7572],{"class":1626},[1027,9342,9343,9345,9347,9349,9351,9353,9355,9357,9359,9361],{"class":1029,"line":1104},[1027,9344,7680],{"class":1083},[1027,9346,7579],{"class":1626},[1027,9348,7582],{"class":1083},[1027,9350,7585],{"class":1079},[1027,9352,148],{"class":1626},[1027,9354,7539],{"class":1079},[1027,9356,7592],{"class":1083},[1027,9358,7595],{"class":1079},[1027,9360,148],{"class":1626},[1027,9362,7935],{"class":1079},[1027,9364,9365,9367,9369,9371,9373,9375,9378,9380,9382,9384,9386,9388,9390],{"class":1029,"line":1231},[1027,9366,7251],{"class":1083},[1027,9368,7585],{"class":1079},[1027,9370,148],{"class":1626},[1027,9372,7539],{"class":1079},[1027,9374,160],{"class":1626},[1027,9376,9377],{"class":1079},"c",[1027,9379,148],{"class":1626},[1027,9381,5724],{"class":1079},[1027,9383,160],{"class":1626},[1027,9385,9377],{"class":1079},[1027,9387,148],{"class":1626},[1027,9389,4830],{"class":1079},[1027,9391,5358],{"class":1626},[1027,9393,9394],{"class":1029,"line":1241},[1027,9395,1064],{"emptyLinePlaceholder":1063},[1027,9397,9398],{"class":1029,"line":1246},[1027,9399,9400],{"class":1033},"-- Now use it just like a regular table\n",[1027,9402,9403,9405,9407,9409,9412,9414,9417,9419,9422],{"class":1029,"line":1252},[1027,9404,5336],{"class":1083},[1027,9406,5339],{"class":1083},[1027,9408,5342],{"class":1083},[1027,9410,9411],{"class":1626}," customer_order_summary ",[1027,9413,5348],{"class":1083},[1027,9415,9416],{"class":1626}," lifetime_value ",[1027,9418,6486],{"class":1083},[1027,9420,9421],{"class":1079}," 10000",[1027,9423,5358],{"class":1626},[1027,9425,9426,9428,9430,9433,9435,9437,9439,9442,9444,9446,9448],{"class":1029,"line":1262},[1027,9427,5336],{"class":1083},[1027,9429,6526],{"class":1083},[1027,9431,9432],{"class":1626},", total_orders ",[1027,9434,6199],{"class":1083},[1027,9436,9411],{"class":1626},[1027,9438,6214],{"class":1083},[1027,9440,9441],{"class":1626}," total_orders ",[1027,9443,6898],{"class":1083},[1027,9445,6960],{"class":1083},[1027,9447,6762],{"class":1079},[1027,9449,5358],{"class":1626},[1027,9451,9452],{"class":1029,"line":1267},[1027,9453,1064],{"emptyLinePlaceholder":1063},[1027,9455,9456],{"class":1029,"line":1273},[1027,9457,9458],{"class":1033},"-- Drop a view\n",[1027,9460,9461,9463,9465],{"class":1029,"line":1283},[1027,9462,5441],{"class":1083},[1027,9464,9256],{"class":1083},[1027,9466,9467],{"class":1626}," customer_order_summary;\n",[11,9469,9470],{},[20,9471,9472],{},"Benefits of Views:",[76,9474,9475,9481,9487,9493],{},[79,9476,9477,9480],{},[20,9478,9479],{},"Simplicity:"," Hide complex joins behind a simple name",[79,9482,9483,9486],{},[20,9484,9485],{},"Security:"," Expose only certain columns to certain users",[79,9488,9489,9492],{},[20,9490,9491],{},"Consistency:"," Everyone queries the same definition",[79,9494,9495,9498],{},[20,9496,9497],{},"Maintainability:"," Change the query in one place",[4355,9500],{},[28,9502,9504],{"id":9503},"_10-a-complete-practical-project","10. A Complete Practical Project",[11,9506,9507,9508,9510,9511,9514],{},"Let's ",[20,9509,8515],{}," — a minimal but real\n",[20,9512,9513],{},"Library Management System",". This is a great hands-on exercise for anyone\nfollowing this relational database tutorial.",[232,9516,9518],{"id":9517},"step-1-design-the-schema","Step 1: Design the Schema",[11,9520,9521],{},[123,9522],{"alt":9523,"src":9524},"Library Management System Database Schema Diagram","/post-images/sql-made-dead-simple-rdbms-guide/library-management-system-database-schema-diagram.png",[127,9526,9528],{"className":4617,"code":9527,"language":4619,"meta":135,"style":135},"-- Authors\nCREATE TABLE authors (\n    id         SERIAL PRIMARY KEY,\n    name       VARCHAR(150) NOT NULL,\n    country    VARCHAR(100),\n    birth_year INT CHECK (birth_year > 1000)\n);\n\n-- Books\nCREATE TABLE books (\n    id            SERIAL PRIMARY KEY,\n    title         VARCHAR(255) NOT NULL,\n    author_id     INT NOT NULL REFERENCES authors(id),\n    isbn          VARCHAR(20) UNIQUE,\n    published_year INT,\n    genre         VARCHAR(100),\n    total_copies  INT DEFAULT 1 CHECK (total_copies >= 0)\n);\n\n-- Members\nCREATE TABLE members (\n    id           SERIAL PRIMARY KEY,\n    name         VARCHAR(150) NOT NULL,\n    email        VARCHAR(255) NOT NULL UNIQUE,\n    joined_on    DATE DEFAULT CURRENT_DATE,\n    is_active    BOOLEAN DEFAULT TRUE\n);\n\n-- Borrowing records\nCREATE TABLE borrowings (\n    id            SERIAL PRIMARY KEY,\n    book_id       INT NOT NULL REFERENCES books(id),\n    member_id     INT NOT NULL REFERENCES members(id),\n    borrowed_on   DATE NOT NULL DEFAULT CURRENT_DATE,\n    due_on        DATE NOT NULL,\n    returned_on   DATE\n);\n",[15,9529,9530,9535,9546,9556,9573,9586,9606,9610,9614,9619,9630,9641,9658,9673,9691,9700,9713,9736,9740,9744,9749,9760,9771,9787,9806,9818,9830,9834,9838,9844,9856,9867,9882,9897,9911,9923,9931],{"__ignoreMap":135},[1027,9531,9532],{"class":1029,"line":1030},[1027,9533,9534],{"class":1033},"-- Authors\n",[1027,9536,9537,9539,9541,9544],{"class":1029,"line":1037},[1027,9538,4631],{"class":1083},[1027,9540,4634],{"class":1083},[1027,9542,9543],{"class":1040}," authors",[1027,9545,4640],{"class":1626},[1027,9547,9548,9550,9552,9554],{"class":1029,"line":1048},[1027,9549,8290],{"class":1626},[1027,9551,5562],{"class":1083},[1027,9553,4651],{"class":1083},[1027,9555,4654],{"class":1626},[1027,9557,9558,9560,9562,9564,9567,9569,9571],{"class":1029,"line":1054},[1027,9559,4659],{"class":1083},[1027,9561,4662],{"class":1083},[1027,9563,4665],{"class":1626},[1027,9565,9566],{"class":1079},"150",[1027,9568,5585],{"class":1626},[1027,9570,5588],{"class":1083},[1027,9572,4654],{"class":1626},[1027,9574,9575,9578,9580,9582,9584],{"class":1029,"line":1060},[1027,9576,9577],{"class":1626},"    country    ",[1027,9579,5693],{"class":1083},[1027,9581,4665],{"class":1626},[1027,9583,4668],{"class":1079},[1027,9585,4671],{"class":1626},[1027,9587,9588,9591,9593,9596,9599,9601,9603],{"class":1029,"line":1067},[1027,9589,9590],{"class":1626},"    birth_year ",[1027,9592,4648],{"class":1083},[1027,9594,9595],{"class":1083}," CHECK",[1027,9597,9598],{"class":1626}," (birth_year ",[1027,9600,6486],{"class":1083},[1027,9602,6489],{"class":1079},[1027,9604,9605],{"class":1626},")\n",[1027,9607,9608],{"class":1029,"line":1073},[1027,9609,4684],{"class":1626},[1027,9611,9612],{"class":1029,"line":1093},[1027,9613,1064],{"emptyLinePlaceholder":1063},[1027,9615,9616],{"class":1029,"line":1098},[1027,9617,9618],{"class":1033},"-- Books\n",[1027,9620,9621,9623,9625,9628],{"class":1029,"line":1104},[1027,9622,4631],{"class":1083},[1027,9624,4634],{"class":1083},[1027,9626,9627],{"class":1040}," books",[1027,9629,4640],{"class":1626},[1027,9631,9632,9635,9637,9639],{"class":1029,"line":1231},[1027,9633,9634],{"class":1626},"    id            ",[1027,9636,5562],{"class":1083},[1027,9638,4651],{"class":1083},[1027,9640,4654],{"class":1626},[1027,9642,9643,9646,9648,9650,9652,9654,9656],{"class":1029,"line":1241},[1027,9644,9645],{"class":1626},"    title         ",[1027,9647,5693],{"class":1083},[1027,9649,4665],{"class":1626},[1027,9651,8308],{"class":1079},[1027,9653,5585],{"class":1626},[1027,9655,5588],{"class":1083},[1027,9657,4654],{"class":1626},[1027,9659,9660,9663,9665,9668,9670],{"class":1029,"line":1246},[1027,9661,9662],{"class":1626},"    author_id     ",[1027,9664,4648],{"class":1083},[1027,9666,9667],{"class":1083}," NOT NULL",[1027,9669,4743],{"class":1083},[1027,9671,9672],{"class":1626}," authors(id),\n",[1027,9674,9675,9678,9680,9682,9685,9687,9689],{"class":1029,"line":1252},[1027,9676,9677],{"class":1626},"    isbn          ",[1027,9679,5693],{"class":1083},[1027,9681,4665],{"class":1626},[1027,9683,9684],{"class":1079},"20",[1027,9686,5585],{"class":1626},[1027,9688,8246],{"class":1083},[1027,9690,4654],{"class":1626},[1027,9692,9693,9696,9698],{"class":1029,"line":1262},[1027,9694,9695],{"class":1626},"    published_year ",[1027,9697,4648],{"class":1083},[1027,9699,4654],{"class":1626},[1027,9701,9702,9705,9707,9709,9711],{"class":1029,"line":1267},[1027,9703,9704],{"class":1626},"    genre         ",[1027,9706,5693],{"class":1083},[1027,9708,4665],{"class":1626},[1027,9710,4668],{"class":1079},[1027,9712,4671],{"class":1626},[1027,9714,9715,9718,9720,9722,9724,9726,9729,9732,9734],{"class":1029,"line":1273},[1027,9716,9717],{"class":1626},"    total_copies  ",[1027,9719,4648],{"class":1083},[1027,9721,5638],{"class":1083},[1027,9723,6043],{"class":1079},[1027,9725,9595],{"class":1083},[1027,9727,9728],{"class":1626}," (total_copies ",[1027,9730,9731],{"class":1083},">=",[1027,9733,5277],{"class":1079},[1027,9735,9605],{"class":1626},[1027,9737,9738],{"class":1029,"line":1283},[1027,9739,4684],{"class":1626},[1027,9741,9742],{"class":1029,"line":1288},[1027,9743,1064],{"emptyLinePlaceholder":1063},[1027,9745,9746],{"class":1029,"line":1294},[1027,9747,9748],{"class":1033},"-- Members\n",[1027,9750,9751,9753,9755,9758],{"class":1029,"line":6733},[1027,9752,4631],{"class":1083},[1027,9754,4634],{"class":1083},[1027,9756,9757],{"class":1040}," members",[1027,9759,4640],{"class":1626},[1027,9761,9762,9765,9767,9769],{"class":1029,"line":6744},[1027,9763,9764],{"class":1626},"    id           ",[1027,9766,5562],{"class":1083},[1027,9768,4651],{"class":1083},[1027,9770,4654],{"class":1626},[1027,9772,9773,9775,9777,9779,9781,9783,9785],{"class":1029,"line":6767},[1027,9774,4659],{"class":1083},[1027,9776,5577],{"class":1083},[1027,9778,4665],{"class":1626},[1027,9780,9566],{"class":1079},[1027,9782,5585],{"class":1626},[1027,9784,5588],{"class":1083},[1027,9786,4654],{"class":1626},[1027,9788,9789,9792,9794,9796,9798,9800,9802,9804],{"class":1029,"line":6772},[1027,9790,9791],{"class":1626},"    email        ",[1027,9793,5693],{"class":1083},[1027,9795,4665],{"class":1626},[1027,9797,8308],{"class":1079},[1027,9799,5585],{"class":1626},[1027,9801,5588],{"class":1083},[1027,9803,8315],{"class":1083},[1027,9805,4654],{"class":1626},[1027,9807,9808,9811,9813,9815],{"class":1029,"line":6783},[1027,9809,9810],{"class":1626},"    joined_on    ",[1027,9812,5181],{"class":1083},[1027,9814,5638],{"class":1083},[1027,9816,9817],{"class":1626}," CURRENT_DATE,\n",[1027,9819,9820,9823,9825,9827],{"class":1029,"line":6806},[1027,9821,9822],{"class":1626},"    is_active    ",[1027,9824,5161],{"class":1083},[1027,9826,5638],{"class":1083},[1027,9828,9829],{"class":1626}," TRUE\n",[1027,9831,9832],{"class":1029,"line":6811},[1027,9833,4684],{"class":1626},[1027,9835,9836],{"class":1029,"line":6817},[1027,9837,1064],{"emptyLinePlaceholder":1063},[1027,9839,9841],{"class":1029,"line":9840},29,[1027,9842,9843],{"class":1033},"-- Borrowing records\n",[1027,9845,9847,9849,9851,9854],{"class":1029,"line":9846},30,[1027,9848,4631],{"class":1083},[1027,9850,4634],{"class":1083},[1027,9852,9853],{"class":1040}," borrowings",[1027,9855,4640],{"class":1626},[1027,9857,9859,9861,9863,9865],{"class":1029,"line":9858},31,[1027,9860,9634],{"class":1626},[1027,9862,5562],{"class":1083},[1027,9864,4651],{"class":1083},[1027,9866,4654],{"class":1626},[1027,9868,9870,9873,9875,9877,9879],{"class":1029,"line":9869},32,[1027,9871,9872],{"class":1626},"    book_id       ",[1027,9874,4648],{"class":1083},[1027,9876,9667],{"class":1083},[1027,9878,4743],{"class":1083},[1027,9880,9881],{"class":1626}," books(id),\n",[1027,9883,9885,9888,9890,9892,9894],{"class":1029,"line":9884},33,[1027,9886,9887],{"class":1626},"    member_id     ",[1027,9889,4648],{"class":1083},[1027,9891,9667],{"class":1083},[1027,9893,4743],{"class":1083},[1027,9895,9896],{"class":1626}," members(id),\n",[1027,9898,9900,9903,9905,9907,9909],{"class":1029,"line":9899},34,[1027,9901,9902],{"class":1626},"    borrowed_on   ",[1027,9904,5181],{"class":1083},[1027,9906,9667],{"class":1083},[1027,9908,5638],{"class":1083},[1027,9910,9817],{"class":1626},[1027,9912,9914,9917,9919,9921],{"class":1029,"line":9913},35,[1027,9915,9916],{"class":1626},"    due_on        ",[1027,9918,5181],{"class":1083},[1027,9920,9667],{"class":1083},[1027,9922,4654],{"class":1626},[1027,9924,9926,9929],{"class":1029,"line":9925},36,[1027,9927,9928],{"class":1626},"    returned_on   ",[1027,9930,4766],{"class":1083},[1027,9932,9934],{"class":1029,"line":9933},37,[1027,9935,4684],{"class":1626},[232,9937,9939],{"id":9938},"step-2-insert-sample-data","Step 2: Insert Sample Data",[127,9941,9943],{"className":4617,"code":9942,"language":4619,"meta":135,"style":135},"INSERT INTO authors (name, country, birth_year) VALUES\n    ('George Orwell', 'United Kingdom', 1903),\n    ('Yuval Noah Harari', 'Israel', 1976),\n    ('Robert C. Martin', 'United States', 1952);\n\nINSERT INTO books (title, author_id, isbn, published_year, genre, total_copies) VALUES\n    ('1984',                1, '978-0451524935', 1949, 'Dystopian', 5),\n    ('Animal Farm',         1, '978-0451526342', 1945, 'Satire',    3),\n    ('Sapiens',             2, '978-0062316097', 2011, 'Non-Fiction', 4),\n    ('Clean Code',          3, '978-0132350884', 2008, 'Technology', 2);\n\nINSERT INTO members (name, email) VALUES\n    ('Priya Sharma', 'priya@example.com'),\n    ('Rahul Das',    'rahul@example.com'),\n    ('Aisha Khan',   'aisha@example.com');\n\nINSERT INTO borrowings (book_id, member_id, borrowed_on, due_on, returned_on) VALUES\n    (1, 1, '2024-01-10', '2024-01-24', '2024-01-20'),  -- returned\n    (3, 2, '2024-01-15', '2024-01-29', NULL),           -- still out\n    (1, 3, '2024-01-18', '2024-02-01', NULL);            -- still out\n",[15,9944,9945,9959,9978,9997,10016,10020,10029,10063,10098,10131,10164,10168,10182,10196,10210,10225,10229,10238,10269,10299],{"__ignoreMap":135},[1027,9946,9947,9949,9952,9954,9957],{"class":1029,"line":1030},[1027,9948,5857],{"class":1083},[1027,9950,9951],{"class":1626}," authors (",[1027,9953,5724],{"class":1083},[1027,9955,9956],{"class":1626},", country, birth_year) ",[1027,9958,5916],{"class":1083},[1027,9960,9961,9963,9966,9968,9971,9973,9976],{"class":1029,"line":1037},[1027,9962,5921],{"class":1626},[1027,9964,9965],{"class":1044},"'George Orwell'",[1027,9967,160],{"class":1626},[1027,9969,9970],{"class":1044},"'United Kingdom'",[1027,9972,160],{"class":1626},[1027,9974,9975],{"class":1079},"1903",[1027,9977,4671],{"class":1626},[1027,9979,9980,9982,9985,9987,9990,9992,9995],{"class":1029,"line":1048},[1027,9981,5921],{"class":1626},[1027,9983,9984],{"class":1044},"'Yuval Noah Harari'",[1027,9986,160],{"class":1626},[1027,9988,9989],{"class":1044},"'Israel'",[1027,9991,160],{"class":1626},[1027,9993,9994],{"class":1079},"1976",[1027,9996,4671],{"class":1626},[1027,9998,9999,10001,10004,10006,10009,10011,10014],{"class":1029,"line":1054},[1027,10000,5921],{"class":1626},[1027,10002,10003],{"class":1044},"'Robert C. Martin'",[1027,10005,160],{"class":1626},[1027,10007,10008],{"class":1044},"'United States'",[1027,10010,160],{"class":1626},[1027,10012,10013],{"class":1079},"1952",[1027,10015,4684],{"class":1626},[1027,10017,10018],{"class":1029,"line":1060},[1027,10019,1064],{"emptyLinePlaceholder":1063},[1027,10021,10022,10024,10027],{"class":1029,"line":1067},[1027,10023,5857],{"class":1083},[1027,10025,10026],{"class":1626}," books (title, author_id, isbn, published_year, genre, total_copies) ",[1027,10028,5916],{"class":1083},[1027,10030,10031,10033,10036,10039,10041,10043,10046,10048,10051,10053,10056,10058,10061],{"class":1029,"line":1073},[1027,10032,5921],{"class":1626},[1027,10034,10035],{"class":1044},"'1984'",[1027,10037,10038],{"class":1626},",                ",[1027,10040,5091],{"class":1079},[1027,10042,160],{"class":1626},[1027,10044,10045],{"class":1044},"'978-0451524935'",[1027,10047,160],{"class":1626},[1027,10049,10050],{"class":1079},"1949",[1027,10052,160],{"class":1626},[1027,10054,10055],{"class":1044},"'Dystopian'",[1027,10057,160],{"class":1626},[1027,10059,10060],{"class":1079},"5",[1027,10062,4671],{"class":1626},[1027,10064,10065,10067,10070,10073,10075,10077,10080,10082,10085,10087,10090,10093,10096],{"class":1029,"line":1093},[1027,10066,5921],{"class":1626},[1027,10068,10069],{"class":1044},"'Animal Farm'",[1027,10071,10072],{"class":1626},",         ",[1027,10074,5091],{"class":1079},[1027,10076,160],{"class":1626},[1027,10078,10079],{"class":1044},"'978-0451526342'",[1027,10081,160],{"class":1626},[1027,10083,10084],{"class":1079},"1945",[1027,10086,160],{"class":1626},[1027,10088,10089],{"class":1044},"'Satire'",[1027,10091,10092],{"class":1626},",    ",[1027,10094,10095],{"class":1079},"3",[1027,10097,4671],{"class":1626},[1027,10099,10100,10102,10105,10108,10110,10112,10115,10117,10120,10122,10125,10127,10129],{"class":1029,"line":1098},[1027,10101,5921],{"class":1626},[1027,10103,10104],{"class":1044},"'Sapiens'",[1027,10106,10107],{"class":1626},",             ",[1027,10109,5618],{"class":1079},[1027,10111,160],{"class":1626},[1027,10113,10114],{"class":1044},"'978-0062316097'",[1027,10116,160],{"class":1626},[1027,10118,10119],{"class":1079},"2011",[1027,10121,160],{"class":1626},[1027,10123,10124],{"class":1044},"'Non-Fiction'",[1027,10126,160],{"class":1626},[1027,10128,7047],{"class":1079},[1027,10130,4671],{"class":1626},[1027,10132,10133,10135,10138,10141,10143,10145,10148,10150,10153,10155,10158,10160,10162],{"class":1029,"line":1104},[1027,10134,5921],{"class":1626},[1027,10136,10137],{"class":1044},"'Clean Code'",[1027,10139,10140],{"class":1626},",          ",[1027,10142,10095],{"class":1079},[1027,10144,160],{"class":1626},[1027,10146,10147],{"class":1044},"'978-0132350884'",[1027,10149,160],{"class":1626},[1027,10151,10152],{"class":1079},"2008",[1027,10154,160],{"class":1626},[1027,10156,10157],{"class":1044},"'Technology'",[1027,10159,160],{"class":1626},[1027,10161,5618],{"class":1079},[1027,10163,4684],{"class":1626},[1027,10165,10166],{"class":1029,"line":1231},[1027,10167,1064],{"emptyLinePlaceholder":1063},[1027,10169,10170,10172,10175,10177,10180],{"class":1029,"line":1241},[1027,10171,5857],{"class":1083},[1027,10173,10174],{"class":1626}," members (",[1027,10176,5724],{"class":1083},[1027,10178,10179],{"class":1626},", email) ",[1027,10181,5916],{"class":1083},[1027,10183,10184,10186,10189,10191,10194],{"class":1029,"line":1246},[1027,10185,5921],{"class":1626},[1027,10187,10188],{"class":1044},"'Priya Sharma'",[1027,10190,160],{"class":1626},[1027,10192,10193],{"class":1044},"'priya@example.com'",[1027,10195,4671],{"class":1626},[1027,10197,10198,10200,10203,10205,10208],{"class":1029,"line":1252},[1027,10199,5921],{"class":1626},[1027,10201,10202],{"class":1044},"'Rahul Das'",[1027,10204,10092],{"class":1626},[1027,10206,10207],{"class":1044},"'rahul@example.com'",[1027,10209,4671],{"class":1626},[1027,10211,10212,10214,10217,10220,10223],{"class":1029,"line":1262},[1027,10213,5921],{"class":1626},[1027,10215,10216],{"class":1044},"'Aisha Khan'",[1027,10218,10219],{"class":1626},",   ",[1027,10221,10222],{"class":1044},"'aisha@example.com'",[1027,10224,4684],{"class":1626},[1027,10226,10227],{"class":1029,"line":1267},[1027,10228,1064],{"emptyLinePlaceholder":1063},[1027,10230,10231,10233,10236],{"class":1029,"line":1273},[1027,10232,5857],{"class":1083},[1027,10234,10235],{"class":1626}," borrowings (book_id, member_id, borrowed_on, due_on, returned_on) ",[1027,10237,5916],{"class":1083},[1027,10239,10240,10242,10244,10246,10248,10250,10253,10255,10258,10260,10263,10266],{"class":1029,"line":1283},[1027,10241,5921],{"class":1626},[1027,10243,5091],{"class":1079},[1027,10245,160],{"class":1626},[1027,10247,5091],{"class":1079},[1027,10249,160],{"class":1626},[1027,10251,10252],{"class":1044},"'2024-01-10'",[1027,10254,160],{"class":1626},[1027,10256,10257],{"class":1044},"'2024-01-24'",[1027,10259,160],{"class":1626},[1027,10261,10262],{"class":1044},"'2024-01-20'",[1027,10264,10265],{"class":1626},"),  ",[1027,10267,10268],{"class":1033},"-- returned\n",[1027,10270,10271,10273,10275,10277,10279,10281,10284,10286,10289,10291,10293,10296],{"class":1029,"line":1288},[1027,10272,5921],{"class":1626},[1027,10274,10095],{"class":1079},[1027,10276,160],{"class":1626},[1027,10278,5618],{"class":1079},[1027,10280,160],{"class":1626},[1027,10282,10283],{"class":1044},"'2024-01-15'",[1027,10285,160],{"class":1626},[1027,10287,10288],{"class":1044},"'2024-01-29'",[1027,10290,160],{"class":1626},[1027,10292,5241],{"class":1083},[1027,10294,10295],{"class":1626},"),           ",[1027,10297,10298],{"class":1033},"-- still out\n",[1027,10300,10301,10303,10305,10307,10309,10311,10314,10316,10319,10321,10323,10326],{"class":1029,"line":1294},[1027,10302,5921],{"class":1626},[1027,10304,5091],{"class":1079},[1027,10306,160],{"class":1626},[1027,10308,10095],{"class":1079},[1027,10310,160],{"class":1626},[1027,10312,10313],{"class":1044},"'2024-01-18'",[1027,10315,160],{"class":1626},[1027,10317,10318],{"class":1044},"'2024-02-01'",[1027,10320,160],{"class":1626},[1027,10322,5241],{"class":1083},[1027,10324,10325],{"class":1626},");            ",[1027,10327,10298],{"class":1033},[232,10329,10331],{"id":10330},"step-3-useful-queries","Step 3: Useful Queries",[127,10333,10335],{"className":4617,"code":10334,"language":4619,"meta":135,"style":135},"-- Q1: All books with their author names\nSELECT b.title, a.name AS author, b.genre, b.published_year\nFROM books b\nJOIN authors a ON b.author_id = a.id\nORDER BY b.published_year DESC;\n\n-- Q2: Which books are currently borrowed (not yet returned)?\nSELECT\n    m.name     AS member,\n    b.title    AS book,\n    br.borrowed_on,\n    br.due_on,\n    CURRENT_DATE - br.due_on AS days_overdue\nFROM borrowings br\nJOIN members m ON br.member_id = m.id\nJOIN books   b ON br.book_id   = b.id\nWHERE br.returned_on IS NULL;\n\n-- Q3: Members who have never borrowed a book\nSELECT m.name, m.email\nFROM members m\nLEFT JOIN borrowings br ON m.id = br.member_id\nWHERE br.id IS NULL;\n\n-- Q4: Most popular book (borrowed most times)\nSELECT b.title, COUNT(*) AS borrow_count\nFROM borrowings br\nJOIN books b ON br.book_id = b.id\nGROUP BY b.title\nORDER BY borrow_count DESC\nLIMIT 3;\n\n-- Q5: Create a view for the library dashboard\nCREATE VIEW library_dashboard AS\nSELECT\n    b.id,\n    b.title,\n    a.name AS author,\n    b.total_copies,\n    b.total_copies - COUNT(br.id) FILTER (WHERE br.returned_on IS NULL) AS available_copies\nFROM books b\nJOIN authors a ON b.author_id = a.id\nLEFT JOIN borrowings br ON b.id = br.book_id\nGROUP BY b.id, b.title, a.name, b.total_copies;\n\nSELECT * FROM library_dashboard;\n",[15,10336,10337,10342,10385,10392,10418,10434,10438,10443,10447,10462,10477,10489,10500,10519,10526,10551,10575,10593,10597,10602,10622,10629,10653,10669,10673,10678,10703,10709,10732,10743,10752,10760,10764,10769,10780,10784,10794,10804,10819,10831,10880,10887,10910,10934,10971,10976],{"__ignoreMap":135},[1027,10338,10339],{"class":1029,"line":1030},[1027,10340,10341],{"class":1033},"-- Q1: All books with their author names\n",[1027,10343,10344,10346,10349,10351,10354,10356,10359,10361,10363,10365,10368,10371,10373,10376,10378,10380,10382],{"class":1029,"line":1037},[1027,10345,5336],{"class":1083},[1027,10347,10348],{"class":1079}," b",[1027,10350,148],{"class":1626},[1027,10352,10353],{"class":1079},"title",[1027,10355,160],{"class":1626},[1027,10357,10358],{"class":1079},"a",[1027,10360,148],{"class":1626},[1027,10362,5724],{"class":1079},[1027,10364,7753],{"class":1083},[1027,10366,10367],{"class":1626}," author, ",[1027,10369,10370],{"class":1079},"b",[1027,10372,148],{"class":1626},[1027,10374,10375],{"class":1079},"genre",[1027,10377,160],{"class":1626},[1027,10379,10370],{"class":1079},[1027,10381,148],{"class":1626},[1027,10383,10384],{"class":1079},"published_year\n",[1027,10386,10387,10389],{"class":1029,"line":1048},[1027,10388,6199],{"class":1083},[1027,10390,10391],{"class":1626}," books b\n",[1027,10393,10394,10396,10399,10401,10403,10405,10408,10410,10413,10415],{"class":1029,"line":1054},[1027,10395,7914],{"class":1083},[1027,10397,10398],{"class":1626}," authors a ",[1027,10400,7582],{"class":1083},[1027,10402,10348],{"class":1079},[1027,10404,148],{"class":1626},[1027,10406,10407],{"class":1079},"author_id",[1027,10409,7592],{"class":1083},[1027,10411,10412],{"class":1079}," a",[1027,10414,148],{"class":1626},[1027,10416,10417],{"class":1079},"id\n",[1027,10419,10420,10422,10424,10426,10429,10432],{"class":1029,"line":1060},[1027,10421,6214],{"class":1083},[1027,10423,10348],{"class":1079},[1027,10425,148],{"class":1626},[1027,10427,10428],{"class":1079},"published_year",[1027,10430,10431],{"class":1083}," DESC",[1027,10433,5358],{"class":1626},[1027,10435,10436],{"class":1029,"line":1067},[1027,10437,1064],{"emptyLinePlaceholder":1063},[1027,10439,10440],{"class":1029,"line":1073},[1027,10441,10442],{"class":1033},"-- Q2: Which books are currently borrowed (not yet returned)?\n",[1027,10444,10445],{"class":1029,"line":1093},[1027,10446,6267],{"class":1083},[1027,10448,10449,10452,10454,10456,10459],{"class":1029,"line":1098},[1027,10450,10451],{"class":1079},"    m",[1027,10453,148],{"class":1626},[1027,10455,5724],{"class":1079},[1027,10457,10458],{"class":1083},"     AS",[1027,10460,10461],{"class":1626}," member,\n",[1027,10463,10464,10467,10469,10471,10474],{"class":1029,"line":1104},[1027,10465,10466],{"class":1079},"    b",[1027,10468,148],{"class":1626},[1027,10470,10353],{"class":1079},[1027,10472,10473],{"class":1083},"    AS",[1027,10475,10476],{"class":1626}," book,\n",[1027,10478,10479,10482,10484,10487],{"class":1029,"line":1231},[1027,10480,10481],{"class":1079},"    br",[1027,10483,148],{"class":1626},[1027,10485,10486],{"class":1079},"borrowed_on",[1027,10488,4654],{"class":1626},[1027,10490,10491,10493,10495,10498],{"class":1029,"line":1241},[1027,10492,10481],{"class":1079},[1027,10494,148],{"class":1626},[1027,10496,10497],{"class":1079},"due_on",[1027,10499,4654],{"class":1626},[1027,10501,10502,10505,10507,10510,10512,10514,10516],{"class":1029,"line":1246},[1027,10503,10504],{"class":1626},"    CURRENT_DATE ",[1027,10506,6373],{"class":1083},[1027,10508,10509],{"class":1079}," br",[1027,10511,148],{"class":1626},[1027,10513,10497],{"class":1079},[1027,10515,7753],{"class":1083},[1027,10517,10518],{"class":1626}," days_overdue\n",[1027,10520,10521,10523],{"class":1029,"line":1252},[1027,10522,6199],{"class":1083},[1027,10524,10525],{"class":1626}," borrowings br\n",[1027,10527,10528,10530,10533,10535,10537,10539,10542,10544,10547,10549],{"class":1029,"line":1262},[1027,10529,7914],{"class":1083},[1027,10531,10532],{"class":1626}," members m ",[1027,10534,7582],{"class":1083},[1027,10536,10509],{"class":1079},[1027,10538,148],{"class":1626},[1027,10540,10541],{"class":1079},"member_id",[1027,10543,7592],{"class":1083},[1027,10545,10546],{"class":1079}," m",[1027,10548,148],{"class":1626},[1027,10550,10417],{"class":1079},[1027,10552,10553,10555,10558,10560,10562,10564,10567,10569,10571,10573],{"class":1029,"line":1267},[1027,10554,7914],{"class":1083},[1027,10556,10557],{"class":1626}," books   b ",[1027,10559,7582],{"class":1083},[1027,10561,10509],{"class":1079},[1027,10563,148],{"class":1626},[1027,10565,10566],{"class":1079},"book_id",[1027,10568,7979],{"class":1083},[1027,10570,10348],{"class":1079},[1027,10572,148],{"class":1626},[1027,10574,10417],{"class":1079},[1027,10576,10577,10579,10581,10583,10586,10589,10591],{"class":1029,"line":1273},[1027,10578,5348],{"class":1083},[1027,10580,10509],{"class":1079},[1027,10582,148],{"class":1626},[1027,10584,10585],{"class":1079},"returned_on",[1027,10587,10588],{"class":1083}," IS",[1027,10590,5301],{"class":1083},[1027,10592,5358],{"class":1626},[1027,10594,10595],{"class":1029,"line":1283},[1027,10596,1064],{"emptyLinePlaceholder":1063},[1027,10598,10599],{"class":1029,"line":1288},[1027,10600,10601],{"class":1033},"-- Q3: Members who have never borrowed a book\n",[1027,10603,10604,10606,10608,10610,10612,10614,10617,10619],{"class":1029,"line":1294},[1027,10605,5336],{"class":1083},[1027,10607,10546],{"class":1079},[1027,10609,148],{"class":1626},[1027,10611,5724],{"class":1079},[1027,10613,160],{"class":1626},[1027,10615,10616],{"class":1079},"m",[1027,10618,148],{"class":1626},[1027,10620,10621],{"class":1079},"email\n",[1027,10623,10624,10626],{"class":1029,"line":6733},[1027,10625,6199],{"class":1083},[1027,10627,10628],{"class":1626}," members m\n",[1027,10630,10631,10633,10636,10638,10640,10642,10644,10646,10648,10650],{"class":1029,"line":6744},[1027,10632,7680],{"class":1083},[1027,10634,10635],{"class":1626}," borrowings br ",[1027,10637,7582],{"class":1083},[1027,10639,10546],{"class":1079},[1027,10641,148],{"class":1626},[1027,10643,7539],{"class":1079},[1027,10645,7592],{"class":1083},[1027,10647,10509],{"class":1079},[1027,10649,148],{"class":1626},[1027,10651,10652],{"class":1079},"member_id\n",[1027,10654,10655,10657,10659,10661,10663,10665,10667],{"class":1029,"line":6767},[1027,10656,5348],{"class":1083},[1027,10658,10509],{"class":1079},[1027,10660,148],{"class":1626},[1027,10662,7539],{"class":1079},[1027,10664,10588],{"class":1083},[1027,10666,5301],{"class":1083},[1027,10668,5358],{"class":1626},[1027,10670,10671],{"class":1029,"line":6772},[1027,10672,1064],{"emptyLinePlaceholder":1063},[1027,10674,10675],{"class":1029,"line":6783},[1027,10676,10677],{"class":1033},"-- Q4: Most popular book (borrowed most times)\n",[1027,10679,10680,10682,10684,10686,10688,10690,10692,10694,10696,10698,10700],{"class":1029,"line":6806},[1027,10681,5336],{"class":1083},[1027,10683,10348],{"class":1079},[1027,10685,148],{"class":1626},[1027,10687,10353],{"class":1079},[1027,10689,160],{"class":1626},[1027,10691,7309],{"class":1079},[1027,10693,4665],{"class":1626},[1027,10695,6073],{"class":1083},[1027,10697,5585],{"class":1626},[1027,10699,6285],{"class":1083},[1027,10701,10702],{"class":1626}," borrow_count\n",[1027,10704,10705,10707],{"class":1029,"line":6811},[1027,10706,6199],{"class":1083},[1027,10708,10525],{"class":1626},[1027,10710,10711,10713,10716,10718,10720,10722,10724,10726,10728,10730],{"class":1029,"line":6817},[1027,10712,7914],{"class":1083},[1027,10714,10715],{"class":1626}," books b ",[1027,10717,7582],{"class":1083},[1027,10719,10509],{"class":1079},[1027,10721,148],{"class":1626},[1027,10723,10566],{"class":1079},[1027,10725,7592],{"class":1083},[1027,10727,10348],{"class":1079},[1027,10729,148],{"class":1626},[1027,10731,10417],{"class":1079},[1027,10733,10734,10736,10738,10740],{"class":1029,"line":9840},[1027,10735,7251],{"class":1083},[1027,10737,10348],{"class":1079},[1027,10739,148],{"class":1626},[1027,10741,10742],{"class":1079},"title\n",[1027,10744,10745,10747,10750],{"class":1029,"line":9846},[1027,10746,6214],{"class":1083},[1027,10748,10749],{"class":1626}," borrow_count ",[1027,10751,6226],{"class":1083},[1027,10753,10754,10756,10758],{"class":1029,"line":9858},[1027,10755,6231],{"class":1083},[1027,10757,6111],{"class":1079},[1027,10759,5358],{"class":1626},[1027,10761,10762],{"class":1029,"line":9869},[1027,10763,1064],{"emptyLinePlaceholder":1063},[1027,10765,10766],{"class":1029,"line":9884},[1027,10767,10768],{"class":1033},"-- Q5: Create a view for the library dashboard\n",[1027,10770,10771,10773,10775,10778],{"class":1029,"line":9899},[1027,10772,4631],{"class":1083},[1027,10774,9256],{"class":1083},[1027,10776,10777],{"class":1040}," library_dashboard",[1027,10779,9262],{"class":1083},[1027,10781,10782],{"class":1029,"line":9913},[1027,10783,6267],{"class":1083},[1027,10785,10786,10788,10790,10792],{"class":1029,"line":9925},[1027,10787,10466],{"class":1079},[1027,10789,148],{"class":1626},[1027,10791,7539],{"class":1079},[1027,10793,4654],{"class":1626},[1027,10795,10796,10798,10800,10802],{"class":1029,"line":9933},[1027,10797,10466],{"class":1079},[1027,10799,148],{"class":1626},[1027,10801,10353],{"class":1079},[1027,10803,4654],{"class":1626},[1027,10805,10807,10810,10812,10814,10816],{"class":1029,"line":10806},38,[1027,10808,10809],{"class":1079},"    a",[1027,10811,148],{"class":1626},[1027,10813,5724],{"class":1079},[1027,10815,7753],{"class":1083},[1027,10817,10818],{"class":1626}," author,\n",[1027,10820,10822,10824,10826,10829],{"class":1029,"line":10821},39,[1027,10823,10466],{"class":1079},[1027,10825,148],{"class":1626},[1027,10827,10828],{"class":1079},"total_copies",[1027,10830,4654],{"class":1626},[1027,10832,10834,10836,10838,10840,10843,10845,10847,10850,10852,10854,10856,10859,10861,10863,10865,10867,10869,10871,10873,10875,10877],{"class":1029,"line":10833},40,[1027,10835,10466],{"class":1079},[1027,10837,148],{"class":1626},[1027,10839,10828],{"class":1079},[1027,10841,10842],{"class":1083}," -",[1027,10844,7136],{"class":1079},[1027,10846,4665],{"class":1626},[1027,10848,10849],{"class":1079},"br",[1027,10851,148],{"class":1626},[1027,10853,7539],{"class":1079},[1027,10855,5585],{"class":1626},[1027,10857,10858],{"class":1083},"FILTER",[1027,10860,5873],{"class":1626},[1027,10862,5348],{"class":1083},[1027,10864,10509],{"class":1079},[1027,10866,148],{"class":1626},[1027,10868,10585],{"class":1079},[1027,10870,10588],{"class":1083},[1027,10872,5301],{"class":1083},[1027,10874,5585],{"class":1626},[1027,10876,6285],{"class":1083},[1027,10878,10879],{"class":1626}," available_copies\n",[1027,10881,10883,10885],{"class":1029,"line":10882},41,[1027,10884,6199],{"class":1083},[1027,10886,10391],{"class":1626},[1027,10888,10890,10892,10894,10896,10898,10900,10902,10904,10906,10908],{"class":1029,"line":10889},42,[1027,10891,7914],{"class":1083},[1027,10893,10398],{"class":1626},[1027,10895,7582],{"class":1083},[1027,10897,10348],{"class":1079},[1027,10899,148],{"class":1626},[1027,10901,10407],{"class":1079},[1027,10903,7592],{"class":1083},[1027,10905,10412],{"class":1079},[1027,10907,148],{"class":1626},[1027,10909,10417],{"class":1079},[1027,10911,10913,10915,10917,10919,10921,10923,10925,10927,10929,10931],{"class":1029,"line":10912},43,[1027,10914,7680],{"class":1083},[1027,10916,10635],{"class":1626},[1027,10918,7582],{"class":1083},[1027,10920,10348],{"class":1079},[1027,10922,148],{"class":1626},[1027,10924,7539],{"class":1079},[1027,10926,7592],{"class":1083},[1027,10928,10509],{"class":1079},[1027,10930,148],{"class":1626},[1027,10932,10933],{"class":1079},"book_id\n",[1027,10935,10937,10939,10941,10943,10945,10947,10949,10951,10953,10955,10957,10959,10961,10963,10965,10967,10969],{"class":1029,"line":10936},44,[1027,10938,7251],{"class":1083},[1027,10940,10348],{"class":1079},[1027,10942,148],{"class":1626},[1027,10944,7539],{"class":1079},[1027,10946,160],{"class":1626},[1027,10948,10370],{"class":1079},[1027,10950,148],{"class":1626},[1027,10952,10353],{"class":1079},[1027,10954,160],{"class":1626},[1027,10956,10358],{"class":1079},[1027,10958,148],{"class":1626},[1027,10960,5724],{"class":1079},[1027,10962,160],{"class":1626},[1027,10964,10370],{"class":1079},[1027,10966,148],{"class":1626},[1027,10968,10828],{"class":1079},[1027,10970,5358],{"class":1626},[1027,10972,10974],{"class":1029,"line":10973},45,[1027,10975,1064],{"emptyLinePlaceholder":1063},[1027,10977,10979,10981,10983,10985],{"class":1029,"line":10978},46,[1027,10980,5336],{"class":1083},[1027,10982,5339],{"class":1083},[1027,10984,5342],{"class":1083},[1027,10986,10987],{"class":1626}," library_dashboard;\n",[4355,10989],{},[28,10991,10993],{"id":10992},"_11-common-beginner-mistakes","11. Common Beginner Mistakes",[11,10995,10996,10997,11000],{},"These are the most frequent errors seen when students first ",[20,10998,10999],{},"learn SQL from\nscratch"," — avoid them and you'll be ahead of the curve.",[450,11002,11003,11016],{},[453,11004,11005],{},[456,11006,11007,11010,11013],{},[459,11008,11009],{},"Mistake",[459,11011,11012],{},"Why It's Wrong",[459,11014,11015],{},"How to Fix It",[469,11017,11018,11040,11060,11087,11101,11115,11126,11137],{},[456,11019,11020,11028,11034],{},[474,11021,11022,11025,11026],{},[15,11023,11024],{},"UPDATE table SET col = val"," without ",[15,11027,5348],{},[474,11029,11030,11031,11033],{},"Updates ",[20,11032,8541],{}," row in the table",[474,11035,11036,11037,11039],{},"Always include ",[15,11038,5348],{}," unless intentional",[456,11041,11042,11049,11056],{},[474,11043,11044,11025,11047],{},[15,11045,11046],{},"DELETE FROM table",[15,11048,5348],{},[474,11050,11051,11052,11055],{},"Deletes ",[20,11053,11054],{},"all"," rows",[474,11057,11036,11058],{},[15,11059,5348],{},[456,11061,11062,11067,11079],{},[474,11063,11064,11065],{},"Comparing NULL with ",[15,11066,5274],{},[474,11068,11069,11072,11073,11076,11077],{},[15,11070,11071],{},"NULL = NULL"," is always ",[15,11074,11075],{},"UNKNOWN",", not ",[15,11078,5166],{},[474,11080,11081,11082,11084,11085],{},"Use ",[15,11083,5318],{}," / ",[15,11086,5321],{},[456,11088,11089,11095,11098],{},[474,11090,11091,11094],{},[15,11092,11093],{},"SELECT *"," in production code",[474,11096,11097],{},"Fetches unnecessary data, breaks if schema changes",[474,11099,11100],{},"Explicitly list only needed columns",[456,11102,11103,11106,11109],{},[474,11104,11105],{},"Not using transactions for multi-step operations",[474,11107,11108],{},"Partial failure leaves data in inconsistent state",[474,11110,11111,11112],{},"Wrap related operations in ",[15,11113,11114],{},"BEGIN...COMMIT",[456,11116,11117,11120,11123],{},[474,11118,11119],{},"Forgetting to index foreign keys",[474,11121,11122],{},"Joins and lookups become full table scans",[474,11124,11125],{},"Add index on every FK column",[456,11127,11128,11131,11134],{},[474,11129,11130],{},"Putting business logic only in app code, not DB",[474,11132,11133],{},"App bugs can corrupt data",[474,11135,11136],{},"Use constraints, foreign keys, and CHECK",[456,11138,11139,11145,11151],{},[474,11140,11141,11142,11144],{},"Using ",[15,11143,5115],{}," for money",[474,11146,11147,11148],{},"Floating-point is imprecise: ",[15,11149,11150],{},"0.1 + 0.2 ≠ 0.3",[474,11152,11081,11153,11156],{},[15,11154,11155],{},"DECIMAL(10,2)"," for monetary values",[4355,11158],{},[28,11160,11162],{"id":11161},"_12-summary-what-to-learn-next","12. Summary & What to Learn Next",[232,11164,11166],{"id":11165},"what-youve-learned","What You've Learned",[450,11168,11169,11179],{},[453,11170,11171],{},[456,11172,11173,11176],{},[459,11174,11175],{},"Concept",[459,11177,11178],{},"Key Takeaway",[469,11180,11181,11188,11196,11204,11212,11220,11228,11236,11244,11252,11260,11268],{},[456,11182,11183,11185],{},[474,11184,4440],{},[474,11186,11187],{},"Software engine that stores and manages relational data",[456,11189,11190,11193],{},[474,11191,11192],{},"Tables",[474,11194,11195],{},"Data is stored in rows and columns, like a strict spreadsheet",[456,11197,11198,11201],{},[474,11199,11200],{},"Keys",[474,11202,11203],{},"Primary keys identify rows; foreign keys link tables",[456,11205,11206,11209],{},[474,11207,11208],{},"Relationships",[474,11210,11211],{},"1:1, 1:N, M:N modeled with tables and foreign keys",[456,11213,11214,11217],{},[474,11215,11216],{},"SQL sublanguages",[474,11218,11219],{},"DDL (structure), DML (change data), DQL (query data)",[456,11221,11222,11225],{},[474,11223,11224],{},"Joins",[474,11226,11227],{},"INNER, LEFT, RIGHT, FULL — combine rows from multiple tables",[456,11229,11230,11233],{},[474,11231,11232],{},"Aggregation",[474,11234,11235],{},"GROUP BY + COUNT/SUM/AVG/MIN/MAX for summarizing data",[456,11237,11238,11241],{},[474,11239,11240],{},"Constraints",[474,11242,11243],{},"Enforce data integrity at the database level",[456,11245,11246,11249],{},[474,11247,11248],{},"Normalization",[474,11250,11251],{},"Design tables to eliminate redundancy (1NF → 2NF → 3NF)",[456,11253,11254,11257],{},[474,11255,11256],{},"Indexes",[474,11258,11259],{},"Speed up SELECT queries; come at a cost to writes",[456,11261,11262,11265],{},[474,11263,11264],{},"Transactions",[474,11266,11267],{},"ACID properties guarantee correctness in multi-step operations",[456,11269,11270,11273],{},[474,11271,11272],{},"Views",[474,11274,11275],{},"Virtual tables from saved queries for simplicity and security",[232,11277,11279],{"id":11278},"recommended-next-topics","Recommended Next Topics",[1748,11281,11282,11301,11309,11315,11321,11330,11336],{},[79,11283,11284,11287,11288,160,11291,160,11294,160,11297,11300],{},[20,11285,11286],{},"Window Functions",": ",[15,11289,11290],{},"RANK()",[15,11292,11293],{},"ROW_NUMBER()",[15,11295,11296],{},"LAG()",[15,11298,11299],{},"LEAD()"," — the\nmost powerful SQL feature most beginners never learn.",[79,11302,11303,11287,11306,11308],{},[20,11304,11305],{},"Query Optimization",[15,11307,8928],{},", reading query plans, index\nstrategies.",[79,11310,11311,11314],{},[20,11312,11313],{},"Stored Procedures & Functions",": reusable logic inside the database.",[79,11316,11317,11320],{},[20,11318,11319],{},"Triggers",": automatic actions that fire on INSERT/UPDATE/DELETE.",[79,11322,11323,11326,11327,148],{},[20,11324,11325],{},"CTEs (Common Table Expressions)",": cleaner alternative to subqueries\nusing ",[15,11328,11329],{},"WITH",[79,11331,11332,11335],{},[20,11333,11334],{},"PostgreSQL-specific features",": JSONB, arrays, full-text search,\npartitioning.",[79,11337,11338,11341],{},[20,11339,11340],{},"Database Security",": roles, row-level security, encryption at rest.",[232,11343,11345],{"id":11344},"practice-resources","Practice Resources",[76,11347,11348,11353,11359,11365],{},[79,11349,11350,11352],{},[20,11351,4500],{},": Zero-install. Download DB Browser for SQLite and start immediately.",[79,11354,11355,11358],{},[20,11356,11357],{},"pgAdmin / DBeaver",": GUI tools for exploring and running queries.",[79,11360,11361,11364],{},[20,11362,11363],{},"LeetCode Database Problems",": SQL problems ranked by difficulty.",[79,11366,11367,11370],{},[20,11368,11369],{},"SQLZoo SQL Tutorial",": Interactive SQL practice in the browser.",[4355,11372],{},[56,11374,11375],{},[11,11376,11377,11380],{},[4263,11378,11379],{},"\"Bad programmers worry about the code. Good programmers worry about data\nstructures and their relationships.\"","\n— Linus Torvalds",[11,11382,11383],{},"The database is the foundation your entire application sits on. Get this\nfoundation right, and everything built on top of it becomes simpler,\nfaster, and more reliable.",[11,11385,11386],{},"Thanks for reading!",[2377,11388,11389],{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}",{"title":135,"searchDepth":1037,"depth":1037,"links":11391},[11392,11395,11404,11410,11417,11418,11422,11423,11427,11428,11433,11434],{"id":4257,"depth":1037,"text":4258,"children":11393},[11394],{"id":4294,"depth":1048,"text":4295},{"id":4359,"depth":1037,"text":4360,"children":11396},[11397,11398,11399,11400,11401,11402,11403],{"id":4363,"depth":1048,"text":4364},{"id":4433,"depth":1048,"text":4434},{"id":4537,"depth":1048,"text":4538},{"id":4588,"depth":1048,"text":4589},{"id":4882,"depth":1048,"text":4883},{"id":5040,"depth":1048,"text":5041},{"id":5235,"depth":1048,"text":5236},{"id":5393,"depth":1037,"text":5394,"children":11405},[11406,11407,11408,11409],{"id":5533,"depth":1048,"text":5534},{"id":5838,"depth":1048,"text":5839},{"id":6167,"depth":1048,"text":6168},{"id":6307,"depth":1048,"text":6308},{"id":6448,"depth":1037,"text":6449,"children":11411},[11412,11413,11414,11415,11416],{"id":6452,"depth":1048,"text":6453},{"id":6843,"depth":1048,"text":6844},{"id":7002,"depth":1048,"text":7003},{"id":7452,"depth":1048,"text":7453},{"id":8005,"depth":1048,"text":8006},{"id":8185,"depth":1037,"text":8186},{"id":8498,"depth":1037,"text":8499,"children":11419},[11420,11421],{"id":8518,"depth":1048,"text":8519},{"id":8551,"depth":1048,"text":8552},{"id":8757,"depth":1037,"text":8758},{"id":8937,"depth":1037,"text":8938,"children":11424},[11425,11426],{"id":8951,"depth":1048,"text":8952},{"id":9063,"depth":1048,"text":9064},{"id":9228,"depth":1037,"text":9229},{"id":9503,"depth":1037,"text":9504,"children":11429},[11430,11431,11432],{"id":9517,"depth":1048,"text":9518},{"id":9938,"depth":1048,"text":9939},{"id":10330,"depth":1048,"text":10331},{"id":10992,"depth":1037,"text":10993},{"id":11161,"depth":1037,"text":11162,"children":11435},[11436,11437,11438],{"id":11165,"depth":1048,"text":11166},{"id":11278,"depth":1048,"text":11279},{"id":11344,"depth":1048,"text":11345},"2026-04-15","Learn SQL and RDBMS fundamentals with simple explanations of relational databases, tables, queries, primary keys vs foreign keys, joins, schema design, normalization, indexes, and transactions.","sql-made-dead-simple-rdbms-guide.png",{},"/backend/sql-made-dead-simple-rdbms-guide",{"title":4252,"description":11440},"Backend/2.sql-made-dead-simple-rdbms-guide",[11447,4440,4397,2455],"SQL","T0ZNeQJaDr9_oMnNS87nraXnakFqyGlRhI1vCayAIKc",{"id":11450,"title":11451,"author":6,"body":11452,"date":12793,"description":12794,"draft":2444,"extension":2445,"guide":2446,"image":12795,"meta":12796,"navigation":1063,"path":12797,"seo":12798,"stem":12799,"tags":12800,"__hash__":12805},"blog/Backend/1.everything-about-json-web-tokens-explained.md","Everything You Actually Need to Know About JWT (Without the Fluff)",{"type":8,"value":11453,"toc":12767},[11454,11457,11461,11471,11478,11483,11487,11494,11506,11510,11517,11520,11562,11565,11569,11578,11584,11588,11603,11648,11667,11671,11682,11771,11780,11784,11791,11884,11891,11895,11901,11904,11908,11911,12017,12021,12031,12035,12047,12052,12056,12059,12063,12070,12073,12077,12088,12091,12100,12104,12107,12179,12184,12219,12224,12446,12450,12453,12458,12472,12477,12500,12509,12513,12516,12521,12538,12543,12559,12563,12570,12573,12612,12616,12619,12687,12692,12756,12758,12764],[11,11455,11456],{},"Welcome, engineers! Today, we’re going to demystify JSON Web Tokens (JWT). By the end of this article, you’ll understand what JWTs are, why they’re used everywhere, and how they work under the hood—all with simple analogies and practical examples.",[28,11458,11460],{"id":11459},"what-is-jwt-and-why-does-it-matter","What is JWT and Why Does it Matter?",[11,11462,11463,11466,11467,11470],{},[20,11464,11465],{},"JSON Web Token (JWT)"," is an open internet standard defined in ",[20,11468,11469],{},"RFC 7519",". At its core, it is a compact, URL-safe string that encodes a set of claims — verifiable facts about a user or session — as a JSON object, and then digitally signs them so the receiver can trust what they read.",[11,11472,11473,11474,11477],{},"Think of a JWT the way you think of a ",[20,11475,11476],{},"government-issued ID card",". The card contains your name, date of birth, and a photo. Anyone who sees it can read the information. But crucially, it carries an official seal or hologram that only the government can produce — so you can't just forge one at home. JWT works on exactly the same principle: the token carries readable data, but it is cryptographically sealed so nobody can tamper with it.",[56,11479,11480],{},[11,11481,11482],{},"Imagine you log into your company's internal dashboard. The server creates a little \"badge\" for you that says: \"This person is X, their role is admin, and this badge is valid until 5 PM.\" The badge is stamped with the server's private seal. Every time you visit a protected page, you flash this badge at the door. The door doesn't need to call HR — it can verify the stamp itself, instantly.",[28,11484,11486],{"id":11485},"a-real-world-example","A Real-World Example",[11,11488,11489,11490,11493],{},"You open your favourite music streaming app. You type your email and password and hit \"Log In\". The app's server checks your credentials and, upon success, generates a JWT that encodes your user ID, subscription tier, and an expiration time of one hour. It sends this token back to your browser. For the rest of the session, every API request your browser makes — \"fetch my playlists,\" \"play this song,\" \"update my preferences\" — attaches this JWT in the ",[15,11491,11492],{},"Authorization"," header. The API server reads and verifies the token and immediately knows who you are and what you're allowed to do, without a single database lookup.",[56,11495,11496],{},[11,11497,11498,11499,1759,11502,11505],{},"Why this matters\nIn a world of microservices, mobile apps, and third-party APIs, passing session cookies between services is cumbersome and fragile. JWTs are ",[20,11500,11501],{},"stateless",[20,11503,11504],{},"self-contained"," — any service that knows the signing key can independently verify a token with zero coordination.",[28,11507,11509],{"id":11508},"the-problem-jwt-solves","The Problem JWT Solves",[11,11511,11512,11513,11516],{},"Before JWTs, the dominant approach was ",[20,11514,11515],{},"server-side sessions",". When you logged in, the server would create a session record in a database or in memory and hand you a random session ID (typically stored in a cookie). On every request, the server would look up that session ID to figure out who you were.",[11,11518,11519],{},"This worked fine for small, single-server applications. But it had serious problems at scale:",[76,11521,11522,11530,11538,11554],{},[79,11523,11524,11527,11529],{},[20,11525,11526],{},"Stickiness problem",[10849,11528],{},"If you have 10 servers behind a load balancer, the server that created your session must also be the one that receives future requests — otherwise it won't find your session in memory.",[79,11531,11532,11535,11537],{},[20,11533,11534],{},"Database bottleneck",[10849,11536],{},"Every protected API call requires a database query to validate the session. Under heavy traffic, this becomes a significant overhead.",[79,11539,11540,11543,11545,11546,11549,11550,11553],{},[20,11541,11542],{},"Cross-domain friction",[10849,11544],{},"Cookies work poorly across different domains. If your frontend is on ",[15,11547,11548],{},"app.example.com"," and your API is on ",[15,11551,11552],{},"api.other.com",", sharing session cookies requires careful and fragile CORS configuration.",[79,11555,11556,11559,11561],{},[20,11557,11558],{},"Microservices mismatch",[10849,11560],{},"In a microservices architecture, each service would need to either share a session store or call a central auth service on every request. Both options add latency and coupling.",[11,11563,11564],{},"JWTs eliminate these problems. The token itself is the session — it carries all the information needed for verification. No shared state. No database lookup. No sticky sessions.",[28,11566,11568],{"id":11567},"structure-of-a-jwt-three-parts-separated-by-dots","Structure of a JWT: Three Parts, Separated by Dots",[11,11570,11571,11572,11575,11576,45],{},"A JWT looks intimidating at first glance — just a long blob of characters. But it has a very precise structure: ",[20,11573,11574],{},"three Base64URL-encoded sections",", separated by dots (",[15,11577,148],{},[11,11579,11580],{},[123,11581],{"alt":11582,"src":11583},"Structure of JWT","/post-images/everything-about-json-web-tokens-explained/structure-of-jwt.png",[232,11585,11587],{"id":11586},"part-1-the-header","Part 1 — The Header",[11,11589,11590,11591,11594,11595,11598,11599,11602],{},"The header is a ",[20,11592,11593],{},"JSON object"," that declares the ",[20,11596,11597],{},"token type"," and the ",[20,11600,11601],{},"signing algorithm",". It's Base64URL encoded and placed as the first segment.",[127,11604,11608],{"className":11605,"code":11606,"language":11607,"meta":135,"style":135},"language-json shiki shiki-themes github-dark","{\n  \"alg\": \"HS256\",   // Algorithm: HMAC + SHA-256\n  \"typ\": \"JWT\"    // Token type: JSON Web Token\n}\n","json",[15,11609,11610,11615,11630,11643],{"__ignoreMap":135},[1027,11611,11612],{"class":1029,"line":1030},[1027,11613,11614],{"class":1626},"{\n",[1027,11616,11617,11620,11622,11625,11627],{"class":1029,"line":1037},[1027,11618,11619],{"class":1079},"  \"alg\"",[1027,11621,11287],{"class":1626},[1027,11623,11624],{"class":1044},"\"HS256\"",[1027,11626,10219],{"class":1626},[1027,11628,11629],{"class":1033},"// Algorithm: HMAC + SHA-256\n",[1027,11631,11632,11635,11637,11640],{"class":1029,"line":1048},[1027,11633,11634],{"class":1079},"  \"typ\"",[1027,11636,11287],{"class":1626},[1027,11638,11639],{"class":1044},"\"JWT\"",[1027,11641,11642],{"class":1033},"    // Token type: JSON Web Token\n",[1027,11644,11645],{"class":1029,"line":1054},[1027,11646,11647],{"class":1626},"}\n",[11,11649,11650,11651,11654,11655,11658,11659,11662,11663,11666],{},"Common values for ",[15,11652,11653],{},"alg"," include ",[15,11656,11657],{},"HS256"," (symmetric key, shared secret), ",[15,11660,11661],{},"RS256"," (RSA asymmetric key pair), and ",[15,11664,11665],{},"ES256"," (Elliptic Curve). The choice of algorithm has significant security implications, which we'll cover in the Signing section.",[232,11668,11670],{"id":11669},"part-2-the-payload","Part 2 — The Payload",[11,11672,11673,11674,11677,11678,11681],{},"The payload is the ",[20,11675,11676],{},"actual data"," — a JSON object of key-value pairs called ",[20,11679,11680],{},"claims",". Claims describe the user or session and carry any additional information the application needs.",[127,11683,11685],{"className":11605,"code":11684,"language":11607,"meta":135,"style":135},"{\n  \"sub\":  \"user_123\",       // Subject: who this token is about\n  \"name\": \"Kashyap\",        // Custom claim: user's display name\n  \"role\": \"admin\",         // Custom claim: access role\n  \"iat\":  1716239022,      // Issued At (Unix timestamp)\n  \"exp\":  1716242622       // Expires At (iat + 1 hour)\n}\n",[15,11686,11687,11691,11707,11723,11738,11754,11767],{"__ignoreMap":135},[1027,11688,11689],{"class":1029,"line":1030},[1027,11690,11614],{"class":1626},[1027,11692,11693,11696,11699,11702,11704],{"class":1029,"line":1037},[1027,11694,11695],{"class":1079},"  \"sub\"",[1027,11697,11698],{"class":1626},":  ",[1027,11700,11701],{"class":1044},"\"user_123\"",[1027,11703,5567],{"class":1626},[1027,11705,11706],{"class":1033},"// Subject: who this token is about\n",[1027,11708,11709,11712,11714,11717,11720],{"class":1029,"line":1048},[1027,11710,11711],{"class":1079},"  \"name\"",[1027,11713,11287],{"class":1626},[1027,11715,11716],{"class":1044},"\"Kashyap\"",[1027,11718,11719],{"class":1626},",        ",[1027,11721,11722],{"class":1033},"// Custom claim: user's display name\n",[1027,11724,11725,11728,11730,11733,11735],{"class":1029,"line":1054},[1027,11726,11727],{"class":1079},"  \"role\"",[1027,11729,11287],{"class":1626},[1027,11731,11732],{"class":1044},"\"admin\"",[1027,11734,10072],{"class":1626},[1027,11736,11737],{"class":1033},"// Custom claim: access role\n",[1027,11739,11740,11743,11745,11748,11751],{"class":1029,"line":1060},[1027,11741,11742],{"class":1079},"  \"iat\"",[1027,11744,11698],{"class":1626},[1027,11746,11747],{"class":1079},"1716239022",[1027,11749,11750],{"class":1626},",      ",[1027,11752,11753],{"class":1033},"// Issued At (Unix timestamp)\n",[1027,11755,11756,11759,11761,11764],{"class":1029,"line":1067},[1027,11757,11758],{"class":1079},"  \"exp\"",[1027,11760,11698],{"class":1626},[1027,11762,11763],{"class":1079},"1716242622",[1027,11765,11766],{"class":1033},"       // Expires At (iat + 1 hour)\n",[1027,11768,11769],{"class":1029,"line":1073},[1027,11770,11647],{"class":1626},[56,11772,11773],{},[11,11774,11775,11776,11779],{},"The Payload is NOT Secret\nThe payload is base64‑encoded, not encrypted. Base64URL encoding is ",[20,11777,11778],{},"not encryption",". Anyone who has the token can decode and read the payload. Never put passwords, credit card numbers, or anything sensitive in the payload. JWTs are designed to be tamper-proof, not confidential.",[232,11781,11783],{"id":11782},"part-3-the-signature","Part 3 — The Signature",[11,11785,11786,11787,11790],{},"The signature is the cryptographic stamp that proves the token has not been altered. The signature is created by combining the encoded header, encoded payload, a ",[20,11788,11789],{},"secret"," (or private key), and the algorithm specified in the header.",[127,11792,11796],{"className":11793,"code":11794,"language":11795,"meta":135,"style":135},"language-js shiki shiki-themes github-dark","// Pseudocode\nconst data = base64url(header) + \".\" + base64url(payload);\n\n// For HS256 (symmetric)\nsignature = HMAC_SHA256(data, SECRET_KEY);\n\n// For RS256 (asymmetric)\nsignature = RSA_SHA256_SIGN(data, PRIVATE_KEY);\n","js",[15,11797,11798,11803,11832,11836,11841,11859,11863,11868],{"__ignoreMap":135},[1027,11799,11800],{"class":1029,"line":1030},[1027,11801,11802],{"class":1033},"// Pseudocode\n",[1027,11804,11805,11808,11811,11813,11816,11819,11821,11824,11827,11829],{"class":1029,"line":1037},[1027,11806,11807],{"class":1083},"const",[1027,11809,11810],{"class":1079}," data",[1027,11812,7592],{"class":1083},[1027,11814,11815],{"class":1040}," base64url",[1027,11817,11818],{"class":1626},"(header) ",[1027,11820,6405],{"class":1083},[1027,11822,11823],{"class":1044}," \".\"",[1027,11825,11826],{"class":1083}," +",[1027,11828,11815],{"class":1040},[1027,11830,11831],{"class":1626},"(payload);\n",[1027,11833,11834],{"class":1029,"line":1048},[1027,11835,1064],{"emptyLinePlaceholder":1063},[1027,11837,11838],{"class":1029,"line":1054},[1027,11839,11840],{"class":1033},"// For HS256 (symmetric)\n",[1027,11842,11843,11846,11848,11851,11854,11857],{"class":1029,"line":1060},[1027,11844,11845],{"class":1626},"signature ",[1027,11847,5274],{"class":1083},[1027,11849,11850],{"class":1040}," HMAC_SHA256",[1027,11852,11853],{"class":1626},"(data, ",[1027,11855,11856],{"class":1079},"SECRET_KEY",[1027,11858,4684],{"class":1626},[1027,11860,11861],{"class":1029,"line":1067},[1027,11862,1064],{"emptyLinePlaceholder":1063},[1027,11864,11865],{"class":1029,"line":1073},[1027,11866,11867],{"class":1033},"// For RS256 (asymmetric)\n",[1027,11869,11870,11872,11874,11877,11879,11882],{"class":1029,"line":1093},[1027,11871,11845],{"class":1626},[1027,11873,5274],{"class":1083},[1027,11875,11876],{"class":1040}," RSA_SHA256_SIGN",[1027,11878,11853],{"class":1626},[1027,11880,11881],{"class":1079},"PRIVATE_KEY",[1027,11883,4684],{"class":1626},[11,11885,11886,11887,11890],{},"The final JWT is just these three parts concatenated with dots: ",[15,11888,11889],{},"header.payload.signature",". If anyone changes even a single character in the payload, the signature will no longer match — and the server will reject the token.",[28,11892,11894],{"id":11893},"claims-the-heart-of-the-payload","Claims — The Heart of the Payload",[11,11896,4279,11897,11900],{},[20,11898,11899],{},"claim"," is simply a key-value pair inside the payload. The word \"claim\" reflects the fact that the token is asserting something about a subject — \"I claim that this user is an admin\" — and the signature is what makes that assertion trustworthy.",[11,11902,11903],{},"Claims are categorised into three types:",[232,11905,11907],{"id":11906},"registered-claims-standardised","Registered Claims (Standardised)",[11,11909,11910],{},"These are defined in RFC 7519. They are not mandatory but are strongly recommended because they are understood by all JWT libraries. They are intentionally short (3 characters) to keep tokens compact.",[450,11912,11913,11924],{},[453,11914,11915],{},[456,11916,11917,11920,11922],{},[459,11918,11919],{},"Claim",[459,11921,5411],{},[459,11923,7025],{},[469,11925,11926,11939,11952,11965,11978,11991,12004],{},[456,11927,11928,11933,11936],{},[474,11929,11930],{},[15,11931,11932],{},"iss",[474,11934,11935],{},"Issuer",[474,11937,11938],{},"Who created and signed the token (e.g., \"auth.myapp.com\")",[456,11940,11941,11946,11949],{},[474,11942,11943],{},[15,11944,11945],{},"sub",[474,11947,11948],{},"Subject",[474,11950,11951],{},"Who the token is about (e.g., a user ID)",[456,11953,11954,11959,11962],{},[474,11955,11956],{},[15,11957,11958],{},"aud",[474,11960,11961],{},"Audience",[474,11963,11964],{},"Who the token is intended for (e.g., \"api.myapp.com\")",[456,11966,11967,11972,11975],{},[474,11968,11969],{},[15,11970,11971],{},"exp",[474,11973,11974],{},"Expiration",[474,11976,11977],{},"Unix timestamp after which the token must be rejected",[456,11979,11980,11985,11988],{},[474,11981,11982],{},[15,11983,11984],{},"nbf",[474,11986,11987],{},"Not Before",[474,11989,11990],{},"Token is invalid before this Unix timestamp",[456,11992,11993,11998,12001],{},[474,11994,11995],{},[15,11996,11997],{},"iat",[474,11999,12000],{},"Issued At",[474,12002,12003],{},"Unix timestamp when the token was created",[456,12005,12006,12011,12014],{},[474,12007,12008],{},[15,12009,12010],{},"jti",[474,12012,12013],{},"JWT ID",[474,12015,12016],{},"A unique ID for this token — useful for preventing replay attacks",[232,12018,12020],{"id":12019},"public-claims","Public Claims",[11,12022,12023,12024,12027,12028,45],{},"These are custom claims that you define yourself. To avoid conflicts with other applications, they should either be registered in the ",[20,12025,12026],{},"IANA JWT Registry"," or use a collision-resistant name such as a URI (e.g., ",[15,12029,12030],{},"\"https://myapp.com/claims/role\"",[232,12032,12034],{"id":12033},"private-claims","Private Claims",[11,12036,12037,12038,160,12041,160,12044,148],{},"These are custom claims agreed upon between the specific issuer and consumer of the token — your backend and your frontend, for example. Since they're not shared with anyone else, collision resistance doesn't matter here. Examples: ",[15,12039,12040],{},"\"role\"",[15,12042,12043],{},"\"plan\"",[15,12045,12046],{},"\"teamId\"",[56,12048,12049],{},[11,12050,12051],{},"Practical tip\nKeep your payload small. Every API call transmits the entire token. Include only what the server actually needs to make an authorization decision — typically user ID, role, and expiration. Avoid embedding profile data that can be fetched on demand.",[28,12053,12055],{"id":12054},"signing-algorithms","Signing Algorithms",[11,12057,12058],{},"JWT supports two families of signing algorithms. Choosing the right one depends on your architecture.",[232,12060,12062],{"id":12061},"symmetric-hmac-hs256-hs384-hs512","Symmetric — HMAC (HS256, HS384, HS512)",[11,12064,12065,12066,12069],{},"Both the issuer and the verifier use the ",[20,12067,12068],{},"same secret key"," to sign and verify. This is simple and fast, but requires all verifying services to share the secret — meaning if any one of them is compromised, an attacker can forge tokens.",[11,12071,12072],{},"Best for: single-service architectures or cases where you fully control all verifying parties.",[232,12074,12076],{"id":12075},"asymmetric-rsa-ecdsa-rs256-es256","Asymmetric — RSA / ECDSA (RS256, ES256)",[11,12078,12079,12080,12083,12084,12087],{},"The issuing server signs tokens with a ",[20,12081,12082],{},"private key",". Verifying services only need the corresponding ",[20,12085,12086],{},"public key",". Sharing a public key is safe — it cannot be used to forge tokens, only to verify them.",[11,12089,12090],{},"Best for: microservices, multi-tenant systems, and any architecture where tokens are verified by parties you don't fully control (e.g., third-party services).",[56,12092,12093],{},[11,12094,12095,12096,12099],{},"Never Use ",[15,12097,12098],{},"\"alg\": \"none\"","\nThe JWT specification technically allows a \"none\" algorithm meaning no signature at all. Some early libraries trusted this — and attackers exploited it to forge arbitrary tokens. Any production-grade library rejects unsigned tokens by default. Always verify that your library is configured to require a valid algorithm.",[28,12101,12103],{"id":12102},"the-jwt-authentication-flow","The JWT Authentication Flow",[11,12105,12106],{},"Here is the complete end-to-end flow of JWT-based authentication — from login to accessing a protected resource.",[1748,12108,12109,12121,12129,12137,12149,12164],{},[79,12110,12111,12114,12116,12117,12120],{},[20,12112,12113],{},"User submits credentials",[10849,12115],{},"\nThe client sends a ",[15,12118,12119],{},"POST /login"," request with username and password over HTTPS.",[79,12122,12123,12126,12128],{},[20,12124,12125],{},"Server authenticates",[10849,12127],{},"\nThe auth server validates the credentials against the database. If correct, it proceeds to generate a token.",[79,12130,12131,12134,12136],{},[20,12132,12133],{},"Server issues a JWT",[10849,12135],{},"\nThe server builds a payload with the user's ID, role, and expiration time, signs it with the secret key, and returns the full token to the client.",[79,12138,12139,12142,12144,12145,12148],{},[20,12140,12141],{},"Client stores the token",[10849,12143],{},"\nThe client stores the JWT — ideally in an ",[15,12146,12147],{},"HttpOnly"," cookie to prevent JavaScript access (XSS protection). Local storage is convenient but less secure.",[79,12150,12151,12154,12156,12157,12159,12160,12163],{},[20,12152,12153],{},"Client sends the token on every request",[10849,12155],{},"\nFor each API call to a protected endpoint, the client attaches the token in the ",[15,12158,11492],{}," header using the ",[15,12161,12162],{},"Bearer"," schema:",[79,12165,12166,12169,12171,12172,160,12174,160,12176,12178],{},[20,12167,12168],{},"Server verifies and responds",[10849,12170],{},"\nThe API server re-computes the signature and checks the claims (",[15,12173,11971],{},[15,12175,11932],{},[15,12177,11958],{},"). If everything checks out, access is granted. No database call needed.",[11,12180,12181],{},[4263,12182,12183],{},"Step 5 — Authorization Header Format",[127,12185,12187],{"className":1021,"code":12186,"language":1023,"meta":135,"style":135},"GET /api/playlists HTTP/1.1\nHost: api.musicapp.com\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdW...\n",[15,12188,12189,12200,12208],{"__ignoreMap":135},[1027,12190,12191,12194,12197],{"class":1029,"line":1030},[1027,12192,12193],{"class":1040},"GET",[1027,12195,12196],{"class":1044}," /api/playlists",[1027,12198,12199],{"class":1044}," HTTP/1.1\n",[1027,12201,12202,12205],{"class":1029,"line":1037},[1027,12203,12204],{"class":1040},"Host:",[1027,12206,12207],{"class":1044}," api.musicapp.com\n",[1027,12209,12210,12213,12216],{"class":1029,"line":1048},[1027,12211,12212],{"class":1040},"Authorization:",[1027,12214,12215],{"class":1044}," Bearer",[1027,12217,12218],{"class":1044}," eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdW...\n",[11,12220,12221],{},[4263,12222,12223],{},"Step 3 + 6 — Node.js Example (jsonwebtoken library)",[127,12225,12227],{"className":11793,"code":12226,"language":11795,"meta":135,"style":135},"const jwt = require('jsonwebtoken');\nconst SECRET = process.env.JWT_SECRET;\n\n// On login: issue a token\nfunction issueToken(user) {\n  return jwt.sign(\n    { sub: user.id, role: user.role },\n    SECRET,\n    { expiresIn: '1h', issuer: 'auth.myapp.com' }\n  );\n}\n\n// On every protected request: verify the token\nfunction verifyToken(token) {\n  try {\n    return jwt.verify(token, SECRET, {\n      issuer: 'auth.myapp.com'\n    }); // Returns decoded payload if valid\n  } catch (err) {\n    throw new Error('Invalid or expired token');\n  }\n}\n",[15,12228,12229,12248,12265,12269,12274,12290,12304,12309,12316,12333,12338,12342,12346,12351,12365,12373,12392,12400,12408,12419,12437,12442],{"__ignoreMap":135},[1027,12230,12231,12233,12236,12238,12241,12243,12246],{"class":1029,"line":1030},[1027,12232,11807],{"class":1083},[1027,12234,12235],{"class":1079}," jwt",[1027,12237,7592],{"class":1083},[1027,12239,12240],{"class":1040}," require",[1027,12242,4665],{"class":1626},[1027,12244,12245],{"class":1044},"'jsonwebtoken'",[1027,12247,4684],{"class":1626},[1027,12249,12250,12252,12255,12257,12260,12263],{"class":1029,"line":1037},[1027,12251,11807],{"class":1083},[1027,12253,12254],{"class":1079}," SECRET",[1027,12256,7592],{"class":1083},[1027,12258,12259],{"class":1626}," process.env.",[1027,12261,12262],{"class":1079},"JWT_SECRET",[1027,12264,5358],{"class":1626},[1027,12266,12267],{"class":1029,"line":1048},[1027,12268,1064],{"emptyLinePlaceholder":1063},[1027,12270,12271],{"class":1029,"line":1054},[1027,12272,12273],{"class":1033},"// On login: issue a token\n",[1027,12275,12276,12279,12282,12284,12287],{"class":1029,"line":1060},[1027,12277,12278],{"class":1083},"function",[1027,12280,12281],{"class":1040}," issueToken",[1027,12283,4665],{"class":1626},[1027,12285,4916],{"class":12286},"s9osk",[1027,12288,12289],{"class":1626},") {\n",[1027,12291,12292,12295,12298,12301],{"class":1029,"line":1067},[1027,12293,12294],{"class":1083},"  return",[1027,12296,12297],{"class":1626}," jwt.",[1027,12299,12300],{"class":1040},"sign",[1027,12302,12303],{"class":1626},"(\n",[1027,12305,12306],{"class":1029,"line":1073},[1027,12307,12308],{"class":1626},"    { sub: user.id, role: user.role },\n",[1027,12310,12311,12314],{"class":1029,"line":1093},[1027,12312,12313],{"class":1079},"    SECRET",[1027,12315,4654],{"class":1626},[1027,12317,12318,12321,12324,12327,12330],{"class":1029,"line":1098},[1027,12319,12320],{"class":1626},"    { expiresIn: ",[1027,12322,12323],{"class":1044},"'1h'",[1027,12325,12326],{"class":1626},", issuer: ",[1027,12328,12329],{"class":1044},"'auth.myapp.com'",[1027,12331,12332],{"class":1626}," }\n",[1027,12334,12335],{"class":1029,"line":1104},[1027,12336,12337],{"class":1626},"  );\n",[1027,12339,12340],{"class":1029,"line":1231},[1027,12341,11647],{"class":1626},[1027,12343,12344],{"class":1029,"line":1241},[1027,12345,1064],{"emptyLinePlaceholder":1063},[1027,12347,12348],{"class":1029,"line":1246},[1027,12349,12350],{"class":1033},"// On every protected request: verify the token\n",[1027,12352,12353,12355,12358,12360,12363],{"class":1029,"line":1252},[1027,12354,12278],{"class":1083},[1027,12356,12357],{"class":1040}," verifyToken",[1027,12359,4665],{"class":1626},[1027,12361,12362],{"class":12286},"token",[1027,12364,12289],{"class":1626},[1027,12366,12367,12370],{"class":1029,"line":1262},[1027,12368,12369],{"class":1083},"  try",[1027,12371,12372],{"class":1626}," {\n",[1027,12374,12375,12378,12380,12383,12386,12389],{"class":1029,"line":1267},[1027,12376,12377],{"class":1083},"    return",[1027,12379,12297],{"class":1626},[1027,12381,12382],{"class":1040},"verify",[1027,12384,12385],{"class":1626},"(token, ",[1027,12387,12388],{"class":1079},"SECRET",[1027,12390,12391],{"class":1626},", {\n",[1027,12393,12394,12397],{"class":1029,"line":1273},[1027,12395,12396],{"class":1626},"      issuer: ",[1027,12398,12399],{"class":1044},"'auth.myapp.com'\n",[1027,12401,12402,12405],{"class":1029,"line":1283},[1027,12403,12404],{"class":1626},"    }); ",[1027,12406,12407],{"class":1033},"// Returns decoded payload if valid\n",[1027,12409,12410,12413,12416],{"class":1029,"line":1288},[1027,12411,12412],{"class":1626},"  } ",[1027,12414,12415],{"class":1083},"catch",[1027,12417,12418],{"class":1626}," (err) {\n",[1027,12420,12421,12424,12427,12430,12432,12435],{"class":1029,"line":1294},[1027,12422,12423],{"class":1083},"    throw",[1027,12425,12426],{"class":1083}," new",[1027,12428,12429],{"class":1040}," Error",[1027,12431,4665],{"class":1626},[1027,12433,12434],{"class":1044},"'Invalid or expired token'",[1027,12436,4684],{"class":1626},[1027,12438,12439],{"class":1029,"line":6733},[1027,12440,12441],{"class":1626},"  }\n",[1027,12443,12444],{"class":1029,"line":6744},[1027,12445,11647],{"class":1626},[28,12447,12449],{"id":12448},"validation-vs-verification","Validation vs. Verification",[11,12451,12452],{},"These two terms are often used interchangeably, but they mean different things and both are necessary.",[11,12454,12455],{},[20,12456,12457],{},"Verification (Cryptographic)",[76,12459,12460,12463,12466,12469],{},[79,12461,12462],{},"Re-computes the signature using the secret/public key",[79,12464,12465],{},"Confirms the token was issued by a trusted party",[79,12467,12468],{},"Confirms the header and payload have not been altered",[79,12470,12471],{},"A single failed bit in the signature rejects the token",[11,12473,12474],{},[20,12475,12476],{},"Validation (Claims-based)",[76,12478,12479,12485,12490,12495],{},[79,12480,12481,12482,12484],{},"Checks ",[15,12483,11971],{},": is the token still valid?",[79,12486,12481,12487,12489],{},[15,12488,11984],{},": is it too early to use?",[79,12491,12481,12492,12494],{},[15,12493,11932],{},": is the issuer expected?",[79,12496,12481,12497,12499],{},[15,12498,11958],{},": is this token meant for us?",[11,12501,12502,12503,12505,12506,148],{},"A token can pass cryptographic verification but still be invalid — for example, if it was issued yesterday and its ",[15,12504,11971],{}," claim has passed. Your server must ",[20,12507,12508],{},"always do both",[28,12510,12512],{"id":12511},"trade-offs-and-limitations","Trade-offs and Limitations",[11,12514,12515],{},"JWTs are powerful but not a silver bullet. Understanding their limitations will save you from real production incidents.",[11,12517,12518],{},[20,12519,12520],{},"Strengths",[76,12522,12523,12526,12529,12532,12535],{},[79,12524,12525],{},"Stateless — no server memory or session store required",[79,12527,12528],{},"Self-contained — all info is in the token itself",[79,12530,12531],{},"Cross-domain — works across microservices and domains",[79,12533,12534],{},"Language-agnostic — libraries exist for every platform",[79,12536,12537],{},"Performance — eliminates per-request database lookups",[11,12539,12540],{},[20,12541,12542],{},"Weaknesses",[76,12544,12545,12550,12553,12556],{},[79,12546,12547,12548],{},"Hard to revoke — a valid token stays valid until ",[15,12549,11971],{},[79,12551,12552],{},"Size — larger than an opaque session ID cookie",[79,12554,12555],{},"Key leak — a leaked secret allows unlimited token forgery",[79,12557,12558],{},"Complexity — more moving parts than a simple session cookie",[232,12560,12562],{"id":12561},"the-revocation-problem-in-detail","The Revocation Problem in Detail",[11,12564,12565,12566,12569],{},"This is the most common gotcha for beginners. Because JWTs are stateless, the server has no record of which tokens it issued. If a user logs out or you need to ban an account, you ",[20,12567,12568],{},"cannot invalidate a JWT that is already out in the wild"," — at least not without extra infrastructure.",[11,12571,12572],{},"The standard solutions are:",[1748,12574,12575,12590,12604],{},[79,12576,12577,12580,12582,12583,12585,12586,12589],{},[20,12578,12579],{},"Short expiration times",[10849,12581],{},"\nSet ",[15,12584,11971],{}," to a short window (5–15 minutes). Pair with a longer-lived ",[20,12587,12588],{},"refresh token"," to silently obtain a new access token. This limits the blast radius of any stolen token.",[79,12591,12592,12595,12597,12598,12600,12601,12603],{},[20,12593,12594],{},"Token blocklist (denylist)",[10849,12596],{},"\nStore revoked ",[15,12599,12010],{}," (JWT ID) values in a fast store like Redis. On every request, check if the token's ",[15,12602,12010],{}," is on the blocklist. This reintroduces some state but only for the invalidated tokens.",[79,12605,12606,12609,12611],{},[20,12607,12608],{},"Key rotation",[10849,12610],{},"\nRotating the signing key instantly invalidates all existing tokens — a useful \"nuclear option\" in a security incident.",[28,12613,12615],{"id":12614},"best-practices","Best Practices",[11,12617,12618],{},"Security is not accidental. Here are some rules that matter most when implementing JWTs in production.",[1748,12620,12621,12629,12647,12655,12663,12679],{},[79,12622,12623,12626,12628],{},[20,12624,12625],{},"Always Use HTTPS",[10849,12627],{},"\nA JWT transmitted over plain HTTP can be intercepted. Always enforce TLS. There are no exceptions to this rule.",[79,12630,12631,12634,12636,12637,171,12640,12643,12644,12646],{},[20,12632,12633],{},"Store Tokens in HttpOnly Cookies",[10849,12635],{},"\nStoring JWTs in ",[15,12638,12639],{},"localStorage",[15,12641,12642],{},"sessionStorage"," makes them accessible to any JavaScript running on the page — including malicious scripts injected via XSS attacks. An ",[15,12645,12147],{}," cookie is inaccessible to JavaScript by design.",[79,12648,12649,12652,12654],{},[20,12650,12651],{},"Keep Expiration Times Short",[10849,12653],{},"\nAccess tokens should expire in minutes or at most an hour. Use a separate, longer-lived refresh token to renew them silently. This way, even a stolen access token is only useful for a short window.",[79,12656,12657,12660,12662],{},[20,12658,12659],{},"Never Store Sensitive Data in the Payload",[10849,12661],{},"\nThe payload is only Base64URL encoded — not encrypted. Anyone who intercepts the token (even over HTTPS, if they have access to the client device) can decode it. Store only non-sensitive identifiers like user ID and role.",[79,12664,12665,12668,12670,12671,160,12673,12675,12676,12678],{},[20,12666,12667],{},"Validate All Registered Claims",[10849,12669],{},"\nDo not assume your library validates everything by default. Explicitly check ",[15,12672,11971],{},[15,12674,11932],{},", and ",[15,12677,11958],{},". The few lines of code required here prevent entire categories of attacks.",[79,12680,12681,12684,12686],{},[20,12682,12683],{},"Prefer RS256 / ES256 for Distributed Systems",[10849,12685],{},"\nIn any system where multiple services verify tokens, use an asymmetric algorithm. Each service only needs the public key — sharing a private key across services is a security liability.",[11,12688,12689],{},[4263,12690,12691],{},"Verification with explicit claim checks:",[127,12693,12695],{"className":11793,"code":12694,"language":11795,"meta":135,"style":135},"// Always pass verification options explicitly\njwt.verify(token, publicKey, {\n  algorithms: ['RS256'],      // Never allow 'none'\n  issuer:     'auth.example.com',\n  audience:   'api.example.com',\n  // 'exp' is checked automatically by the library\n});\n",[15,12696,12697,12702,12712,12726,12736,12746,12751],{"__ignoreMap":135},[1027,12698,12699],{"class":1029,"line":1030},[1027,12700,12701],{"class":1033},"// Always pass verification options explicitly\n",[1027,12703,12704,12707,12709],{"class":1029,"line":1037},[1027,12705,12706],{"class":1626},"jwt.",[1027,12708,12382],{"class":1040},[1027,12710,12711],{"class":1626},"(token, publicKey, {\n",[1027,12713,12714,12717,12720,12723],{"class":1029,"line":1048},[1027,12715,12716],{"class":1626},"  algorithms: [",[1027,12718,12719],{"class":1044},"'RS256'",[1027,12721,12722],{"class":1626},"],      ",[1027,12724,12725],{"class":1033},"// Never allow 'none'\n",[1027,12727,12728,12731,12734],{"class":1029,"line":1054},[1027,12729,12730],{"class":1626},"  issuer:     ",[1027,12732,12733],{"class":1044},"'auth.example.com'",[1027,12735,4654],{"class":1626},[1027,12737,12738,12741,12744],{"class":1029,"line":1060},[1027,12739,12740],{"class":1626},"  audience:   ",[1027,12742,12743],{"class":1044},"'api.example.com'",[1027,12745,4654],{"class":1626},[1027,12747,12748],{"class":1029,"line":1067},[1027,12749,12750],{"class":1033},"  // 'exp' is checked automatically by the library\n",[1027,12752,12753],{"class":1029,"line":1073},[1027,12754,12755],{"class":1626},"});\n",[28,12757,2323],{"id":2322},[11,12759,12760,12761,12763],{},"Use JWTs for stateless, cross-service authorization. Keep them short-lived. Transmit only over HTTPS. Store in ",[15,12762,12147],{}," cookies. Never put secrets in the payload. Always verify the signature and all critical claims. For multi-service architectures, use RS256 so only one service ever touches the private key.",[2377,12765,12766],{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":135,"searchDepth":1037,"depth":1037,"links":12768},[12769,12770,12771,12772,12777,12782,12786,12787,12788,12791,12792],{"id":11459,"depth":1037,"text":11460},{"id":11485,"depth":1037,"text":11486},{"id":11508,"depth":1037,"text":11509},{"id":11567,"depth":1037,"text":11568,"children":12773},[12774,12775,12776],{"id":11586,"depth":1048,"text":11587},{"id":11669,"depth":1048,"text":11670},{"id":11782,"depth":1048,"text":11783},{"id":11893,"depth":1037,"text":11894,"children":12778},[12779,12780,12781],{"id":11906,"depth":1048,"text":11907},{"id":12019,"depth":1048,"text":12020},{"id":12033,"depth":1048,"text":12034},{"id":12054,"depth":1037,"text":12055,"children":12783},[12784,12785],{"id":12061,"depth":1048,"text":12062},{"id":12075,"depth":1048,"text":12076},{"id":12102,"depth":1037,"text":12103},{"id":12448,"depth":1037,"text":12449},{"id":12511,"depth":1037,"text":12512,"children":12789},[12790],{"id":12561,"depth":1048,"text":12562},{"id":12614,"depth":1037,"text":12615},{"id":2322,"depth":1037,"text":2323},"2026-04-04","A comprehensive guide to JSON Web Tokens (JWT) that cuts through the jargon and gets straight to the point. Learn what JWTs are, how JWT works, and how to use JWTs effectively in your applications.","everything-about-json-web-tokens-explained.png",{},"/backend/everything-about-json-web-tokens-explained",{"title":11451,"description":12794},"Backend/1.everything-about-json-web-tokens-explained",[12801,12802,12803,12804],"JWT","JSON Web Tokens","Authentication","Security","mjEU-xXBmUUlUL8Tkj6ZQsPFjWEDC3Np3qY8tTa6zgo",{"id":12807,"title":12808,"author":6,"body":12809,"date":13410,"description":13411,"draft":2444,"extension":2445,"guide":2446,"image":13412,"meta":13413,"navigation":1063,"path":13414,"seo":13415,"stem":13416,"tags":13417,"__hash__":13420},"blog/How-To/1.git-commit-to-wrong-branch-fix.md","How to Fix a Git Commit to Wrong Branch: A Step-by-Step Guide",{"type":8,"value":12810,"toc":13398},[12811,12829,12832,12836,12844,12847,12861,12864,12868,12871,12898,12910,12914,12923,12926,12948,12951,12971,13022,13031,13035,13038,13047,13052,13056,13059,13077,13081,13088,13091,13115,13162,13170,13181,13185,13190,13193,13207,13210,13228,13231,13258,13308,13313,13317,13320,13340,13344,13351,13383,13387,13390,13393,13395],[11,12812,12813,12814,12817,12818,12821,12822,171,12825,12828],{},"I know you’ve been there. You are deep in the \"flow,\" writing code, and hitting ",[15,12815,12816],{},"git commit"," with confidence. Then, you look at your terminal and realize the mistake: you just made a ",[20,12819,12820],{},"git commit to wrong branch",". Specifically, you’ve pushed feature code directly onto the ",[15,12823,12824],{},"main",[15,12826,12827],{},"master"," branch.",[11,12830,12831],{},"Don't panic. This is a rite of passage for every developer. Whether you forgot to switch branches or your IDE defaulted to master, it is easily fixable. In this guide, I shall show you how to safely move those commits to a feature branch and restore order to your repository.",[28,12833,12835],{"id":12834},"the-common-git-mistake-developers-make","The Common Git Mistake Developers Make",[11,12837,12838,12839,171,12841,12843],{},"Git is a powerful version control system, but its flexibility means it doesn't always stop us from making mistakes. Most junior developers start their work in the ",[15,12840,12827],{},[15,12842,12824],{}," branch because it’s the default state of a new repository.",[11,12845,12846],{},"Accidentally committing to the wrong branch usually happens because:",[76,12848,12849,12855,12858],{},[79,12850,12851,12852,148],{},"You forgot to run ",[15,12853,12854],{},"git checkout -b \u003Cbranch-name>",[79,12856,12857],{},"You switched tasks quickly and didn't check your current branch status.",[79,12859,12860],{},"You assumed you were on a feature branch when you were actually on the primary production branch.",[11,12862,12863],{},"Whatever the reason, the result is the same: your feature code is now part of the main branch history, which can lead to issues in production and complicate collaboration with other developers.",[28,12865,12867],{"id":12866},"example-scenario-real-situation","Example Scenario (Real Situation)",[11,12869,12870],{},"Let's look at a common scenario. Imagine you are building a website:",[1748,12872,12873,12885,12888,12895],{},[79,12874,12875,12876,12879,12880,171,12882,12884],{},"You initialize a Git repository and commit your ",[15,12877,12878],{},"index.html"," to ",[15,12881,12827],{},[15,12883,12824],{},". This is correct.",[79,12886,12887],{},"You start working on a \"Login\" feature.",[79,12889,12890,12891,12894],{},"Without switching branches, you create ",[15,12892,12893],{},"login.html",", write the API integration.",[79,12896,12897],{},"You made two commits: \"add login.html\" and \"add authentication\".",[11,12899,12900,12901,12903,12904,12907,12908,148],{},"Now, your production-ready ",[15,12902,12827],{}," branch contains experimental, unreviewed feature code. You need to move those \"Login\" commits to a branch called ",[15,12905,12906],{},"feature-login"," and remove them from ",[15,12909,12827],{},[28,12911,12913],{"id":12912},"step-1-identify-the-mistake-using-git-logs","Step 1 – Identify the Mistake Using Git Logs",[11,12915,12916,12917],{},"Before you move anything, you need to see exactly what happened. We use the log command to visualize the commit history. ",[4263,12918,12919,12920,12922],{},"(You're in ",[15,12921,12827],{}," branch yet)",[11,12924,12925],{},"Run the following command:",[127,12927,12929],{"className":1021,"code":12928,"language":1023,"meta":135,"style":135},"git log --oneline --all --graph\n",[15,12930,12931],{"__ignoreMap":135},[1027,12932,12933,12936,12939,12942,12945],{"class":1029,"line":1030},[1027,12934,12935],{"class":1040},"git",[1027,12937,12938],{"class":1044}," log",[1027,12940,12941],{"class":1079}," --oneline",[1027,12943,12944],{"class":1079}," --all",[1027,12946,12947],{"class":1079}," --graph\n",[11,12949,12950],{},"What this does:",[76,12952,12953,12959,12965],{},[79,12954,12955,12958],{},[15,12956,12957],{},"--oneline",": Condenses the output so each commit is one line.",[79,12960,12961,12964],{},[15,12962,12963],{},"--all",": Shows all branches, not just the one you are on.",[79,12966,12967,12970],{},[15,12968,12969],{},"--graph",": Draws a text-based graphical representation of the branch history.",[127,12972,12974],{"className":1021,"code":12973,"language":1023,"meta":135,"style":135},"# example output of the above command:\n* a781459 (HEAD -> main) add authentication\n* c00ffa3 add login.html\n* a6567f9 update index.html\n* 4f1c99f add index.html\n",[15,12975,12976,12981,13001,13008,13015],{"__ignoreMap":135},[1027,12977,12978],{"class":1029,"line":1030},[1027,12979,12980],{"class":1033},"# example output of the above command:\n",[1027,12982,12983,12985,12988,12991,12993,12995,12998],{"class":1029,"line":1037},[1027,12984,6073],{"class":1083},[1027,12986,12987],{"class":1626}," a781459 (",[1027,12989,12990],{"class":1040},"HEAD",[1027,12992,10842],{"class":1626},[1027,12994,6486],{"class":1083},[1027,12996,12997],{"class":1044}," main",[1027,12999,13000],{"class":1626},") add authentication\n",[1027,13002,13003,13005],{"class":1029,"line":1048},[1027,13004,6073],{"class":1083},[1027,13006,13007],{"class":1626}," c00ffa3 add login.html\n",[1027,13009,13010,13012],{"class":1029,"line":1054},[1027,13011,6073],{"class":1083},[1027,13013,13014],{"class":1626}," a6567f9 update index.html\n",[1027,13016,13017,13019],{"class":1029,"line":1060},[1027,13018,6073],{"class":1083},[1027,13020,13021],{"class":1626}," 4f1c99f add index.html\n",[11,13023,13024,13025,13027,13028,148],{},"Look for the most recent commits on ",[15,13026,12827],{},". You will see the \"add authentication\" commit at the top. Note that each commit has a unique 7-character ID (the \"hash\"), such as ",[15,13029,13030],{},"a1b2c3d",[28,13032,13034],{"id":13033},"step-2-copy-the-commit-ids","Step 2 – Copy the Commit IDs",[11,13036,13037],{},"To move your work to the correct feature branch, Git needs to know exactly which commits you are talking about. Identify the hashes of the commits that belong in the feature branch.",[11,13039,13040,13041,1759,13044,148],{},"If you made three commits to the wrong branch, you need the hashes for all three. In our scenario, the hashes for \"add login\" and \"add authentication\" are ",[15,13042,13043],{},"c00ffa3",[15,13045,13046],{},"a781459",[56,13048,13049],{},[11,13050,13051],{},"Tip: Always copy the hashes into a notepad or keep your terminal window open so you don't lose them!",[28,13053,13055],{"id":13054},"step-3-switch-to-the-correct-feature-branch","Step 3 – Switch to the Correct Feature Branch",[11,13057,13058],{},"Now, you need to go where the code should have gone. If the branch doesn't exist yet, create it and switch to it.",[127,13060,13062],{"className":1021,"code":13061,"language":1023,"meta":135,"style":135},"git checkout -b feature-login\n",[15,13063,13064],{"__ignoreMap":135},[1027,13065,13066,13068,13071,13074],{"class":1029,"line":1030},[1027,13067,12935],{"class":1040},[1027,13069,13070],{"class":1044}," checkout",[1027,13072,13073],{"class":1079}," -b",[1027,13075,13076],{"class":1044}," feature-login\n",[28,13078,13080],{"id":13079},"step-4-move-commits-using-git-cherry-pick","Step 4 – Move Commits Using git cherry-pick",[11,13082,13083,13084,13087],{},"The \"magic\" command here is ",[15,13085,13086],{},"git cherry-pick",". This command takes a commit from one place and applies it to another.",[11,13089,13090],{},"Run the command using the hash you identified in Step 2:",[127,13092,13094],{"className":1021,"code":13093,"language":1023,"meta":135,"style":135},"git cherry-pick c00ffa3\ngit cherry-pick a781459\n",[15,13095,13096,13106],{"__ignoreMap":135},[1027,13097,13098,13100,13103],{"class":1029,"line":1030},[1027,13099,12935],{"class":1040},[1027,13101,13102],{"class":1044}," cherry-pick",[1027,13104,13105],{"class":1044}," c00ffa3\n",[1027,13107,13108,13110,13112],{"class":1029,"line":1037},[1027,13109,12935],{"class":1040},[1027,13111,13102],{"class":1044},[1027,13113,13114],{"class":1044}," a781459\n",[127,13116,13118],{"className":1021,"code":13117,"language":1023,"meta":135,"style":135},"# After cherry-picking\n* a781459 (HEAD -> feature-login, main) add authentication\n* c00ffa3 add login.html\n* a6567f9 update index.html\n* 4f1c99f add index.html\n",[15,13119,13120,13125,13144,13150,13156],{"__ignoreMap":135},[1027,13121,13122],{"class":1029,"line":1030},[1027,13123,13124],{"class":1033},"# After cherry-picking\n",[1027,13126,13127,13129,13131,13133,13135,13137,13140,13142],{"class":1029,"line":1037},[1027,13128,6073],{"class":1083},[1027,13130,12987],{"class":1626},[1027,13132,12990],{"class":1040},[1027,13134,10842],{"class":1626},[1027,13136,6486],{"class":1083},[1027,13138,13139],{"class":1044}," feature-login,",[1027,13141,12997],{"class":1044},[1027,13143,13000],{"class":1626},[1027,13145,13146,13148],{"class":1029,"line":1048},[1027,13147,6073],{"class":1083},[1027,13149,13007],{"class":1626},[1027,13151,13152,13154],{"class":1029,"line":1054},[1027,13153,6073],{"class":1083},[1027,13155,13014],{"class":1626},[1027,13157,13158,13160],{"class":1029,"line":1060},[1027,13159,6073],{"class":1083},[1027,13161,13021],{"class":1626},[56,13163,13164],{},[11,13165,13166,13169],{},[20,13167,13168],{},"Important Note:"," If you have multiple commits to move, apply them in chronological order (oldest first). This prevents merge conflicts and keeps your history logical.",[11,13171,13172,13174,13175,13177,13178,13180],{},[15,13173,13086],{}," essentially \"copies\" the changes. Your \"Login\" code is now safely on the ",[15,13176,12906],{}," branch. However, a copy still exists on ",[15,13179,12827],{},". We need to fix that next.",[28,13182,13184],{"id":13183},"step-5-clean-the-master-branch","Step 5 – Clean the Master Branch",[11,13186,13187,13188,12828],{},"Now that your work is safe on the correct branch, we must remove the accidental commits from the ",[15,13189,12827],{},[11,13191,13192],{},"First, switch back to master:",[127,13194,13196],{"className":1021,"code":13195,"language":1023,"meta":135,"style":135},"git checkout master\n",[15,13197,13198],{"__ignoreMap":135},[1027,13199,13200,13202,13204],{"class":1029,"line":1030},[1027,13201,12935],{"class":1040},[1027,13203,13070],{"class":1044},[1027,13205,13206],{"class":1044}," master\n",[11,13208,13209],{},"Then, use the reset command to roll back the branch to its state before the mistake:",[127,13211,13213],{"className":1021,"code":13212,"language":1023,"meta":135,"style":135},"git reset --hard HEAD~2\n",[15,13214,13215],{"__ignoreMap":135},[1027,13216,13217,13219,13222,13225],{"class":1029,"line":1030},[1027,13218,12935],{"class":1040},[1027,13220,13221],{"class":1044}," reset",[1027,13223,13224],{"class":1079}," --hard",[1027,13226,13227],{"class":1044}," HEAD~2\n",[11,13229,13230],{},"What this command does:",[76,13232,13233,13239,13245],{},[79,13234,13235,13238],{},[15,13236,13237],{},"git reset",": Moves the current branch pointer to a previous state.",[79,13240,13241,13244],{},[15,13242,13243],{},"--hard",": This tells Git to discard all changes in the working directory. It makes master look exactly like it did before you made that mistake.",[79,13246,13247,13250,13251,13254,13255,148],{},[15,13248,13249],{},"HEAD~2",": This tells Git to go back exactly ",[20,13252,13253],{},"two"," commits. If you made three accidental commits, you would use ",[15,13256,13257],{},"HEAD~3",[127,13259,13261],{"className":1021,"code":13260,"language":1023,"meta":135,"style":135},"# After reset\n* a781459 (feature-login) add authentication\n* c00ffa3 add login.html\n* a6567f9 (HEAD -> main) update index.html\n* 4f1c99f add index.html\n",[15,13262,13263,13268,13278,13284,13302],{"__ignoreMap":135},[1027,13264,13265],{"class":1029,"line":1030},[1027,13266,13267],{"class":1033},"# After reset\n",[1027,13269,13270,13272,13274,13276],{"class":1029,"line":1037},[1027,13271,6073],{"class":1083},[1027,13273,12987],{"class":1626},[1027,13275,12906],{"class":1040},[1027,13277,13000],{"class":1626},[1027,13279,13280,13282],{"class":1029,"line":1048},[1027,13281,6073],{"class":1083},[1027,13283,13007],{"class":1626},[1027,13285,13286,13288,13291,13293,13295,13297,13299],{"class":1029,"line":1054},[1027,13287,6073],{"class":1083},[1027,13289,13290],{"class":1626}," a6567f9 (",[1027,13292,12990],{"class":1040},[1027,13294,10842],{"class":1626},[1027,13296,6486],{"class":1083},[1027,13298,12997],{"class":1044},[1027,13300,13301],{"class":1626},") update index.html\n",[1027,13303,13304,13306],{"class":1029,"line":1060},[1027,13305,6073],{"class":1083},[1027,13307,13021],{"class":1626},[56,13309,13310],{},[11,13311,13312],{},"Use --hard with caution. Any uncommitted work in your directory will be permanently deleted. Always ensure your git status is clean before running this.",[28,13314,13316],{"id":13315},"when-should-you-use-git-cherry-pick","When Should You Use git cherry-pick?",[11,13318,13319],{},"Beyond fixing mistakes, git cherry-pick is useful in several real-world situations:",[76,13321,13322,13328,13334],{},[79,13323,13324,13327],{},[20,13325,13326],{},"Hotfixes:"," When a bug is fixed on a development branch but needs to be applied to the production branch immediately.",[79,13329,13330,13333],{},[20,13331,13332],{},"Undoing a Revert:"," If a feature was reverted but you want to bring back specific parts of it.",[79,13335,13336,13339],{},[20,13337,13338],{},"Collaborative Work:"," If a teammate wrote a helper function on their branch that you need on yours.",[28,13341,13343],{"id":13342},"quick-summary","Quick Summary",[11,13345,13346,13347,13350],{},"Need to ",[20,13348,13349],{},"fix a git commit to wrong branch"," in 30 seconds? I know you don't have time. Here is the cheat sheet:",[1748,13352,13353,13359,13365,13371,13377],{},[79,13354,13355,13356],{},"Find the commit hash: ",[15,13357,13358],{},"git log --oneline",[79,13360,13361,13362],{},"Go to the right branch: ",[15,13363,13364],{},"git checkout feature-branch",[79,13366,13367,13368],{},"Copy the work over: ",[15,13369,13370],{},"git cherry-pick \u003Ccommit-hash>",[79,13372,13373,13374],{},"Go back to master: ",[15,13375,13376],{},"git checkout master",[79,13378,13379,13380],{},"Erase the mistake: ",[15,13381,13382],{},"git reset --hard HEAD~1",[28,13384,13386],{"id":13385},"conclusion","Conclusion",[11,13388,13389],{},"Fixing a git commit to wrong branch is a foundational skill that transforms you from a panicked beginner into a confident developer.",[11,13391,13392],{},"The next time you realize you're on the wrong branch, don't delete your folder and start over. Use the steps above to move your code like a pro.",[11,13394,11386],{},[2377,13396,13397],{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}",{"title":135,"searchDepth":1037,"depth":1037,"links":13399},[13400,13401,13402,13403,13404,13405,13406,13407,13408,13409],{"id":12834,"depth":1037,"text":12835},{"id":12866,"depth":1037,"text":12867},{"id":12912,"depth":1037,"text":12913},{"id":13033,"depth":1037,"text":13034},{"id":13054,"depth":1037,"text":13055},{"id":13079,"depth":1037,"text":13080},{"id":13183,"depth":1037,"text":13184},{"id":13315,"depth":1037,"text":13316},{"id":13342,"depth":1037,"text":13343},{"id":13385,"depth":1037,"text":13386},"2026-03-06","Accidentally made a git commit to wrong branch? Learn how to move commits to a feature branch and clean up master using git cherry-pick and reset.","git-commit-to-wrong-branch-fix.png",{},"/how-to/git-commit-to-wrong-branch-fix",{"title":12808,"description":13411},"How-To/1.git-commit-to-wrong-branch-fix",[12935,13418,13419],"version control","cherry-pick","n8isUYA0g4UX-h0sD-YAESjnQ7-UuIHQEF_OxEKfHs8",1777303358224]