Think Like a Developer #10: Data Thinking - "Dữ liệu là xương sống, UI chỉ là quần áo"
Bạn đổi màu nút từ xanh sang đỏ. 2 giây. Xong.
Bạn đổi font chữ toàn app. 5 phút. Xong.
Bạn dời nút "Đặt hàng" từ trên xuống dưới. 30 giây. Xong.
Rồi bạn quyết định: "À, mỗi đơn hàng nên có nhiều địa chỉ giao, không phải 1 như hiện tại."
Bạn prompt AI. Nó sửa. Trang đặt hàng vỡ. Bạn sửa. Trang lịch sử đơn vỡ. Bạn sửa. Trang admin vỡ. Bạn sửa. Email xác nhận sai địa chỉ. Bạn sửa. Báo cáo doanh thu tính sai. Bạn sửa.
3 tiếng sau, bạn nhìn lại. Một thay đổi nhỏ trong cách lưu địa chỉ đã làm vỡ 7 chỗ trong app. Mà bạn chưa chắc đã hết.
Tại sao đổi màu nút xong là xong, mà đổi cách lưu dữ liệu thì như sập nhà?
Vì màu nút chỉ là quần áo. Còn dữ liệu là xương sống.
Đây là Phase 4 của series. Tư duy hệ thống. Và bài đầu tiên là tư duy quan trọng nhất phân biệt người vibe code chơi chơi với người build sản phẩm thật: Data Thinking.
Tại sao data là xương sống?
Hãy tưởng tượng bạn xây nhà.
Quần áo bạn mặc trong nhà là gì cũng được. Hôm nay áo trắng, mai áo đen, không sao. Đồ đạc cũng vậy. Hôm nay kê ghế bên trái, mai chuyển sang phải, không sao.
Nhưng nếu bạn quyết định: "Tôi muốn thêm 1 tầng." Hoặc: "Tôi muốn dời cầu thang sang chỗ khác." Bạn phải đập tường, đào móng, làm lại kết cấu. Vì cấu trúc nhà phải support tầng đó. Cầu thang phải có nền móng phù hợp.
Software giống y chang.
UI (giao diện) là quần áo. Đổi màu, đổi font, đổi vị trí nút, đổi text trên screen. Tất cả đều ở bề mặt. Sửa nhanh, không ảnh hưởng ai.
Data (dữ liệu) là kết cấu. User được lưu thế nào, order có những trường gì, một sản phẩm có 1 ảnh hay nhiều ảnh, một đơn hàng giao 1 chỗ hay nhiều chỗ. Tất cả những quyết định này nằm dưới đáy, support mọi tính năng phía trên.
Đổi UI thì chỉ chỗ đó thay đổi. Đổi data thì mọi chỗ dùng data đó phải thay đổi theo.
Developer hiểu điều này từ ngày đầu tiên. Người no-code thường không. Họ nhảy vào prompt UI trước, rồi đến tính năng, rồi mới phát hiện data structure đã sai. Sửa lại tốn gấp 10 lần so với nghĩ đúng từ đầu.
Câu hỏi developer hỏi đầu tiên
Khi nhận một yêu cầu, developer KHÔNG nghĩ về màn hình. Họ nghĩ về data.
"Tôi muốn build app quản lý khách hàng."
Developer hỏi:
Một khách hàng có những thông tin gì? (tên, email, số điện thoại, địa chỉ, ngày sinh...)
Một khách hàng có bao nhiêu địa chỉ? 1 hay nhiều?
Một khách hàng có thể có bao nhiêu số điện thoại?
Mỗi khách hàng có lịch sử gì? (đơn hàng, ghi chú, tương tác...)
Khách hàng kết nối với cái gì khác? (nhân viên chăm sóc, công ty...)
Trả lời xong những câu này, mới có thể nghĩ tới màn hình.
Vì màn hình chỉ là cách hiển thị data. Không có data thì hiển thị cái gì?
Ví dụ thực tế: Câu chuyện 1 địa chỉ vs nhiều địa chỉ
Quay lại tình huống đầu bài. Tại sao đổi từ 1 địa chỉ sang nhiều địa chỉ lại làm vỡ app?
Lúc bạn build, bạn nghĩ: "Đơn hàng giao đến 1 chỗ. Đơn giản. Lưu 1 trường address là xong."
Database lúc đó nhìn như này:
Đơn hàng:
id
tên khách
địa chỉ (1 dòng text)
tổng tiền
Và mọi thứ build trên đó. Form đặt hàng có 1 ô nhập địa chỉ. Trang lịch sử hiển thị 1 địa chỉ. Email xác nhận in 1 địa chỉ. Báo cáo tính theo 1 địa chỉ.
Giờ bạn muốn 1 đơn hàng có thể giao đến nhiều địa chỉ (ví dụ mua quà sinh nhật cho 3 người bạn cùng lúc).
Data phải đổi từ:
Đơn hàng có 1 địa chỉ
Sang:
Đơn hàng có nhiều địa chỉ + mỗi địa chỉ có bao nhiêu sản phẩm
Đây không còn là sửa nhỏ. Đây là tái cấu trúc.
Form đặt hàng phải sửa: cho thêm nhiều địa chỉ + chia sản phẩm theo địa chỉ. Trang lịch sử phải sửa: hiển thị danh sách địa chỉ. Email phải sửa: in từng địa chỉ kèm sản phẩm. Báo cáo phải sửa: tính lại logic.
7 chỗ trong app cùng phải đổi. Vì cùng phụ thuộc vào data đã thay đổi.
Nếu bạn nghĩ đúng từ đầu? Chỉ tốn thêm 30 phút lúc thiết kế data. Tiết kiệm 3 tiếng debug sau.
Công thức Data Thinking trước khi prompt
Mỗi khi có ý tưởng, trước khi mở Lovable hay Bolt, bạn làm 4 bước này:
Bước 1: Liệt kê các "thực thể" trong app
Thực thể là gì? Là những danh từ chính trong ý tưởng. App quản lý phòng tập gym? Thực thể là: thành viên, gói tập, huấn luyện viên, lịch tập, thanh toán. App giao đồ ăn? Thực thể là: khách hàng, nhà hàng, món ăn, đơn hàng, shipper.
Cứ liệt kê hết các danh từ. Chưa cần đúng. Liệt kê xong sẽ lọc.
Bước 2: Với mỗi thực thể, liệt kê các "thuộc tính"
Thuộc tính là thông tin mô tả thực thể đó.
Thành viên gym: tên, email, ngày sinh, số điện thoại, ngày đăng ký, gói tập hiện tại, ngày hết hạn.
Đơn hàng: id, khách hàng, nhà hàng, danh sách món, tổng tiền, trạng thái, thời gian đặt, địa chỉ giao, shipper.
Chỉ giữ những thuộc tính thật sự cần. Đừng tham. Chưa cần thì đừng thêm.
Bước 3: Tự hỏi "1 hay nhiều?"
Đây là câu hỏi quan trọng nhất. Bạn phải hỏi cho mỗi mối quan hệ.
Một khách hàng có 1 hay nhiều địa chỉ? (Nhiều)
Một đơn hàng có 1 hay nhiều món? (Nhiều)
Một món thuộc 1 hay nhiều đơn hàng? (Nhiều)
Một khách hàng có 1 hay nhiều đơn hàng? (Nhiều)
Một đơn hàng giao đến 1 hay nhiều địa chỉ? (Trả lời cái này SAI là vỡ app như ví dụ trên)
Trả lời sai câu "1 hay nhiều?" là sai lầm data thường gặp nhất. Và sửa lại tốn nhiều nhất.
Bước 4: Vẽ sơ đồ trên giấy
Không cần phần mềm. Tờ giấy + cây bút. Vẽ ô vuông cho mỗi thực thể. Liệt kê thuộc tính bên trong. Vẽ mũi tên giữa các thực thể có liên quan, ghi rõ "1" hay "nhiều".
Sơ đồ này chính là "bản đồ" của app. Có nó rồi, prompt AI mới chính xác.
Cách prompt AI có nghĩ về data
So sánh 2 cách prompt.
Cách sai (UI-first):
"Tạo app quản lý phòng gym. Có trang đăng nhập, trang dashboard hiển thị danh sách thành viên, trang thêm thành viên mới với form nhập tên, email, số điện thoại."
AI sẽ build. Nhưng không có cấu trúc data rõ ràng. Sau này bạn muốn thêm "lịch sử thanh toán cho mỗi thành viên" sẽ phải sửa lại tất cả.
Cách đúng (Data-first):
"Tôi muốn build app quản lý phòng gym. Trước khi build UI, đây là cấu trúc dữ liệu:
Thành viên có: tên, email, số điện thoại, ngày sinh, ngày tham gia, gói tập hiện tại, ngày hết hạn gói tập.
Gói tập có: tên gói, giá, thời hạn (số tháng), mô tả.
Thanh toán có: thành viên, gói tập, số tiền, ngày thanh toán, phương thức.
Quan hệ:
1 thành viên có nhiều thanh toán (lịch sử)
1 thành viên có 1 gói tập hiện tại
1 gói tập áp dụng cho nhiều thành viên
Hãy setup database theo cấu trúc này trước. Sau khi xong, mình sẽ nói tiếp về UI."
Cách thứ hai dài hơn. Nhưng AI build sẽ vững. Thêm tính năng sau dễ. Không phải sửa nền móng.
Template prompt Data Thinking
Copy-paste cái này khi bắt đầu app mới:
"Tôi muốn build [mô tả app ngắn].
Trước khi build UI hay tính năng, hãy giúp tôi thiết kế cấu trúc dữ liệu.
Các thực thể chính tôi nghĩ tới: [liệt kê các thực thể bạn đã nghĩ]
Với mỗi thực thể, giúp tôi:
Liệt kê các thuộc tính cần có
Xác định kiểu dữ liệu cho từng thuộc tính (text, số, ngày...)
Xác định mối quan hệ giữa các thực thể (1-1, 1-nhiều, nhiều-nhiều)
Đưa ra sơ đồ data trước. Chưa build gì. Mình sẽ review rồi mới nói tiếp."
Trước và sau khi dùng Data Thinking
TRƯỚC:
Prompt: "Tạo app blog cá nhân, có trang chủ hiển thị bài viết, trang chi tiết bài viết, trang admin để viết bài mới."
Kết quả: AI build. Mọi thứ chạy. 2 tuần sau bạn muốn thêm: "Mỗi bài có nhiều tag, người dùng có thể follow tag." Hỏng. Vì lúc đầu mỗi bài chỉ có 1 trường "category" là text. Giờ thành nhiều tag thì phải tái cấu trúc.
SAU:
Prompt: "Tôi muốn build blog cá nhân. Cấu trúc data:
Bài viết: tiêu đề, nội dung, ngày đăng, tác giả, danh sách tag, trạng thái (draft/published).
Tag: tên tag, mô tả.
Tác giả: tên, email, bio, ảnh đại diện.
Quan hệ:
1 bài viết có 1 tác giả
1 tác giả viết nhiều bài
1 bài viết có nhiều tag
1 tag thuộc nhiều bài
Setup database theo cấu trúc này trước. Sau đó build trang chủ hiển thị danh sách bài viết, lọc được theo tag."
Kết quả: App build từ nền móng vững. Sau này thêm "user follow tag" hoặc "comment cho bài viết" chỉ là thêm thực thể mới, không phải đập đi xây lại.
4 sai lầm data thường gặp của người no-code
Sai lầm 1: Để mọi thứ là "text"
"Số điện thoại để text cho dễ." "Giá để text vì có chữ k." "Ngày sinh để text vì dễ nhập."
Sai. Số phải là số. Ngày phải là ngày. Vì khi cần tính toán, sắp xếp, lọc, AI sẽ làm sai trên text. Lưu đúng kiểu từ đầu.
Sai lầm 2: Gộp nhiều thứ vào 1 trường
"Địa chỉ để 1 trường text cho gọn: '123 Lê Lợi, Q1, TPHCM'."
Sau này muốn lọc theo quận, theo thành phố, hoặc đếm có bao nhiêu khách ở Q1, không làm được. Vì tất cả gộp vào 1 string.
Tách ra: số nhà, đường, phường, quận, thành phố. Lúc cần lọc dễ. Lúc cần hiển thị thì ghép lại.
Sai lầm 3: Quên "1 hay nhiều?"
Đã nói ở trên. Sai lầm tốn nhất. Hỏi câu này cho MỌI mối quan hệ trước khi prompt.
Sai lầm 4: Thêm trường không cần
"Để dành cho tương lai" là cái bẫy. Mỗi trường bạn thêm là 1 thứ phải duy trì, hiển thị, validate. Chỉ thêm khi thật sự cần. Sau này cần thêm dễ. Lúc đầu cứ tối giản.
Bài tập thực hành (15 phút)
Chọn 1 trong các ý tưởng app sau (hoặc dùng app bạn đang build):
App quản lý sách đã đọc
App theo dõi chi tiêu cá nhân theo nhóm
App đặt lịch lớp học cho trung tâm tiếng Anh
Làm 3 bước:
Bước 1 (5 phút): Lấy giấy bút. Liệt kê các thực thể chính (3 đến 5 cái). Với mỗi thực thể, liệt kê thuộc tính.
Bước 2 (5 phút): Vẽ mũi tên giữa các thực thể có liên quan. Ghi rõ "1" hay "nhiều" trên mỗi mũi tên.
Bước 3 (5 phút): Viết prompt cho AI dựa trên template ở trên. So sánh với cách bạn từng prompt trước đây.
Làm xong share trong comment, mình sẽ review.
Kết nối với toàn bộ series
Đây là Phase 4, và bài này cùng với 9 bài trước là một bộ tư duy hoàn chỉnh.
Phase 1 (Bài 1-3) dạy bạn cách NHÌN: chia nhỏ, nhận pattern, chọn level chi tiết.
Phase 2 (Bài 4-6) dạy bạn cách THIẾT KẾ: vẽ flow, nghĩ state, chọn MVP.
Phase 3 (Bài 7-9) dạy bạn cách SỬA: đọc lỗi, lường trước, cô lập.
Phase 4 bắt đầu với Data Thinking. Bạn vừa lên một level. Trước đây bạn build app như mặc quần áo. Giờ bạn build app như xây nhà. Có nền móng, có kết cấu, có chỗ để mở rộng.
Đây cũng là chỗ mà 90% người vibe code dừng lại. Họ vẫn build được app demo, vẫn ship được prototype. Nhưng họ không bao giờ scale lên thành sản phẩm thật. Vì data sai từ đầu, sửa không nổi.
Bạn không cần phải thuộc database theory. Bạn chỉ cần thói quen: trước khi prompt UI, hỏi "data của app này trông như thế nào?". Vẽ 5 phút trên giấy. Tiết kiệm 5 tiếng sửa sau.
Build app như xây nhà. Đào móng trước. Xây tường sau. Quần áo treo sau cùng.
Bài tiếp theo
Bài 11 - Security Thinking: "Nghĩ như kẻ xấu để bảo vệ người tốt."
App của bạn chạy ngon. Cho đến khi ai đó tìm thấy API key bạn để lộ giữa code và dùng hết 2,000 USD credit OpenAI của bạn trong 1 đêm. Tuần sau mình dạy checklist bảo mật tối thiểu mà bất kỳ người no-code nào cũng phải có. Không cần biết hack. Chỉ cần biết phòng.
Follow mình để xem thêm nhiều bài khác.