Skip to content

บทที่ 0 — Database คืออะไร และทำไมต้องมี

สารบัญ | บทถัดไป →


1. ปัญหาก่อนมี Database

ลองคิดดู — ถ้าเราจะเก็บข้อมูล user 1 ล้านคน:

วิธี 1: ไฟล์ text

users.txt:
1,anna@example.com,Anna,25
2,ben@example.com,Ben,30
3,carol@example.com,Carol,28
...

ปัญหา:

  • หา user คนหนึ่ง → อ่านไฟล์ทั้งไฟล์ (ช้า)
  • 2 คน edit พร้อมกัน → ทับกัน
  • ไฟล์พัง → ข้อมูลหายหมด
  • ไม่มี structure ที่บังคับ (insert "abc,xyz" ก็ได้)
  • ทำ join กับไฟล์อื่นยาก
  • ไม่มี backup เป็นระบบ

วิธี 2: JSON file

json
[
  {"id": 1, "email": "anna@example.com", "name": "Anna", "age": 25},
  ...
]

ยังเจอปัญหาเหมือนเดิม

Database = software ที่ออกแบบมาแก้ปัญหาเหล่านี้ทั้งหมด:

  • ✅ เก็บ + ค้น data ได้เร็วแม้มีหลายร้อยล้านแถว
  • ✅ หลายคนใช้พร้อมกันได้ (concurrency (คอน-เคอ-เรน-ซี) = การทำงานพร้อมกันหลายคน/หลายงาน)
  • ✅ Crash → ข้อมูลไม่หาย (durability = ความคงทน — COMMIT แล้วข้อมูลอยู่ถาวรแม้ไฟดับ/เครื่องพัง)
  • ✅ บังคับ structure (schema)
  • ✅ Join data หลายตาราง
  • ✅ Backup, replication, security

2. ประเภท Database

A. Relational (SQL) Database — RDBMS

  • เก็บเป็น table ที่มี row + column
  • ใช้ SQL (Structured Query Language)
  • มี schema บังคับ (column ไหนเก็บอะไร)
  • มี relation ระหว่าง table

ตัวอย่าง: PostgreSQL, MySQL, SQL Server, Oracle, SQLite

B. NoSQL Database

ประเภทเก็บยังไง (อธิบายง่าย)ตัวอย่างใช้เมื่อ
Documentเก็บข้อมูลเป็นก้อน JSON 1 ก้อนต่อ 1 recordMongoDB, CouchDBschema ยืดหยุ่น, nested data
Key-Valueจับคู่ key → value เหมือน dictionaryRedis, DynamoDBcache, session, queue
Column-familyเก็บแยกเป็น column ทำให้เขียน/อ่าน column ใหญ่ ๆ เร็วCassandra (แคส-ซาน-ดร้า), HBase (เอช-เบส)write-heavy, time series
Graphเก็บเป็นจุด (node) + เส้นเชื่อม (edge)Neo4j (นี-โอ-โฟร์-เจ), Dgraphsocial network, recommendation
Time-seriesoptimize เฉพาะข้อมูลที่มี timestamp (IoT, log, metric)TimescaleDB, InfluxDB v3, QuestDBIoT, observability, monitoring
Vectorเก็บ vector ที่ AI แปลงข้อความ/รูปเป็นตัวเลข เพื่อค้น "ความหมาย"Pinecone, Qdrant (คิว-ดรานท์), Milvus, Weaviate, Turbopuffer, pgvectorAI search, RAG (Retrieval-Augmented Generation — ระบบ AI ที่ค้นข้อมูลก่อนตอบ)

3. SQL vs NoSQL — เลือกยังไง

SQLNoSQL
Structurerigid schemaflexible
Relationดี (JOIN)จำกัด
Scalevertical (ดูหมายเหตุด้านล่าง)horizontal
ACIDstrongeventual consistency (มัก)
Use casebanking, e-commerce, CRM (Customer Relationship Management — ระบบจัดการลูกค้า)social feed, log, cache
Query languageSQL (standard)ต่างกันทุกตัว

📖 คำศัพท์ในตาราง — แยกศัพท์กับคำอธิบายให้อ่านง่าย:

  • vertical scale (เวอร์-ทิ-คอล สเกล) = ขยายแนวตั้ง — เพิ่มสเปกเครื่องเดิม CPU/RAM ให้ใหญ่ขึ้น
  • horizontal scale (ฮอ-ริ-ซอน-ทอล สเกล) = ขยายแนวนอน — เพิ่มจำนวนเครื่อง/server
  • ACID (แอซิด) = 4 คุณสมบัติของ transaction (บทที่ 5 จะอธิบาย)
  • eventual consistency (อี-เวน-ชวล คอน-ซิส-เทน-ซี) = "สุดท้ายข้อมูลจะตรงกัน" แต่ช่วงสั้น ๆ หลังเขียน แต่ละ server อาจเห็นค่าไม่ตรงกันชั่วคราว
  • sharding (ชาร์-ดิ้ง) = แบ่ง data ออกเป็นชิ้น ๆ ไปเก็บคนละ server
  • replication (เรพ-ลิ-เค-ชัน) = สำเนาข้อมูลข้าม server เพื่อกระจายโหลด/กัน data หาย

🟡 หมายเหตุเรื่อง scale (2026): ตาราง "SQL = vertical, NoSQL = horizontal" เป็นภาพแบบดั้งเดิมของ single-node SQL ปัจจุบันมี distributed SQL ที่ทำ horizontal scale ได้ (มี sharding/replication built-in) — ตัวอย่าง:

  • Amazon Aurora (ออ-โร-ร่า) — managed PostgreSQL/MySQL บน AWS
  • Citus (ไซ-ตัส) — extension ของ Postgres ทำ sharding
  • CockroachDB (ค็อก-โรช-ดี-บี) — Postgres-compatible distributed SQL
  • Google Spanner (สแปน-เนอร์) — distributed SQL ของ Google
  • YugabyteDB (ยู-กา-ไบต์-ดี-บี) — Postgres-compatible distributed SQL
  • Vitess (วิ-เทส) — sharding สำหรับ MySQL เท่านั้น (ไม่ใช่ Postgres — ใช้ใน YouTube, Slack)

ดังนั้นข้อจำกัดเรื่อง scale ของ SQL ในปี 2026 ไม่ได้แข็งเหมือนสมัยก่อน (last reviewed: 2026-06)

กฎทอง สำหรับมือใหม่:

  • เริ่มด้วย SQL (PostgreSQL) — 95% ของ app ใช้ได้
  • ใช้ NoSQL เมื่อมี use case ชัดเจน:
    • Cache → Redis
    • Search → Elasticsearch
    • Real-time chat / feed → MongoDB
    • AI embedding (เอ็ม-เบด-ดิ้ง — vector ที่ AI แปลงข้อความเป็นตัวเลข เพื่อค้นความหมาย) → pgvector (พี-จี-เวก-เตอร์ — extension ของ Postgres, extension = plugin เสริมความสามารถของ Postgres) หรือ Qdrant

"Pick boring technology" — Dan McKinley (แปล: "เลือกเทคโนโลยีที่น่าเบื่อ" — ในที่นี้ "boring" ไม่ได้แปลว่าน่าเบื่อในแง่ลบ แต่หมายถึง "ของที่นิ่ง พิสูจน์แล้ว ไม่มี surprise" — ตรงข้ามกับเทคโนโลยีใหม่ที่ตื่นเต้นแต่ยังมีบั๊ก) PostgreSQL "boring" แต่ปลอดภัย + flexible + รองรับ JSON ถ้าต้องการ


4. RDBMS Landscape — เลือกตัวไหน?

จุดเด่นจุดอ่อนLicense
PostgreSQLfeature เยอะที่สุด (JSONB, GIS, full-text), open-source, รองรับ extensionlearning curve สูงเล็กน้อยfree
MySQLpopularity สูง, replication ง่ายbug + edge case แปลก ๆfree (Oracle ดูแล)
MariaDBfork ของ MySQL — community-drivenecosystem/tooling รอบ Oracle MySQL ยังใหญ่กว่าfree
SQLiteembedded, ไม่ต้อง server, ไฟล์เดียวไม่ scalable, ไม่ multi-userfree
SQL Serverenterprise + Windows + integration ดีpaid, lock-in MSpaid
Oracle DBenterprise + feature ครบpaid + แพง + ซับซ้อนpaid

ปี 2026 มือใหม่: ใช้ PostgreSQL ครับ — ฟรี + features ครบ + community ใหญ่

📌 Version stamp: ตัวอย่าง SQL ในเล่มนี้ใช้ PostgreSQL 17 เป็นหลัก (Docker image postgres:17-alpine — GA กันยายน 2024) feature ส่วนใหญ่ทำงานได้ตั้งแต่ PG 15 ขึ้นไป (PG 14 EOL พฤศจิกายน 2026; PG 16 ยัง supported) — ก่อนนำไปใช้บน production แนะนำตรวจ release notes ของ Postgres เพื่อยืนยัน syntax/behavior ตาม minor version ที่คุณใช้

สำหรับ MySQL หนังสือเล่มนี้อ้างอิง MySQL 8.4 LTS (เมษายน 2024) — MySQL 8.0 EOL เมษายน 2026 (last reviewed: 2026-06)


5. คำศัพท์พื้นฐาน

🔑 ก่อนเริ่ม — ในศัพท์ DB คำว่า "key" ไม่ใช่แค่ "ชื่อ column" (อย่างที่ Excel เรียก) แต่หมายถึง column ที่ทำหน้าที่พิเศษ — ระบุตัวตน ของ row (Primary Key) หรือ ชี้ไปแถวอื่น (Foreign Key)

คำคำอ่านความหมาย
Databaseเด-ต้า-เบสcontainer ที่เก็บ table หลาย ๆ ตาราง
Tableเท-เบิล"ตาราง" ใน excel — row + column
Row / Recordโรว / เร็ค-คอร์ด1 แถว = 1 entity (1 user, 1 order)
Column / Fieldคอ-ลัมน์ / ฟิลด์1 attribute (email, name, age)
Primary Keyไพร-มา-รี คีย์column ที่ระบุตัวตน 1 row (ไม่ซ้ำ, ไม่ null)
Foreign Keyฟอ-เริน คีย์column ที่ชี้ไปยัง Primary Key ของ table อื่น
Indexอิน-เด็กซ์data structure ช่วย lookup เร็ว (เหมือน index หนังสือ)
Queryคิว-เออ-รีคำสั่ง SQL ที่เราเขียน
Schemaสคี-ม่า"โครงสร้าง" ของ database (table + column + type)
Transactionทราน-แซก-ชันกลุ่มคำสั่งที่ทำสำเร็จร่วมกัน หรือ rollback ทั้งหมด
DDLดี-ดี-แอลData Definition Language — CREATE/ALTER/DROP
DMLดี-เอ็ม-แอลData Manipulation Language — SELECT/INSERT/UPDATE/DELETE

6. ตัวอย่าง — โครงสร้าง Table

table: users
┌────┬───────────────────┬───────┬─────┬─────────────────────┐
│ id │ email             │ name  │ age │ created_at          │
├────┼───────────────────┼───────┼─────┼─────────────────────┤
│ 1  │ anna@example.com  │ Anna  │ 25  │ 2026-01-15 10:00:00 │
│ 2  │ ben@example.com   │ Ben   │ 30  │ 2026-01-16 14:30:00 │
│ 3  │ carol@example.com │ Carol │ 28  │ 2026-02-01 09:15:00 │
└────┴───────────────────┴───────┴─────┴─────────────────────┘


Primary Key (unique, ไม่ซ้ำ, ไม่ null)
table: orders
┌────┬─────────┬────────┬─────────────────────┐
│ id │ user_id │ total  │ created_at          │
├────┼─────────┼────────┼─────────────────────┤
│ 10 │ 1       │ 99.50  │ 2026-02-10 11:00:00 │
│ 11 │ 1       │ 250.00 │ 2026-02-15 16:20:00 │
│ 12 │ 2       │ 50.00  │ 2026-03-01 10:00:00 │
└────┴─────────┴────────┴─────────────────────┘


Foreign Key → users.id

user_id ใน orders อ้างถึง id ใน users = "order นี้เป็นของ user คนไหน"


7. PostgreSQL — Setup

ก่อนจะเขียน SQL ต้องมี database ให้เล่นก่อน — หนังสือนี้ใช้ PostgreSQL ติดตั้งได้ 2 ทาง: Docker (แนะนำสำหรับ dev เพราะลบ/สร้างใหม่ง่าย ไม่รก OS) หรือ install ตรงบน OS เลือกทางที่สะดวก แล้วทุกตัวอย่างในเล่มจะรันตามได้:

⚠️ ก่อนรัน — ถ้ายังไม่รู้จัก Docker ให้ข้ามไป Option B ก่อน (Docker เป็นเครื่องมือรัน software ในกล่องเล็ก ๆ ที่เรียกว่า container แยกจาก OS — เหมาะกับ dev เพราะลบ/สร้างใหม่ง่าย ไม่รก OS) ถ้าจะใช้ Option A ต้องติดตั้ง Docker Desktop ก่อน → docker.com/products/docker-desktop

yaml
# docker-compose.yml
services:                                # services = list ของ container ที่จะรัน
  db:                                    # ชื่อ service (ใช้เรียกจาก container อื่น)
    image: postgres:17-alpine            # image = template ที่จะรัน (postgres 17 ตัวเล็ก alpine)
    environment:                         # environment variable ที่ส่งให้ container
      POSTGRES_DB: learning              # ชื่อ database ที่จะสร้าง
      POSTGRES_USER: dev                 # ชื่อ user
      POSTGRES_PASSWORD: secret          # ⚠️ DEV ONLY — production ห้ามใช้ password อ่อนแบบนี้
    ports:                               # ports = แมป port ของ container → port ของเครื่อง
      - "5432:5432"                      # "เครื่อง:container" — 5432 คือ port มาตรฐาน Postgres
    volumes:                             # volumes = พื้นที่เก็บ data ถาวร (ไม่หายตอน restart)
      - pgdata:/var/lib/postgresql/data  # ชื่อ volume : path ใน container

volumes:
  pgdata:                                # ประกาศ named volume ให้ Docker จัดการ
bash
docker compose up -d   # -d = ทำงานเบื้องหลัง (detached)

⚠️ Production: password secret ในตัวอย่างเป็น dev-only — production ต้องใช้ secret manager (AWS Secrets Manager, Vault, ฯลฯ) อย่า hard-code password ใน docker-compose ที่ commit ขึ้น git

Option B: Install บน OS


8. GUI Tool — เลือก 1 ตัว

Toolฟรี?ระบบ
DBeaverฟรี (Community)Mac/Win/Linux — รองรับ DB หลายตัว
pgAdminฟรีPostgres เท่านั้น
DataGrippaidJetBrains — ดีที่สุดถ้าจ่ายได้
TablePlusฟรี (limited)Mac/Win — UI สวย

ใช้ DBeaver ในหนังสือนี้ — ขั้นตอน connect ครั้งแรก:

  1. เปิด DBeaver → คลิกเมนู Database > New Database Connection (หรือกดไอคอน "+" ที่มุมบนซ้าย)
  2. เลือก PostgreSQL → คลิก Next
  3. กรอกข้อมูลในแท็บ Main:
    • Host: localhost
    • Port: 5432
    • Database: learning
    • Username: dev
    • Password: secret
  4. คลิก Test Connection — ถ้าขึ้น "Connected" แสดงว่า OK → คลิก Finish

(ครั้งแรก DBeaver อาจถามให้ดาวน์โหลด JDBC driver ของ PostgreSQL — กด Download รอสักครู่)


9. CLI — psql

นอกจาก GUI แล้ว PostgreSQL มี CLI ชื่อ psql ที่ควรใช้เป็น — เร็วกว่าตอนทำงานบนเซิร์ฟเวอร์ที่ไม่มี GUI และมีคำสั่ง backslash (เครื่องหมาย \ — แบ็คสแลช, อยู่บนคีย์บอร์ดเหนือปุ่ม Enter) เช่น \dt, \d, \l สำหรับสำรวจ schema ส่วนนี้รวมคำสั่งที่ใช้บ่อย:

bash
# เข้าผ่าน docker
docker compose exec db psql -U dev -d learning

# หรือถ้า install บน host
psql -U dev -d learning

# คำสั่งใน psql
\dt          # list tables
\d users     # describe table
\l           # list databases
\c learning  # connect to database
\q           # quit

10. Hello, Database!

ลองครบวงจรแรกกัน — สร้าง table, เพิ่มข้อมูล, แล้ว query ออกมา เพื่อให้เห็นว่า database ทำงานยังไงตั้งแต่ต้นจนจบในไม่กี่บรรทัด ก่อนจะลงรายละเอียดแต่ละคำสั่งในบทถัด ๆ ไป:

💡 อย่ากังวลกับ keyword พวก SERIAL, VARCHAR, UNIQUE, NOT NULL, TIMESTAMP, DEFAULT NOW() — บทที่ 1 จะอธิบายทุกตัว ที่นี่แค่อยากให้เห็นภาพรวม โค้ดสรุปสั้น ๆ:

  • SERIAL = เลขที่ DB นับเองอัตโนมัติ 1, 2, 3, ... (รุ่นใหม่แนะนำใช้ GENERATED ALWAYS AS IDENTITY แทน — บทที่ 1)
  • VARCHAR(255) = string ยาวไม่เกิน 255 ตัวอักษร
  • UNIQUE = ห้ามซ้ำในตาราง
  • NOT NULL = ห้ามเป็นค่าว่าง
  • INTEGER = ตัวเลขจำนวนเต็ม
  • TIMESTAMP DEFAULT NOW() = เวลาปัจจุบัน ถ้าไม่ใส่ค่าเอง
sql
-- สร้าง table
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(100) NOT NULL,
    age INTEGER,
    created_at TIMESTAMP DEFAULT NOW()
);

-- เพิ่มข้อมูล
INSERT INTO users (email, name, age) VALUES
    ('anna@example.com', 'Anna', 25),
    ('ben@example.com', 'Ben', 30);

-- ดึงข้อมูล
SELECT * FROM users;

-- ผลลัพธ์:
--  id │      email        │ name │ age │     created_at      
-- ────┼───────────────────┼──────┼─────┼─────────────────────
--   1 │ anna@example.com  │ Anna │  25 │ 2026-05-18 10:00:00
--   2 │ ben@example.com   │ Ben  │  30 │ 2026-05-18 10:00:00

ทำได้ → พร้อมเริ่มบทถัดไป


11. Mental Model ที่จะใช้ตลอดเล่ม

ทุกครั้งที่เขียน query — คิดว่า:

  1. What table? — query ตัวไหน
  2. What rows? — filter ด้วย WHERE
  3. What columns? — select column ไหนบ้าง
  4. In what order? — ORDER BY
  5. How many? — LIMIT
sql
SELECT name, email        -- 3. column
FROM users                -- 1. table
WHERE age > 18            -- 2. filter
ORDER BY created_at DESC  -- 4. order
LIMIT 10;                 -- 5. count

Database ทำงานในลำดับ:

FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

💡 อ่านผ่าน ๆ ก่อนGROUP BY, HAVING, DISTINCT ยังไม่ได้สอน — บทถัดไป (1) จะอธิบาย DISTINCT บทที่ 3 จะอธิบาย GROUP BY/HAVING ที่นี่แค่อยากให้รู้ว่า "DB รันคำสั่งตามลำดับนี้ ไม่ใช่ตามที่เราเขียน"

SELECT ไม่ใช่ขั้นตอนแรก! — DB รัน WHERE ก่อน SELECT ลำดับเหตุการณ์เป็นแบบนี้:

  1. WHERE ทำงานก่อน SELECT
  2. ตอนนั้น alias (ชื่อเล่นที่ตั้งใน SELECT ด้วย AS) ยังไม่ถูกสร้าง
  3. จึงใช้ alias ใน WHERE ไม่ได้
sql
-- ❌ error: WHERE ทำงานก่อน SELECT → ไม่รู้จัก "age_next"
SELECT age + 1 AS age_next FROM users WHERE age_next > 20;

-- ✅ ถูก: เขียน expression เต็มใน WHERE
SELECT age + 1 AS age_next FROM users WHERE age + 1 > 20;

12. Checkpoint

🛠️ Checkpoint 0.1 — Setup
ติดตั้ง PostgreSQL + DBeaver → connect ได้ → รัน SELECT version(); → เห็น version

🛠️ Checkpoint 0.2 — First Table
สร้าง table books:

  • id (Primary Key, auto increment)
  • title (String, required)
  • author (String, required)
  • published_year (Integer)
  • created_at (Timestamp, default now)

Insert 5 row → SELECT ทั้งหมด → ลบ 1 row → ดูอีกที


13. สรุปบท

✅ Database = software ที่จัดการข้อมูลให้ปลอดภัย + เร็ว + concurrent
SQL (PostgreSQL/MySQL) vs NoSQL (MongoDB/Redis) — ใช้ต่างกัน
มือใหม่ → เริ่มด้วย PostgreSQL — boring but reliable
✅ Table = row + column, มี Primary Key + Foreign Key
✅ Database ทำงานในลำดับ: FROM → WHERE → GROUP → HAVING → SELECT → ORDER → LIMIT
✅ Setup: Docker (postgres:17-alpine) + DBeaver


บทถัดไป → SQL พื้นฐาน


🔤 Glossary · 📋 Style guide · 📅 last_verified: 2026-06-03