สคีมาแบบดาวและแบบเกล็ดหิมะ
จำลองข้อมูลเพื่อการวิเคราะห์ที่รวดเร็ว
สคีมาแบบดาวและแบบเกล็ดหิมะ เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
สคีมาคลังข้อมูลคืออะไร
ในฐานข้อมูลเชิงธุรกรรม (OLTP) คุณทำให้ข้อมูลอยู่ในรูปแบบนอร์มัลไลซ์เพื่อหลีกเลี่ยงข้อมูลซ้ำซ้อน ส่วนในคลังข้อมูล คุณมักทำให้ข้อมูลเป็นแบบดีนอร์มัลไลซ์โดยตั้งใจ — ยอมใช้พื้นที่จัดเก็บมากขึ้นเพื่อแลกกับความเร็วในการสืบค้น รูปแบบคลาสสิกสองแบบสำหรับจัดระเบียบตารางในคลังข้อมูลคือ สคีมาแบบดาว และ สคีมาแบบเกล็ดหิมะ
ทั้งสองรูปแบบมีตาราง ข้อเท็จจริง อยู่ตรงกลางและล้อมรอบด้วยตาราง มิติ ความแตกต่างอยู่ที่ระดับการทำให้ตารางมิติเป็นนอร์มัลไลซ์
ตารางข้อเท็จจริงและตารางมิติ
ตารางข้อเท็จจริง จัดเก็บเหตุการณ์ที่วัดค่าได้ เช่น การขาย การคลิก และการจัดส่ง ตารางนี้มีจำนวนแถวมาก และประกอบด้วยค่ามาตรวัดเชิงตัวเลขพร้อมคีย์นอกที่อ้างอิงมิติ
ตารางมิติ อธิบายบริบทของแต่ละเหตุการณ์ ได้แก่ ใคร อะไร เมื่อไร และที่ไหน ตารางมิติมีจำนวนแถวน้อยกว่า แต่มีคอลัมน์เชิงพรรณนาที่หลากหลายกว่า
CREATE TABLE fact_sales (
sale_id SERIAL PRIMARY KEY,
date_key INT NOT NULL,
product_key INT NOT NULL,
customer_key INT NOT NULL,
store_key INT NOT NULL,
quantity INT NOT NULL,
revenue NUMERIC(12, 2) NOT NULL
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category VARCHAR(100),
brand VARCHAR(100),
unit_price NUMERIC(10, 2)
);สคีมาแบบดาว
ใน สคีมาแบบดาว ตารางมิติทุกตารางเชื่อมต่อกับตารางข้อเท็จจริง โดยตรง หากวาดความสัมพันธ์ลงบนกระดาษ จะดูเหมือนดาว โดยมีตารางข้อเท็จจริงเป็นจุดศูนย์กลางและตารางมิติเป็นแฉก
ตารางมิติเป็นแบบดีนอร์มัลไลซ์อย่างสมบูรณ์ คุณลักษณะเชิงพรรณนาทั้งหมดอยู่ในตารางเดียว แม้ว่าคุณลักษณะบางอย่างจะซ้ำกันในหลายแถว
-- Star schema: all product info in one flat dimension table
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_name VARCHAR(100), -- denormalized
subcategory VARCHAR(100), -- denormalized
brand_name VARCHAR(100), -- denormalized
brand_country VARCHAR(100), -- denormalized
unit_price NUMERIC(10, 2)
);
CREATE TABLE dim_date (
date_key INT PRIMARY KEY, -- e.g. 20240315
full_date DATE,
year INT,
quarter INT,
month INT,
month_name VARCHAR(20),
week INT,
day_of_week VARCHAR(10)
);คำสั่งสืบค้นสคีมาแบบดาว
ตารางมิติแบบแบนทำให้คำสั่งสืบค้นเรียบง่าย คุณเชื่อมตารางข้อเท็จจริงกับมิติหนึ่งรายการขึ้นไปแล้วรวมค่า โดยไม่ต้องมีการเชื่อมตารางรองผ่านสายโซ่ของตารางแบบนอร์มัลไลซ์
นี่คือเหตุผลที่สคีมาแบบดาวให้คำสั่งสืบค้นเชิงวิเคราะห์ที่รวดเร็ว เพราะกราฟการเชื่อมตารางมีความลึกน้อย
SELECT
d.year,
d.quarter,
p.category_name,
SUM(f.revenue) AS total_revenue,
SUM(f.quantity) AS units_sold
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
WHERE d.year = 2024
GROUP BY d.year, d.quarter, p.category_name
ORDER BY d.quarter, total_revenue DESC;สคีมาแบบเกล็ดหิมะ
สคีมาแบบเกล็ดหิมะทำให้ตารางมิติเป็นรูปแบบปกติมากขึ้นด้วยการแบ่งตารางออกเป็นมิติย่อย ตัวอย่างเช่น แทนที่จะจัดเก็บ category_name และ brand_name ไว้ใน dim_product คุณจะสร้างตาราง dim_category และ dim_brand แยกกัน
แผนภาพที่ได้จะดูคล้ายเกล็ดหิมะ ซึ่งมีแขนงของตารางที่เกี่ยวข้องแตกออกจากกัน
-- Snowflake schema: product dimension is normalized
CREATE TABLE dim_brand (
brand_key SERIAL PRIMARY KEY,
brand_name VARCHAR(100),
brand_country VARCHAR(100)
);
CREATE TABLE dim_category (
category_key SERIAL PRIMARY KEY,
category_name VARCHAR(100),
subcategory VARCHAR(100)
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_key INT REFERENCES dim_category(category_key),
brand_key INT REFERENCES dim_brand(brand_key),
unit_price NUMERIC(10, 2)
);คิวรีสคีมาแบบเกล็ดหิมะ
การคิวรีสคีมาแบบเกล็ดหิมะต้องใช้การเชื่อมตารางมากขึ้น เพื่อประกอบข้อมูลมิติที่ถูกแบ่งไว้ในหลายตารางกลับเข้าด้วยกัน ตัวเพิ่มประสิทธิภาพคิวรีต้องสำรวจระดับเพิ่มเติมเหล่านี้ ซึ่งอาจทำให้เกิดความหน่วงมากกว่าสคีมาแบบดาว
อย่างไรก็ตาม มิติที่ทำให้เป็นรูปแบบปกติจะมีขนาดเล็กกว่าและสอดคล้องกัน การอัปเดตชื่อแบรนด์ในหนึ่งแถวของ dim_brand จะมีผลโดยอัตโนมัติในทุกที่
SELECT
d.year,
c.category_name,
b.brand_name,
SUM(f.revenue) AS total_revenue
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
JOIN dim_category c ON c.category_key = p.category_key
JOIN dim_brand b ON b.brand_key = p.brand_key
WHERE d.year = 2024
GROUP BY d.year, c.category_name, b.brand_name
ORDER BY total_revenue DESC;คีย์ตัวแทนเทียบกับคีย์ธรรมชาติ
โดยทั่วไปตารางมิติจะใช้ คีย์ตัวแทน ซึ่งเป็นจำนวนเต็มที่คลังข้อมูลสร้างขึ้น (เช่น SERIAL) แทนคีย์ธรรมชาติจากระบบต้นทาง
คีย์ตัวแทนยังคงเสถียรแม้ระบบต้นทางจะเปลี่ยนแปลง ใช้พื้นที่น้อยสำหรับตารางข้อเท็จจริงขนาดใหญ่ และรองรับ มิติที่เปลี่ยนแปลงช้า ซึ่งต้องติดตามประวัติ
-- Surrogate key (product_key) vs natural key (sku)
INSERT INTO dim_product (product_name, category_key, brand_key, unit_price)
VALUES ('Wireless Headphones', 3, 7, 89.99);
-- product_key is assigned by SERIAL -- the natural key (SKU) lives elsewhere
-- Natural key would be:
-- INSERT INTO dim_product (sku, product_name, ...)
-- VALUES ('WH-1000XM5', 'Wireless Headphones', ...);
-- Risky: SKU can be reused or reassigned by the source systemมิติวันที่
มิติวันที่มีลักษณะพิเศษ เพราะแทบจะมีอยู่เสมอ และมักเติมข้อมูลวันที่ล่วงหน้าไว้หลายปี การจัดเก็บคุณลักษณะที่คำนวณไว้แล้ว เช่น ปี ไตรมาส ชื่อเดือน งวดบัญชี และตัวบ่งชี้วันหยุด ไว้ในตารางมิติจะช่วยหลีกเลี่ยงการคำนวณซ้ำขณะคิวรี
-- Populate dim_date for one year using generate_series
INSERT INTO dim_date (date_key, full_date, year, quarter, month, month_name, week, day_of_week)
SELECT
TO_CHAR(d, 'YYYYMMDD')::INT AS date_key,
d AS full_date,
EXTRACT(YEAR FROM d)::INT AS year,
EXTRACT(QUARTER FROM d)::INT AS quarter,
EXTRACT(MONTH FROM d)::INT AS month,
TO_CHAR(d, 'Month') AS month_name,
EXTRACT(WEEK FROM d)::INT AS week,
TO_CHAR(d, 'Day') AS day_of_week
FROM generate_series('2024-01-01'::DATE, '2024-12-31'::DATE, '1 day') AS d;มิติที่เปลี่ยนแปลงช้า (SCD ประเภท 2)
จะเกิดอะไรขึ้นเมื่อลูกค้าย้ายเมืองหรือสินค้าเปลี่ยนหมวดหมู่ คุณต้องติดตามประวัติ SCD ประเภท 2จะแทรกแถวมิติใหม่สำหรับการเปลี่ยนแปลงแต่ละครั้ง พร้อมปิดแถวก่อนหน้าด้วยวันที่สิ้นสุด แถวในตารางข้อเท็จจริงยังคงชี้ไปยังคีย์มิติเดิม จึงรักษาความถูกต้องของข้อมูลในอดีตไว้ได้
-- SCD Type 2 customer dimension
CREATE TABLE dim_customer (
customer_key SERIAL PRIMARY KEY,
customer_id INT NOT NULL,
customer_name VARCHAR(200),
city VARCHAR(100),
country VARCHAR(100),
valid_from DATE NOT NULL,
valid_to DATE,
is_current BOOLEAN DEFAULT TRUE
);
-- When a customer moves, close old row and insert new one:
UPDATE dim_customer
SET valid_to = CURRENT_DATE - 1, is_current = FALSE
WHERE customer_id = 42 AND is_current = TRUE;
INSERT INTO dim_customer (customer_id, customer_name, city, country, valid_from, is_current)
VALUES (42, 'Alice Muller', 'Berlin', 'Germany', CURRENT_DATE, TRUE);สคีมาแบบดาวเทียบกับแบบเกล็ดหิมะ — ข้อแลกเปลี่ยน
ไม่มีสคีมาใดดีกว่าเสมอไป ให้เลือกตามลำดับความสำคัญของคุณ:
- แบบดาว — การเชื่อมตารางน้อยกว่า คิวรีเร็วกว่า ETL ง่ายกว่า แต่มีค่าใช้พื้นที่จัดเก็บสูงกว่า เหมาะที่สุดสำหรับเครื่องมือวิเคราะห์ที่อ่านข้อมูลเป็นหลัก เช่น Tableau และ Power BI
- แบบเกล็ดหิมะ — มิติเป็นรูปแบบปกติ มีข้อมูลซ้ำซ้อนน้อยกว่า และอัปเดตมิติได้ง่ายกว่า แต่ต้องเชื่อมตารางมากกว่า เหมาะกว่าเมื่อมิติมีขนาดใหญ่หรือใช้ร่วมกันในตารางข้อเท็จจริงหลายตาราง
-- Checking how much storage the denormalized category column costs
-- in a large dim_product (star schema) vs a separate dim_category (snowflake)
SELECT
COUNT(*) AS total_products,
COUNT(DISTINCT category_name) AS unique_categories,
pg_size_pretty(
SUM(pg_column_size(category_name))
) AS category_storage
FROM dim_product;สคีมาแบบกาแล็กซี (กลุ่มดาวของตารางข้อเท็จจริง)
เมื่อคลังข้อมูลมีตารางข้อเท็จจริงหลายตารางที่ใช้ตารางมิติร่วมกัน ผลลัพธ์จะเรียกว่า สคีมาแบบกาแล็กซี (หรือกลุ่มดาวของตารางข้อเท็จจริง) ตัวอย่างเช่น คลังข้อมูลค้าปลีกอาจมีตารางข้อเท็จจริงแยกกันสำหรับยอดขายและการคืนสินค้า โดยทั้งสองตารางอ้างอิง dim_product และ dim_date เดียวกัน
มิติที่ใช้ร่วมกันช่วยบังคับให้การกรองข้อมูลสอดคล้องกัน และทำให้การเปรียบเทียบข้ามตารางข้อเท็จจริงทำได้โดยตรง
CREATE TABLE fact_returns (
return_id SERIAL PRIMARY KEY,
date_key INT NOT NULL REFERENCES dim_date(date_key),
product_key INT NOT NULL REFERENCES dim_product(product_key),
customer_key INT NOT NULL,
quantity INT NOT NULL,
refund_amount NUMERIC(12, 2) NOT NULL
);
-- Cross-fact query: net revenue = sales - refunds
SELECT
d.year,
d.month,
SUM(s.revenue) AS gross_revenue,
SUM(r.refund_amount) AS total_refunds,
SUM(s.revenue) - COALESCE(SUM(r.refund_amount), 0) AS net_revenue
FROM dim_date d
LEFT JOIN fact_sales s ON s.date_key = d.date_key
LEFT JOIN fact_returns r ON r.date_key = d.date_key
WHERE d.year = 2024
GROUP BY d.year, d.month
ORDER BY d.month;สคีมาแบบดาวเทียบกับแบบเกล็ดหิมะ
ทดสอบความเข้าใจของคุณเกี่ยวกับสคีมาแบบดาวและแบบเกล็ดหิมะ
สรุปบทเรียน
ในบทเรียนนี้ คุณได้สำรวจรูปแบบการออกแบบคลังข้อมูลพื้นฐานสองรูปแบบ:
- สคีมาแบบดาว — ตารางข้อเท็จจริงส่วนกลางที่ล้อมรอบด้วยตารางมิติแบบแบนและไม่ทำให้เป็นรูปแบบปกติ การเชื่อมตารางน้อยกว่า คิวรีเร็วกว่า และใช้พื้นที่จัดเก็บมากกว่าเล็กน้อย
- สคีมาแบบเกล็ดหิมะ — ตารางมิติถูกทำให้เป็นรูปแบบปกติมากขึ้นเป็นมิติย่อย มีข้อมูลซ้ำซ้อนน้อยกว่า อัปเดตได้ง่ายกว่า แต่ต้องใช้การเชื่อมตารางมากกว่า
- ตารางข้อเท็จจริงเก็บเหตุการณ์ที่วัดค่าได้ ส่วนตารางมิติให้บริบท เช่น ใคร อะไร เมื่อไร และที่ไหน
- คีย์ตัวแทนช่วยรักษาความถูกต้องของข้อมูลในอดีต และแยกคลังข้อมูลออกจากการเปลี่ยนแปลงของระบบต้นทาง
- SCD ประเภท 2ติดตามประวัติของมิติด้วยการเพิ่มแถวใหม่พร้อมวันที่มีผล แทนการเขียนทับแถวเดิม
- เมื่อตารางข้อเท็จจริงหลายตารางใช้มิติร่วมกัน การออกแบบจะกลายเป็นสคีมาแบบกาแล็กซี (กลุ่มดาวของตารางข้อเท็จจริง)
เลือกสคีมาแบบดาวเมื่อให้ความสำคัญกับความเรียบง่ายและความเร็ว และเลือกแบบเกล็ดหิมะเมื่อมิติมีขนาดใหญ่ มีการอัปเดตบ่อย หรือใช้ร่วมกันในตารางข้อเท็จจริงหลายตาราง
เรียนรู้ SQL ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 46
- บทเรียน
- 183
คำถามที่พบบ่อย
บทเรียน “สคีมาแบบดาวและแบบเกล็ดหิมะ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สคีมาแบบดาวและแบบเกล็ดหิมะ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สคีมาแบบดาวและแบบเกล็ดหิมะ”
จำลองข้อมูลเพื่อการวิเคราะห์ที่รวดเร็ว คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “สคีมาแบบดาวและแบบเกล็ดหิมะ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- OLTP เทียบกับ OLAP
- ตารางข้อเท็จจริงและตารางมิติ
- สคีมาแบบดาวและแบบเกล็ดหิมะ
- การเขียนคำค้นหาเชิงวิเคราะห์