1. Home
  2. Insights
  3. BigQuery
  4. ออกแบบ event schema ใน BigQuery ยังไงให้ query ง่ายและไม่พังทีหลัง
BigQuery

ออกแบบ event schema ใน BigQuery ยังไงให้ query ง่ายและไม่พังทีหลัง

อธิบายการออกแบบ event schema ใน BigQuery สำหรับงาน analytics จริง ว่าควรตั้งชื่อ event และ fields อย่างไร แยก dimensions กับ facts แบบไหน และวาง partition, nested fields และ context IDs อย่างไรให้ query ง่ายและไม่สร้างหนี้ข้อมูลในระยะยาว

ออกแบบ event schema ใน BigQuery ยังไงให้ query ง่ายและไม่พังทีหลัง

หลายทีมเริ่มเก็บ event analytics ด้วยความตั้งใจที่ดีมาก

  • อยากรู้ว่าผู้ใช้ทำอะไรบ้าง
  • อยากวัด funnel
  • อยากดู conversion
  • อยากตาม operational events
  • อยากดู behavior หลัง release
  • อยากตอบคำถามของ product, ops, support และ management ได้เร็วขึ้น

ช่วงแรกการเริ่มเก็บ event มักดูง่าย แค่ส่งชื่อ event เข้าไปพร้อม payload บางอย่าง แล้วค่อยคิดเรื่อง query ทีหลัง แต่พอข้อมูลเริ่มโต ปัญหาจะค่อย ๆ โผล่มาเอง

ชื่อ event ไม่สม่ำเสมอ
field เดิมความหมายเปลี่ยนไปเรื่อย ๆ
ทีมหนึ่งส่ง userId อีกทีมส่ง user_id
บาง event มี order_id บาง event ใช้ orderId
timestamp มีหลายแบบ
payload ยืดหยุ่นเกินไปจน query ยาก
พอผ่านไปไม่กี่เดือน คนเริ่มไม่มั่นใจว่า query ที่เขียนกำลังตอบคำถามถูกเรื่องจริงหรือไม่

BigQuery ช่วยเรื่องการ query ข้อมูลจำนวนมากได้ดีมาก แต่ถ้า event schema ตั้งต้นไม่ดี ความเร็วของ engine ก็ช่วยได้แค่ระดับหนึ่ง เพราะปัญหาจริงจะกลายเป็นเรื่อง semantic debt มากกว่า performance อย่างเดียว

บทความนี้อธิบายว่า event schema ใน BigQuery ควรออกแบบอย่างไรให้ query ง่าย ใช้ต่อได้จริง และไม่สร้างหนี้ข้อมูลจนพังทีหลัง

TL;DR

สรุปให้สั้นที่สุด

event schema ที่ดีต้องทำให้ event แต่ละรายการตอบได้ชัดว่า ใคร ทำอะไร เมื่อไร ที่ไหน กับ resource อะไร และอยู่ใน flow ไหน

ถ้าจะเริ่มให้ถูก ควรมีอย่างน้อย

  • ชื่อ event ที่เสถียรและสื่อความหมาย
  • ชื่อ field ที่สม่ำเสมอ
  • timestamp ที่ชัด
  • actor / resource / context identifiers ที่ตามเรื่องได้
  • partitioning ตามเวลา
  • การแยก event-level columns ออกจาก nested metadata อย่างมีวินัย
  • schema governance แบบง่ายแต่จริง

ถ้าเริ่มเก็บแบบ “ใส่ JSON อะไรก็ได้ เดี๋ยวค่อย query ทีหลัง” วันหนึ่ง query จะเริ่มยากและทีมจะเริ่มไม่เชื่อข้อมูลของตัวเอง

ก่อนออกแบบ ต้องถามก่อนว่า event นี้ถูกเก็บไปเพื่ออะไร

ปัญหาที่เจอบ่อยคือทีมเริ่มเก็บ event โดยยังไม่ชัดว่าใครจะใช้ และใช้ตอบคำถามแบบไหน

คำถามที่ควรถามก่อนมีประมาณนี้

  • event นี้ใช้ตอบคำถาม product analytics หรือ operational analytics
  • ใครจะ query ข้อมูลนี้
  • query ส่วนใหญ่จะดูรายวัน รายสัปดาห์ หรือย้อนหลังยาว ๆ
  • ต้อง trace รายการเดียวให้ครบ flow หรือเน้น aggregate trends
  • ต้องเชื่อมกับ user, session, order, payment หรือ job execution อะไรบ้าง
  • ต้องการ near-realtime แค่ไหน
  • มี PII หรือข้อมูลอ่อนไหวอยู่หรือไม่

คำถามพวกนี้สำคัญ เพราะ event schema ที่ดีไม่ได้เริ่มจาก field เยอะที่สุด แต่เริ่มจากการรู้ว่าจะตอบคำถามอะไรให้คนใช้งานจริง

Event schema ที่ดีควรตอบคำถามพื้นฐานอะไรได้บ้าง

ถ้าจะสรุปให้เป็นหลักง่าย ๆ event ที่ใช้งานได้ดีควรตอบคำถามเหล่านี้ให้ได้

  • เกิดอะไรขึ้น
  • เกิดเมื่อไร
  • ใครเป็นคนทำ หรือ actor คืออะไร
  • เกิดกับ resource ไหน
  • เกิดในระบบหรือ flow ไหน
  • เกิดจาก request ไหนหรือ correlation ไหน
  • อยู่ใน tenant / environment / service ไหน
  • มี properties สำคัญอะไรเพิ่มที่ช่วยให้วิเคราะห์ต่อได้

ถ้า event ตอบคำถามเหล่านี้ไม่ชัด เวลา query จะเริ่มต้องเดา และเมื่อทีมเริ่มเดาไม่ตรงกัน data layer จะเริ่มเสื่อมความน่าเชื่อถือ

เริ่มจาก naming ก่อน เพราะนี่คือจุดที่พังง่ายที่สุด

สิ่งที่ดูเล็กที่สุดแต่มักทำให้ระบบ analytics พังเร็วที่สุดคือชื่อ event และชื่อ field

ตัวอย่าง event naming ที่เริ่มพาไปลำบาก เช่น

  • clickButton
  • user_do_checkout
  • paymentDone
  • refund_ok
  • openpage
  • success

ปัญหาคือชื่อเหล่านี้ไม่ชัดว่ากำลังอธิบายเหตุการณ์ในระดับไหน และทีมอื่นจะตีความต่างกันได้ง่าย

แนวทางที่อ่านง่ายกว่าและคุมได้ดีกว่ามักเป็น pattern แบบนี้

  • user_signed_up
  • quote_created
  • payment_succeeded
  • refund_requested
  • refund_approved
  • document_uploaded
  • job_completed
  • order_status_changed

ข้อสำคัญไม่ใช่ว่าต้องใช้รูปแบบไหนเป๊ะ แต่ต้อง ใช้แบบเดียวกันทั้งระบบ

ตั้งชื่อ event ให้สื่อความหมายเชิงธุรกิจ ไม่ใช่แค่ชื่อปุ่ม

นี่สำคัญมาก

ถ้าคุณตั้ง event ตาม UI element มากเกินไป เช่น

  • submit_button_clicked
  • blue_cta_clicked
  • tab_2_opened

ข้อมูลจะเริ่มตอบคำถามเชิงธุรกิจยากขึ้นเรื่อย ๆ เพราะ UI เปลี่ยนได้ตลอด และชื่อ event จะหลุดจากความหมายของระบบจริง

ในหลายกรณีสิ่งที่ควรวัดคือ business action เช่น

  • quote_requested
  • checkout_started
  • payment_succeeded
  • claim_document_uploaded
  • admin_user_role_changed

ถ้าจำเป็นต้องเก็บ interaction ระดับ UI จริง ก็ควรทำให้แยกชั้นจาก event เชิงธุรกิจให้ชัด ไม่เช่นนั้น dataset จะเริ่มปนกันเร็วมาก

Field names ต้องสม่ำเสมอแบบน่าเบื่อให้ได้

นี่คือเรื่องที่ทีมมักเบื่อแต่สำคัญที่สุดในระยะยาว

ถ้าระบบหนึ่งส่ง userId อีกระบบส่ง user_id
ระบบหนึ่งใช้ createdAt อีกระบบใช้ event_time
ระบบหนึ่งใช้ paymentStatus อีกระบบใช้ status

ในวันแรกมันดูเล็กมาก แต่พอ query ข้าม event หลายชุด งานจะเริ่มช้าทั้งในแง่ performance และในแง่ความคิด เพราะ analyst ต้องจำ dialect ของแต่ละ event family เอง

แนวทางที่ดีกว่าคือกำหนด field naming convention กลาง เช่น

  • ใช้ snake_case
  • ใช้ event_name
  • ใช้ event_timestamp
  • ใช้ user_id
  • ใช้ tenant_id
  • ใช้ resource_type
  • ใช้ resource_id
  • ใช้ request_id
  • ใช้ correlation_id

ความสม่ำเสมอแบบนี้ช่วยมากกว่าการพยายามทำ schema ให้ฉลาดเกินไป

Core columns ที่ควรมีเกือบทุก event

ในหลายระบบ คุณจะคุมคุณภาพได้ดีขึ้นมากถ้ามี “event envelope” กลางที่ใช้ร่วมกันเกือบทุก event

ตัวอย่าง columns ที่มักควรมี เช่น

  • event_name
  • event_timestamp
  • event_date
  • actor_type
  • actor_id
  • resource_type
  • resource_id
  • tenant_id
  • environment
  • service_name
  • request_id
  • correlation_id
  • session_id
  • metadata หรือ properties สำหรับรายละเอียดเฉพาะ event

ไม่ได้แปลว่าทุก field ต้อง non-null เสมอไป แต่การมี envelope กลางทำให้ query ข้ามโดเมนง่ายขึ้นมาก

event_timestamp ต้องมีอันเดียวที่เป็น canonical

อีกปัญหาที่เจอบ่อยคือเวลาใน event มีหลายค่าและไม่มีใครรู้ว่าอันไหนควรใช้เป็นหลัก เช่น

  • created_at
  • sent_at
  • received_at
  • inserted_at
  • client_time
  • server_time

แนวทางที่ดีคือกำหนดให้ชัดว่า field ไหนคือ canonical event time เช่น

  • event_timestamp = เวลาที่ระบบถือว่าเหตุการณ์นี้เกิดขึ้นจริงในเชิงธุรกิจหรือ ingestion policy ที่ตกลงกัน

แล้วค่อยมี field เสริมถ้าจำเป็น เช่น

  • received_at
  • processed_at
  • client_timestamp

ถ้าไม่มีจุดยึดกลาง เวลา query ตามวันหรือทำ funnel จะเริ่มเพี้ยนง่ายมาก

แนะนำให้มี event_date แยกด้วย

แม้ BigQuery จะ query จาก timestamp ได้ แต่การมี event_date เป็น DATE แยกไว้จะช่วยให้ query, partitioning และ dashboard logic หลายอย่างง่ายขึ้น

ตัวอย่างเช่น

  • filter ช่วงวัน
  • group by รายวัน
  • partition pruning
  • scheduled aggregations

event_date จึงมักคุ้มที่จะมีเป็น first-class column แยกจาก event_timestamp

แยก actor ออกจาก resource ให้ชัด

event จำนวนมากเริ่ม query ยากเพราะไม่แยกว่าใครเป็นผู้กระทำ และอะไรคือสิ่งที่ถูกกระทำ

ตัวอย่างเช่น event refund_approved

สิ่งที่ควรตอบให้ชัดคือ

  • actor คือใคร เช่น admin_7
  • resource คืออะไร เช่น refund: rf_1001

ถ้าคุณเก็บแค่ user_id ลอย ๆ ในทุก event วันหนึ่ง query จะเริ่มสับสนว่า field นี้หมายถึง user เจ้าของ resource หรือ user คนที่กด action กันแน่

แนวทางที่ดีกว่าคือแยกเป็น

  • actor_type
  • actor_id
  • resource_type
  • resource_id

สิ่งนี้ช่วยมากเวลา query ข้ามโดเมนและเวลาอธิบายข้อมูลกับทีมอื่น

request_id และ correlation_id ควรมาอยู่ใน event schema ด้วย

นี่คือ field ที่หลายทีมข้ามไป แต่พอมี incident หรืออยาก trace flow ข้าม systems จะเสียดายมาก

ถ้า event schema มี

  • request_id
  • correlation_id

คุณจะ query สิ่งเหล่านี้ได้ง่ายขึ้น เช่น

  • request ไหนสร้าง event sequence นี้
  • failure นี้ผูกกับ flow ไหน
  • payment event, webhook event และ worker event อยู่ในเรื่องเดียวกันหรือไม่
  • incident หนึ่งกระทบ events กลุ่มใดบ้าง

สำหรับ operational analytics และ debugging ข้าม service field สองตัวนี้มีค่ามากกว่าที่ดูเผิน ๆ

เมื่อไรควรใช้ nested / repeated fields

BigQuery รองรับ nested และ repeated fields ได้ดี ซึ่งมีประโยชน์มากถ้าใช้อย่างมีวินัย

มันเหมาะกับกรณีเช่น

  • metadata ย่อยที่ไม่จำเป็นต้องเป็น top-level columns ทุกตัว
  • arrays ของ attributes
  • context groups เช่น device info, location info, request context
  • objects ที่มีโครงสร้างค่อนข้างเสถียร

ตัวอย่างเช่น

  • actor object
  • resource object
  • context object
  • device object

แต่ข้อควรระวังคืออย่าใช้ nested แบบ “โยนทุกอย่างลงไปก้อนเดียวแล้วค่อย query เอาเอง” เพราะจะทำให้ discoverability และ consistency แย่ลง

แนวคิดที่ดีคือ

  • field ที่ใช้ filter/join/group บ่อย ควรอยู่ top-level
  • field ที่เป็นรายละเอียดเฉพาะ event และไม่ใช่แกนหลักของ query ค่อยอยู่ nested

อย่าใช้ metadata เป็นหลุมดำของทุกอย่าง

หลายทีมเริ่มต้นด้วยการมี metadata หรือ properties แล้วทุกอย่างที่คิดไม่ออกก็โยนลงไปหมด

ช่วงแรกมันเร็วมาก แต่ระยะยาวจะเริ่มเกิดปัญหา

  • field เดิมชื่อไม่เหมือนกันข้าม event
  • ไม่มี schema governance
  • analyst ต้องเปิดดูตัวอย่าง payload ก่อนทุกครั้ง
  • query ซับซ้อนโดยไม่จำเป็น
  • data quality checks ทำยาก
  • documentation เริ่มตามไม่ทัน

metadata ควรมี แต่ไม่ควรกลายเป็นที่ซ่อนความไม่ชัดของ schema

หลักคิดง่าย ๆ คือ

  • ถ้า field นี้สำคัญพอจะ filter, join, group หรือวัดผลบ่อย ควรดันขึ้นเป็น top-level
  • ถ้า field นี้เป็นแค่รายละเอียดประกอบบาง event ค่อยอยู่ใน metadata

Partitioning ควรเริ่มยังไง

สำหรับ event tables ส่วนใหญ่ partition ตามเวลาเป็น baseline ที่ควรทำแทบเสมอ โดยมากก็มักเป็น event_date หรือ event_timestamp

เหตุผลไม่ได้มีแค่เรื่อง cost แต่รวมถึง

  • query เร็วขึ้น
  • สแกนน้อยลง
  • retention จัดการง่าย
  • scheduled processing คาดเดาได้ขึ้น

ถ้าคุณไม่ partition event table ตั้งแต่ต้น พอข้อมูลโตขึ้น query จะเริ่มแพงและการควบคุม workload จะยากขึ้นเรื่อย ๆ

Clustering ควรคิดจาก query patterns จริง

หลัง partition แล้ว field ที่อาจเหมาะกับ clustering มักเป็นพวกที่ใช้ filter บ่อย เช่น

  • event_name
  • tenant_id
  • actor_id
  • resource_type
  • resource_id

แต่การเลือก cluster fields ควรมาจาก query patterns จริง ไม่ใช่ใส่ทุกอย่างที่ดูสำคัญพร้อมกัน

ถามง่าย ๆ ว่า

  • คนชอบ filter จากอะไร
  • dashboard ใช้ field ไหนบ่อย
  • scheduled queries ชอบเริ่มจากเงื่อนไขอะไร

field เหล่านี้มักเป็นตัวเลือกที่ดีสำหรับ clustering

อย่าเก็บ event ทุกอย่างใน table เดียวเพียงเพราะทำได้

นี่เป็นเรื่องที่ต้องตัดสินใจอย่างมีสติ

การรวมทุก event ไว้ในตารางเดียวมีข้อดี เช่น query รวมง่าย, envelope กลางชัด, governance ง่ายขึ้นระดับหนึ่ง

แต่ถ้าระบบใหญ่มากและ event ต่างชนิดต่าง shape กันเกินไป table เดียวก็อาจกลายเป็นถังใหญ่ที่ดูแลงานยากขึ้น

แนวทางที่มักใช้ได้จริงคือ

  • มี table หลักสำหรับ event envelope ที่ shape ใกล้เคียงกัน
  • หรือแยก event families ตามโดเมน เช่น product events, operational events, audit events

สิ่งสำคัญคืออย่าแยกจนกระจัดกระจายเกินไป และอย่ารวมจน schema governance พัง

ออกแบบให้รองรับ additive changes ได้

event schema ที่ดีไม่ใช่ schema ที่ไม่เคยเปลี่ยน แต่คือ schema ที่เพิ่มได้โดยไม่พังง่าย

สิ่งที่ควรเลี่ยง เช่น

  • เปลี่ยนความหมายของ field เดิมเงียบ ๆ
  • เปลี่ยน type ของ field เดิม
  • reuse field เดิมไปแทนความหมายใหม่
  • เปลี่ยนชื่อ event เดิมโดยไม่มี migration plan

สิ่งที่มักปลอดภัยกว่า เช่น

  • เพิ่ม optional fields ใหม่
  • เพิ่ม nested properties ใหม่อย่างมีวินัย
  • deprecate field เดิมก่อนลบ
  • เก็บ changelog ของ event schema

analytics จะอยู่กับคุณยาวกว่าที่คิด ดังนั้น additive schema mindset สำคัญมาก

ตัวอย่าง schema แบบ practical

ตัวอย่างนี้เป็น event schema แบบกลางที่ใช้ต่อได้ดีในหลาย use case

create table analytics.events (
  event_name string not null,
  event_timestamp timestamp not null,
  event_date date not null,
  actor_type string,
  actor_id string,
  resource_type string,
  resource_id string,
  tenant_id string,
  environment string,
  service_name string,
  request_id string,
  correlation_id string,
  session_id string,
  metadata json
)
partition by event_date
cluster by event_name, tenant_id;

schema นี้ยังไม่สมบูรณ์สำหรับทุกระบบ แต่ช่วยให้เห็นหลักสำคัญคือ

  • มี envelope กลาง
  • มี canonical time
  • มี actor / resource separation
  • มี request context
  • ยังเปิดพื้นที่ให้ metadata อยู่ แต่ไม่ปล่อยให้ทุกอย่างอยู่ในนั้นทั้งหมด

ตัวอย่าง event records

{
  "event_name": "payment_succeeded",
  "event_timestamp": "2026-04-18T10:21:04Z",
  "event_date": "2026-04-18",
  "actor_type": "user",
  "actor_id": "usr_1024",
  "resource_type": "payment",
  "resource_id": "pay_8001",
  "tenant_id": "tenant_acme",
  "environment": "production",
  "service_name": "payments-api",
  "request_id": "req_9f13f2",
  "correlation_id": "corr_checkout_1001",
  "session_id": "sess_8821",
  "metadata": {
    "currency": "THB",
    "amount": 1250,
    "provider": "2c2p"
  }
}
{
  "event_name": "document_uploaded",
  "event_timestamp": "2026-04-18T10:25:11Z",
  "event_date": "2026-04-18",
  "actor_type": "user",
  "actor_id": "usr_1024",
  "resource_type": "document",
  "resource_id": "doc_5561",
  "tenant_id": "tenant_acme",
  "environment": "production",
  "service_name": "documents-api",
  "request_id": "req_91baf0",
  "correlation_id": "corr_claim_404",
  "session_id": "sess_8821",
  "metadata": {
    "mime_type": "application/pdf",
    "storage_provider": "gcs",
    "status": "pending_scan"
  }
}

ตัวอย่างแบบนี้ query trend, funnel, and trace flows ได้ง่ายกว่าการมี payload แบบหลวม ๆ มาก

ตัวอย่าง query ที่ schema ดีจะช่วยทันที

ตัวอย่างเช่นหายอด event รายวันแยกตาม event_name

select
  event_date,
  event_name,
  count(*) as total_events
from analytics.events
where event_date between '2026-04-01' and '2026-04-18'
group by event_date, event_name
order by event_date, event_name;

หรือ query ตาม correlation flow

select
  event_timestamp,
  event_name,
  service_name,
  resource_type,
  resource_id
from analytics.events
where correlation_id = 'corr_checkout_1001'
order by event_timestamp;

หรือดู document uploads ที่ยัง pending_scan

select
  resource_id,
  actor_id,
  event_timestamp,
  metadata
from analytics.events
where event_name = 'document_uploaded'
  and json_value(metadata, '$.status') = 'pending_scan';

schema ที่ดีทำให้ query แบบนี้เป็นเรื่องตรงไปตรงมา ไม่ต้องใช้การแกะ payload แบบเดาไปเรื่อย ๆ

Governance แบบเบาที่ควรมีตั้งแต่ต้น

คุณไม่จำเป็นต้องมี data governance committee ตั้งแต่วันแรก แต่ควรมีอย่างน้อย

  • รายการ event names กลาง
  • naming convention กลาง
  • field dictionary สั้น ๆ
  • owner ของ schema แต่ละโดเมน
  • policy ว่าอะไรขึ้น top-level ได้
  • policy ว่า event ใหม่ต้องประกอบด้วยอะไรบ้าง
  • changelog ของ schema changes

สิ่งเหล่านี้ช่วยมากกว่าการหวังว่าทุกคนจะตั้งชื่อเหมือนกันเอง

ข้อผิดพลาดที่เจอบ่อย

1) เก็บ payload เป็น JSON อย่างเดียวทุกอย่าง

ทำให้ query สำคัญช้าและอ่านยากโดยไม่จำเป็น

2) ไม่มี canonical timestamp

สุดท้ายแต่ละคนใช้เวลาไม่เหมือนกัน และ dashboard ตอบคนละเรื่อง

3) field names ไม่สม่ำเสมอ

ทำให้ query ข้ามโดเมนยากมาก

4) เอา UI interactions กับ business events ปนกันแบบไร้โครง

สุดท้าย dataset ใหญ่ขึ้นแต่ความหมายพร่า

5) เปลี่ยน semantics ของ field เดิมเงียบ ๆ

อันนี้อันตรายกว่าลบ field ตรง ๆ เพราะ query เก่าอาจยังรันได้ แต่ตอบผิด

Internal links และ discoverability ก็สำคัญ

เมื่อ event schema เริ่มเยอะ การค้นว่า “มี event อะไรให้ใช้บ้าง” จะสำคัญขึ้นเรื่อย ๆ ถ้า schema ดีแต่ไม่มีเอกสารหรือ mapping ที่ discoverable คนในทีมก็ยังใช้ยาก

อย่างน้อยควรมีหน้าหรือ document ที่ช่วยตอบว่า

  • event อะไรอยู่ในโดเมนไหน
  • event ไหนใช้วัด funnel นี้
  • field ไหนเป็น canonical
  • correlation ระหว่าง event families เป็นอย่างไร

data model ที่ดีต้องค้นเจอและทำความเข้าใจได้ง่ายด้วย ไม่ใช่แค่ technically query ได้

รีวิวเชิง production-minded

Correctness

event schema ที่ดีช่วยให้ query ตอบคำถามทางธุรกิจได้ถูกเรื่องมากขึ้น ไม่ใช่แค่รันผ่าน ซึ่งสำคัญกว่าความเร็วอย่างเดียวในระยะยาว

Security

ยิ่ง event analytics โต ยิ่งต้องคิดเรื่อง PII และ access control ให้ชัดว่า field ไหนควรเก็บ, ใครควรเห็น, และอะไรควรถูก mask หรือแยกออก

Efficiency

top-level columns ที่สม่ำเสมอ, partitioning ที่ถูกต้อง และ metadata ที่ไม่มั่ว ช่วยให้ query ทั้งเร็วขึ้นและอ่านง่ายขึ้น พร้อมกัน

Error handling

ถ้า schema governance ไม่ดี ปัญหาจะไม่โผล่เป็น error ตรง ๆ แต่จะโผล่เป็น “query ได้แต่ตอบผิด” ซึ่งอันตรายกว่า เพราะทีมอาจตัดสินใจจากข้อมูลที่เพี้ยนโดยไม่รู้ตัว

Checklist สั้น ๆ ก่อนปล่อย event schema ใช้งานจริง

  • event name สื่อความหมายเชิงธุรกิจชัด
  • field naming convention ใช้เหมือนกันทั้งระบบ
  • มี event_timestamp เป็น canonical time
  • มี event_date สำหรับ partition/query ใช้ง่าย
  • แยก actor_* ออกจาก resource_*
  • มี request_id และ correlation_id เมื่อเหมาะสม
  • field ที่ใช้ filter/join/group บ่อยอยู่ top-level
  • metadata ไม่ถูกใช้เป็นหลุมดำของทุกอย่าง
  • partitioning และ clustering อิง query patterns จริง
  • มี field dictionary หรือ schema guide กลาง
  • มี policy สำหรับ additive changes และ deprecation

บทความที่ควรอ่านต่อ

สรุป

event schema ใน BigQuery ที่ดีไม่ได้เกิดจากการใส่ field ให้เยอะที่สุด แต่เกิดจากการกำหนด envelope ที่ชัด ตั้งชื่อให้สม่ำเสมอ และรู้ว่าอะไรควรเป็น top-level field อะไรควรอยู่เป็น metadata

ถ้าคุณเริ่มต้นดี query จะง่ายขึ้น, cost จะคุมง่ายขึ้น, incident tracing จะดีขึ้น และทีมจะเชื่อข้อมูลมากขึ้น แต่ถ้าเริ่มต้นแบบปล่อยให้ payload โตตามใจ วันหนึ่งปัญหาจะไม่ใช่แค่ query ช้า แต่จะเป็นการที่ไม่มีใครมั่นใจว่าข้อมูลกำลังบอกอะไรแน่

สรุปสั้นที่สุดคือ

event schema ที่ดีต้องทำให้ทั้งเครื่อง query ได้ง่าย และคนอ่านเข้าใจตรงกันว่า event นั้นหมายถึงอะไร

💬 Chat (ตอบเร็ว)