Bỏ qua để đến nội dung

Trường cũng là kiến trúc

Cũng có bằng 28 ngôn ngữ khác

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A wooden shape-sorter block with round, square, triangular and star holes, the matching pieces beside it and the star resting by its hole.
Hình ảnh được tạo bằng AI

Mô-đun 6 trong 10 của chương Kiến trúc dữ liệu Salesforce, chương 3 của khóa học Data Architect. Mỗi mô-đun có thể đọc độc lập. Trước: Chọn đúng đối tượng · Tiếp theo: Quan hệ có hệ quả

Câu hỏi mô-đun này trả lời: Salesforce nên biểu diễn vật lý từng mẩu dữ liệu như thế nào?

Tạo một trường mất khoảng một phút. New Field, chọn kiểu, đặt tên, Next, Next, Save. Chính vì thế mà trường không được đối xử như kiến trúc.

Hãy vào một org đã tồn tại mười năm và mở Tài khoản. Năm trăm trường. Status2__c, Legacy_Status__c, Old_Status__c, Status_New__c. Ba mã khách hàng khác nhau. Một hộp kiểm không ai dám xóa vì không ai biết tích hợp nào còn dùng nó. Tạo trường mất một phút. Sống chung với nó mất nhiều năm. Vì vậy ý tưởng của mô-đun này rất đơn giản: một trường là một quyết định kiến trúc. Không phải lúc nào cũng là quyết định lớn, nhưng mỗi trường mã hóa điều gì đó về ý nghĩa, hành vi, danh tính hay chất lượng của dữ liệu, và cũng như đối tượng, trường rất dễ thêm và khó gỡ bỏ đến bất ngờ.

Ở chương 2 chúng ta đã gán thuộc tính cho các thực thể: một Giao hàng có khung giờ dự kiến, một Xe tải có số VIN. Giờ chúng ta hiện thực chúng, và đây là chỗ người ta nhảy thẳng vào “trường văn bản”. Khoan đã. Trước kiểu dữ liệu, tôi muốn biết dữ liệu đó có nghĩa là gì. Đó là một con số, hay một mã định danh tình cờ có chữ số? Một ngày, hay một thời điểm? Văn bản tự do, hay một giá trị trong danh sách được duyệt? Do con người nhập, hay do hệ thống khác sở hữu? Nó có thể thay đổi không? Có bắt buộc duy nhất không? Có thể thiếu không? Có nên lưu nó không, hay tính toán ra? Đó không phải câu hỏi về Thiết lập. Đó là câu hỏi kiến trúc dữ liệu, và kiểu trường đến sau khi chúng ta trả lời chúng.

Một con số không phải lúc nào cũng là con số

Phần tiêu đề “Một con số không phải lúc nào cũng là con số ”

Steve Trucking cấp cho mỗi xe tải một số hiệu đội xe, ví dụ 001247. Trường số? Có lẽ không. Chúng ta có cộng các số hiệu đội xe với nhau không? Xe 1247 trừ xe 1246 có phải là một chiếc xe không? Đó là một mã định danh tình cờ chứa chữ số, và trường số thậm chí sẽ bỏ mất các số 0 ở đầu. Mã bưu chính, mã sản phẩm, số tài khoản và mã vận đơn cũng vậy. Hình dáng của giá trị không cho bạn biết ý nghĩa của nó. Hãy chọn kiểu theo hành vi bạn cần, không theo hình dáng của dữ liệu mẫu.

Mỗi đối tượng tùy chỉnh đều có một trường Name, và quyết định đầu tiên là văn bản hay số tự động. Tôi hỏi: con người có cần nhận diện thứ này không? Người ta biết một Đối tác bán lẻ qua tên và một chiếc xe tải qua số hiệu đội xe. Nhưng một bảng kê hàng hệ thống tạo ra mỗi đêm thì sao? Không ai nên phải gõ “Bảng kê 10-02 số 3” chỉ vì Salesforce bắt buộc có Name. Hãy dùng số tự động. Chỉ đừng nhầm Name được tạo ra đó với danh tính của bản ghi: số tự động giúp người dùng, ID Salesforce định danh bản ghi, và mã tham chiếu bảng kê của chính Đối tác bán lẻ có thể định danh cùng một thứ giữa các hệ thống. Ba việc khác nhau.

Chọn một kiểu, bấm Next, và Thiết lập hỏi bạn các chi tiết. Đây là màn hình nơi phần lớn các quyết định trong mô-đun này thực sự được đưa ra, thường là trong vội vàng.

New Custom Field, bước 2: Description (mô tả), Help Text (văn bản trợ giúp), Required (bắt buộc), Unique (duy nhất) với lựa chọn phân biệt chữ hoa chữ thường, External ID (ID bên ngoài), Auto add to custom report types, và Default Value (giá trị mặc định)

New Custom Field, bước 2: các chi tiết (ảnh chụp màn hình, 2026-10-12). Kích thước đầy đủ

Có hai ô trông giống nhau nhưng làm hai việc khác nhau. Description (mô tả) dành cho những người bảo trì org, và giờ là cho cả các công cụ AI đọc org: trường này có nghĩa là gì, ai sở hữu nó, nó đến từ đâu. Help Text (văn bản trợ giúp) dành cho người dùng trên màn hình: nhập gì vào đây. Hãy điền cả hai. Tiếp theo là Required (bắt buộc), Unique (duy nhất) và External ID (ID bên ngoài), và mỗi thứ xứng đáng có một phần riêng. Bên dưới chúng, Default Value (giá trị mặc định) có thể là một công thức, để một bản ghi mới bắt đầu với một giá trị hợp lý thay vì để trống.

Bắt buộc là một quyết định lớn hơn vẻ ngoài

Phần tiêu đề “Bắt buộc là một quyết định lớn hơn vẻ ngoài ”

Có một hộp kiểm nhỏ trong trình hướng dẫn tạo trường ghi Required (Bắt buộc), và như chúng ta đã thấy ở chương 1, nó có thể là một quả bom hẹn giờ. Bạn có một đối tượng đã năm năm với hai triệu bản ghi, và giờ ai đó quyết định một trường mới phải luôn có giá trị. Còn hai triệu bản ghi có trước nó thì sao? Các tích hợp không gửi nó? Tự động hóa tạo bản ghi trước khi biết giá trị? Quy trình mà giá trị chỉ xuất hiện ba bước sau đó?

“Bắt buộc” nghe như một quyết định về chất lượng dữ liệu, và đôi khi đúng vậy. Nhưng khi nào một giá trị được biết là một phần của quy trình nghiệp vụ. Vì vậy đừng đánh dấu Bắt buộc chỉ vì ai đó nói “chúng tôi luôn muốn có nó”. Hãy hỏi khi nào nó được biết, ai cung cấp nó, và chuyện gì xảy ra khi không có. Chúng ta sẽ đặt điều này lên toàn bộ nấc thang nhất quán ở mô-đun 7.

Nếu tôi đánh dấu một trường là duy nhất, tôi đang tuyên bố một điều về nghiệp vụ: không phải “nó thường không lặp lại”, mà là “hai bản ghi không bao giờ được có giá trị này”. Đó là một tuyên bố mạnh. Và màn hình buộc bạn quyết định thêm một điều: “ABC” và “abc” là cùng một giá trị hay hai giá trị khác nhau? Không phân biệt chữ hoa chữ thường là mặc định an toàn hơn cho bất cứ thứ gì do con người gõ vào. Quy tắc về khóa của chương 2, duy nhất, không thay đổi, không mang nghĩa, không bao giờ là dữ liệu cá nhân (PII), áp dụng ở đây. Nếu ai đó nói với tôi email nhân viên là duy nhất, tôi bắt đầu hỏi: nó có thể thay đổi không, một người có thể nghỉ rồi quay lại không, địa chỉ có thể được dùng lại không, chuyện gì xảy ra sau một vụ mua lại? Email có thể hữu ích, thậm chí duy nhất ở hiện tại. Điều đó không biến nó thành một danh tính tốt.

Đây là chỗ ID bên ngoài chứng tỏ giá trị. Màn hình mô tả nó rất đúng: trường này trở thành “mã định danh bản ghi duy nhất từ một hệ thống bên ngoài”. ERP có khách hàng 873492; Salesforce có ID bản ghi riêng của nó. Khi ERP gửi một bản cập nhật, làm sao chúng ta biết nó thuộc về bản ghi nào? Đánh dấu một trường là ID bên ngoài và tích hợp có thể upsert dựa trên nó: tạo bản ghi nếu chưa có, cập nhật nếu đã có (Upsert a Record Using an External ID (opens in a new tab), tiếng Anh). Và khi nạp bản ghi con, bạn có thể trỏ đến bản ghi cha bằng ID bên ngoài của nó thay vì phải truy vấn ID Salesforce trước. Tôi hay nói là bạn để Salesforce tra cứu giúp bạn. Rất mạnh.

Hãy để ý rằng mã của ERP không trở thành danh tính của bản ghi Salesforce. Nó là một thuộc tính, và một bản ghi có thể mang nhiều mã như vậy: ID khách hàng của ERP, ID cũ, ID của đối tác. Không sao cả. Một thực thể nghiệp vụ có thể được nhiều hệ thống biết đến theo những cách khác nhau. Câu hỏi kiến trúc là hệ thống nào sở hữu từng mã định danh, và nó đưa ra lời hứa gì: chỉ đánh dấu duy nhất nếu nghiệp vụ thực sự bảo đảm điều đó.

Giờ đến chính các kiểu trường. Mở New Field trên bất kỳ đối tượng nào và Thiết lập cho bạn thấy toàn bộ danh sách, được nhóm theo đúng cách tôi sẽ đi qua: các trường Salesforce tính giúp bạn, các trường quan hệ, rồi đến các kiểu dữ liệu.

Danh sách kiểu dữ liệu trên màn hình New Custom Field, theo nhóm: Auto Number, Formula và Roll-Up Summary; Lookup, Master-Detail và External Lookup Relationship; rồi Checkbox, Currency, Date, Date/Time, Email, Geolocation, Number, Percent, Phone, Picklist, Multi-Select Picklist, Text, Text Area, Long, Rich và Encrypted Text, Time, URL và Address

Thiết lập, New Custom Field, bước 1: các kiểu dữ liệu (ảnh chụp màn hình, 2026-10-12). Kích thước đầy đủ

Đây là toàn bộ danh sách trong một cái nhìn, với một điều tôi muốn bạn nhớ về mỗi kiểu.

NhómKiểuCần nhớ
Được tính toánSố tự động (Auto Number)Tối đa 30 ký tự, 20 trong số đó cho tiền tố hoặc hậu tố; một nhãn cho con người, không phải danh tính của bản ghi
Công thức (Formula)Được tính khi đọc, không lưu trữ; 3.900 ký tự
Tổng hợp cuộn lên (Roll-Up Summary)Đếm, tổng, nhỏ nhất hoặc lớn nhất của các bản ghi chi tiết; chỉ với chính-chi tiết
Quan hệTra cứu, Chính-chi tiết, Tra cứu bên ngoàiMô-đun 7
Dữ liệuHộp kiểm (Checkbox)Đúng hoặc sai, với giá trị mặc định do bạn chọn; null vẫn có thể xuất hiện trong flow
Số, Phần trăm, Tiền tệQuy tắc làm tròn; số 0 ở đầu bị bỏ; 15 chữ số thập phân
Ngày, Ngày/Giờ, GiờMột ngày, một thời điểm, hoặc một giờ trong ngày; thời điểm được lưu theo UTC
Email, Điện thoại, URLĐược định dạng và kiểm tra khi lưu: 80, 40 và 255 ký tự
Vị trí địa lý, Địa chỉTrường phức hợp tốn hơn một trường: 3 và 9
Danh sách chọn, Chọn nhiềuMột bộ từ vựng có kiểm soát, do quản trị viên sở hữu
Văn bản, Vùng văn bản, Dài, Đa định dạng, Mã hóaTối đa 255 trên bản ghi và lập chỉ mục được; trên mức đó, không có chỉ mục hay lọc

Số tự động (Auto Number) gán số tiếp theo trong một dãy cho mỗi bản ghi mới, theo định dạng bạn định nghĩa, như T-{000000}. Hãy dùng nó khi con người cần một cái tên dễ gọi và không ai phải tự nghĩ ra. Toàn bộ giá trị dài tối đa 30 ký tự, và 20 trong số đó dành cho tiền tố hoặc hậu tố. Chỉ cần nhớ điều từ chương 2: nó là một nhãn cho con người, không phải danh tính của bản ghi, và các con số không phải lúc nào cũng liên tiếp tuyệt đối.

Trường Công thức (Formula) tính một giá trị từ các trường khác. Chúng rất mạnh, và chúng được tính khi bản ghi được đọc, không phải khi được lưu, nên không có gì được lưu lại để trở nên cũ. Bạn chọn công thức trả về kiểu gì: hộp kiểm, tiền tệ, ngày, ngày/giờ, số, phần trăm, văn bản hoặc giờ.

Các kiểu trả về của công thức: Checkbox, Currency, Date, Date/Time, Number, Percent, Text và Time, mỗi kiểu có một công thức ví dụ

New Custom Field, công thức: chọn kiểu trả về (ảnh chụp màn hình, 2026-10-12). Kích thước đầy đủ

Sau đó bạn viết chính công thức, với các trường, toán tử và hàm, rồi kiểm tra cú pháp. Hãy để ý nút Use Formula Assistant: AI của Salesforce giờ sẽ giúp bạn viết công thức. Hãy dùng nó, rồi đọc những gì nó viết. Bạn sở hữu công thức, không phải trợ lý.

Trình soạn công thức: các thẻ Simple Formula và Advanced Formula, Insert Field, Use Formula Assistant và Insert Operator

Trình soạn công thức, với Formula Assistant (ảnh chụp màn hình, 2026-10-12). Kích thước đầy đủ Một công thức có thể dài tới 3.900 ký tự, và không được vượt quá 15.000 byte khi lưu hoặc biên dịch; một công thức dài có thể được tách ra thành nhiều trường công thức tham chiếu lẫn nhau. Không dùng được vùng văn bản dài, trường mã hóa và trường Description trong công thức.

Trường tổng hợp cuộn lên (roll-up summary) nằm trên bản ghi chính và đếm, cộng tổng, hoặc lấy giá trị nhỏ nhất hay lớn nhất của các bản ghi chi tiết. Chúng chỉ hoạt động qua một quan hệ chính-chi tiết, và đó là một trong những lý do lớn nhất để chọn chính-chi tiết. Chúng ta sẽ quay lại với chúng, và các giới hạn của chúng, trong mô-đun 7.

Chúng ta có cần lưu giá trị này không? Nếu tôi có số lượng và đơn giá, có ai đó, hay tự động hóa nào đó, cần duy trì một tổng không? Có thể một công thức nên suy ra nó: một nguồn duy nhất cho phép tính, tính lại khi đọc, nên đổi số lượng thì kết quả đổi theo. Công thức cũng có giới hạn riêng (kích thước khi lưu và độ dài hiển thị; Formula Field Limits and Restrictions (opens in a new tab), tiếng Anh), và công thức phức tạp thì khó bảo trì.

Nhưng đôi khi nghiệp vụ không muốn câu trả lời của hôm nay. Họ muốn câu trả lời như nó đã từng là. Nếu quy tắc chiết khấu thay đổi vào năm sau, hóa đơn năm ngoái có nên đột nhiên hiện một số tiền khác không? Dĩ nhiên là không. Vì vậy câu hỏi không phải “Salesforce có tính được cái này không?” Mà là “đây là một phép tính hiện tại hay một sự thật lịch sử?” Sự thật lịch sử thì được lưu lại.

Quan hệ tra cứu (Lookup), chính-chi tiết (Master-Detail) và tra cứu bên ngoài (External Lookup) cũng là các trường, và chúng là nơi các đường kẻ trong mô hình của bạn trở thành hiện thực. Quan hệ tra cứu là liên kết lỏng; chính-chi tiết buộc cuộc đời, quyền sở hữu và bảo mật của bản ghi con vào bản ghi cha; tra cứu bên ngoài với tới một đối tượng bên ngoài từ mô-đun 4, khớp theo ID bên ngoài của nó. Lựa chọn giữa chúng là một quyết định đủ lớn để có mô-đun riêng.

Hộp kiểm là trường đơn giản nhất: đúng hoặc sai, được chọn hoặc không. Nó hoàn hảo cho một sự thật có/không về bản ghi: Đang hoạt động, Cần lắp đặt, Đã ký nhận. Khi bạn tạo một hộp kiểm, Salesforce buộc bạn chọn giá trị mặc định của nó, được chọn hay không, và đó là một quyết định thật sự: đó là giá trị mọi bản ghi mới bắt đầu, kể cả các bản ghi do tích hợp tạo ra mà không gửi trường này. Báo cáo và list view lọc nó là True và False; các công cụ nhập dữ liệu và bản xuất hằng tuần hiển thị nó là 1 và 0.

Có một cái bẫy cần biết. Trường trên bản ghi có hai giá trị, nhưng tự động hóa quanh nó có thể có giá trị thứ ba. Trong một flow, một biến hộp kiểm chưa bao giờ được gán là null, không phải false, và lưu nó vào bản ghi sẽ thất bại (Trailblazer Community (opens in a new tab), tiếng Anh; xem thêm lỗi đã biết của Salesforce W-11208535 (opens in a new tab)). Hãy chọn một giá trị mặc định hợp lý, và làm cho flow và code của bạn xử lý null một cách có chủ đích.

Số (Number) lưu một số thực, và bỏ đi mọi số 0 ở đầu, chính vì thế mà một mã số xe như 001247 không phải là một Số. Salesforce làm tròn trường số theo kiểu làm tròn nửa ra xa số 0: 12,345 thành 12,35, và −12,345 thành −12,35. Và trong merge field, nó làm tròn theo ngôn ngữ và vùng (locale) của người dùng, không theo số chữ số thập phân bạn đặt trên trường.

Phần trăm (Percent) lưu một số thập phân và hiển thị dạng phần trăm: nhập 0,10 và bạn thấy 10%. Giá trị mất độ chính xác sau 15 chữ số thập phân.

Tiền tệ (Currency) được định dạng cho tiền, và trong một org có nhiều loại tiền tệ, nó mang mã tiền tệ và có thể dùng tỷ giá hối đoái; với quản lý tiền tệ nâng cao (opens in a new tab) (tiếng Anh), cơ hội có thể dùng tỷ giá theo ngày, tức tỷ giá của kỳ mà thương vụ được chốt. Chỉ cơ hội và những thứ xung quanh nó (sản phẩm, lịch, phân chia và báo cáo của chúng) dùng tỷ giá theo ngày; trường tiền tệ trên các đối tượng khác giữ một tỷ giá tĩnh duy nhất. Hãy để ý cách làm tròn: khi không có chữ số thập phân, Salesforce đơn giản là cắt bỏ (23,5 thành 23); khi có một chữ số trở lên, nó làm tròn nửa ra xa số 0.

Ba kiểu, ba ý nghĩa khác nhau. Ngày (Date) là một ngày: một hợp đồng hết hạn vào một ngày. Ngày/Giờ (Date/Time) là một thời điểm: lần giao hàng đến lúc 9:42 sáng hôm đó. Giờ (Time) là một giờ trong ngày, hoàn toàn không có ngày: cửa hàng mở cửa lúc 7:00, mỗi ngày.

Cái bẫy nằm ở thời điểm. Salesforce lưu giá trị ngày/giờ theo GMT (UTC). Giờ người dùng nhập được hiểu theo múi giờ của họ, được chuyển đổi, rồi được lưu; khi ai đó đọc nó, nó lại được chuyển đổi sang múi giờ của người đọc. Phần lớn thời gian đó đúng là điều bạn muốn. Nhưng đây là ví dụ tôi hay đưa ra trong lớp: một điều phối viên ở Los Angeles ghi nhận một lần giao hàng vào khuya tối Chủ nhật, lúc 22:00 giờ Thái Bình Dương. Bên dưới, Salesforce đã lưu sáng thứ Hai, 5:00 GMT. Một báo cáo nhóm theo ngày ở múi giờ khác, hoặc một tích hợp đọc giá trị thô, có thể xếp lần giao hàng Chủ nhật đó vào thứ Hai. “Ngày nó xảy ra” phụ thuộc vào việc bạn hỏi đồng hồ của ai. Hãy để ý múi giờ của người dùng, và quyết định doanh nghiệp muốn nói đến múi giờ nào.

Và hãy cẩn thận khi so sánh chúng. Bên dưới, một ngày/giờ là một con số lớn: Apex đọc nó là số mili giây kể từ ngày 1 tháng 1 năm 1970, 00:00:00 GMT (Datetime Class (opens in a new tab), tiếng Anh). Nó là một thời điểm chính xác, không phải một ngày. Vì vậy hỏi xem hai ngày/giờ có bằng nhau (==) hay không hầu như không bao giờ cho kết quả bạn muốn: 9:42:00 và 9:42:01 không bằng nhau, và “thứ Hai” với bất kỳ thời điểm nào trong thứ Hai cũng vậy. Thay vào đó, hãy hỏi theo khoảng: từ thời điểm bắt đầu trở đi (>=) và đến thời điểm kết thúc trở về trước (<=). “Mọi lần giao hàng vào thứ Hai” là mọi lần giao hàng >= thứ Hai 00:00 và <= thứ Hai 23:59:59, theo múi giờ mà bạn đã quyết định là múi giờ doanh nghiệp muốn nói đến.

Và một điều thú vị: Salesforce không lưu được bất kỳ ngày nào. Ngày hợp lệ chạy từ ngày 1 tháng 1 năm 1700 đến ngày 31 tháng 12 năm 4000, và Salesforce đưa ra cùng khoảng đó cho ngày và ngày/giờ (Data Import Dates (opens in a new tab), tiếng Anh). Ngay cả hai đầu mút cũng là thời điểm theo GMT, nên với một người dùng ở giờ Thái Bình Dương, giá trị hợp lệ sớm nhất là 16:00 ngày 31 tháng 12 năm 1699. Ngày thành lập của hội lịch sử địa phương bạn có thể không lọt vào được. Và mẹo kinh điển “không có ngày kết thúc”, ngày 31 tháng 12 năm 9999, sẽ bị từ chối; nếu bạn cần một giá trị giữ chỗ ở tương lai xa, nó phải nằm trong năm 4000 hoặc trước đó.

Đây là các trường được định dạng, và chúng làm nhiều hơn là lưu ký tự. Email chứa tối đa 80 ký tự và được kiểm tra đúng định dạng; trên liên hệ và khách hàng tiềm năng, bấm vào nó sẽ bắt đầu một email gửi đến địa chỉ đó. Điện thoại (Phone) chứa tối đa 40 ký tự, được định dạng như số điện thoại, và trở thành bấm để gọi (click-to-dial) khi org có kết nối hệ thống điện thoại. URL chứa tối đa 255 ký tự và mở ra như một liên kết. Đó là nền tảng cho bạn hành vi miễn phí, và vì thế tôi sẽ không bao giờ lưu số điện thoại trong một trường văn bản thuần.

Tích hợp cũng bị kiểm tra. Một giá trị không khớp với định dạng của trường, chẳng hạn một địa chỉ email sai cấu trúc, sẽ không qua được kiểm tra, và toàn bộ bản ghi bị từ chối, không chỉ trường đó. Vì vậy khi dữ liệu của hệ thống nguồn lộn xộn, hãy làm sạch nó trước khi nó đến, hoặc lên kế hoạch cho những bản ghi sẽ không nạp được.

Vị trí địa lý (Geolocation) chứa một vĩ độ và một kinh độ. Bên dưới, một trường tên Location__c thực ra là hai giá trị mà bạn có thể đọc và gán riêng, Location__Latitude__s và Location__Longitude__s. Và bạn có thể truy vấn trên nó: các hàm DISTANCE và GEOLOCATION của SOQL tìm các bản ghi trong một bán kính, hoặc sắp xếp chúng theo khoảng cách. “Mọi lần giao hàng đang mở trong vòng 25 dặm quanh chiếc xe tải này” là một truy vấn duy nhất: WHERE DISTANCE(Location__c, GEOLOCATION(33.45, -112.07), 'mi') < 25 (Location-Based SOQL Queries (opens in a new tab), tiếng Anh). Địa chỉ (Address) chứa cả một địa chỉ, gồm đường, thành phố, bang hoặc tỉnh, mã bưu chính và quốc gia, và người dùng có thể tìm một địa chỉ rồi để các phần được điền tự động.

Cả hai đều là trường phức hợp (compound field): một trường trên màn hình, nhiều giá trị bên dưới. Và chúng tốn hơn một trường trong giới hạn của đối tượng: một Vị trí địa lý tính là ba trường tùy chỉnh, và một Địa chỉ tính là chín. Trên một đối tượng vốn đã chật, điều đó quan trọng.

Một danh sách chọn kiểm soát những gì người dùng có thể nhập: một giá trị từ một danh sách bạn định nghĩa. Trạng thái? Có lẽ là danh sách chọn. Nhưng các giá trị là siêu dữ liệu, và quản trị viên phải thêm hoặc sửa chúng. Vì vậy tôi vẫn hỏi ai sở hữu các giá trị, chúng thay đổi thường xuyên đến đâu, có nhiều đối tượng cần cùng một danh sách không, bản thân các giá trị có mang thông tin riêng không, và có hệ thống nào khác sở hữu bộ từ vựng đó không.

Các giá trị nằm ở đâu cũng là một quyết định. Khi một danh sách chỉ dùng một lần, trên một trường, hãy giữ các giá trị ngay trên trường đó, trên đối tượng; đó là điều Salesforce làm theo mặc định. Nhưng khi cùng một bộ giá trị bắt đầu xuất hiện ở nhiều nơi, một Vùng trên tài khoản, trên giao hàng và trên kho, hãy nâng nó lên thành bộ giá trị toàn cục trước khi các bản sao trôi lệch nhau. Một bộ giá trị toàn cục giữ một danh sách cho tất cả, tối đa 1.000 giá trị, tính cả đang hoạt động lẫn không hoạt động (Picklist Limitations (opens in a new tab), tiếng Anh). Chính mô tả trong Thiết lập nói lên vì sao điều này quan trọng: bộ giá trị “bị hạn chế để người dùng không thể thêm giá trị chưa được duyệt qua API”. Một danh sách, một chủ sở hữu, và không tích hợp nào lén đưa vào một cách viết mới.

Điểm cuối đó là khác biệt giữa hạn chế và không hạn chế. Trên một danh sách chọn hạn chế, chỉ những giá trị quản trị viên đã định nghĩa được phép, từ bất kỳ đâu: một người dùng, một lần nhập dữ liệu hay một tích hợp gửi bất cứ thứ gì khác sẽ nhận lỗi, “bad value for restricted picklist field”, và bản ghi không được lưu. Trên một danh sách chọn không hạn chế, người dùng vẫn chọn từ danh sách trên màn hình, nhưng API, các lần nhập dữ liệu và tự động hóa có thể gửi bất kỳ giá trị nào, và Salesforce lưu nó rồi thêm nó vào như một giá trị không hoạt động (Picklist Limitations (opens in a new tab); Create a Custom Picklist Field (opens in a new tab), tiếng Anh). Đó là cách một org rốt cuộc có cả “Delivered”, “delivered” và “Dlvrd”. Bộ giá trị toàn cục luôn bị hạn chế. Mặc định của tôi là hạn chế; không hạn chế là một lựa chọn có chủ đích khi một hệ thống khác thực sự sở hữu các giá trị, và khi đó phải có người chịu trách nhiệm dọn dẹp các giá trị không hoạt động.

Một bộ giá trị toàn cục mới: nhãn, tên, mô tả, các giá trị mỗi dòng một giá trị, và tùy chọn sắp xếp theo bảng chữ cái hoặc dùng giá trị đầu tiên làm mặc định

Thiết lập, Picklist Value Sets: một bộ giá trị toàn cục mới (ảnh chụp màn hình, 2026-10-12). Kích thước đầy đủ

Một danh sách chọn nhiều giá trị (multi-select picklist) cho phép người dùng chọn nhiều giá trị, được lưu chung và phân cách bằng dấu chấm phẩy. Tiện trên màn hình, nhưng vướng víu ở mọi chỗ khác: khó lọc, khó báo cáo và khó tích hợp hơn, và không dùng được trong bộ lọc của trường tổng hợp cuộn lên. Nhiều giá trị cho một bản ghi thường có nghĩa là bài học của chương 2: có một đối tượng con đang muốn thoát ra.

Một danh sách chọn còn có thêm một giá trị ngoài những giá trị bạn đã định nghĩa: trống. Một bản ghi có thể nằm đó mà không có gì được chọn, và điều đó làm nhiều người vấp. Trong một công thức hay quy tắc xác thực, bạn không thể kiểm tra một danh sách chọn chỉ bằng ISBLANK; bạn viết ISBLANK(TEXT(Field__c)), hoặc ISPICKVAL(Field__c, "") (Trailblazer Community (opens in a new tab), tiếng Anh). Vì vậy hãy quyết định “không có giá trị” nghĩa là gì cho mọi danh sách chọn: nó có được phép không, và khi nó xảy ra thì có nghĩa là gì? Rồi làm cho công thức, quy tắc xác thực và bộ lọc của bạn xử lý được nó.

Và đôi khi một thuộc tính thực ra là một thực thể. Ai đó yêu cầu một danh sách chọn các trung tâm phân phối. Có chín cái. Dễ thôi. Rồi chúng ta biết mỗi trung tâm có một địa chỉ, một người quản lý, giờ làm việc, công suất, một vùng và các xe tải. Đó không phải danh sách chọn; đó là một thứ. Đừng biến một thực thể thành danh sách chọn chỉ vì hiện giờ chưa có nhiều. Năm thứ nhất thấy tuyệt vời, năm thứ năm thấy khủng khiếp. (Mô-đun 5 của chương 2 có các quy tắc kinh nghiệm của tôi về khi nào một danh sách xứng đáng có đối tượng riêng.)

Tôi dạy văn bản như hai loại, và ranh giới giữa chúng là 255 ký tự.

Tối đa 255: lưu cùng bản ghi. Văn bản (Text) chứa tối đa 255 ký tự, và bạn có thể dùng nó gần như ở mọi nơi: trong công thức, bộ lọc, báo cáo, list view, làm trường duy nhất hoặc ID bên ngoài, và nó có thể được lập chỉ mục. Vùng văn bản (Text Area) cũng chứa 255, trên nhiều dòng riêng, như một ghi chú ngắn.

Trên 255: lưu theo tham chiếu. Vùng văn bản (dài) (Text Area (Long)) chứa tối đa 131.072 ký tự, và Vùng văn bản (đa định dạng) (Text Area (Rich)) chứa cùng mức đó với định dạng, liên kết và hình ảnh. Tôi nghĩ về chúng như được cất sang một bên, với bản ghi giữ một con trỏ, và chúng hành xử đúng như vậy: không có chỉ mục, nên bạn không thể đặt chúng là duy nhất hay ID bên ngoài; bạn không thể lọc trên chúng trong mệnh đề WHERE của SOQL (SOQL WHERE (opens in a new tab), tiếng Anh); công thức không dùng được chúng (Formula Field Limits and Restrictions (opens in a new tab), tiếng Anh); và báo cáo chỉ hiển thị 254 ký tự đầu tiên của một trường tùy chỉnh loại này, với bộ lọc báo cáo chỉ tìm trong khoảng 255 ký tự đầu (Filter Restrictions for Text Area (Long) Fields (opens in a new tab), tiếng Anh). Hình ảnh tải lên một trường văn bản đa định dạng có thể lớn tới 1 MB mỗi ảnh, và chúng tính vào dung lượng lưu trữ tệp, còn văn bản tính vào dung lượng lưu trữ dữ liệu (Rich Text Area Field Considerations (opens in a new tab), tiếng Anh). Vì vậy nếu có ai cần tìm kiếm, sắp xếp, khớp hoặc báo cáo trên giá trị, hãy giữ nó dưới 255 và giữ nó là một trường Văn bản.

Văn bản (mã hóa) (Text (Encrypted)) lưu tối đa 175 ký tự ở dạng mã hóa, dùng Classic Encryption. Nếu org của bạn dùng Shield Platform Encryption, bạn mã hóa một trường Văn bản thông thường thay vào đó, và nhiều kiểu khác cũng có thể được mã hóa theo cách đó.

Tiêu chuẩn của tôi: mỗi trường đều có mô tả. Tôi đã tin điều đó từ lâu, và trong thời đại AI, nó quan trọng hơn bao giờ hết: mọi công cụ AI và tác tử đọc org của bạn đều đọc phần mô tả để hiểu một trường có nghĩa là gì. Một mô tả trống là một sự phỏng đoán đang chờ xảy ra. Customer_Status__c có nghĩa là gì? Ai sở hữu nó? Nó đến từ đâu? Người dùng có sửa được không, hay ERP sẽ ghi đè nó tối nay? Sáu tháng nữa tôi sẽ không nhớ, và ba năm nữa quản trị viên bảo trì org sẽ không biết trừ khi chúng ta đã nói cho họ. Nhãn không phải là tài liệu, tên API cũng vậy.

Trên các đối tượng dùng chung nhiều (Tài khoản, Liên hệ, Cơ hội), tôi cũng dùng tiền tố đặt tên cho các trường chuyên biệt, để nguồn gốc và mục đích hiện ngay trong tên: ví dụ mọi thứ ERP sở hữu đều bắt đầu bằng cùng một tiền tố. Tôi không cần tên API mười hai chữ. Tôi muốn mô hình tự giải thích chính nó.

Phân loại những gì quan trọng: các trường phân loại

Phần tiêu đề “Phân loại những gì quan trọng: các trường phân loại ”

Salesforce cấp cho mỗi trường một bộ siêu dữ liệu phân loại. Tôi gọi chúng là các trường phân loại (taxonomy fields). Bạn có thể ghi lại chủ sở hữu dữ liệu; mức sử dụng trường (Active, DeprecateCandidate, Hidden); mức độ nhạy cảm của dữ liệu (Public, Internal, Confidential, Restricted, MissionCritical); và phân loại tuân thủ: PII, HIPAA, GDPR, PCI, CCPA và các loại khác. Chúng hoạt động trên cả trường chuẩn lẫn trường tùy chỉnh (Data Classification Metadata Fields (opens in a new tab), tiếng Anh).

Sao phải bận tâm? Vì các quy trình đọc được chúng. Gắn cờ GDPR cho một trường và một quy trình có thể tìm mọi trường GDPR trên một bản ghi rồi che hoặc xóa chúng. Và khi lớp tin cậy của Salesforce gửi một lời nhắc đến mô hình ngôn ngữ lớn, nó có thể dùng chính phân loại này để che các trường nhạy cảm: nó đổi tên của một khách hàng, chẳng hạn “Maria Lopez”, thành một chỗ giữ chỗ trên đường đi, mô hình không bao giờ thấy cái tên, và cái tên được đổi lại vào câu trả lời trên đường về (Einstein Trust Layer (opens in a new tab), tiếng Anh).

Một cập nhật. Salesforce hiện ghi rõ rằng việc che dữ liệu theo mẫu và theo trường cho mô hình ngôn ngữ lớn bị tắt đối với tác tử: việc che có thể làm mất ngữ cảnh mà tác tử cần để trả lời (Data Masking Limitations in Agentforce (opens in a new tab), tiếng Anh). Phân loại vẫn điều khiển việc che cho các tính năng AI tạo sinh khác, nhưng đừng trông vào nó để giữ dữ liệu cá nhân tránh xa một tác tử; đó là một quyết định về quyền truy cập và thiết kế (chương 12).

Lập trường của tôi: phân loại quan trọng vào những thời điểm then chốt. Đừng biến nó thành ba tuần điền mọi ô chỉ vì bộ phận quản trị bảo vậy. Hãy dùng nó ở nơi quan trọng: dữ liệu cá nhân, dữ liệu tài chính, dữ liệu chịu quản lý, và các trường mà nghiệp vụ cần một chủ sở hữu có tên. Điểm mấu chốt là mức độ nhạy cảm không còn là kiến thức nằm trong đầu ai đó, mà trở thành một phần của trường.

Ngoài kỳ thi: AI thay đổi điều gì. Tài liệu về trường kém trước đây chỉ làm khổ quản trị viên tiếp theo. Giờ nó đánh lừa mọi công cụ AI và tác tử đọc lược đồ: Flag2__c có nhạy cảm không, có phải nguồn có thẩm quyền không, còn được dùng không? AI cũng tạo trường nhanh hơn bất kỳ đội nào, nên tên, mô tả và phân loại là một phần của kiến trúc, không phải việc dọn dẹp.

Một khi trường đã ở ngoài đó thu thập dữ liệu, mọi thứ bắt đầu dựa vào nó. Màn hình hiển thị nó, flow rẽ nhánh theo nó, quy tắc xác thực kiểm tra nó, báo cáo nhóm theo nó, tích hợp gửi và đọc nó, và giờ các công cụ AI suy luận về nó. Mỗi thứ trong số đó đều đưa ra giả định về trường: kiểu của nó, độ dài của nó, nó có bao giờ trống không, và các giá trị của nó có nghĩa là gì. Thay đổi trường về sau và bạn phải tìm ra từng giả định đó trước. Đổi tên một giá trị danh sách chọn, rút ngắn một trường văn bản, hay biến một trường Văn bản thành danh sách chọn nghe như một thay đổi nhỏ, nhưng nó có thể làm hỏng một tích hợp trong hệ thống của một công ty khác. Đó là lý do một trường là một cam kết.

Một thuộc tính, bốn quyết định Một thuộc tính, Trạng thái giao hàng (Delivery Status), qua bốn quyết định. Thứ nhất, ý nghĩa: lần giao hàng đang ở đâu ngay lúc này, với các giá trị Scheduled, Out, Delivered và Failed, được bộ phận điều phối, báo cáo và nguồn cấp cho nhà bán lẻ sử dụng. Thứ hai, kiểu: một danh sách có kiểm soát, nên là danh sách chọn, được lưu chứ không suy ra, và là một bộ giá trị toàn cục vì nó được dùng ở nhiều nơi. Thứ ba, quy tắc: bắt buộc, vì mỗi lần giao hàng đều có một trạng thái; hạn chế, để không có cách viết mới nào đến từ API; không duy nhất và không phải ID bên ngoài. Thứ tư, tài liệu hóa: một mô tả cho con người và cho AI, một chủ sở hữu ở bộ phận điều phối, và mức độ nhạy cảm Nội bộ. Bên dưới: bấm New Field là bước cuối cùng, không phải bước đầu tiên. 1 · Ý nghĩa nó có nghĩa là gì? Lần giao hàng đang ở đâu, ngay lúc này Scheduled, Out, Delivered, Failed Được điều phối, báo cáo và nguồn cấp cho nhà bán lẻ dùng 2 · Kiểu đây là loại dữ liệu gì? Một danh sách có kiểm soát: danh sách chọn Được lưu, không suy ra Dùng ở nhiều nơi: bộ giá trị toàn cục 3 · Quy tắc nó cam kết điều gì? Bắt buộc: mỗi lần giao hàng có một trạng thái Hạn chế: không có cách viết mới từ API Không duy nhất, không phải ID bên ngoài 4 · Tài liệu hóa ai sẽ đọc nó sau này? Một mô tả, cho con người và cho AI Một chủ sở hữu: bộ phận điều phối Mức độ nhạy cảm: Nội bộ Bấm New Field là bước cuối cùng, không phải bước đầu tiên. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Tôi không muốn bạn rời mô-đun này với nỗi sợ tạo trường. Salesforce được xây để mở rộng; hãy dùng nó. Tôi muốn câu hỏi thay đổi từ “tôi nên chọn kiểu trường nào?” thành “dữ liệu này có nghĩa là gì, và chúng ta đang cam kết hành vi gì?” Kiểu, bắt buộc, duy nhất, ID bên ngoài, danh sách chọn, công thức, mô tả, phân loại: cùng nhau chúng là biểu hiện vật lý của mô hình logic ở chương 2.

  • Giá trị có nghĩa là gì trước khi chọn kiểu trường, và đó là một thuộc tính, một mã định danh, một bộ từ vựng được kiểm soát hay thực chất là một thực thể khác.
  • Một giá trị là phép tính hiện tại có thể suy ra hay là sự thật lịch sử phải được lưu.
  • Hệ thống nào sở hữu từng mã định danh, và tính duy nhất của nó có phải là một lời hứa nghiệp vụ thực sự không.
  • Khi nào một giá trị bắt buộc thực sự được biết, và chuyện gì xảy ra với các bản ghi và tích hợp không có nó.
  • Trường cần mô tả, cách đặt tên và phân loại nào để con người, quy trình và AI dùng nó an toàn.