Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Database (Lưu trữ dữ liệu)

Technical Basics

Dữ liệu sống ở đâu, đọc và ghi tốn gì — và vì sao số trên dashboard là "tính đến tối qua".

Bạn đang ở đâu với kỹ năng này?

Làm bài Đánh giá Nền tảng Kỹ thuật cho PM/BA — 3 người đã làm. Một lần làm chấm điểm cho tất cả kỹ năng trong nhóm Technical Basics, không chỉ kỹ năng này.

Làm bài đánh giá

Hai mức độ

Baseline — bạn hiểu

Relational (SQL — bảng/dòng/cột: MySQL, PostgreSQL) vs non-relational (NoSQL — linh hoạt: MongoDB, Redis). Đa số sản phẩm dùng cả hai. Đọc và ghi đều có chi phí.

Mọi người làm sản phẩm, từ ngày đầu.
Working — bạn làm được

Hỏi "dữ liệu này sống ở đâu?"; nhận ra spec đang đòi thứ đắt (quét cả bảng lớn, tổng hợp real-time, query không filter); hiểu vì sao số trên dashboard là "tính đến tối qua".

Product Analyst và Product Owner.

Roadmap — Cách học và đạt kỹ năng

Database là gì?

Database là nơi dữ liệu của sản phẩm được ghi xuống và đọc lên: người dùng, đơn hàng, giao dịch, tồn kho. Mọi con số bạn nhìn thấy trên màn hình đều đến từ một chỗ nào đó trong database — nếu chỗ đó chưa tồn tại thì feature của bạn phải tạo ra nó trước.

Relational (SQL) — dữ liệu nằm trong bảng, mỗi bảng có cột cố định, mỗi dòng là một bản ghi. MySQL, PostgreSQL. Hợp với dữ liệu cần chính xác và có quan hệ với nhau: đơn hàng, thanh toán, tồn kho.

Non-relational (NoSQL) — linh hoạt hơn, mỗi bản ghi có thể có hình dạng khác nhau. MongoDB (document), Redis (thường dùng làm cache, đọc cực nhanh nhưng dữ liệu có thể cũ vài giây).

Đa số sản phẩm dùng cả hai. Và điều quan trọng nhất với BA/PO: đọc và ghi đều có chi phí. Một câu hỏi "20 đơn mới nhất của khách này" là rẻ. Một câu hỏi "tổng doanh thu theo tỉnh từ trước tới nay, tính lại mỗi lần mở trang" là đắt — đắt tới mức có thể làm chậm cả luồng đặt hàng thật.

Bên trái một bảng SQL với cột cố định, bên phải một document NoSQL linh hoạt, kèm chú thích chi phí đọc ghi
Bảng có cột cố định so với document linh hoạt — và ô dưới cùng: cùng một dữ liệu, cách hỏi khác nhau thì chi phí khác nhau rất xa.

Baseline — bạn hiểu

  • Relational (SQL — bảng/dòng/cột: MySQL, PostgreSQL) so với non-relational (NoSQL — linh hoạt: MongoDB, Redis).
  • Đa số sản phẩm dùng cả hai.
  • Đọc và ghi đều có chi phí — không có thao tác nào là miễn phí.

Working — bạn làm được

  • Hỏi "dữ liệu này sống ở đâu?" trước khi thiết kế màn hình.
  • Nhận ra spec đang đòi thứ đắt: quét cả bảng lớn, tổng hợp real-time, query không filter.
  • Hiểu vì sao số trên dashboard là "tính đến tối qua", và biết khi nào nên chấp nhận điều đó.

Cơ chế hoạt động

Khái niệmNghĩa là gìDấu hiệu bạn đã hiểu
Bảng, dòng, cộtBảng = một loại dữ liệu; dòng = một bản ghi; cột = một thuộc tính.Bạn hỏi "cột này đã có sẵn chưa" trước khi hứa hiển thị nó.
IndexMục lục giúp tìm nhanh theo một cột nhất định.Bạn biết vì sao lọc theo ngày nhanh mà tìm chữ tự do thì chậm.
MigrationThay đổi cấu trúc: thêm cột, đổi kiểu dữ liệu.Bạn luôn hỏi kèm: "dữ liệu cũ điền gì vào cột mới?"
Cache (Redis)Bản sao tạm để đọc nhanh, chấp nhận cũ vài giây.Bạn không hoảng khi hai màn hình lệch nhau vài giây.
Bảng tổng hợpKết quả được tính sẵn theo lịch thay vì tính lại mỗi lần xem.Bạn ghi rõ trong spec: số liệu tính đến thời điểm nào.
Xoá mềmĐánh dấu đã xoá thay vì xoá hẳn khỏi bảng.Bạn phân biệt "khách không thấy nữa" và "dữ liệu biến mất".

Ví dụ theo cấp độ

Cơ bản — Dữ liệu người dùng nằm ở bảng nào?

Tình huống: bạn được giao thiết kế màn hình "Danh sách khách hàng mới" cho đội chăm sóc khách hàng, và bạn chưa từng nhìn vào database bao giờ.

Bước đầu tiên là xin xem cấu trúc bảng. Bảng users thường trông như sau — mỗi dòng là một người dùng, mỗi cột là một thuộc tính của người đó:

idemailho_tentrang_thaicreated_at
1041an.nguyen@example.comNguyễn Văn Anactive2026-08-01 09:12
1042binh.tran@example.comTrần Thị Bìnhactive2026-08-01 10:03
1043cuong.le@example.comLê Quốc Cườngblocked2026-08-02 21:47

Câu hỏi tương ứng, viết bằng SQL:

SELECT id, ho_ten, email, created_at
FROM users
WHERE trang_thai = 'active'
ORDER BY created_at DESC
LIMIT 20;

Đọc bằng lời: "lấy 4 cột này, từ bảng users, chỉ những người đang hoạt động, sắp xếp người mới nhất lên đầu, và chỉ lấy 20 dòng". Kết quả là đúng 20 dòng — không phải cả bảng.

Học được: mọi thứ hiển thị trên màn hình đều đến từ một cột có thật. Nếu bạn muốn hiện "nguồn khách đến từ đâu" mà bảng không có cột đó, thì yêu cầu của bạn không phải là "thêm một dòng chữ" — nó là thêm cột, thu thập dữ liệu mới, và quyết định xem những khách cũ sẽ hiện gì.

Trung bình — Vì sao lọc theo ngày thì nhanh mà tìm tự do thì chậm?

Tình huống: bảng don_hang có 5 triệu dòng. Cùng một màn hình, hai bộ lọc, thời gian phản hồi chênh nhau hàng chục lần.

Bộ lọcCâu hỏi tới databaseKết quả
Lọc theo ngàyWHERE created_at >= '2026-08-01'Nhanh. Cột created_at có index, database nhảy thẳng tới đoạn cần đọc.
Tìm chữ trong ghi chúWHERE ghi_chu LIKE '%giao gấp%'Chậm. Không index nào giúp được — phải mở từng dòng trong 5 triệu dòng để xem bên trong.

Điều này thay đổi cách bạn viết yêu cầu: "thêm ô tìm kiếm tự do trên màn hình đơn hàng" nghe như một dòng spec, nhưng thực chất là một quyết định kỹ thuật đáng kể. Cách viết tốt hơn:

  • Bắt buộc phải chọn khoảng thời gian (mặc định 30 ngày gần nhất) trước khi tìm.
  • Tìm chính xác theo mã đơn hoặc số điện thoại thì cho phép ngay — đó là các cột có index.
  • Tìm chữ tự do trong ghi chú: hỏi dev trước, vì có thể cần một hệ thống tìm kiếm riêng.

Học được: tốc độ không phụ thuộc vào việc màn hình trông đơn giản hay phức tạp, mà phụ thuộc vào cách hỏi dữ liệu. Một filter bắt buộc trong spec thường là thứ duy nhất giữ cho màn hình đó dùng được sau hai năm.

Nâng cao — Dashboard "real-time" trên bảng 40 triệu dòng

Tình huống: ban giám đốc yêu cầu: "Dashboard doanh thu theo tỉnh, cập nhật real-time." Bảng đơn hàng có 40 triệu dòng và vẫn đang tăng mỗi ngày. Dev trả lời: "Chỉ làm được nếu số liệu tính đến tối qua." Bạn cần hiểu vì sao, để đàm phán chứ không chỉ chuyển lời.

Vì sao dev nói vậy:

  • Để có doanh thu theo tỉnh, database phải cộng dồn toàn bộ 40 triệu dòng và nhóm lại theo từng tỉnh. Đây là quét cả bảng, không phải đọc vài dòng.
  • Một lần quét như vậy tốn hàng chục giây và chiếm tài nguyên. Nếu 20 người cùng mở dashboard lúc 9 giờ sáng, chính database đang phục vụ việc đặt hàng của khách cũng chậm theo. Rủi ro không nằm ở dashboard — nó nằm ở doanh thu thật.
  • Cách rẻ: chạy một lượt tính vào ban đêm, ghi kết quả vào bảng tổng hợp chỉ một dòng cho mỗi tỉnh. Sáng hôm sau mở dashboard là đọc đúng bấy nhiêu dòng — gần như tức thời.

Cái bẫy: không phải mọi con số đều chịu được "tính đến tối qua". Trước khi đồng ý, hãy tách yêu cầu theo mục đích sử dụng:

  • Số để nhìn xu hướng (doanh thu tháng, tăng trưởng theo tỉnh): "tính đến tối qua" hoàn toàn ổn — không ai ra quyết định khác đi vì thiếu số của sáng nay.
  • Số để hành động ngay (tồn kho còn bao nhiêu, đơn nghi ngờ gian lận, khiếu nại đang chờ): không được cũ. Nhưng những số này có phạm vi hẹp — chỉ hôm nay, chỉ một kho, chỉ đơn chưa xử lý — nên chúng đọc ít dòng và vẫn nhanh.
  • Vì vậy đừng hỏi "có real-time được không". Hãy hỏi từng con số: "dữ liệu cũ tối đa bao nhiêu phút thì vẫn ra quyết định đúng?" Câu trả lời đó chính là thứ quyết định chi phí.

Phải viết vào spec: mỗi khối số ghi rõ mốc dữ liệu ("cập nhật lúc 02:00 hằng ngày" hoặc "cập nhật mỗi 5 phút"), hiển thị mốc đó ngay trên màn hình cho người xem, và nói rõ chuyện gì xảy ra nếu lượt tính ban đêm chạy lỗi — dashboard hiện số của hôm kia kèm cảnh báo, chứ không hiện số 0.

Học được: "real-time" là một yêu cầu về chi phí chứ không phải về công nghệ. Việc của BA là quy nó về một con số phút mà nghiệp vụ chấp nhận được — và luôn hiển thị mốc dữ liệu cho người đọc số.

Áp dụng khi viết spec

Với mỗi màn hình hoặc báo cáo có dữ liệu, ticket của bạn phải trả lời được bốn câu:

  1. Dữ liệu này sống ở đâu — bảng nào, hay service nào? Cột đã có sẵn chưa?
  2. Người dùng lọc theo cái gì? Có filter nào bắt buộc để tránh quét cả bảng không?
  3. Số liệu tính đến thời điểm nào, và mốc đó có được hiển thị cho người xem không?
  4. Nếu thêm cột mới thì các bản ghi cũ hiển thị gì?

Câu hỏi nên hỏi dev

  • "Dữ liệu này sống ở đâu — bảng nào, hay phải hỏi service khác?"
  • "Cột này đã có sẵn chưa, hay cần migration?"
  • "Bảng này đang bao nhiêu dòng, và query của màn hình này có dùng index không?"
  • "Số trên báo cáo được tính đến thời điểm nào? Cập nhật theo lịch nào?"
  • "Xoá tài khoản ở đây là xoá thật hay đánh dấu đã xoá?"

Sai lầm thường gặp

  • Viết "cho phép tìm kiếm theo mọi trường" mà không giới hạn thời gian hay điều kiện bắt buộc.
  • Đòi real-time cho mọi con số, kể cả những số không ai hành động trong ngày.
  • Thêm cột mới nhưng quên nói dữ liệu lịch sử hiển thị gì.
  • Bắt hai màn hình phải luôn khớp nhau tuyệt đối trong khi một bên đang đọc từ cache.
  • Yêu cầu xoá cứng dữ liệu, rồi tháng sau cần đối soát thì không còn gì để đối soát.
  • Nhận số trên dashboard mà không biết nó tính đến lúc nào — rồi họp bàn về một sai lệch vốn chỉ là độ trễ.

Definition of done — dấu hiệu bạn đã đạt

  • Với mọi trường dữ liệu trên màn hình bạn thiết kế, bạn nói được nó lấy từ đâu.
  • Mọi báo cáo bạn spec đều có mốc "dữ liệu tính đến" hiển thị cho người xem.
  • Bạn nhận ra một yêu cầu đắt ngay trong buổi refinement, trước khi nó vào sprint.

Đi sâu hơn

  • SQL cơ bản — tự viết câu hỏi dữ liệu, từ đọc một bảng tới nhóm và nối bảng.
  • Mô hình dữ liệu và ERD — thiết kế bảng và quan hệ giữa chúng trước khi viết spec.

Khóa học liên quan (2)

Sử dụng trong vai trò

Thảo luận & tài liệu thêm 0

Chia sẻ kinh nghiệm, đặt câu hỏi, hoặc đính kèm tài liệu/YouTube giúp người khác học kỹ năng này.

Hãy là người đầu tiên chia sẻ kinh nghiệm cho kỹ năng này.

Nên làm bài đánh giá nào

Bắt đầu từ bài chẩn đoán
1 Chẩn đoán

Đánh giá mức sẵn sàng làm Business Analyst

Chấm từng chiều kỹ năng và cho ra hồ sơ — biết mình đứng ở đâu trước.

13 người đã làm
Làm bài này

Học kỹ năng này ở đâu?

Có 2 khóa dạy đúng phần này, miễn phí và bằng tiếng Việt.

Bắt đầu học