DHDataHọc
TheoryLesson 1/84 min read+10 XP

Sự kiện và dữ liệu hành vi

Bạn sẽ học được

  • Cấu trúc tối thiểu của một sự kiện hành vi.
  • Quy ước đặt tên sự kiện và thuộc tính.
  • Xây dựng kế hoạch tracking (tracking plan) trước khi code.
  • Những lỗi dữ liệu sự kiện thường gặp.
  • Kiểm tra chất lượng dữ liệu sự kiện trước khi phân tích.

Khái niệm cốt lõi

Mọi phân tích sản phẩm bắt đầu từ bảng sự kiện. Một sự kiện tối thiểu cần:

TrườngÝ nghĩaVí dụ
user_idAiu_10231
event_nameLàm gìcheckout_completed
occurred_atKhi nào2026-01-05 14:30:12+07
propertiesNgữ cảnh{ "value": 250000, "method": "cod" }

Thiếu user_id thì không tính được retention. Thiếu thời điểm chính xác thì không xếp được phễu. Thiếu ngữ cảnh thì không phân tích được nguyên nhân.

Đặt tên sự kiện

Quy ước phổ biến: đối_tượng_hành_động ở thì quá khứ.

code
page_viewed
product_viewed
cart_item_added
checkout_started
checkout_completed
subscription_cancelled

Tránh:

  • Tên mơ hồ: click, action, event1.
  • Trộn ngôn ngữ và kiểu chữ: Checkout_Completed, checkoutDone.
  • Nhét ngữ cảnh vào tên: checkout_completed_cod_mobile — dùng properties.
  • Đổi tên sự kiện cũ giữa chừng — dữ liệu lịch sử bị tách đôi.

Một sự kiện, một ý nghĩa. Nếu cần phân biệt cách thanh toán, thêm thuộc tính method, không tạo sự kiện mới.

Kế hoạch tracking

Viết trước khi lập trình:

Sự kiệnKhi nào bắnThuộc tính bắt buộcChỉ số dùng
product_viewedMở trang chi tiếtproduct_id, sourcePhễu xem → thêm giỏ
cart_item_addedThêm vào giỏproduct_id, quantity, priceTỷ lệ thêm giỏ
checkout_startedMở trang thanh toáncart_value, item_countPhễu thanh toán
checkout_completedThanh toán thành côngorder_id, value, methodDoanh thu, chuyển đổi
subscription_cancelledHuỷ góiplan, reasonTỷ lệ rời bỏ

Mỗi sự kiện phải gắn với ít nhất một chỉ số sẽ dùng. Sự kiện không dùng để tính gì thì không cần bắn — mỗi sự kiện là chi phí lưu trữ và rủi ro nhiễu.

Cấu trúc bảng sự kiện

code
CREATE TABLE events (
  id          bigserial PRIMARY KEY,
  user_id     text NOT NULL,
  event_name  text NOT NULL,
  occurred_at timestamptz NOT NULL,
  properties  jsonb NOT NULL DEFAULT '{}'::jsonb
);

CREATE INDEX events_user_time ON events (user_id, occurred_at);
CREATE INDEX events_name_time ON events (event_name, occurred_at);

Hai chỉ mục trên phục vụ hai truy vấn phổ biến nhất: theo người dùng (retention, phễu) và theo sự kiện (đếm, xu hướng).

Nếu dữ liệu rất lớn, cân nhắc partition theo tháng trên occurred_at.

Kiểm tra chất lượng dữ liệu

Bốn kiểm tra trước khi phân tích:

1. Sự kiện có tồn tại nhưng không bao giờ xảy ra đúng thứ tự?

code
SELECT COUNT(*)
FROM events
WHERE event_name = 'checkout_completed'
  AND occurred_at < (
    SELECT MIN(occurred_at) FROM events e2
    WHERE e2.user_id = events.user_id
      AND e2.event_name = 'checkout_started'
  );

Nếu số này lớn, có lỗi ghi nhận thời gian hoặc gửi sự kiện theo lô sai thứ tự.

2. Sự kiện trùng lặp?

code
SELECT user_id, event_name, occurred_at, COUNT(*) AS n
FROM events
GROUP BY 1, 2, 3
HAVING COUNT(*) > 1
ORDER BY n DESC
LIMIT 20;

Trùng có thể do retry mạng. Cần quy tắc khử trùng (ví dụ giữ một bản ghi theo id nhỏ nhất trong cùng giây).

3. Sự kiện tăng đột biến?

code
SELECT date_trunc('day', occurred_at)::date AS ngay,
       COUNT(*) AS n
FROM events
GROUP BY 1
ORDER BY 1 DESC
LIMIT 30;

Tăng đột biến thường do bug gửi lặp, không phải người dùng thật.

4. Thuộc tính bắt buộc có đủ?

code
SELECT COUNT(*) FILTER (WHERE properties->>'product_id' IS NULL) AS thieu_product_id,
       COUNT(*) AS tong
FROM events
WHERE event_name = 'product_viewed';

Thực hành

  1. Viết kế hoạch tracking cho ba sự kiện của một phễu mua hàng.
  2. Kiểm tra sự kiện checkout_completed có xảy ra sau checkout_started không.
  3. Tìm sự kiện trùng lặp theo người dùng và thời điểm.
  4. Vẽ số sự kiện theo ngày trong 30 ngày gần nhất.
  5. Kiểm tra tỷ lệ thiếu product_id trong product_viewed.

Lỗi thường gặp

Triệu chứngNguyên nhânCách sửa
Không tính được retentionThiếu user_id hoặc là nullBắt buộc user_id khi bắn
Phễu âmSự kiện gửi sai thứ tựKiểm tra client, gửi ngay khi xảy ra
Số liệu nhảy vọtSự kiện gửi lặpKhử trùng, sửa client
Không phân tích được nguyên nhânThiếu thuộc tínhBổ sung vào tracking plan
Đổi tên làm mất lịch sửKhông có quy ướcGiữ tên cũ, thêm sự kiện mới
Sự kiện không ai dùngBắn tràn lanMỗi sự kiện gắn một chỉ số

Tóm tắt

  • Sự kiện cần user_id, event_name, occurred_at, properties.
  • Đặt tên theo quy ước đối_tượng_hành_động, ngữ cảnh để trong thuộc tính.
  • Viết tracking plan trước khi code.
  • Chỉ mục theo (user_id, occurred_at) và (event_name, occurred_at).
  • Kiểm tra thứ tự, trùng lặp, đột biến và thiếu thuộc tính trước khi phân tích.

Use ← → to move between lessons