Menu
ESC

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

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

Đang tải...

Bài 24 — Data model & ERD cho ex-CS

Từ Customer Service sang BA: Lộ Trình Chuyển Đổi Bài 24/60

Mở đầu — vì sao bài này quan trọng

Khi bạn còn làm Customer Service, mỗi ngày bạn đều "chạm" vào một mô hình dữ liệu mà không hề biết mình đang chạm. Bạn mở một ticket, thấy nó gắn với một khách hàng (contact), khách hàng đó lại thuộc về một công ty (account), và ticket đó có thể chứa nhiều tin nhắn qua lại (messages). Bạn kéo bộ lọc "tất cả ticket của công ty ABC" và hệ thống trả kết quả trong tích tắc. Đằng sau sự mượt mà đó là một data model — một bản thiết kế mô tả các thực thể dữ liệu và cách chúng liên kết với nhau.

Đây chính là lợi thế ngầm rất lớn của người từ CS chuyển sang BA. Trong khi một bạn BA fresh phải học ERD (Entity Relationship Diagram) từ con số không và loay hoay hình dung "một khách hàng có nhiều đơn hàng nghĩa là gì", thì bạn đã sống trong cấu trúc đó hàng nghìn giờ. Bạn biết vì sao một ticket không thể "lơ lửng" mà phải gắn với ai đó. Bạn biết vì sao khi merge hai contact trùng nhau lại làm hỏng lịch sử ticket. Bạn có trực giác về dữ liệu mà nhiều người phải mất năm mới có.

Bài này giúp bạn "dịch" trực giác đó thành ngôn ngữ chính thức của BA: thực thể (entity), thuộc tính (attribute), quan hệ (relationship), khóa chính (primary key), khóa ngoại (foreign key) và cardinality. Khi bạn đọc xong, bạn sẽ vẽ được một ERD, đọc được ERD của người khác, và quan trọng nhất — biết đặt câu hỏi đúng để phát hiện lỗ hổng trong thiết kế dữ liệu trước khi nó trở thành thảm họa production.

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

Data model là gì và ba tầng của nó

Data model là cách chúng ta mô tả dữ liệu của một hệ thống ở dạng có cấu trúc. Trong thực tế BA, bạn sẽ gặp ba tầng:

  • Conceptual model (mô hình khái niệm): chỉ nói về các "thực thể" và mối quan hệ ở mức nghiệp vụ, không quan tâm kỹ thuật. Ví dụ: "Khách hàng đặt Đơn hàng, Đơn hàng chứa Sản phẩm." Đây là tầng BA làm việc nhiều nhất, dùng để nói chuyện với stakeholder.
  • Logical model (mô hình logic): bổ sung thuộc tính, khóa, kiểu dữ liệu tương đối, nhưng vẫn độc lập với công nghệ database cụ thể.
  • Physical model (mô hình vật lý): là bảng thật trong database, có tên cột, kiểu VARCHAR(255), index, ràng buộc. Đây là địa hạt của developer/DBA.
BA sống chủ yếu ở tầng conceptual và logical. Bạn không cần viết CREATE TABLE, nhưng bạn phải hiểu đủ để đối thoại với dev.

Thực thể và thuộc tính — bạn đã quen mặt chúng

Entity (thực thể) là một "danh từ" nghiệp vụ mà hệ thống cần lưu thông tin. Trong CRM của CS, bạn đã thấy rất rõ: Contact, Account, Ticket, Agent, Message, Tag. Mỗi entity thường tương ứng một bảng.

Attribute (thuộc tính) là các trường mô tả một entity. Ticket có ticket_id, subject, status, priority, created_at, channel. Contact có contact_id, full_name, email, phone. Bạn đã điền và đọc những trường này hàng ngày.

Primary key (khóa chính) là thuộc tính định danh duy nhất một dòng. ticket_id là khóa chính của Ticket — không hai ticket nào trùng ID. Trong Zendesk hay HubSpot, mỗi ticket có một số riêng, đó chính là primary key mà bạn vẫn dùng để tra cứu khi khách hỏi "cho em số case của em".

Quan hệ (relationship) và cardinality — trái tim của ERD

Đây là phần làm nên sức mạnh của data model, và cũng là phần bạn đã cảm nhận bằng trực giác. Quan hệ mô tả cách hai entity gắn với nhau. Cardinality cho biết "bao nhiêu chọi bao nhiêu":

  • One-to-many (1:N): Một Account có nhiều Contact. Một Contact tạo nhiều Ticket. Đây là quan hệ phổ biến nhất bạn gặp trong CRM. Về mặt kỹ thuật, entity phía "nhiều" (Ticket) sẽ giữ một foreign key (contact_id) trỏ về entity phía "một" (Contact). Câu "ticket belongs to a contact" mà bạn cảm nhận được chính là foreign key này.
  • One-to-one (1:1): Một Agent có một hồ sơ cấu hình (Agent Settings). Ít gặp hơn, thường dùng để tách bảng cho gọn.
  • Many-to-many (M:N): Một Ticket có nhiều Tag, và một Tag gắn cho nhiều Ticket. Quan hệ này không thể lưu trực tiếp; nó cần một bảng trung gian (junction / bridge table) như ticket_tags chứa cặp (ticket_id, tag_id). Đây là điểm nhiều ex-CS bỏ sót khi mới học, nên hãy ghi nhớ kỹ.
Ngoài "bao nhiêu chọi bao nhiêu", còn có modality (bắt buộc hay tùy chọn): một Ticket bắt buộc phải có Contact (không thể tạo ticket không người), nhưng một Contact có thể chưa có Ticket nào. Trong ký hiệu crow's foot (chân quạ) mà bạn sẽ thấy trên ERD, điều này thể hiện bằng vòng tròn (tùy chọn) và gạch (bắt buộc) ở đầu đường nối.

Normalization ở mức BA cần biết

Bạn không cần thuộc lòng ba dạng chuẩn (1NF, 2NF, 3NF) như dân database, nhưng cần hiểu tinh thần: đừng lặp lại dữ liệu, mỗi sự thật lưu một chỗ. Nếu tên công ty được chép vào từng ticket, thì khi công ty đổi tên bạn phải sửa hàng nghìn ticket — sai sót là chắc chắn. Thay vào đó, tên công ty lưu ở bảng Account, còn Ticket chỉ giữ account_id. Trực giác "chỗ này lặp dữ liệu, dễ sai" của bạn từ thời CS chính là bản năng normalization.

Tình huống thực tế

Tình huống 1 — Tiki: khi một Contact có nhiều số điện thoại phá vỡ mô hình

Một team BA tại một sàn thương mại điện tử lớn kiểu Tiki nhận yêu cầu: "Cho phép khách lưu nhiều số điện thoại và nhiều địa chỉ giao hàng." Bạn Lan, vừa chuyển từ vị trí CS Lead sang BA, ngồi họp. Bản thiết kế ban đầu của dev để phone1, phone2, phone3 ngay trong bảng Customer.

Lan lập tức thấy vấn đề, vì hồi làm CS chị đã khổ sở với đúng kiểu dữ liệu này: khách có số thứ tư thì sao? Muốn tìm "khách nào có số 090..." thì phải quét cả ba cột. Chị đề xuất tách thành entity riêng Customer_Phone với quan hệ 1:N (một Customer có nhiều Phone), mỗi số là một dòng có phone_id, customer_id, phone_number, is_primary. Tương tự cho địa chỉ: bảng Shipping_Address riêng.

Diễn giải: Dấu hiệu "cần tách entity" là khi bạn thấy các cột đánh số _1, _2, _3 — đó gần như luôn là một quan hệ 1:N bị nén sai vào một bảng. Con mắt CS của Lan phát hiện điều này nhanh hơn cả dev, vì chị từng là người trực tiếp chịu hậu quả của thiết kế xấu.

Bài học: Trực giác "dữ liệu này sẽ nở ra không giới hạn" là tín hiệu để đề xuất một entity con với quan hệ one-to-many. Đừng để dữ liệu lặp lại theo chiều ngang (thêm cột), hãy để nó nở theo chiều dọc (thêm dòng).

Tình huống 2 — Fintech VN: bảng trung gian bị bỏ quên gây double-count

Tại một công ty fintech ở TP.HCM (giả định tên MoMoPay), team xây tính năng cho phép một giao dịch hỗ trợ (support case) liên quan đến nhiều giao dịch tài chính, và một giao dịch tài chính cũng có thể bị nhiều case đề cập. Dev ban đầu để transaction_id trực tiếp trong bảng Support_Case — tức giả định mỗi case chỉ gắn một giao dịch (1:N).

Minh, BA cũ là CS chuyên xử lý khiếu nại hoàn tiền, phản đối. Anh kể lại thực tế: nhiều khách bị lỗi trừ tiền hàng loạt, một khiếu nại thường liệt kê 5–7 giao dịch. Nếu ép 1:N, agent buộc phải tạo 7 case rời rạc cho cùng một khách, làm báo cáo "số vụ khiếu nại" bị thổi phồng gấp nhiều lần — một dạng double-count nguy hiểm khi báo cáo cho ban lãnh đạo.

Minh đề xuất một bảng trung gian case_transaction chứa (case_id, transaction_id), biến quan hệ thành đúng bản chất M:N. Nhờ đó một case gom được nhiều giao dịch mà báo cáo vẫn đếm chuẩn "một khiếu nại một khách".

Diễn giải: Cái sai không nằm ở kỹ thuật thuần túy, mà ở việc hiểu nghiệp vụ thực. Minh biết bản chất khiếu nại là "nhiều chọi nhiều" vì anh đã xử lý chúng thật sự. ERD đúng phải phản ánh nghiệp vụ đúng.

Bài học: Khi bạn nghi ngờ một quan hệ là M:N, hãy hỏi hai chiều: "Một A có thể liên quan nhiều B không?" và "Một B có thể liên quan nhiều A không?" Nếu cả hai đều "có", bạn cần bảng trung gian. Bỏ qua nó không chỉ là lỗi thiết kế, mà làm sai luôn cả số liệu quản trị.

Tình huống 3 — Chuỗi bán lẻ: nhầm lẫn giữa Contact và Account làm hỏng báo cáo doanh thu

Một chuỗi bán lẻ ở Hà Nội triển khai CRM mới. BA phụ trách (một bạn từng làm tổng đài B2B) phát hiện dev gộp chung "người liên hệ" và "công ty khách hàng" vào một bảng Customer duy nhất. Với khách lẻ thì ổn, nhưng với khách doanh nghiệp — nơi một công ty có phòng mua hàng gồm 4 người cùng đặt hàng — mô hình này gây rối: doanh thu bị chia rời theo từng người, không tổng hợp được về công ty.

Bạn BA vẽ lại ERD tách hai entity: Account (công ty, giữ mã số thuế, hạn mức công nợ) và Contact (cá nhân, thuộc về một Account qua account_id), quan hệ 1:N. Đơn hàng gắn với Contact, nhưng nhờ chuỗi khóa ngoại, hệ thống tổng hợp doanh thu ngược lên tới Account dễ dàng.

Diễn giải: "Ai là khách hàng?" nghe đơn giản nhưng trong B2B có hai tầng: pháp nhân và con người. Nhầm hai tầng này là lỗi kinh điển, và người từng phục vụ khách B2B nhận ra ngay vì họ biết "gọi cho anh Tuấn nhưng xuất hóa đơn cho công ty".

Bài học: Trước khi vẽ entity, hãy tách bạch "danh từ" cho rõ. Contact ≠ Account, Đơn hàng ≠ Sản phẩm, Ticket ≠ Message. Mỗi danh từ có vòng đời và thuộc tính riêng thì đáng là một entity riêng.

Hướng dẫn từng bước

Đây là quy trình để bạn xây một ERD từ đầu, tận dụng nền CS:

  • Liệt kê danh từ nghiệp vụ (entity). Đọc kỹ mô tả yêu cầu, gạch chân mọi danh từ quan trọng: Khách hàng, Đơn hàng, Sản phẩm, Ticket, Đại lý... Loại bỏ trùng lặp và danh từ chỉ là thuộc tính (ví dụ "số điện thoại" là thuộc tính của Khách hàng, không phải entity — trừ khi cần nhiều số như tình huống 1).
  • Xác định thuộc tính và khóa chính cho từng entity. Với mỗi entity, hỏi "cần lưu những thông tin gì?" và "cái gì định danh duy nhất một dòng?". Nếu không có định danh tự nhiên, tạo khóa nhân tạo như customer_id tự tăng.
  • Xác định quan hệ giữa các cặp entity. Với từng cặp, hỏi câu chuẩn: "Một A có bao nhiêu B? Một B có bao nhiêu A?". Trả lời được sẽ ra 1:1, 1:N hay M:N.
  • Xử lý quan hệ M:N bằng bảng trung gian. Bất cứ chỗ nào ra M:N, tạo ngay một bảng nối chứa hai khóa ngoại. Đặt tên rõ nghĩa: order_items, ticket_tags, case_transaction.
  • Gắn foreign key đúng chỗ. Trong quan hệ 1:N, khóa ngoại luôn nằm ở phía "nhiều". Ticket (nhiều) giữ contact_id trỏ về Contact (một). Đây là quy tắc bạn nên thuộc lòng.
  • Xác định modality (bắt buộc/tùy chọn). Với mỗi đầu quan hệ, hỏi "có bắt buộc phải có không?". Ticket bắt buộc có Contact; Contact không bắt buộc có Ticket.
  • Vẽ và kiểm chứng ngược với stakeholder. Dùng ký hiệu crow's foot trên draw.io, Lucidchart hoặc dbdiagram.io. Sau đó đọc ERD thành câu tiếng Việt cho stakeholder nghe: "Một khách hàng có thể có nhiều đơn hàng, mỗi đơn hàng thuộc về đúng một khách hàng" — nếu họ gật đầu, mô hình đúng nghiệp vụ.
Công cụ gợi ý cho ex-CS mới bắt đầu: dbdiagram.io (viết code đơn giản ra sơ đồ, dễ học) và draw.io (kéo thả miễn phí). Không cần công cụ đắt tiền để bắt đầu.

Lỗi thường gặp & mẹo

  • Nhầm attribute thành entity và ngược lại. "Trạng thái ticket" là thuộc tính, không phải entity. Nhưng "Danh mục sản phẩm" nếu có nhiều thông tin đi kèm (mô tả, thứ tự, cha-con) thì nên là entity. Mẹo: nếu một "danh từ" chỉ có mỗi cái tên, nó thường là attribute; nếu nó có nhiều thuộc tính riêng và vòng đời riêng, nó là entity.
  • Bỏ quên bảng trung gian cho M:N. Đây là lỗi phổ biến nhất (xem tình huống 2). Mẹo: mỗi khi bạn định vẽ một đường nối mà cả hai đầu đều "nhiều", dừng lại và tạo bảng nối.
  • Đặt foreign key sai phía. Người mới hay để order_id trong bảng Customer, dẫn tới một khách chỉ lưu được một đơn. Nhớ: FK nằm ở phía "nhiều".
  • Lặp dữ liệu theo chiều ngang (phone1, phone2, phone3). Dấu hiệu vàng của một quan hệ 1:N bị nén sai. Tách entity ngay.
  • Vẽ ERD quá chi tiết ở giai đoạn đầu. Với stakeholder nghiệp vụ, đừng sa đà vào kiểu dữ liệu VARCHAR. Giữ ở tầng conceptual: entity và quan hệ thôi. Chi tiết vật lý để dành cho buổi làm việc với dev.
  • Mẹo vàng cho ex-CS: mỗi khi bí, hãy tự hỏi "trong CRM cũ của mình, cái này được tổ chức thế nào?". Zendesk, HubSpot, Salesforce đều là những data model đã được thiết kế bởi chuyên gia hàng đầu. Chúng là "giáo trình sống" mà bạn đã học miễn phí suốt thời gian làm CS.

Bài tập thực hành

Bài 1 — Đọc ngược ERD (15 phút). Mở CRM bạn từng dùng (hoặc bản trial Zendesk/HubSpot). Liệt kê 5 entity chính bạn thấy và ít nhất 3 quan hệ giữa chúng, viết mỗi quan hệ thành một câu dạng "Một X có nhiều Y". Đây là kỹ năng đọc data model từ hệ thống thật.

Bài 2 — Vẽ ERD cho hệ thống support đơn giản (45 phút). Dùng dbdiagram.io hoặc draw.io, mô hình hóa một hệ thống ticket gồm: Account, Contact, Ticket, Message, Agent, Tag. Yêu cầu: một Account có nhiều Contact; một Contact tạo nhiều Ticket; một Ticket có nhiều Message; một Ticket gắn nhiều Tag và một Tag dùng cho nhiều Ticket (nhớ bảng trung gian!); một Ticket được giao cho một Agent. Ghi rõ khóa chính, khóa ngoại và cardinality.

Bài 3 — Phát hiện lỗi thiết kế (20 phút). Cho bảng Order có các cột: order_id, customer_name, customer_phone, product1_name, product1_qty, product2_name, product2_qty. Chỉ ra hai vấn đề về data model và đề xuất cách tách entity. (Gợi ý: một là dữ liệu khách bị lặp, hai là sản phẩm bị nén theo chiều ngang.)

Bài 4 — Viết lời giải thích cho stakeholder (10 phút). Chọn ERD ở Bài 2, viết một đoạn 4–5 câu tiếng Việt giải thích mô hình cho một người không kỹ thuật, không dùng từ "foreign key" hay "cardinality". Đây là kỹ năng BA thật: dịch mô hình sang ngôn ngữ nghiệp vụ.

Tóm tắt

Data model và ERD không phải lãnh địa xa lạ với người từ Customer Service — ngược lại, bạn đã sống trong đó mỗi ngày qua ticket, contact và account. Bài này giúp bạn chuyển trực giác thành ngôn ngữ chính thức: entity (danh từ nghiệp vụ), attribute (thuộc tính), primary key (định danh), foreign key (mối nối), và relationship với cardinality 1:1, 1:N, M:N. Điểm mấu chốt cần khắc sâu: quan hệ M:N luôn cần bảng trung gian; foreign key luôn nằm ở phía "nhiều"; và dữ liệu lặp theo chiều ngang (phone1, phone2) là tín hiệu tách entity.

Ba tình huống thực tế — số điện thoại ở sàn e-commerce, khiếu nại đa giao dịch ở fintech, và Contact-Account ở chuỗi bán lẻ — cho thấy điều quan trọng nhất: ERD đúng phải phản ánh nghiệp vụ đúng, và chính hiểu biết nghiệp vụ sâu từ thời CS là thứ giúp bạn phát hiện lỗi thiết kế nhanh hơn cả dev. Hãy tận dụng CRM cũ như một giáo trình sống, luyện đọc và vẽ ERD đến khi thành phản xạ. Ở bài tiếp theo về business rule catalog, bạn sẽ thấy data model và business rule bổ trợ nhau chặt chẽ ra sao.