Di chuyển từ Airtable sang PostgreSQL: các mẫu chuyển đổi thực tiễn
Học cách di chuyển từ Airtable sang PostgreSQL bằng cách dịch linked records, rollups, formulas và quyền truy cập để có ứng dụng production.

Tại sao các mẫu Airtable cảm thấy khác trong cơ sở dữ liệu production
Airtable hoạt động tốt khi bạn cần thứ gì đó giống bảng tính nhưng có cấu trúc. Vấn đề bắt đầu khi base trở thành “hệ thống” và nhiều người phụ thuộc vào nó hàng ngày. Một thiết lập khéo léo với linked records, rollups và formulas có thể trở nên chậm, khó kiểm soát và dễ bị thay đổi vô ý.
Một ứng dụng production dựa trên PostgreSQL được xây dựng với kỳ vọng khác. Dữ liệu được chia sẻ. Quy tắc được áp dụng mọi lúc (không chỉ trong một view). Thay đổi cần có khả năng truy vết. Đó là lý do “di chuyển từ Airtable sang PostgreSQL” thường ít liên quan tới việc sao chép bảng hơn là dịch hành vi.
Sử dụng production thường kéo theo vài yêu cầu cụ thể:
- Độ tin cậy: ứng dụng hoạt động giống nhau cho mọi người dùng, mọi lúc.
- Kiểm soát truy cập: người dùng chỉ thấy và chỉnh sửa những gì họ được phép.
- Khả năng kiểm toán: bạn trả lời được “ai đã thay đổi gì và khi nào?”.
- Hiệu năng khi nhiều dữ liệu: nhiều bản ghi và nhiều người dùng không làm gián đoạn công việc hàng ngày.
- Quyền sở hữu rõ ràng: cập nhật diễn ra qua quy tắc của ứng dụng, không phải chỉnh sửa thủ công rải rác trong các view.
Trong Airtable, nhiều quy tắc là “tại thời điểm xem”. Một rollup hiển thị tổng, một formula cho giá trị tính toán, và một view lọc ẩn bản ghi. Trong PostgreSQL, những hành vi đó thường trở thành quan hệ, truy vấn aggregate và logic ứng dụng chạy nhất quán bất kể người dùng đang ở đâu.
Một số hành vi Airtable sẽ không map 1-1. Một field link mà “chỉ hoạt động” có thể trở thành bảng nối với quy tắc chặt chẽ hơn. Một formula trộn text, date và lookup có thể trở thành biểu thức SQL, một view cơ sở dữ liệu, hoặc logic backend.
Ví dụ đơn giản: trong Airtable, một quản lý có thể thấy “Tổng Pipeline” thông qua một rollup trong view. Trong ứng dụng production, cùng một con số phải tôn trọng quyền truy cập (họ được thấy những deal nào?), cập nhật dự đoán được và tái tạo được trong báo cáo.
Bắt đầu với kiểm toán Airtable phù hợp với luồng công việc thực tế
Trước khi di chuyển từ Airtable sang PostgreSQL, hãy viết ra cách base được sử dụng hàng ngày. Airtable thường bắt đầu như “bảng tính sống,” nên cùng một bảng có thể vừa dùng để báo cáo, phê duyệt và chỉnh sửa nhanh cùng lúc. Ứng dụng có backend cần quy tắc rõ ràng hơn.
Kiểm kê những gì tồn tại, kể cả những phần mọi người hay quên, như views “tạm thời” và script một lần đang lặng lẽ giữ mọi thứ chạy.
- Bảng (bao gồm những bảng ẩn hoặc đã lưu trữ)
- Views và bộ lọc các nhóm phụ thuộc (đặc biệt các view “Việc của tôi”)
- Interfaces, forms và ai dùng từng cái
- Automations, scripts và tích hợp
- Thói quen thủ công (copy/paste imports, dọn dẹp hàng tuần)
Tiếp theo, gán nhãn các trường là nguồn chân thực (source of truth) hoặc dẫn xuất (derived).
- Trường nguồn chân thực do người hoặc hệ thống đáng tin cậy nhập (email khách hàng, ngày ký hợp đồng).
- Trường dẫn xuất là rollups, formulas, lookups và cờ trạng thái dựa trên dữ liệu khác.
Điều này quan trọng vì một số giá trị dẫn xuất nên được lưu (để giữ lịch sử và audit), trong khi những giá trị khác nên tính khi cần.
Quy tắc hữu ích: nếu mọi người cần biết “nó là bao nhiêu tại thời điểm đó” (ví dụ hoa hồng khi deal đóng), hãy lưu nó. Nếu chỉ để hiển thị (ví dụ “Số ngày kể từ hoạt động gần nhất”), hãy tính khi cần.
Ghi lại các điểm đau bằng ngôn ngữ thông thường. Ví dụ: “View Deals mất 20 giây để tải,” “Quản lý thấy trường lương,” “Chúng tôi liên tục sửa links hỏng sau khi import.” Những điều này trở thành yêu cầu thực cho quyền truy cập, hiệu năng và kiểm tra dữ liệu trong ứng dụng mới.
Dịch mô hình dữ liệu: bảng, trường và ID
Khi bạn di chuyển từ Airtable sang PostgreSQL, thay đổi tư duy lớn nhất là cơ sở dữ liệu cần các quy tắc giữ nguyên ngay cả khi nhãn và bố cục thay đổi. Airtable chịu được “bất cứ gì trong ô hôm nay.” PostgreSQL thì không.
Bắt đầu bằng cách dịch mỗi bảng Airtable thành một thực thể với khoá chính ổn định. Đừng dùng tên người/hãng (ví dụ “Acme, Inc.”) làm ID. Tên thay đổi, bị viết sai và đôi khi trùng. Dùng ID nội bộ (thường UUID hoặc ID số) và giữ tên như thuộc tính có thể chỉnh sửa.
Loại trường cần xem kỹ lại vì “number” và “text” của Airtable có thể che giấu khác biệt quan trọng:
- Nếu trường có một tập giá trị nhỏ đã biết, coi nó là lựa chọn kiểm soát (status, priority, tier).
- Nếu nó chứa tiền, lưu dưới kiểu số phù hợp cho tính toán tiền tệ (và quyết định đơn vị tiền tệ).
- Với thời gian, chọn giữa date (không có thời điểm) và timestamp (thời điểm chính xác).
Giá trị trống cũng cần chính sách rõ. Airtable thường trộn “trống,” “0” và “không biết” theo cách trông ổn trong lưới. Trong PostgreSQL bạn phải quyết nghĩa của từng trạng thái:
- Dùng NULL khi “chúng ta thực sự không biết.”
- Dùng default khi “có giá trị bình thường” (ví dụ status = "new").
- Chuyển chuỗi rỗng thành NULL khi rỗng thực sự có nghĩa là “thiếu.”
- Giữ chuỗi rỗng chỉ khi rỗng mang ý nghĩa.
- Thêm kiểm tra cơ bản (ví dụ amount >= 0) để phát hiện import xấu.
Cuối cùng, thêm vài index dựa trên cách dùng thực tế. Nếu mọi người lọc theo account, status và created date mỗi ngày, những cột đó nên có index. Tránh index phức tạp cho tới khi có dữ liệu hiệu năng thực, nhưng đừng bỏ qua các index rõ ràng.
Ví dụ: bảng “Deals” có thể trở thành deals(id, account_id, stage, amount, close_date, created_at). Cấu trúc đó ổn định bất kể UI bạn đặt lên trên.
Linked records: biến links thành quan hệ và bảng nối
Airtable làm cho quan hệ trông đơn giản: bạn thêm field linked record rồi xong. Trong PostgreSQL, bạn phải quyết nó nghĩa là gì.
Bắt đầu với tính số lượng (cardinality): mỗi bản ghi có một kết quả hay nhiều?
- Một-nhiều: một Company có nhiều Contacts, nhưng mỗi Contact thuộc về một Company.
- Nhiều-nhiều: một Contact có thể làm việc với nhiều Deals, và một Deal có thể có nhiều Contacts.
Trong PostgreSQL:
- Link một-nhiều thường là một cột trên phía “nhiều” (ví dụ contacts.company_id).
- Link nhiều-nhiều thường thành bảng nối, như deal_contacts(deal_id, contact_id).
Bảng nối đó cũng có thể chứa chi tiết thêm mà người dùng thường nhét vào quan hệ, như role_on_deal hoặc added_by.
Giữ links an toàn với ràng buộc tham chiếu
Airtable để links lộn xộn theo thời gian. Trong app có backend, bạn ngăn điều đó bằng foreign keys và quy tắc xóa rõ ràng.
Quyết:
- Xóa cascade, chặn xóa, hay đặt link về null?
- Có nên chặn hàng mồ côi (ví dụ deal_contacts không có deal hoặc contact thực sự)?
IDs so với tên hiển thị
Airtable hiển thị “primary field” thân thiện làm nhãn link. PostgreSQL nên lưu khoá ổn định (ID số hoặc UUID), và app hiển thị tên thân thiện.
Một mẫu thực tế: lưu company_id mọi nơi, giữ companies.name (và có thể companies.code) để hiển thị và tìm kiếm.
Rollups: từ toán ở thời điểm xem sang aggregate của DB
Trong Airtable, rollup là “phép toán qua các record liên quan.” Nó trông như một trường đơn, nhưng thực ra là tóm tắt nhiều hàng: counts, sums, min/max dates, averages hoặc list kéo qua link.
Trong PostgreSQL, ý tưởng tương tự thành truy vấn aggregate. Bạn join các bảng liên quan, group by bản ghi cha, và tính tổng bằng hàm có sẵn. Khi di chuyển từ Airtable sang PostgreSQL, rollups ngừng là các trường kiểu bảng tính mà trở thành các câu hỏi DB có thể trả lời.
Dịch rollup phổ biến sang tư duy SQL
Các mẫu thường gặp bao gồm:
- “Tổng số hóa đơn cho khách hàng này” -> SUM(amount) group by customer
- “Số task mở trên dự án này” -> COUNT(*) với filter status
- “Ngày hoạt động mới nhất” -> MAX(activity_date)
- “Kích thước deal trung bình cho rep này” -> AVG(deal_value)
Rollup Airtable thường có filter như “chỉ items Active” hoặc “chỉ 30 ngày gần nhất.” Trong DB, đó là mệnh đề WHERE. Hãy rõ ràng về timezone và ý nghĩa của “30 ngày gần nhất,” vì báo cáo production dễ bị tranh cãi.
Rollup tính toán so với lưu trữ
Bạn có hai lựa chọn:
- Tính rollup khi cần (luôn mới, đơn giản bảo trì).
- Lưu chúng (màn hình nhanh hơn, nhưng phải đảm bảo cập nhật).
Quy tắc thực tế: tính cho dashboards và lists; chỉ lưu khi cần tốc độ ở quy mô hoặc cần snapshot ổn định.
Formulas: quyết cái gì trở thành SQL và cái gì trở thành logic ứng dụng
Khi bạn di chuyển từ Airtable sang PostgreSQL, formulas thường cần dịch cẩn thận nhất. Trong Airtable, một formula có thể âm thầm điều phối view, filter và workflow cùng lúc. Trong app production, bạn muốn kết quả nhất quán, nhanh và giống nhau ở mọi màn hình.
Phân loại formulas theo chức năng thực sự của chúng:
- Định dạng: biến giá trị thành nhãn như "Q1 2026" hoặc "Ưu tiên cao"
- Cờ điều kiện: TRUE/FALSE như "Quá hạn" hoặc "Cần xem lại"
- Tính toán: tổng, biên lợi nhuận, hiệu số ngày
- Lookups: kéo giá trị qua linked records
- Quy tắc nghiệp vụ: mọi thứ ảnh hưởng đến những gì người dùng có thể làm (đủ điều kiện, phê duyệt)
Các phép tính đơn giản và cờ thường thích hợp cho SQL (biểu thức truy vấn, views, hoặc computed fields). Điều này giữ mọi màn hình nhất quán và tránh việc tái hiện cùng phép toán ở nhiều nơi.
Nếu một formula thực sự là một quy tắc (ví dụ “Chỉ được cho giảm giá nếu account đang active và deal trên $5,000”), thường nên chuyển vào logic backend. Bằng vậy nó không thể bị bỏ qua bởi client khác, import CSV, hay báo cáo mới.
Giữ phần định dạng gần UI. Nhãn hiển thị có thể tạo trong web/mobile interface mà không cài cứng vào database.
Trước khi hoàn tất, chọn vài đầu ra phải luôn khớp (như Status, Amount Due, SLA Breach) và quyết nơi lưu chúng. Rồi test từ mọi client để con số người thấy trong app khớp với xuất của finance sau này.
Thiết kế lại quyền truy cập: vai trò, truy cập theo bản ghi và audit trails
Quyền trong Airtable thường trông đơn giản vì chủ yếu dựa trên base, table và view. Trong ứng dụng production, điều đó hiếm khi đủ. Views hữu ích cho workflow nhưng không phải ranh giới bảo mật. Khi di chuyển từ Airtable sang PostgreSQL, hãy xem mọi quyết định “ai thấy cái này?” như một quy tắc truy cập bạn áp dụng ở mọi nơi: API, UI, export và background jobs.
Bắt đầu bằng việc liệt kê các vai trò ứng dụng cần, không phải các tab người dùng bấm. Một tập điển hình:
- Admin: quản lý cài đặt, người dùng và toàn bộ dữ liệu
- Manager: phê duyệt thay đổi và xem công việc của đội mình
- Staff: tạo và cập nhật bản ghi được giao, báo cáo hạn chế
- Customer: xem yêu cầu, hóa đơn hoặc trạng thái của riêng họ
Rồi định nghĩa quy tắc ở mức bản ghi (row-level access). Nhiều app thực sự rơi vào các mô hình: “chỉ bản ghi của tôi,” “đội của tôi,” hoặc “tổ chức của tôi.” Dù bạn thực thi bằng row-level security ở DB hay ở lớp API, chìa khóa là nhất quán: mọi truy vấn cần quy tắc đó, bao gồm exports và màn hình “ẩn”.
Lên kế hoạch audit ngay từ đầu. Quyết bạn cần ghi gì cho mỗi thay đổi:
- Ai làm (user ID, vai trò)
- Thay đổi gì (trước/sau theo trường khi cần)
- Khi nào xảy ra (timestamp và timezone)
- Đến từ đâu (UI, import, API)
- Tại sao (ghi chú hoặc mã lý do tùy chọn)
Kế hoạch di chuyển bước từng bước để tránh bất ngờ
Các migration an toàn thường trông nhàm chán. Bạn chọn ngày, giảm biến động, và làm cho việc so sánh base cũ với app mới trở nên dễ dàng.
Một tuần trước chuyển, dừng thay đổi schema. Đồng ý ngày cutover và quy tắc: không bảng mới, không field mới, không đổi tên field. Những chỉnh sửa nhỏ có thể phá imports và formulas một cách âm thầm.
Kế hoạch năm bước đơn giản:
- Khóa cấu trúc và định nghĩa “hoàn thành” (màn hình, workflow và báo cáo nào phải khớp).
- Export dữ liệu và làm sạch bên ngoài Airtable. Chuẩn hóa multi-selects, tách các field kết hợp, và tạo ID ổn định để links giữ nguyên.
- Tạo schema PostgreSQL, rồi import theo lô với các kiểm tra. Xác thực số hàng, trường bắt buộc, tính duy nhất và foreign keys.
- Xây dựng các chức năng thiết yếu hàng ngày trước: vài màn hình mọi người dùng hằng ngày, kèm luồng create/update.
- Chạy song song trong một cửa sổ ngắn, sau đó cut over. Giữ kế hoạch rollback: chế độ chỉ đọc cho Airtable, snapshot PostgreSQL trước cutover, và quy tắc dừng rõ ràng nếu có sai lệch quan trọng.
Ví dụ: với base Sales Ops, chạy cả hai hệ thống trong một tuần. Reps ghi hoạt động trong app mới, nhưng đội so sánh tổng pipeline với Airtable mỗi sáng cho tới khi các con số khớp ổn định.
Chất lượng dữ liệu và kiểm thử: chứng minh app mới khớp với thực tế
Hầu hết lỗi migration không phải “lỗi PostgreSQL.” Chúng là sự không khớp giữa ý nghĩa trong Airtable và những gì bảng mới lưu. Hãy coi testing là một phần của công việc dữ liệu, không phải nhiệm vụ cuối cùng.
Giữ một bảng map đơn giản. Với mọi field Airtable, viết cột tương ứng trong Postgres và nơi nó dùng trong app (màn hình, báo cáo, rule). Điều này ngăn “chúng tôi đã import” biến thành “chúng tôi không bao giờ dùng nó.”
Bắt đầu với kiểm tra nhanh:
- So sánh số hàng mỗi bảng trước và sau import.
- Kiểm tra liên kết thiếu (foreign keys trỏ tới không có gì).
- Tìm bản sao nơi giá trị từng “duy nhất trên thực tế” (email, deal ID).
- Phát hiện trường bắt buộc bị để trống mà Airtable cho phép qua form.
Rồi xác thực các phép tính người dùng dựa vào. Chọn bản ghi thực và đối chiếu tổng, trạng thái và rollups với ví dụ đã biết. Đây là nơi thay thế công thức thường trệch, vì blank, zero và linked record thiếu hành xử khác nhau.
Cuối cùng, test có chủ ý các dữ liệu biên: trống, link đã xóa, text dài, ký tự lạ và xuống dòng. Tên như "O'Neil" và ghi chú nhiều dòng thường gây lỗi import và hiển thị.
Những bẫy thường gặp khi dịch Airtable sang PostgreSQL
Bẫy lớn nhất là coi base Airtable như một xuất dữ liệu thô. Airtable trộn lưu trữ, logic view, formulas và chia sẻ. PostgreSQL tách các mối quan tâm đó, điều này tốt cho production nhưng buộc bạn chọn nơi đặt từng hành vi.
Linked records là ví dụ kinh điển. Nhiều đội nghĩ mọi link là một-nhiều vì trong lưới nó có vẻ như một field đơn. Thực tế, nhiều link Airtable là nhiều-nhiều. Nếu bạn mô hình hoá thành foreign key đơn, bạn sẽ mất mối quan hệ lặng lẽ và phải làm việc chắp vá sau này.
Rollups gây vấn đề khác. Nếu bạn import con số rollup hiện tại như là “sự thật,” bạn cần lưu cách nó được tính. Nếu không bạn không giải thích được tại sao số thay đổi. Ưu tiên aggregate có thể tính lại (SUM/COUNT) với định nghĩa rõ ràng, và quyết xem có cần cache hay materialize không và cách cập nhật.
Views cũng gây nhầm. Các team đôi khi dựng lại views của Airtable như bộ lọc cố định trong app mới, rồi phát hiện các view đó là quy trình cá nhân chứ không phải yêu cầu chung. Trước khi cố định bộ lọc, hỏi ai dùng view, hành động tiếp theo họ làm, và họ có cần saved filters, segments hay dashboard không.
Checklist bẫy nhanh:
- Status viết tự do ("In progress", "in-progress", "IP") mà không làm sạch và kiểm soát giá trị
- Rollups import như kết quả cuối cùng mà không có định nghĩa hay kế hoạch tái tính
- Link field mô hình không có bảng nối khi quan hệ thực là nhiều-nhiều
- Views dựng lại thành màn hình cố định mà chưa xác nhận ý định người dùng
- Quyền được thêm cuối cùng, gây viết lại đau đớn
Kịch bản ví dụ: base sales ops tái xây như một app thực sự
Hãy tưởng tượng base Sales Ops Airtable có bốn bảng: Accounts, Deals, Activities, và Owners (reps và managers). Trong Airtable, một Deal link tới một Account và một Owner, và Activities link tới một Deal (cuộc gọi, email, demo).
Trong PostgreSQL, điều này thành một tập quan hệ rõ ràng: deals.account_id trỏ tới accounts.id, deals.owner_id trỏ tới owners.id, và activities.deal_id trỏ tới deals.id. Nếu bạn cần nhiều owner cho một deal (rep + sales engineer), thêm bảng nối như deal_owners.
Một metric phổ biến trong Airtable là “Deal Value rollup theo Account” (tổng giá trị deal liên kết). Trong app có backend, rollup đó thành truy vấn aggregate bạn có thể chạy khi cần, cache hoặc materialize:
SELECT a.id, a.name,
COALESCE(SUM(d.amount), 0) AS total_pipeline
FROM accounts a
LEFT JOIN deals d ON d.account_id = a.id
AND d.stage NOT IN ('Closed Won', 'Closed Lost')
GROUP BY a.id, a.name;
Bây giờ xét đến một formula “Health score.” Trong Airtable dễ bị cộp mọi thứ vào một field. Cho production, giữ các input có thể kiểm toán (last_activity_at, next_step_date, open_deal_count, overdue_tasks_count). Rồi tính health_score trong backend để thay đổi quy tắc mà không phải viết lại các bản ghi cũ. Bạn vẫn có thể lưu score mới nhất để lọc và báo cáo.
Quyền truy cập thường cần suy nghĩ lại nhiều nhất. Thay vì filter view, định nghĩa quy tắc truy cập rõ ràng:
- Reps chỉ thấy và chỉnh sửa deals và activities của họ.
- Managers thấy deals của đội họ.
- Finance thấy doanh thu closed-won, nhưng không thấy ghi chú private.
- Sales Ops quản lý stages và scoring rules.
Checklist nhanh trước khi ra mắt app PostgreSQL mới
Trước khi go-live, rà soát lần cuối để đảm bảo “cảm giác Airtable” đã được dịch thành thứ ổn định, có thể kiểm thử và an toàn. Đây nơi các khe hở nhỏ trở thành sự cố thật.
Nếu bạn đang cố di chuyển từ Airtable sang PostgreSQL, tập trung vào những gì Airtable từng “xử lý thầm” cho bạn: quan hệ, giá trị tính toán và ai thấy/đổi gì.
Kiểm tra trước khi ra mắt bắt lỗi hầu hết sự cố
- Quan hệ: mọi linked record trước kia có kiểu quan hệ rõ (one-to-many, many-to-many) và chiến lược key rõ (ID ổn định, ràng buộc duy nhất, quy tắc xóa).
- Aggregates: gắn nhãn các tổng phải luôn đúng (hóa đơn, quota, đủ điều kiện) so với những thứ có thể trễ một chút (dashboards).
- Logic quyết định: mọi formula thay đổi kết quả (phê duyệt, giá, hoa hồng, đủ điều kiện) đã được triển khai và test đúng nơi.
- Quyền: với mỗi vai trò, chạy các user story thực tế end-to-end (tạo, sửa, xuất, xóa, phê duyệt) và xác nhận truy cập theo bản ghi.
- Sở hữu và triển khai: quyết ai quản lý thay đổi schema, ai review thay đổi logic, cách rollback hoạt động và nơi app chạy.
Một thực tế: nếu rep có thể chỉnh Account Tier trong Airtable và tier đó quyết định giảm giá, bạn có lẽ cần cả thay đổi quyền (chỉ manager được edit) và audit ghi ai đổi và khi nào.
Bước tiếp theo: xây dựng, ra mắt và liên tục cải thiện
Sau khi di chuyển từ Airtable sang PostgreSQL, rủi ro lớn nhất là cố gắng làm lại toàn bộ cùng lúc. Bắt đầu với pilot chạy một luồng công việc thực sự end-to-end với người dùng thực. Chọn thứ có thể đo lường, ví dụ “tạo bản ghi - phê duyệt - thông báo - báo cáo,” và giữ phạm vi chặt.
Xử lý pilot như một sản phẩm. Viết mô hình dữ liệu và quy tắc quyền bằng ngôn ngữ thông thường để người không chuyên kỹ thuật trả lời nhanh hai câu: “Giá trị này đến từ đâu?” và “Ai thấy hoặc thay đổi nó?”.
Giữ tài liệu nhẹ. Hầu hết đội thành công với:
- Các bảng chính và ý nghĩa của mỗi bảng
- Quan hệ quan trọng (và hành vi khi xóa/ lưu trữ)
- Trường nào được tính (SQL vs logic app) và vì sao
- Vai trò, quy tắc truy cập theo bản ghi và ai cấp quyền
- Kỳ vọng audit (cái gì phải được log)
Nếu bạn muốn nhanh mà không xây mọi thứ từ đầu, nền tảng no-code có thể hữu dụng miễn là nó tạo backend thực sự và cưỡng chế quy tắc nhất quán. Ví dụ, AppMaster (appmaster.io) được thiết kế để xây ứng dụng PostgreSQL-backed với business logic và role-based access, đồng thời sinh source code production.
Ra mắt theo từng giai đoạn để người dùng chuyển an toàn: pilot với một đội, chạy song song ngắn, cutover có kế hoạch với rollback, rồi mở rộng dần theo workflow.
Câu hỏi thường gặp
Bắt đầu bằng cách liệt kê những gì Airtable base của bạn thực sự làm, chứ không chỉ các bảng tồn tại. Hãy chú ý đặc biệt đến views, interfaces, automations, scripts và các quy trình thủ công định kỳ, vì những thứ đó thường chứa các “quy tắc” thực sự mà ứng dụng PostgreSQL phải xử lý nhất quán.
Hãy coi các bảng như thực thể ổn định với khóa chính thực sự, và coi các quan hệ là các ràng buộc rõ ràng phải đúng ở mọi nơi. Thay vì để "bất cứ gì ở ô đó" tiếp tục, hãy dùng kiểu dữ liệu rõ ràng, giá trị mặc định và các kiểm tra để dữ liệu xấu không lẻn vào khi nhập hoặc chỉnh sửa sau này.
Không dùng tên làm định danh vì tên có thể thay đổi, trùng lặp hoặc bị viết sai. Sử dụng ID nội bộ (thường là UUID hoặc số) làm khóa chính, và giữ tên như thuộc tính có thể chỉnh sửa dùng để hiển thị và tìm kiếm.
Xác định xem mỗi liên kết là một-nhiều hay nhiều-nhiều dựa trên cách mọi người thực sự sử dụng nó. Một-nhiều thường trở thành một cột foreign key, trong khi nhiều-nhiều trở thành một bảng nối (join table) có thể lưu thêm chi tiết về quan hệ như role hoặc ngày thêm liên kết.
Thêm foreign key để cơ sở dữ liệu ngăn các liên kết bị hỏng và cưỡng chế hành vi nhất quán. Rồi chọn hành vi khi xóa một cách chủ đích: xóa theo cascade, chặn xóa hay đặt tham chiếu thành null, tùy ý nghĩa nghiệp vụ.
Xem rollup như câu hỏi mà cơ sở dữ liệu trả lời bằng các truy vấn aggregate, chứ không phải là các trường bảng tính lưu sẵn. Mặc định hãy tính on-demand cho độ chính xác; chỉ lưu hoặc cache khi có lý do hiệu năng rõ ràng và cách cập nhật đáng tin cậy.
Phân nhóm công thức theo mục đích: định dạng hiển thị, các phép toán đơn giản, cờ/flag, lookup, và các quy tắc nghiệp vụ thực sự. Giữ định dạng cho UI, đặt toán học đơn giản vào SQL khi cần nhất quán, và chuyển quy tắc nghiệp vụ vào backend để không thể bỏ qua qua import hoặc client khác.
Views hữu ích cho luồng công việc nhưng không phải là ranh giới bảo mật. Hãy định nghĩa các vai trò và quy tắc truy cập theo hàng (record-level) một cách rõ ràng, rồi áp dụng chúng nhất quán ở API, UI, xuất dữ liệu và các job nền; đồng thời thêm auditing để biết ai đã thay đổi gì và khi nào.
Khóa cấu trúc trước cutover, xuất và làm sạch dữ liệu, rồi import với các kiểm tra như trường bắt buộc, tính duy nhất và foreign key. Chạy song song hai hệ thống trong một thời gian ngắn, so sánh các con số chính, và có kế hoạch rollback rõ ràng (chẳng hạn chỉ đọc Airtable và snapshot của DB).
Nếu muốn nhanh mà không code hết từ đầu, chọn nền tảng tạo backend thực sự và cưỡng chế quy tắc, chứ không chỉ UI trên kho dữ liệu kiểu bảng tính. AppMaster là một ví dụ cho việc xây ứng dụng dựa trên PostgreSQL với quyền theo vai trò và business logic, đồng thời sinh source code để dùng production.


