慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
茶与SQL——初学者探求数据库之途
Abdul Rahman · 2026-05-24 · via DEV Community

SQL者,结构化查询语言也。此乃吾辈与关系型数据库如MySQL、PostgreSQL、SQLite等交谈之语也。


服务器为何物?数据库安在何处?

初学者多以为数据库悬于“云”中。非也。

数据库者,服务器上运行之软件也。服务器,不过为运行于数据中心、昼夜不息之强计算机耳——如亚马逊AWS、谷歌云、DigitalOcean等。当是软件存汝之数据时,则书之于服务器之SSD或硬盘中之实文件也。

MySQL与PostgreSQL存数据为.ibd文件或WAL(预写日志)文件。MongoDB则存为.bson之檔。此檔置於硬盤,猶君之筆記型電腦上檔案無異。

當君於後端程式寫此:

const pool = new Pool({ host: 'localhost', port: 5432 })

Enter fullscreen mode Exit fullscreen mode

君告後端,當開一連結至資料庫聆聽之端口。此即之。此乃一TCP連結——猶君之應用程式與資料庫間之電話。


何故择Docker以载PostgreSQL乎?

非直于吾之系统安装PostgreSQL,吾乃用Docker。Docker创一隔离之境(名曰容器),使吾不乱吾笔记本电脑之设。

此乃吾用以创持久数据之PostgreSQL容器之命也:

Mac / Linux / WSL:

docker run -d --name sql_class \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=sql_class_01_db \
  -p 5433:5432 \
  -v "$(pwd)/pgdata:/var/lib/postgresql/data" \
  postgres

入全屏模式: 出全屏模式:

Windows (PowerShell):

docker run -d --name sql_class -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sql_class_01_db -p 5433:5432 -v "${PWD}/pgdata:/var/lib/postgresql/data" postgres

入全屏模式 出全屏模式

是故-v之标识,将尔当前目录中pgdata之文件夹,映射于容器之存储。故纵容器被毁,尔之数据犹存于尔之笔记本电脑。

欲验容器是否运行:

docker ps

入全屏模式 退出全屏模式

欲去此容器:

docker rm -f sql_class

入全屏模式 退出全屏模式


为何习原SQL?吾有Prisma与Drizzle,何须之?

此乃吾初问。习原SQL,Prisma可代吾成之,何故习之?

吾所察得者如是:

如Prisma、Drizzle之ORM,能将尔之JavaScript/TypeScript代码化而为SQL之字符串,而送诸数据库。尔若不知SQL,则不知Prisma实为之何也。

N+1之问题,确为实有。ORM时或生百问,而非一优化之问。尔惟通SQL,乃能察此。

夫繁难之询,合六表、制财报,则ORM之文法难继。众工复归乎素SQL。

然SQL五十年未易。Sequelize兴衰,Prisma出,Drizzle现,SQL犹故。


DDL——制表之道

DDL者,数据定义之语也。此乃定数据库之形制,非其数据,惟其形制耳。

四主DDL之令,曰CREATE,曰ALTER,曰DROP,曰TRUNCATE

今示一表,乃吾习作所创。

CREATE TABLE students (
    student_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50),
    email VARCHAR(100) UNIQUE NOT NULL,
    phone_number CHAR(10) UNIQUE,
    age INT CHECK (age > 12),
    current_status VARCHAR(20) DEFAULT 'active'
        CHECK (current_status IN ('active', 'graduated', 'dropped_out', 'on_leave')),
    has_joined_masterji BOOLEAN DEFAULT FALSE,
    current_score NUMERIC(5, 2) CHECK (current_score >= 0 AND current_score <= 100),
    enrollment_date DATE DEFAULT CURRENT_DATE
);

入全屏观之。 出全屏。

SERIAL者,自增之整数也——PostgreSQL自为之。NOT NULL者,此列不可空也。UNIQUE者,两行不得同值也。CHECK者,特制之条件也——此中年龄须逾十二。DEFAULT者,若无所供,则自定其值也。

者,欲于既成之表增新列也。

ALTER TABLE students ADD COLUMN batch_name VARCHAR(50) DEFAULT 'Web Dev 2026';

入全景模式 出全景模式


查询之选——览尔之数据

SELECT乃取诸表之数据者也.

-- Get everything
SELECT * FROM ipl_players;

-- Get specific columns
SELECT name, team, auction_price_crores FROM ipl_players;

入全景模式 出全景模式

以WHERE为滤:

-- Basic condition
SELECT * FROM ipl_players WHERE team = 'Mumbai Indians';

-- Multiple conditions
SELECT * FROM ipl_players WHERE role = 'All-Rounder' AND wickets_taken > 10;

-- Either condition
SELECT * FROM ipl_players WHERE team = 'CSK' OR team = 'RCB';

-- Range
SELECT * FROM ipl_players WHERE auction_price_crores BETWEEN 5 AND 12;

-- From a list
SELECT * FROM ipl_players WHERE team NOT IN ('Mumbai Indians', 'CSK', 'RCB');

-- Pattern matching — names starting with R
SELECT * FROM ipl_players WHERE name LIKE 'R%';

-- Check for empty values
SELECT * FROM ipl_players WHERE team IS NULL;

入全景模式 出全景模式

% 谓之零或更多字符。_ 谓之恰一字符。LIKE 乃区分大小写。ILIKE 乃不区分大小写(唯 PostgreSQL 可用)。

排序与限制:

-- Sort by price, highest first
SELECT name, auction_price_crores FROM ipl_players ORDER BY auction_price_crores DESC;

-- Top 3 results
SELECT name, auction_price_crores FROM ipl_players ORDER BY auction_price_crores DESC LIMIT 3;

-- Skip first 3, get next 3 (pagination)
SELECT name, auction_price_crores FROM ipl_players ORDER BY auction_price_crores DESC LIMIT 3 OFFSET 3;

进入全屏模式 退出全屏模式


DML — 插入、更新、删除

DML,乃数据操作之语也。此乃汝与表内之数据实际相交互之法也。

INSERT:

-- Single row
INSERT INTO canteen_menu (item_name, category, price)
VALUES ('Vada Pav', 'Snacks', 15);

-- Multiple rows at once
INSERT INTO canteen_menu (item_name, category, price) VALUES
('Masala Chai', 'Beverages', 10),
('Samosa', 'Snacks', 12),
('Maggi', 'Snacks', 25);

进入全屏模式 退出全屏模式

UPDATE:

UPDATE canteen_menu
SET price = 20
WHERE item_name = 'Vada Pav';

进入全屏模式 退出全屏模式

DELETE:

DELETE FROM canteen_menu WHERE item_name = 'Cold Coffee';

进入全屏模式 退出全屏模式

恒用WHEREUPDATEDELETE。若忘WHERE之句,SQL将损益表中之每一行。吾于实践中学此,艰而得之.


聚合函数—计、总、均、极、极

聚合函数取全列,返一数.

-- How many rows?
SELECT COUNT(*) FROM smart_watch_sales;

-- Total revenue
SELECT SUM(units_sold * price_per_unit) AS total_revenue FROM smart_watch_sales;

-- Average price
SELECT AVG(price_per_unit) AS avg_price FROM smart_watch_sales;

-- Cheapest and most expensive
SELECT MIN(price_per_unit) AS cheapest, MAX(price_per_unit) AS costliest FROM smart_watch_sales;

退出全屏模式

GROUP BY 可使汝分此计算于类:

-- Total units sold per brand
SELECT brand, SUM(units_sold) AS total_units_sold
FROM smart_watch_sales
GROUP BY brand
ORDER BY total_units_sold DESC;

进入全屏模式 退出全屏模式

HAVING 于组立之后滤之。WHERE 不可为之,盖 WHERE 先于分组而行也:

-- Only show brands that sold more than 20 units total
SELECT brand, SUM(units_sold) AS total_units
FROM smart_watch_sales
GROUP BY brand
HAVING SUM(units_sold) > 20;

进入全屏模式 退出全屏模式


並合 — 联多表也

此乃关系之库显其能处也

吾等分置数据于异表,以避重。学子一表,实习一表。并合使汝于一问中合之。

外键者,联表之由也。实习之表有student_id之列,引据学子之表student_id也:

CREATE TABLE internships (
    internship_id SERIAL PRIMARY KEY,
    student_id INT REFERENCES students(student_id) ON DELETE SET NULL,
    company_name VARCHAR(100),
    role VARCHAR(50),
    stipend INT,
    status VARCHAR(20)
);

入全屏模式 出全屏模式

ON DELETE SET NULL者,若生徒被删,则实习之记存,然student_id为空。ON DELETE CASCADE则亦删实习之记。

内联——惟相合之行:

SELECT s.name, s.branch, i.company_name, i.role
FROM students s
INNER JOIN internships i ON s.student_id = i.student_id;

入全屏模式 出全屏模式

无实习者,不至于此。

左联 — 所有学生,无论是否匹配者:

SELECT
    s.name,
    s.branch,
    COALESCE(i.company_name, 'No Internship') AS company_name,
    COALESCE(i.stipend, 0) AS stipend
FROM students s
LEFT JOIN internships i ON s.student_id = i.student_id;

入全景模式 出全屏模式

COALESCE以默认值易空。无实习者,将显"无实习"代空。

欲寻未往任何处申请者

SELECT s.name, s.email
FROM students s
LEFT JOIN internships i ON s.student_id = i.student_id
WHERE i.internship_id IS NULL;

入全景模式 退出全屏模式

RIGHT JOIN则返回右表所有行。实践中,开发者鲜少使用RIGHT JOIN,反其道而行之,改用LEFT JOIN,读来更顺。

FULL OUTER JOIN — 两表之全:

SELECT s.name AS student_name, i.company_name
FROM students s
FULL OUTER JOIN internships i ON s.student_id = i.student_id;

进入全屏模式 退出全屏模式

此显诸生与诸实习。若两方无匹,则得虚值.


索引——询之速也

吾于表入百万人,以试此法.

无索引者,按名索之,PostgreSQL自首至尾遍察每一行。此谓次第之索.

EXPLAIN ANALYZE SELECT marks FROM marks WHERE name = '809E15792322';

入全景模式 退出全屏模式

EXPLAIN ANALYZE示汝查询之策与执行之时。未加索引时,吾之查询于百万行中需时约四十至五十毫秒。

索引既立:

CREATE INDEX idx_name ON marks (name);

进入全屏模式 退出全屏模式

同查询已降至毫秒之下。PostgreSQL今以B-树之结构,直寻行,不复遍扫诸物。

一索引之覆,更进一筹。若汝之询求marks与之偕name,可于索引中并储之。

CREATE INDEX idx_name ON marks (name) INCLUDE (marks);

入全景模式 出全屏模式

今PostgreSQL无需遍历主表,直取索引便得。此谓索引独扫。


交易与ACID

交易者,合诸SQL操作为一工之单元也。或尽成,或尽败。

典例若银行转账:

BEGIN;

    UPDATE accounts SET balance = balance - 500 WHERE owner = 'Shubham';
    UPDATE accounts SET balance = balance + 500 WHERE owner = 'Hitesh';

COMMIT;

退出全屏模式

若服务器于两次UPDATE语句之间崩溃,则数据库将回滚所有变更。Shubham之账户非空,Hitesh亦能得款。

倘有变故,可手动撤销诸事:

BEGIN;
    UPDATE accounts SET balance = balance - 5000 WHERE owner = 'Shubham';
ROLLBACK;

进入全屏模式 退出全屏模式

ACID者,成此功之要也:

原子性——全或无。若第二步败,第一步亦复。吾以SELECT 1/0(除零之误)置交易之中,其事尽废。

一致性——数据库惟自一有效态迁至另一有效态。吾设CHECK (balance >= 0) 载于账簿之表。吾尝欲自一千之户扣五千,PostgreSQL乃掷误,拒此行焉。

隔离 — 未决之交易,他连不可见。吾启二终端以试之。终端一始交易,更余额而未COMMIT。终端二犹见旧额。直至终端一运行COMMIT 终端二见新数乎.

耐久性 — 既立,数据永存。PostgreSQL先于返回成功应答,将立交事务写入磁盘之先见日志(WAL)。纵使服务器立交后一息崩溃,重启时数据犹在.


此博客所有代码,皆存于吾GitHub之库:github.com/abdulrdeveloper/Learn-SQL


吾之更多著述,可于abdulrdeveloper.me
观之blog.abdulrdeveloper.me