ai

Database Design คือ — หลักการออกแบบฐานข้อมูลที่ดี

Database Design คือ — หลักการออกแบบฐานข้อมูลที่ดี

Database Design คือ

Database Design คือ — หลักการออกแบบฐานข้อมูลที่ดี

Database Design ออกแบบโครงสร้างฐานข้อมูล ลด Redundancy รักษา Integrity Scalability Conceptual Logical Physical Design ER Diagram Normalization Index

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน Wireless Site Survey Scaling Strategy 2026: ขยายธุรกิจให้เติบโตกับเทคโนโลยีไร…

ขั้นตอนOutputเครื่องมือ
RequirementsData Requirements DocumentInterview, User Stories
ConceptualER DiagramERDPlus, Draw.io, Lucidchart
LogicalTables, Columns, RelationsMySQL Workbench, pgModeler
PhysicalIndexes, Partitions, StorageSQL DDL, Migration Tools
ImplementationDatabase SchemaSQL, ORM (SQLAlchemy, Prisma)

SQL Schema Design

# === Database Schema Design ===



# E-commerce Database Schema

# CREATE DATABASE ecommerce;

# USE ecommerce;



# -- Users Table

# CREATE TABLE users (

#     id INT PRIMARY KEY AUTO_INCREMENT,

#     email VARCHAR(255) UNIQUE NOT NULL,

#     password_hash VARCHAR(255) NOT NULL,

#     first_name VARCHAR(100) NOT NULL,

#     last_name VARCHAR(100) NOT NULL,

#     phone VARCHAR(20),

#     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

#     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

#     INDEX idx_email (email),

#     INDEX idx_name (first_name, last_name)

# );



# -- Categories Table

# CREATE TABLE categories (

#     id INT PRIMARY KEY AUTO_INCREMENT,

#     name VARCHAR(100) NOT NULL,

#     slug VARCHAR(100) UNIQUE NOT NULL,

#     parent_id INT NULL,

#     description TEXT,

#     FOREIGN KEY (parent_id) REFERENCES categories(id)

# );



# -- Products Table

# CREATE TABLE products (

#     id INT PRIMARY KEY AUTO_INCREMENT,

#     name VARCHAR(255) NOT NULL,

#     slug VARCHAR(255) UNIQUE NOT NULL,

#     description TEXT,

#     price DECIMAL(10,2) NOT NULL,

#     stock INT DEFAULT 0,

#     category_id INT NOT NULL,

#     is_active BOOLEAN DEFAULT TRUE,

#     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

#     FOREIGN KEY (category_id) REFERENCES categories(id),

#     INDEX idx_category (category_id),

#     INDEX idx_price (price),

#     INDEX idx_active_category (is_active, category_id)

# );



# -- Orders Table

# CREATE TABLE orders (

#     id INT PRIMARY KEY AUTO_INCREMENT,

#     user_id INT NOT NULL,

#     status ENUM('pending','paid','shipped','delivered','cancelled') DEFAULT 'pending',

#     total_amount DECIMAL(10,2) NOT NULL,

#     shipping_address TEXT NOT NULL,

#     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

#     FOREIGN KEY (user_id) REFERENCES users(id),

#     INDEX idx_user (user_id),

#     INDEX idx_status (status),

#     INDEX idx_created (created_at)

# );



# -- Order Items Table

# CREATE TABLE order_items (

#     id INT PRIMARY KEY AUTO_INCREMENT,

#     order_id INT NOT NULL,

#     product_id INT NOT NULL,

#     quantity INT NOT NULL,

#     unit_price DECIMAL(10,2) NOT NULL,

#     FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,

#     FOREIGN KEY (product_id) REFERENCES products(id),

#     INDEX idx_order (order_id)

# );



# Python Schema Builder

from dataclasses import dataclass, field

from typing import List, Optional

from enum import Enum



class DataType(Enum):

    INT = "INT"

    VARCHAR = "VARCHAR"

    TEXT = "TEXT"

    DECIMAL = "DECIMAL"

    BOOLEAN = "BOOLEAN"

    TIMESTAMP = "TIMESTAMP"

    ENUM = "ENUM"



@dataclass

class Column:

    name: str

    data_type: DataType

    length: Optional[int] = None

    nullable: bool = True

    primary_key: bool = False

    unique: bool = False

    default: Optional[str] = None

    foreign_key: Optional[str] = None



@dataclass

class Table:

    name: str

    columns: List[Column] = field(default_factory=list)

    indexes: List[str] = field(default_factory=list)



    def add_column(self, col: Column):

        self.columns.append(col)



    def generate_sql(self) -> str:

        lines = [f"CREATE TABLE {self.name} ("]

        col_defs = []

        for col in self.columns:

            d = f"  {col.name} {col.data_type.value}"

            if col.length:

                d += f"({col.length})"

            if col.primary_key:

                d += " PRIMARY KEY AUTO_INCREMENT"

            if not col.nullable and not col.primary_key:

                d += " NOT NULL"

            if col.unique:

                d += " UNIQUE"

            if col.default:

                d += f" DEFAULT {col.default}"

            col_defs.append(d)

        for col in self.columns:

            if col.foreign_key:

                col_defs.append(f"  FOREIGN KEY ({col.name}) REFERENCES {col.foreign_key}")

        for idx in self.indexes:

            col_defs.append(f"  INDEX idx_{idx} ({idx})")

        lines.append(",\n".join(col_defs))

        lines.append(");")

        return "\n".join(lines)



# สร้าง Table

users = Table("users")

users.add_column(Column("id", DataType.INT, primary_key=True))

users.add_column(Column("email", DataType.VARCHAR, 255, nullable=False, unique=True))

users.add_column(Column("name", DataType.VARCHAR, 100, nullable=False))

users.indexes = ["email"]



print("Generated SQL:")

print(users.generate_sql())

Normalization

Database Design คือ — หลักการออกแบบฐานข้อมูลที่ดี
# normalization.py — Database Normalization

normal_forms = {

    "1NF (First Normal Form)": {

        "rule": "ทุก Column เก็บค่าเดียว ไม่มี Repeating Groups",

        "bad": "name: 'John, Jane' | phones: '081,082'",

        "good": "แยกเป็น row ละคน row ละเบอร์",

        "fix": "แยก Multi-valued Columns เป็นตารางใหม่",

    },

    "2NF (Second Normal Form)": {

        "rule": "1NF + ไม่มี Partial Dependency (ทุก Column ขึ้นกับ PK ทั้งหมด)",

        "bad": "order_items(order_id, product_id, product_name) — product_name ขึ้นกับ product_id อย่างเดียว",

        "good": "แยก product_name ไปตาราง products",

        "fix": "แยก Column ที่ขึ้นกับ PK บางส่วนไปตารางใหม่",

    },

    "3NF (Third Normal Form)": {

        "rule": "2NF + ไม่มี Transitive Dependency (ไม่มี non-key ขึ้นกับ non-key)",

        "bad": "employees(id, dept_id, dept_name) — dept_name ขึ้นกับ dept_id ไม่ใช่ id",

        "good": "แยก dept_name ไปตาราง departments",

        "fix": "แยก Column ที่ขึ้นกับ non-key ไปตารางใหม่",

    },

    "BCNF (Boyce-Codd)": {

        "rule": "3NF + ทุก Determinant เป็น Candidate Key",

        "bad": "กรณีพิเศษที่มี Candidate Key หลายตัวซ้อนกัน",

        "good": "แยกตารางให้ทุก Determinant เป็น Key",

        "fix": "ไม่ค่อยพบในทางปฏิบัติ 3NF เพียงพอ",

    },

}



print("=== Database Normalization ===\n")

for nf, info in normal_forms.items():

    print(f"  [{nf}]")

    print(f"    Rule: {info['rule']}")

    print(f"    Bad:  {info['bad']}")

    print(f"    Good: {info['good']}")

    print(f"    Fix:  {info['fix']}\n")



# Denormalization

denorm_cases = {

    "Read-heavy": "JOIN หลายตารางช้า Cache ข้อมูลซ้ำในตาราง",

    "Reporting": "สร้าง Materialized View หรือ Summary Table",

    "Caching": "เก็บ Computed Values เช่น total_amount",

    "NoSQL": "Document DB เก็บ Nested Data ไม่ต้อง Normalize",

}



print("=== When to Denormalize ===")

for case, desc in denorm_cases.items():

    print(f"  {case}: {desc}")

Indexing Strategy

# indexing.py — Database Indexing Strategy

index_types = {

    "B-Tree Index": {

        "use": "ค้นหา =, <, >, BETWEEN, ORDER BY",

        "example": "CREATE INDEX idx_price ON products(price)",

        "when": "Column ที่ถูก WHERE, ORDER BY บ่อย",

    },

    "Hash Index": {

        "use": "ค้นหา = เท่านั้น (Exact Match)",

        "example": "CREATE INDEX idx_email ON users USING HASH(email)",

        "when": "Lookup by exact value เท่านั้น",

    },

    "Composite Index": {

        "use": "ค้นหาหลาย Column พร้อมกัน",

        "example": "CREATE INDEX idx_cat_price ON products(category_id, price)",

        "when": "Query ที่ WHERE หลาย Column ลำดับสำคัญ",

    },

    "Full-text Index": {

        "use": "ค้นหาข้อความ MATCH AGAINST",

        "example": "CREATE FULLTEXT INDEX idx_desc ON products(description)",

        "when": "Search ข้อความยาว Blog Content",

    },

    "Partial Index": {

        "use": "Index เฉพาะ rows ที่ตรงเงื่อนไข",

        "example": "CREATE INDEX idx_active ON products(price) WHERE is_active=true",

        "when": "ลดขนาด Index เฉพาะข้อมูลที่ใช้บ่อย",

    },

}



print("=== Index Types ===")

for idx_type, info in index_types.items():

    print(f"\n  [{idx_type}]")

    for k, v in info.items():

        print(f"    {k}: {v}")



# Indexing Best Practices

practices = [

    "Index Column ที่ถูก WHERE, JOIN, ORDER BY บ่อย",

    "Composite Index ลำดับ Column สำคัญ (Selectivity สูงก่อน)",

    "ไม่ Index Column ที่มีค่าซ้ำมาก (Low Cardinality) เช่น gender",

    "EXPLAIN ANALYZE ทุก Query ก่อนสร้าง Index",

    "ลบ Index ที่ไม่ได้ใช้ ตรวจด้วย pg_stat_user_indexes",

    "Covering Index ใส่ Column ที่ SELECT ด้วยลด Table Lookup",

    "Index ใช้พื้นที่ Disk + ทำ INSERT/UPDATE ช้าลง",

]



print(f"\n\n=== Indexing Best Practices ===")

for i, p in enumerate(practices, 1):

    print(f"  {i}. {p}")

เคล็ดลับ

  • 3NF: ออกแบบถึง 3NF เพียงพอสำหรับงานส่วนใหญ่
  • Naming: ใช้ snake_case ชื่อตารางพหูพจน์ (users, orders)
  • EXPLAIN: ใช้ EXPLAIN ANALYZE ทุก Query ก่อน Production
  • Soft Delete: ใช้ is_deleted แทน DELETE จริง
  • UUID vs INT: INT เร็วกว่า UUID ปลอดภัยกว่าสำหรับ Distributed

Database Design คืออะไร

ออกแบบโครงสร้างฐานข้อมูล ลด Redundancy Integrity Scalability ER Diagram Normalization Tables Columns Indexes

แนะนำเพิ่มเติม — ติดตาม XM Signal

เนื้อหาเกี่ยวข้อง — อนาคตเหรียญ dogecoin วันนี้

เนื้อหาเกี่ยวข้อง — Fail2ban Advanced Distributed System

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง