Ngân hàng đề — Google Cloud Associate Data Practitioner
Tìm thấy 333 câu.
A new analyst joins your team and needs permission to query all the tables in your project's BigQuery datasets. However, there is one specific table, employee_salaries, that contains sensitive PII, and they must be prevented from accessing it.
What is the most effective way to grant the required permissions while enforcing the restriction?
- A Grant the BigQuery Data Viewer role on each non-sensitive dataset individually.
- B Grant the BigQuery Metadata Viewer role at the project level.
- C Put the sensitive table in a separate project.
- D Grant the BigQuery Data Viewer role at the project level and deny access to the sensitive table using an IAM Deny policy.
Xem giải thích
Đáp án
D — Cấp BigQuery Data Viewer ở cấp project, rồi CHẶN quyền truy cập bảng nhạy cảm bằng IAM Deny policy.
Vì sao đúng
Yêu cầu là truy vấn được MỌI bảng trong project nhưng KHÔNG được đụng vào đúng MỘT bảng. IAM Deny policy sinh ra cho đúng kiểu ngoại lệ này.
⚠ Điểm mấu chốt — deny THẮNG allow, luôn luôn:
Cấp roles/bigquery.dataViewer ở cấp PROJECT
↓
→ đọc được mọi dataset, mọi bảng
↓
+ IAM DENY POLICY cho employee_salaries
↓
⚠ DENY LUÔN THẮNG ALLOW
→ dù có bao nhiêu vai trò cho phép,
bảng đó vẫn bị chặn
⚠ Vì sao cách này "hiệu quả nhất":
Cấp từng dataset một (phương án A)
↓
⚠ Có dataset MỚI → phải nhớ cấp thêm
⚠ Quên một lần → nhà phân tích kêu
⚠ Danh sách phình theo thời gian
Deny policy
↓
→ cấp MỘT lần ở cấp project
→ chặn ĐÚNG một ngoại lệ
→ dataset mới TỰ ĐỘNG dùng được
→ ngoại lệ vẫn được giữ
⚠ Deny policy trông thế nào:
{
"displayName": "chan-bang-luong",
"rules": [{
"denyRule": {
"deniedPrincipals": ["principal://.../analyst@congty.com"],
"deniedPermissions": ["bigquery.tables.getData"],
"resource": ".../datasets/hr/tables/employee_salaries"
}
}]
}
Xem thêm câu #12963, #12965 và #12969 (cùng lô): cùng chủ đề kiểm soát truy cập BigQuery nhưng khác yêu cầu — chia sẻ kết quả cho bên ngoài → authorized view; chặn một CỘT → policy tag; chặn một số DÒNG → row-level security. Bốn khoá khác nhau vì bốn phạm vi khác nhau — hoàn toàn nhất quán.
Vì sao các phương án khác sai
-
A (cấp Data Viewer trên từng dataset không nhạy cảm) — đây là phương án gần nhất và chạy được, nhưng phải bảo trì thủ công mãi mãi: mỗi dataset mới lại phải nhớ cấp thêm. Đó chính là điều Deny policy loại bỏ.
-
C (đưa bảng nhạy cảm sang project riêng) — cũng là cách tách bạch tốt về mặt kiến trúc, nhưng đây là thay đổi lớn về tổ chức dữ liệu, và đề hỏi cách cấp quyền, không phải cách tái cấu trúc.
-
B (cấp Metadata Viewer ở cấp project) — chỉ cho xem tên bảng và lược đồ, không đọc được dữ liệu — không đáp ứng yêu cầu truy vấn.
Ghi nhớ
⚠ Bốn cơ chế kiểm soát truy cập BigQuery — bảng phải thuộc: | Cần chặn | Cơ chế | |---|---| | Một BẢNG cụ thể, giữa quyền rộng | IAM Deny policy | | Một số CỘT | column-level security (policy tag) | | Một số DÒNG | row-level security | | Chỉ lộ kết quả, giấu bảng gốc | authorized view | | Che giá trị theo vai trò | dynamic data masking |
Từ khoá nhận diện:
"cho tất cả trừ một bảng" → IAM Deny policy "ẩn một cột" → policy tag / column-level security "chỉ thấy dòng của mình" → row-level security "chia sẻ kết quả, giấu nguồn" → authorized view "chia sẻ dataset ra ngoài có quản trị" → Analytics Hub
| IAM Deny policy — điều cần nhớ | Nội dung |
|---|---|
| Deny LUÔN thắng allow | không có ngoại lệ |
| Gắn ở | organization, folder, hoặc project |
| Khai | deniedPrincipals, deniedPermissions, resource |
exceptionPrincipals |
miễn trừ cho một số người |
| Lệnh | gcloud iam policies create --kind=denypolicies ... |
| Kiểm tra | Policy Troubleshooter hiểu cả deny |
| Vì sao deny policy đáng giá | Lý do |
|---|---|
| Diễn đạt được "tất cả TRỪ" | allow-only không làm được |
| Không phụ thuộc việc nhớ cấp quyền | tài nguyên mới tự nằm trong quy tắc |
| Áp ở cấp tổ chức | mọi project bên dưới |
| Dùng cho | dữ liệu cực nhạy cảm, ranh giới cứng |
| Cẩn thận | deny quá rộng làm hỏng cả dịch vụ |
| Thứ tự đánh giá quyền của IAM | Bước |
|---|---|
| 1 | Deny policy — nếu bị deny thì DỪNG, từ chối |
| 2 | Allow policy (các vai trò được cấp) |
| 3 | IAM condition trên binding |
| 4 | VPC Service Controls — vành đai |
| 5 | Kiểm soát ở tầng dịch vụ (row/column-level) |
| Ghi nhớ | deny đứng đầu, không gì vượt qua được |
| Cách tiếp cận khác cho dữ liệu nhạy cảm | Cách |
|---|---|
| Dataset riêng, quyền hẹp | đơn giản, dễ hiểu |
| Project riêng | ranh giới cứng nhất |
| Policy tag trên cột | giữ bảng chung, ẩn cột |
| Dynamic masking | vẫn truy vấn được, giá trị bị che |
| Thực tế | thường kết hợp nhiều lớp |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Deny policy đang có gì | gcloud iam policies list --attachment-point=... --kind=denypolicies | | Người này truy cập được không | Policy Troubleshooter | | Có ai lách được không | Policy Analyzer trên bảng nhạy cảm |
Và một điều nên cân nhắc bên cạnh deny policy: bảng lương có thật sự nên nằm chung project với dữ liệu phân tích không? Deny policy giải quyết gọn tình huống hiện tại, nhưng dữ liệu nhân sự đặt trong một project riêng với vòng người truy cập rất hẹp là ranh giới dễ giải thích với kiểm toán hơn nhiều — và không phụ thuộc vào việc ai đó nhớ duy trì một quy tắc ngoại lệ.
You have successfully trained and saved a classification model in BigQuery ML named my_models.customer_churn_model. Now, you have a new table called new_customers with the same features used for training. You need to use your trained model to generate churn predictions for everyone in the new_customers table.
Which SQL function should you use in your query?
- A ML.TRAIN
- B ML.FEATURE_INFO
- C ML.EVALUATE
- D ML.PREDICT
Xem giải thích
Đáp án
D — ML.PREDICT
Vì sao đúng
Mô hình đã huấn luyện xong, và việc cần làm là sinh dự đoán cho dữ liệu MỚI. ML.PREDICT là hàm của BigQuery ML cho đúng việc đó.
⚠ Điểm mấu chốt — cú pháp:
SELECT *
FROM ML.PREDICT(
MODEL `my_models.customer_churn_model`,
(SELECT * FROM `du_an.new_customers`)
);
↓
Tham số 1: MODEL — mô hình đã huấn luyện
Tham số 2: một TRUY VẤN CON cấp dữ liệu vào
↓
⚠ Bảng vào phải có ĐÚNG các cột đặc trưng
đã dùng khi huấn luyện
⚠ Kết quả trả về với mô hình phân loại:
Các cột gốc của new_customers
+
predicted_<label>
→ nhãn dự đoán, ví dụ "churn" / "no_churn"
+
predicted_<label>_probs
→ MẢNG xác suất cho từng lớp
↓
Lấy xác suất của một lớp:
(SELECT prob FROM UNNEST(predicted_churn_probs)
WHERE label = 'churn')
⚠ Bốn hàm ML. — mỗi hàm một giai đoạn:
HUẤN LUYỆN
→ CREATE MODEL (KHÔNG phải ML.TRAIN)
ĐÁNH GIÁ
→ ML.EVALUATE — mô hình tốt tới đâu
TÌM HIỂU ĐẶC TRƯNG
→ ML.FEATURE_INFO — thống kê đầu vào
DỰ ĐOÁN ← đề này
→ ML.PREDICT
⚠ Với bài toán rời bỏ khách hàng, đừng dừng ở nhãn:
predicted_label chỉ cho "có / không"
↓
XÁC SUẤT hữu ích hơn nhiều:
- xếp hạng khách theo rủi ro
- chọn ngưỡng theo NGÂN SÁCH
giữ chân khách
↓
Ngưỡng 0,5 chỉ là mặc định,
không phải ngưỡng đúng
Xem thêm câu #12919, #12928 và #12929 (lô 133): cùng chủ đề BigQuery ML — chọn công cụ, chọn loại mô hình phân cụm, chọn loại mô hình hồi quy. Câu này là bước cuối: dùng mô hình đã có.
Vì sao các phương án khác sai
-
C (
ML.EVALUATE) — đây là phương án gần nhất và là hàm rất hay dùng, nhưng nó đánh giá chất lượng mô hình trên dữ liệu đã có nhãn, trả về accuracy, AUC, precision — không sinh dự đoán cho dữ liệu mới. -
A (
ML.TRAIN) — không tồn tại; huấn luyện dùngCREATE MODEL. -
B (
ML.FEATURE_INFO) — trả về thống kê về các đặc trưng đầu vào (min, max, trung bình, số giá trị null), không dự đoán.
Ghi nhớ
⚠ Các hàm BigQuery ML — bảng phải thuộc: | Hàm | Việc | |---|---| | CREATE MODEL | huấn luyện — không phải ML.TRAIN | | ML.PREDICT | sinh dự đoán cho dữ liệu mới | | ML.EVALUATE | đo chất lượng mô hình | | ML.EXPLAIN_PREDICT | giải thích từng dự đoán | | ML.FEATURE_IMPORTANCE | đặc trưng nào quan trọng | | ML.FEATURE_INFO | thống kê đặc trưng đầu vào | | ML.CONFUSION_MATRIX | ma trận nhầm lẫn | | ML.TRAINING_INFO | quá trình huấn luyện | | ML.CENTROIDS | tâm cụm — cho KMEANS |
Từ khoá nhận diện:
"dự đoán cho dữ liệu mới" →
ML.PREDICT"mô hình chính xác tới đâu" →ML.EVALUATE"vì sao dự đoán như vậy" →ML.EXPLAIN_PREDICT"huấn luyện" →CREATE MODEL"ML.TRAIN" → KHÔNG TỒN TẠI
Yêu cầu với dữ liệu đầu vào của ML.PREDICT |
Yêu cầu |
|---|---|
| Phải có đủ các cột ĐẶC TRƯNG | tên khớp với lúc huấn luyện |
| Cột thừa | được bỏ qua, và giữ nguyên trong kết quả |
| Cột thiếu | lỗi |
| Kiểu dữ liệu | phải tương thích |
| Không cần cột nhãn | đó là thứ đang dự đoán |
TRANSFORM |
nếu mô hình khai, tiền xử lý tự áp dụng lại |
| Lưu kết quả dự đoán | Cách |
|---|---|
| Ghi vào bảng | CREATE OR REPLACE TABLE ... AS SELECT * FROM ML.PREDICT(...) |
| Chạy theo lịch | scheduled query hằng ngày |
| Chỉ dự đoán khách mới | lọc trong truy vấn con — rẻ hơn |
| Bảng phân vùng theo ngày dự đoán | dễ so sánh theo thời gian |
| Sau đó | Reverse ETL đẩy sang công cụ marketing |
| Chọn ngưỡng cho bài toán rời bỏ | Nội dung |
|---|---|
| Ngưỡng 0,5 là mặc định, không phải tối ưu | |
| Recall cao | bắt được nhiều khách sắp rời — tốn chi phí giữ chân |
| Precision cao | ít báo nhầm — bỏ sót nhiều khách |
| Chọn theo | chi phí giữ chân so với giá trị khách hàng |
| Công cụ | ML.ROC_CURVE để xem đánh đổi |
| Mô hình cũ đi theo thời gian | Nội dung |
|---|---|
| Data drift | phân phối đầu vào thay đổi |
| Concept drift | quan hệ giữa đặc trưng và nhãn thay đổi |
| Phát hiện | so ML.EVALUATE trên dữ liệu mới theo thời gian |
| Xử lý | huấn luyện lại định kỳ |
| Tự động hoá | scheduled query hoặc Vertex AI Pipelines |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Mô hình cần cột nào | SELECT * FROM ML.FEATURE_INFO(MODEL ...) | | Dự đoán có hợp lý không | so phân phối dự đoán với tỉ lệ rời bỏ thực tế | | Mô hình còn tốt không | ML.EVALUATE trên dữ liệu gần đây |
Và một bước rất đáng làm ngay sau lần dự đoán đầu tiên: so tỉ lệ dự đoán "sẽ rời bỏ" với tỉ lệ rời bỏ thực tế trong quá khứ. Nếu mô hình gắn cờ 40% khách hàng trong khi lịch sử chỉ có 5% rời bỏ, vấn đề nằm ở ngưỡng hoặc ở dữ liệu huấn luyện mất cân bằng — và phát hiện điều đó trước khi đội marketing gọi điện cho 40% khách hàng sẽ tiết kiệm rất nhiều.
An analyst has run a complex query on a sensitive financials table in BigQuery. They need to share only the aggregated results of this query with an external consultant. The consultant must be able to query the result set but must be prevented from accessing the underlying financials table.
What is the most secure and efficient method to achieve this?
- A Grant the consultant the BigQuery Data Viewer role on the financials table.
- B Export the query results to a Google Sheet and share the sheet with the consultant.
- C Save the query results to a new table, create an Authorized View on that table, and grant the consultant access only to the view.
- D Use Analytics Hub to create a listing for the financials table.
Xem giải thích
Đáp án
C — Lưu kết quả truy vấn vào bảng mới, tạo Authorized View trên bảng đó, và chỉ cấp quyền cho tư vấn viên trên view.
Vì sao đúng
Yêu cầu tách rất rõ: tư vấn viên bên ngoài truy vấn được KẾT QUẢ TỔNG HỢP, nhưng tuyệt đối không chạm được vào bảng financials gốc. Authorized view là cơ chế của BigQuery cho đúng việc đó.
⚠ Điểm mấu chốt — authorized view phá vỡ chuỗi quyền thông thường:
BÌNH THƯỜNG
↓
Muốn truy vấn một view
→ phải có quyền trên BẢNG GỐC
↓
⚠ tức là vẫn thấy được dữ liệu nhạy cảm
AUTHORIZED VIEW
↓
View được UỶ QUYỀN trên dataset chứa
bảng gốc
↓
→ người dùng chỉ cần quyền TRÊN VIEW
→ KHÔNG cần và KHÔNG có quyền
trên bảng gốc
↓
⚠ Đây chính là điều đề yêu cầu
⚠ Ba bước triển khai:
1. Lưu kết quả tổng hợp
CREATE TABLE ket_qua.tong_hop AS
SELECT ... FROM financials GROUP BY ...
2. Tạo view ở DATASET KHÁC
CREATE VIEW chia_se.bao_cao AS
SELECT * FROM ket_qua.tong_hop;
3. UỶ QUYỀN cho view trên dataset nguồn
→ console: dataset ket_qua → Sharing
→ Authorize views → chọn chia_se.bao_cao
4. Cấp cho tư vấn viên:
roles/bigquery.dataViewer trên dataset chia_se
roles/bigquery.jobUser trên project của họ
⚠ Vì sao xuất ra Google Sheet lại kém an toàn:
Xuất sang Sheet
↓
⚠ Tạo một BẢN SAO — không thu hồi được
⚠ Tải xuống, chuyển tiếp thoải mái
⚠ Không cập nhật khi dữ liệu đổi
⚠ Không truy vấn được như bảng
⚠ Không có audit log truy cập
↓
Đề nói "truy vấn được" và "an toàn nhất"
Xem thêm câu #12961, #12965 và #12969 (cùng lô): cùng họ kiểm soát truy cập BigQuery — chặn một BẢNG → deny policy; ẩn một CỘT → policy tag; lọc DÒNG → row-level security. Bốn khoá khác nhau vì bốn phạm vi khác nhau, nhất quán với nhau.
Vì sao các phương án khác sai
-
B (xuất sang Google Sheet) — đây là phương án gần nhất về mặt "chia sẻ nhanh", nhưng nó tạo bản sao không thu hồi được, không truy vấn được như bảng, và không có nhật ký truy cập.
-
A (cấp Data Viewer trên bảng
financials) — cho phép truy cập thẳng bảng nhạy cảm — đúng điều đề cấm. -
D (dùng Analytics Hub cho bảng
financials) — Analytics Hub là công cụ chia sẻ tốt, nhưng tạo listing cho chính bảng nhạy cảm là chia sẻ nguyên bảng gốc. (Chia sẻ một view qua Analytics Hub thì lại hợp lý.)
Ghi nhớ
⚠ Bốn cơ chế kiểm soát truy cập BigQuery — bảng phải thuộc: | Cần | Cơ chế | |---|---| | Chỉ lộ KẾT QUẢ, giấu bảng gốc | authorized view | | Chặn một BẢNG giữa quyền rộng | IAM Deny policy | | Ẩn một số CỘT | column-level security (policy tag) | | Lọc DÒNG theo người dùng | row-level security | | Chia sẻ dataset ra ngoài có quản trị | Analytics Hub |
Từ khoá nhận diện:
"chia sẻ kết quả, không cho thấy nguồn" → authorized view "tất cả trừ một bảng" → deny policy "ẩn cột lương" → policy tag "mỗi chi nhánh chỉ thấy dòng của mình" → row-level security "xuất ra Sheet/CSV rồi gửi" → hầu như luôn là phương án SAI về bảo mật
| Authorized view — điều cần nhớ | Nội dung |
|---|---|
| View phải ở DATASET KHÁC với bảng gốc | bắt buộc |
| Uỷ quyền trên dataset NGUỒN | không phải trên bảng |
| Người dùng cần | quyền trên dataset chứa VIEW |
| Không cần quyền trên bảng gốc | đó là điểm mấu chốt |
| Mở rộng | authorized dataset — uỷ quyền cả dataset |
| Authorized routine | tương tự cho hàm và thủ tục |
| Chuẩn bị dữ liệu trước khi chia sẻ ra ngoài | Việc |
|---|---|
| Tổng hợp đủ mức | không lộ được bản ghi cá nhân |
| Bỏ hoặc che định danh | Sensitive Data Protection |
| Kiểm tra tấn công suy luận | nhóm quá nhỏ vẫn lộ danh tính |
| Thêm ngưỡng tối thiểu | ví dụ chỉ hiện nhóm có ≥ 10 bản ghi |
| Ghi rõ điều khoản sử dụng | trong hợp đồng |
| Cấp quyền cho người NGOÀI tổ chức | Nội dung |
|---|---|
| Domain Restricted Sharing | Organization Policy có thể chặn tài khoản ngoài |
| → phải thêm ngoại lệ cho domain của tư vấn viên | |
| Cấp cho GROUP | dễ thu hồi khi hợp đồng kết thúc |
| IAM condition có hạn | tự hết hạn theo ngày |
| Bật Data Access audit log | biết họ đã đọc gì |
| Khi kết thúc | thu hồi ngay, đừng để sót |
| Vì sao "xuất file rồi gửi" luôn kém hơn | Lý do |
|---|---|
| Không thu hồi được | bản sao đã ra khỏi tầm kiểm soát |
| Không có nhật ký truy cập | |
| Lỗi thời ngay lập tức | |
| Dễ chuyển tiếp nhầm người | |
| Ngoại lệ hợp lý | khi bên nhận không dùng Google Cloud |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | View đã được uỷ quyền chưa | bq show --format=prettyjson <dataset nguồn> → access.view | | Tư vấn viên có đọc được bảng gốc không | Policy Troubleshooter trên bảng financials | | Họ đã truy vấn gì | Data Access audit log |
Và một rủi ro cần kiểm tra kỹ trước khi chia sẻ dữ liệu tài chính đã tổng hợp: nhóm quá nhỏ vẫn có thể lộ thông tin cá nhân. Một dòng "doanh thu theo chi nhánh" mà chi nhánh đó chỉ có một khách hàng thì thực chất đang tiết lộ đúng con số của khách hàng ấy — thêm ngưỡng số lượng tối thiểu vào chính view là cách phòng ngừa rẻ và hiệu quả.
Your company has a strict data residency policy requiring all customer PII to be stored and processed exclusively within Germany. You need to create a BigQuery dataset for customer analytics and a Cloud Storage bucket for raw data files.
What must you do when creating these resources to comply with the policy?
- A Apply an Organization Policy that restricts all resource locations to Europe.
- B Select a German region (e.g., europe-west3) as the location for both the bucket and the dataset.
- C Tag the resources with a location:germany label for auditing.
- D Enable CMEK on the resources using a key from a German key ring in Cloud KMS.
Xem giải thích
Đáp án
B — Chọn một Region của Đức (ví dụ europe-west3) làm vị trí cho CẢ bucket và dataset.
Vì sao đúng
Chính sách yêu cầu dữ liệu PII được lưu và xử lý CHỈ TRONG nước Đức. Vị trí thực tế của tài nguyên là thứ duy nhất quyết định điều đó.
⚠ Điểm mấu chốt — vị trí là thuộc tính cố định, chọn lúc tạo:
BigQuery dataset
bq mk --location=europe-west3 du_an:phan_tich
Cloud Storage bucket
gcloud storage buckets create gs://du-lieu-tho \
--location=europe-west3
↓
⚠ VỊ TRÍ KHÔNG ĐỔI ĐƯỢC sau khi tạo
→ sai thì phải tạo mới và chép lại
⚠ Vì sao "Europe" là chưa đủ:
Multi-region EU
↓
Dữ liệu nằm trong LÃNH THỔ CHÂU ÂU,
nhưng có thể ở Bỉ, Hà Lan, Phần Lan...
↓
⚠ Chính sách nói CHỈ TRONG NƯỚC ĐỨC
↓
→ phải là REGION CỤ THỂ của Đức:
europe-west3 (Frankfurt)
europe-west10 (Berlin)
⚠ "Xử lý" cũng phải trong Đức, không chỉ "lưu":
Dữ liệu ở europe-west3
↓
Nhưng job Dataflow chạy ở us-central1
↓
⚠ Dữ liệu ĐI RA khỏi Đức để xử lý
↓
→ MỌI dịch vụ xử lý cũng phải
đặt ở europe-west3:
Dataflow, Dataproc, Cloud Run,
Composer, và cả job BigQuery
↓
⚠ BigQuery job chạy ở CHÍNH Region
của dataset — điểm này thì tự động
Xem thêm câu #12921 (lô 133): cũng chọn vị trí bucket theo người dùng, ở đó là Úc vì lý do độ trễ. Câu này chọn theo chủ quyền dữ liệu. Cùng một quyết định kỹ thuật, hai lý do khác nhau — cả hai đều dẫn tới region cụ thể.
Vì sao các phương án khác sai
-
A (Organization Policy giới hạn vị trí ở Europe) — đây là phương án gần nhất và là một biện pháp CƯỠNG CHẾ rất tốt nên có thêm, nhưng "Europe" rộng hơn nước Đức, và bản thân chính sách không tạo ra tài nguyên ở đúng chỗ — bạn vẫn phải chọn vị trí khi tạo. (Chính sách nên đặt là danh sách Region của Đức.)
-
D (bật CMEK với khoá từ key ring ở Đức) — kiểm soát khoá mã hoá, nhưng dữ liệu vẫn có thể nằm ở Region khác.
-
C (gắn nhãn
location:germany) — nhãn không cưỡng chế gì cả, chỉ để phân loại và tính chi phí.
Ghi nhớ
⚠ Chủ quyền dữ liệu — bốn lớp, dùng cùng nhau: | Lớp | Việc | |---|---| | Chọn REGION cụ thể khi tạo | quyết định dữ liệu nằm ở đâu | | Organization Policy gcp.resourceLocations | CHẶN tạo tài nguyên ngoài vùng cho phép | | CMEK với key ring cùng Region | kiểm soát khoá | | VPC Service Controls | chống dữ liệu bị chuyển ra ngoài | | Assured Workloads | gói tuân thủ có sẵn cho một số khu vực |
Từ khoá nhận diện:
"dữ liệu phải ở trong nước X" → chọn REGION cụ thể của nước đó "ngăn người khác tạo tài nguyên sai chỗ" → Organization Policy resourceLocations "tự quản khoá mã hoá" → CMEK "chống rò rỉ ra ngoài vành đai" → VPC Service Controls "nhãn để tuân thủ" → nhãn KHÔNG cưỡng chế gì
| Vị trí của tài nguyên — điều cần nhớ | Nội dung |
|---|---|
| BigQuery dataset | --location, KHÔNG đổi được |
| Cloud Storage bucket | --location, KHÔNG đổi được |
| Job BigQuery | chạy ở Region của dataset |
| JOIN giữa hai dataset khác Region | KHÔNG được |
| Chuyển dataset sang Region khác | BigQuery Data Transfer Service (dataset copy) |
| Region của Đức | europe-west3 (Frankfurt), europe-west10 (Berlin) |
Organization Policy gcp.resourceLocations |
Nội dung |
|---|---|
| Việc | chặn tạo tài nguyên ngoài danh sách vị trí |
| Đặt ở | organization, folder, hoặc project |
| Giá trị | Region cụ thể, hoặc nhóm giá trị như in:eu-locations |
| Với đề này | nên đặt chỉ các Region của Đức |
| Lợi ích | ngăn lỗi con người, không phải trông chờ vào kỷ luật |
| Đừng quên các dịch vụ XỬ LÝ | Dịch vụ |
|---|---|
| Dataflow | --region=europe-west3 |
| Dataproc | --region=europe-west3 |
| Cloud Run / Functions | Region khi triển khai |
| Cloud Composer | Region của môi trường |
| Cloud KMS | key ring cùng Region |
| Cloud Logging | log bucket cũng có Region — dễ quên nhất |
| GDPR — vài điểm liên quan | Nội dung |
|---|---|
| Không bắt buộc dữ liệu ở lại một nước | nhưng hợp đồng nội bộ có thể bắt |
| Chuyển dữ liệu ra ngoài EU | có quy định riêng |
| Data Processing Addendum | Google cung cấp |
| Quyền được xoá | thiết kế để xoá được theo cá nhân |
| Assured Workloads EU | hỗ trợ nhân sự hỗ trợ đặt tại EU |
| Nếu lỡ tạo sai Region | Cách xử lý |
|---|---|
| BigQuery | Data Transfer Service — dataset copy sang Region mới |
| Cloud Storage | Storage Transfer Service sang bucket mới |
| Chi phí | phí truyền dữ liệu và thao tác |
| Sau khi chuyển | xoá bản cũ — không để sót dữ liệu ngoài lãnh thổ |
| Phòng ngừa | đặt Organization Policy TRƯỚC khi đội bắt đầu làm |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Dataset ở đâu | bq show --format=prettyjson <dataset> → location | | Bucket ở đâu | gcloud storage buckets describe gs://b --format="value(location)" | | Có tài nguyên nào sai chỗ không | Cloud Asset Inventory, lọc theo vị trí |
Và một chi tiết rất hay bị bỏ sót trong dự án có yêu cầu chủ quyền dữ liệu: vị trí của log bucket trong Cloud Logging. Dữ liệu chính nằm đúng chỗ, nhưng audit log và log ứng dụng — vốn có thể chứa cả PII trong thông báo lỗi — lại mặc định đi về vị trí global. Đặt log bucket theo đúng Region là bước nên làm cùng lúc với việc tạo dataset.
A company stores employee data in a BigQuery table named hr_dataset.employees. This table contains columns such as employee_id, department, start_date, and a highly sensitive column, salary.
A new business analyst needs to query this table to perform headcount analysis but must be prevented from accessing the salary column under any circumstances. The solution should adhere to the principle of least privilege and be the most scalable and governable method available in Google Cloud.
Which is the most appropriate method to grant this level of access?
-
A
Define a policy tag (e.g.,
Confidential) in Data Catalog, apply it to thesalarycolumn's schema, and configure an IAM policy that denies the analyst theFine-Grained Readerrole for that specific tag. -
B
Create an authorized view on the
hr_dataset.employeestable using the querySELECT * EXCEPT (salary), and then grant the analyst permissions to query only this view. -
C
Grant the analyst the
roles/bigquery.dataViewerrole on the table and trust them not to include thesalarycolumn in theirSELECTstatements. -
D
Apply a dynamic data masking rule to the
salarycolumn that replaces the column's value withNULLfor any user not in a privileged group.
Xem giải thích
Đáp án
A — Định nghĩa policy tag (ví dụ Confidential) trong Data Catalog, gắn vào cột salary trong lược đồ, và cấu hình IAM sao cho nhà phân tích KHÔNG có vai trò Fine-Grained Reader.
Vì sao đúng
Đề yêu cầu rõ ba điều: chặn truy cập MỘT CỘT, theo quyền tối thiểu, và bằng cách CÓ THỂ MỞ RỘNG và QUẢN TRỊ ĐƯỢC. Column-level security bằng policy tag là cơ chế duy nhất thoả cả ba.
⚠ Điểm mấu chốt — bảo vệ gắn vào CỘT, không gắn vào truy vấn:
Tạo taxonomy trong Data Catalog / Dataplex
↓
Policy tag: "Confidential"
↓
Gắn vào cột `salary` trong LƯỢC ĐỒ bảng
↓
Ai muốn đọc cột đó phải có
roles/datacatalog.categoryFineGrainedReader
trên policy tag ấy
↓
⚠ Nhà phân tích KHÔNG có vai trò đó
→ SELECT * cũng KHÔNG trả về cột salary
→ truy vấn đích danh salary thì BỊ TỪ CHỐI
⚠ Vì sao cách này "mở rộng và quản trị được":
Cùng một policy tag dùng cho
NHIỀU CỘT, ở NHIỀU BẢNG,
trong NHIỀU DATASET
↓
Cấp hay thu hồi quyền MỘT LẦN
trên chính policy tag
↓
→ mọi cột mang tag đó đổi theo
↓
So với authorized view:
mỗi bảng lại phải tạo và bảo trì
một view riêng
⚠ Vì sao authorized view kém hơn TRONG TÌNH HUỐNG NÀY:
CREATE VIEW ... AS SELECT * EXCEPT(salary)
↓
⚠ Hoạt động được, nhưng:
- bảng thêm cột nhạy cảm mới
→ phải nhớ sửa view
- có N bảng → N view phải bảo trì
- bảo vệ nằm ở VIEW, không nằm ở CỘT
→ ai có quyền bảng gốc vẫn thấy hết
↓
Với column-level security:
bảo vệ đi THEO CỘT ở mọi nơi
Xem thêm câu #12961, #12963 và #12969 (cùng lô): cùng họ kiểm soát truy cập — chặn một BẢNG → deny policy; chia sẻ kết quả ra ngoài → authorized view; lọc DÒNG → row-level security. Bốn khoá khác nhau theo phạm vi cần chặn, hoàn toàn nhất quán.
Vì sao các phương án khác sai
-
B (authorized view với
SELECT * EXCEPT(salary)) — đây là phương án gần nhất và thực sự chạy được, nhưng phải bảo trì thủ công theo từng bảng, và bảo vệ gắn vào view chứ không gắn vào cột. Đề nhấn mạnh "mở rộng và quản trị được". -
D (dynamic data masking trả về NULL) — cũng là tính năng thật và hữu ích, nhưng nó che GIÁ TRỊ chứ không CHẶN truy cập; đề nói "phải bị ngăn truy cập cột lương trong mọi hoàn cảnh", và cách chặt chẽ hơn là column-level security. (Masking thường dùng khi vẫn muốn truy vấn chạy được bình thường.)
-
C (cấp
dataViewerrồi tin tưởng người dùng) — không phải biện pháp kỹ thuật nào cả, vi phạm hoàn toàn nguyên tắc quyền tối thiểu.
Ghi nhớ
⚠ Column-level security — bảng phải thuộc: | Thành phần | Việc | |---|---| | Taxonomy | cây phân loại mức nhạy cảm | | Policy tag | nhãn gắn vào CỘT, ví dụ Confidential, PII | | roles/datacatalog.categoryFineGrainedReader | vai trò cho phép ĐỌC cột mang tag | | Không có vai trò | cột bị chặn, kể cả với SELECT * | | Phạm vi | một tag dùng cho nhiều cột, nhiều bảng | | Quản lý ở | Dataplex Universal Catalog (trước là Data Catalog) |
Từ khoá nhận diện:
"chặn một CỘT, có thể mở rộng, quản trị được" → policy tag / column-level security "che giá trị nhưng vẫn truy vấn được" → dynamic data masking "chỉ thấy một số DÒNG" → row-level security "chia sẻ kết quả, giấu bảng gốc" → authorized view "chặn cả một bảng" → IAM Deny policy
| Column-level security ↔ Dynamic data masking | Nội dung |
|---|---|
| Column-level security | TỪ CHỐI truy cập cột |
| Dynamic data masking | trả về giá trị ĐÃ CHE (NULL, hash, mặc định) |
Truy vấn SELECT salary |
CLS: lỗi quyền; masking: chạy được, ra giá trị che |
| Dùng CLS khi | không được phép biết gì về cột đó |
| Dùng masking khi | truy vấn có sẵn không được vỡ |
| Dùng chung | cùng một policy tag, khác vai trò gán |
| Thiết kế taxonomy cho tốt | Nội dung |
|---|---|
| Ít mức, rõ nghĩa | ví dụ Public / Internal / Confidential / Restricted |
| Đặt tên theo MỨC NHẠY CẢM, không theo tên cột | |
| Gắn tag khi tạo bảng | đưa vào quy trình, không làm sau |
| Cấp quyền cho GROUP | dễ vào ra |
| Taxonomy có Region | phải cùng Region với dữ liệu |
| Rà soát | Dataplex hiển thị cột nào mang tag nào |
| Áp policy tag bằng lệnh | Cách |
|---|---|
| Trong lược đồ JSON | "policyTags": {"names": ["projects/.../policyTags/123"]} |
| Cập nhật | bq update --schema schema.json <dataset>.<bảng> |
| Terraform | google_bigquery_table với policy_tags |
| Bật cưỡng chế | Data Policy phải ở trạng thái enforced |
| Kiểm tra | bq show --schema --format=prettyjson |
| Bức tranh đầy đủ về bảo vệ dữ liệu BigQuery | Lớp |
|---|---|
| IAM ở cấp dataset/bảng | ai vào được |
| IAM Deny policy | ngoại lệ cứng |
| Column-level security | ẩn cột |
| Row-level security | lọc dòng |
| Dynamic data masking | che giá trị |
| Authorized view | chỉ lộ kết quả |
| Sensitive Data Protection | phát hiện PII để biết cột nào cần tag |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Cột nào mang tag gì | bq show --schema --format=prettyjson <bảng> | | Ai đọc được cột nhạy cảm | gcloud data-catalog taxonomies policy-tags get-iam-policy | | Cưỡng chế đã bật chưa | trạng thái Data Policy trong Dataplex |
Và một bước nên làm trước khi gắn tag thủ công cho từng cột: chạy Sensitive Data Protection quét toàn bộ dataset. Nó tìm ra những cột chứa PII mà không ai nhớ tới — số điện thoại lẫn trong trường ghi chú, email trong cột mô tả — và danh sách đó thường dài hơn đáng kể so với những gì đội dữ liệu tự liệt kê được.
You are designing a data pipeline in Dataflow that ingests CSV files. As part of the pipeline, you need to implement a data quality check that verifies that the customer_id field in each row is not null and is a positive integer. Rows that fail this check should be sent to a separate BigQuery "error" table, while valid rows are sent to the main "clean" table.
What is this pattern of separating good and bad data within a pipeline called?
- A Fan-out
- B Side input
- C Dead-letter queue
- D Windowing
Xem giải thích
Đáp án
C — Dead-letter queue (hàng đợi thư chết).
Vì sao đúng
Mẫu thiết kế được mô tả trong đề — tách bản ghi HỎNG ra một đường riêng thay vì để chúng làm chết cả pipeline — được gọi là dead-letter pattern.
⚠ Điểm mấu chốt — chia luồng thành hai nhánh:
Đọc CSV
↓
Kiểm tra customer_id:
khác NULL và là số nguyên dương?
↓
┌──── HỢP LỆ ────→ bảng "clean"
│
└──── KHÔNG HỢP LỆ ──→ bảng "error"
(dead-letter)
↓
⚠ Pipeline KHÔNG DỪNG vì vài dòng hỏng
⚠ Dòng hỏng KHÔNG bị mất
⚠ Trong Apache Beam, cơ chế là TupleTag và output phụ:
HOP_LE = TupleTag('hop_le')
HONG = TupleTag('hong')
class KiemTra(beam.DoFn):
def process(self, dong):
if dong.get('customer_id') and dong['customer_id'] > 0:
yield beam.pvalue.TaggedOutput('hop_le', dong)
else:
yield beam.pvalue.TaggedOutput(
'hong', {'dong': str(dong),
'ly_do': 'customer_id khong hop le'})
↓
⚠ Bản ghi hỏng nên kèm LÝ DO,
dấu thời gian, và nội dung GỐC
⚠ Vì sao mẫu này quan trọng đến vậy:
KHÔNG có dead-letter
↓
Lựa chọn 1: pipeline CHẾT vì một dòng xấu
→ dữ liệu tốt cũng không vào được
Lựa chọn 2: âm thầm BỎ QUA dòng xấu
→ mất dữ liệu, không ai biết
↓
CÓ dead-letter
↓
→ dữ liệu tốt vẫn chảy
→ dữ liệu xấu được GIỮ LẠI để điều tra
→ đếm được, cảnh báo được
Vì sao các phương án khác sai
-
A (fan-out) — đây là phương án gần nhất về mặt "chia thành nhiều nhánh", nhưng fan-out là gửi CÙNG một dữ liệu tới NHIỀU đích; ở đây dữ liệu được phân loại rồi đi hai đường khác nhau.
-
B (side input) — cơ chế của Beam để đưa thêm một tập dữ liệu phụ vào phép biến đổi (bảng tra cứu), không liên quan tới xử lý bản ghi hỏng.
-
D (windowing) — nhóm dữ liệu theo thời gian trong pipeline luồng.
Ghi nhớ
⚠ Các mẫu thiết kế trong pipeline dữ liệu — bảng phải thuộc: | Mẫu | Việc | |---|---| | Dead-letter queue | tách bản ghi HỎNG ra đường riêng | | Fan-out | một nguồn → NHIỀU đích cùng dữ liệu | | Fan-in | nhiều nguồn gộp về một | | Side input | đưa tập dữ liệu phụ vào phép biến đổi | | Windowing | nhóm theo thời gian trong luồng | | Idempotency | xử lý lại không sinh sai lệch |
Từ khoá nhận diện:
"tách dữ liệu tốt và xấu" → dead-letter "cùng dữ liệu tới nhiều hệ thống" → fan-out (Pub/Sub nhiều subscription) "bảng tra cứu nhỏ dùng trong xử lý" → side input "tổng hợp mỗi 5 phút" → windowing "thông điệp thất bại nhiều lần" → dead-letter topic của Pub/Sub
| Dead-letter ở các dịch vụ khác nhau | Dịch vụ |
|---|---|
| Dataflow / Beam | TaggedOutput, output phụ |
| Pub/Sub | dead-letter topic, maxDeliveryAttempts |
bq load |
--max_bad_records + xem lỗi trong job |
| Cloud Tasks | hàng đợi thử lại rồi bỏ |
| Cloud Composer | tác vụ thất bại → cảnh báo |
| Nguyên tắc chung | đừng bao giờ âm thầm nuốt lỗi |
| Bản ghi trong bảng lỗi nên có gì | Trường |
|---|---|
| Nội dung GỐC của dòng | để sửa và nạp lại |
| LÝ DO thất bại | phân loại được |
| Dấu thời gian | biết khi nào xảy ra |
| Tên tệp / offset nguồn | truy về nguồn |
| Phiên bản pipeline | biết logic nào đã loại nó |
| Thiếu lý do | bảng lỗi gần như vô dụng |
| Sau khi có bảng lỗi — làm gì | Việc |
|---|---|
| Cảnh báo khi tỉ lệ lỗi vượt ngưỡng | ví dụ > 1% |
| Phân loại lý do | GROUP BY ly_do để thấy mẫu |
| Báo cho chủ nguồn dữ liệu | sửa từ gốc |
| Nạp lại sau khi sửa | pipeline phải cho phép chạy lại |
| Sai lầm | tạo bảng lỗi rồi không ai bao giờ mở ra xem |
| Đặt ngưỡng thất bại thế nào | Nội dung |
|---|---|
| Vài dòng hỏng | ghi vào dead-letter, tiếp tục |
| Tỉ lệ lỗi vượt ngưỡng | DỪNG hẳn — có thể nguồn đã đổi lược đồ |
| 100% lỗi | gần như chắc chắn lỗi cấu hình |
| Cách làm | đếm trong pipeline, so với tổng |
| Vì sao | một lô toàn rác đi qua im lặng còn tệ hơn một job thất bại |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tỉ lệ lỗi bao nhiêu | SELECT COUNT(*) FROM error_table so với bảng clean | | Lý do nào phổ biến nhất | GROUP BY ly_do ORDER BY COUNT(*) DESC | | Lỗi có tăng đột biến không | cảnh báo dựa trên chỉ số tuỳ chỉnh của Dataflow |
Và điều quyết định một dead-letter queue có ích hay không: có ai thật sự nhìn vào nó hay không. Rất nhiều pipeline có bảng lỗi được ghi đều đặn suốt nhiều tháng mà không ai mở ra, cho tới khi một báo cáo thiếu số liệu — hãy đặt một cảnh báo theo tỉ lệ lỗi ngay khi tạo bảng, chứ không để sau.
A new gaming application is being launched in North America and Europe. To ensure low latency for users on both continents, the team wants to store user profile pictures in a way that serves content quickly from locations close to the users. The solution must also provide high availability by default and be a single solution for all users.
Which combination of Cloud Storage and other Google Cloud services should they choose?
- A A multi-region bucket in the US, such as US
- B A multi-region bucket in Europe, such as EU.
- C A multi-region bucket and Cloud CDN.
- D A dual-region bucket, such as us-central1 and us-east1.
Xem giải thích
Đáp án
C — Một bucket multi-region kết hợp với Cloud CDN.
Vì sao đúng
Đề có ba ràng buộc: người dùng ở CẢ Bắc Mỹ và châu Âu, độ trễ thấp cho cả hai, và MỘT giải pháp duy nhất kèm sẵn sàng cao mặc định. Chỉ phương án kết hợp mới thoả cả ba.
⚠ Điểm mấu chốt — mỗi thành phần giải một phần của bài toán:
MULTI-REGION BUCKET
↓
Dữ liệu nhân bản qua nhiều Region
↓
→ SẴN SÀNG CAO mặc định
→ một bucket duy nhất, một giải pháp
CLOUD CDN
↓
Đệm nội dung ở HÀNG TRĂM ĐIỂM BIÊN
trên toàn thế giới
↓
→ độ trễ thấp cho CẢ HAI châu lục
→ ảnh phục vụ từ điểm gần người dùng nhất
⚠ Vì sao chỉ multi-region là chưa đủ:
Multi-region US
↓
Dữ liệu nhân bản trong nước Mỹ
↓
⚠ Người dùng châu Âu vẫn phải
vượt Đại Tây Dương cho MỖI ảnh
↓
Multi-region không phải CDN:
nó lo ĐỘ BỀN và SẴN SÀNG,
không lo ĐỘ TRỄ toàn cầu
⚠ Vì sao ảnh hồ sơ là trường hợp lý tưởng cho CDN:
Ảnh hồ sơ người dùng
↓
- ĐỌC rất nhiều lần, ghi rất ít
- Nội dung TĨNH, không đổi
- Cùng một ảnh phục vụ nhiều người
↓
→ tỉ lệ trúng cache rất cao
→ giảm cả ĐỘ TRỄ lẫn CHI PHÍ EGRESS
↓
Đặt Cache-Control hợp lý:
Cache-Control: public, max-age=86400
⚠ Cách nối CDN vào bucket:
Global external Application Load Balancer
↓
Backend bucket trỏ tới bucket GCS
↓
Bật Cloud CDN trên backend đó
↓
→ một địa chỉ IP toàn cầu
→ anycast tự chọn điểm gần nhất
Xem thêm câu #12921 (lô 133): cũng hỏi vị trí bucket cho ứng dụng ảnh, nhưng ở đó người dùng CHỈ ở Úc → khoá là một Region cụ thể. Hai khoá khác nhau vì phạm vi người dùng khác nhau — không mâu thuẫn. Quy tắc: một khu vực → region; nhiều châu lục → multi-region + CDN.
Vì sao các phương án khác sai
-
A (multi-region US) và B (multi-region EU) — mỗi phương án chỉ phục vụ tốt MỘT châu lục; bên còn lại chịu độ trễ xuyên đại dương. Đề yêu cầu tốt cho cả hai.
-
D (dual-region us-central1 và us-east1) — cả hai Region đều ở Mỹ, nên không giúp gì cho người dùng châu Âu.
Ghi nhớ
⚠ Chọn vị trí bucket theo phạm vi người dùng — bảng phải thuộc: | Người dùng ở | Chọn | |---|---| | Một khu vực | region cụ thể — rẻ nhất, độ trễ thấp nhất tại chỗ | | Hai Region cụ thể | dual-region | | Một châu lục | multi-region (US, EU, ASIA) | | NHIỀU CHÂU LỤC | multi-region + Cloud CDN | | Ghi nhớ | CDN giải bài toán ĐỘ TRỄ; multi-region giải bài toán SẴN SÀNG |
Từ khoá nhận diện:
"nhiều châu lục, độ trễ thấp, một giải pháp" → multi-region + Cloud CDN "người dùng một nước" → region cụ thể "chịu lỗi Region nhưng vẫn gần người dùng" → dual-region "nội dung động, không cache được" → CDN ít giúp; cân nhắc nhiều Region "dữ liệu phải ở trong nước" → region cụ thể + Organization Policy
| Cloud CDN — điều cần nhớ | Nội dung |
|---|---|
| Đứng sau | global external Application Load Balancer |
| Backend | backend bucket (GCS) hoặc backend service |
| Điều khiển cache | Cache-Control header của đối tượng |
| Cache mode | CACHE_ALL_STATIC, USE_ORIGIN_HEADERS, FORCE_CACHE_ALL |
| Vô hiệu hoá cache | cache invalidation — dùng dè, có giới hạn |
| Signed URL / signed cookie | cho nội dung riêng tư |
| Lợi ích chi phí của CDN | Nội dung |
|---|---|
| Giảm egress từ bucket | phần lớn yêu cầu dừng ở biên |
| Giá egress từ CDN thường rẻ hơn | tuỳ khu vực |
| Giảm số thao tác đọc | class A/B operation |
| Với nội dung đọc nhiều | tiết kiệm đáng kể |
| Theo dõi | cache hit ratio trong Monitoring |
| Đặt cache cho ảnh hồ sơ | Cách |
|---|---|
Cache-Control: public, max-age=86400 |
cache một ngày |
| Tên tệp có phiên bản | avatar-{uuid}.jpg |
| Đổi ảnh → đổi TÊN | không cần invalidate cache |
| Vì sao | invalidation chậm và có giới hạn số lần |
| Ảnh riêng tư | signed URL có hạn |
| Bốn cách giảm độ trễ cho người dùng toàn cầu | Cách |
|---|---|
| Cloud CDN | hiệu quả nhất cho nội dung tĩnh |
| Global Load Balancer | một IP, tự định tuyến tới backend gần nhất |
| Multi-region bucket | dữ liệu gốc gần hơn |
| Ảnh nhiều kích thước, định dạng hiện đại | giảm byte phải truyền |
| Kết hợp | ba cái đầu thường đi cùng nhau |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tỉ lệ trúng cache | Monitoring → chỉ số của Cloud CDN | | Ảnh có được cache không | xem header Age và Cache-Control trong phản hồi | | Độ trễ thực tế | đo từ máy khách ở cả hai châu lục |
Và một quy ước rất đáng áp dụng ngay từ đầu với nội dung phục vụ qua CDN: đặt tên tệp có phiên bản và đừng bao giờ ghi đè. Khi người dùng đổi ảnh đại diện, tải lên một tên mới thay vì ghi đè tên cũ — cách đó cho phép đặt thời gian cache rất dài mà vẫn cập nhật tức thì, và tránh hoàn toàn việc phải dùng cơ chế vô hiệu hoá cache vốn chậm và bị giới hạn.
You are writing a complex SQL query in BigQuery to analyze customer lifetime value. The query involves several subqueries and temporary tables created using WITH clauses. To ensure the query is logically correct, you want to see the results of an intermediate WITH clause before you run the full, expensive query.
What should you do?
- A Use the ML.PREDICT function to sample the intermediate results.
- B You cannot view the results of an intermediate CTE; you must run the full query.
- C Comment out the final SELECT statement and replace it with SELECT * FROM intermediate_table;.
- D Run the entire query and then filter the final results.
Xem giải thích
Đáp án
C — Tạm khoá câu SELECT cuối và thay bằng SELECT * FROM bang_trung_gian;
Vì sao đúng
Mệnh đề WITH (CTE — common table expression) tạo ra các tập kết quả có tên, và bạn hoàn toàn truy vấn được trực tiếp bất kỳ CTE nào bằng cách đổi câu SELECT cuối cùng.
⚠ Điểm mấu chốt — CTE có tên nên gọi thẳng được:
WITH
don_hang_loc AS (
SELECT * FROM `du_an.don_hang` WHERE nam = 2026
),
tong_theo_khach AS (
SELECT khach_id, SUM(tien) AS tong
FROM don_hang_loc GROUP BY khach_id
)
-- SELECT ... phần tính toán phức tạp và tốn kém
SELECT * FROM tong_theo_khach LIMIT 100;
↓
⚠ Chỉ đổi DÒNG CUỐI
→ thấy ngay kết quả của bước giữa
→ phần sau chưa chạy, chưa tốn tiền
⚠ Vì sao cách này còn RẺ HƠN:
BigQuery chỉ tính tiền cho
dữ liệu THỰC SỰ QUÉT
↓
Dừng ở CTE trung gian
↓
→ các bước sau KHÔNG chạy
→ JOIN nặng phía sau KHÔNG chạy
↓
⚠ Thêm LIMIT không giảm byte quét,
nhưng CẮT BỚT CÁC BƯỚC thì có
⚠ Hai cách khác cũng rất hữu ích:
1. --dry_run
bq query --dry_run --use_legacy_sql=false '...'
→ biết TRƯỚC sẽ quét bao nhiêu byte,
KHÔNG tốn tiền
2. Bảng tạm hoặc materialize từng bước
CREATE TEMP TABLE buoc_1 AS (...);
SELECT * FROM buoc_1;
→ giữ kết quả để dùng lại nhiều lần
Vì sao các phương án khác sai
-
B (không xem được CTE trung gian, phải chạy cả truy vấn) — đây là phương án dễ tin nhất nếu chưa thử, nhưng sai: CTE có tên và truy vấn thẳng được.
-
D (chạy cả truy vấn rồi lọc kết quả cuối) — tốn đúng cái mà đề muốn tránh: chạy hết truy vấn đắt tiền.
-
A (dùng
ML.PREDICTđể lấy mẫu) —ML.PREDICTlà hàm dự đoán của BigQuery ML, không liên quan gì tới việc xem kết quả trung gian.
Ghi nhớ
⚠ Gỡ lỗi truy vấn phức tạp — bảng phải thuộc: | Cách | Việc | |---|---| | Đổi SELECT cuối thành SELECT * FROM <cte> | xem kết quả bước giữa | | --dry_run | biết trước số byte quét, MIỄN PHÍ | | CREATE TEMP TABLE | giữ kết quả bước giữa để dùng lại | | maximum_bytes_billed | trần an toàn | | Execution details | xem bước nào tốn nhất | | Query validator trong UI | ước tính byte ngay khi gõ |
Từ khoá nhận diện:
"xem kết quả CTE trung gian" → đổi
SELECTcuối "biết trước truy vấn tốn bao nhiêu" →--dry_run"đặt trần chi phí" →maximum_bytes_billed"bước nào chậm" → Execution details "lưu kết quả trung gian để dùng lại" →CREATE TEMP TABLE
WITH (CTE) — điều cần nhớ |
Nội dung |
|---|---|
| Đặt tên cho tập kết quả trung gian | dễ đọc hơn subquery lồng |
| Có thể tham chiếu CTE trước đó | xây dựng theo tầng |
| ⚠ KHÔNG được vật chất hoá | dùng nhiều lần → tính lại nhiều lần |
| Khắc phục | CREATE TEMP TABLE khi dùng lại nhiều lần |
WITH RECURSIVE |
BigQuery có hỗ trợ đệ quy |
| Không tồn tại sau truy vấn | khác view |
| Bốn cách giữ kết quả trung gian | Cách |
|---|---|
CTE (WITH) |
tạm, tính lại mỗi lần dùng |
CREATE TEMP TABLE |
tồn tại trong PHIÊN, tính một lần |
| Bảng thường | tồn tại lâu dài |
| View | logic lưu lại, dữ liệu tính lại mỗi lần |
| Materialized view | tự làm mới, BigQuery tự dùng khi có lợi |
| Kiểm soát chi phí khi phát triển truy vấn | Cách |
|---|---|
Luôn --dry_run trước |
trên bảng lớn |
| Phát triển trên bảng mẫu | TABLESAMPLE SYSTEM (1 PERCENT) |
| Lọc theo phân vùng ngay từ đầu | |
| Chọn cột tường minh | tránh SELECT * |
maximum_bytes_billed |
đặt mặc định cho cả project nếu được |
| Preview | xem dữ liệu miễn phí |
| Đọc Execution details | Trường |
|---|---|
| Slot time consumed | tổng công tính toán |
| Bytes shuffled | JOIN lớn hay không |
| Records read / written theo bước | bước nào phình dữ liệu |
| Skew | một worker làm lâu hơn hẳn → dữ liệu lệch |
| Dùng để | tìm bước nào cần tối ưu |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bước giữa cho ra gì | đổi SELECT cuối rồi chạy | | Truy vấn sẽ tốn bao nhiêu | --dry_run | | Bước nào chậm nhất | Execution details |
Và một thói quen tiết kiệm rất nhiều tiền khi làm việc với bảng lớn: --dry_run trước mỗi truy vấn mới. Nó không tốn gì, trả lời trong một giây, và cho biết chính xác truy vấn sắp chạy sẽ quét bao nhiêu byte — đủ để bạn kịp nhận ra một điều kiện lọc bị viết sai trước khi nó quét vài chục terabyte.
You have a BigQuery table with a customer_id column. You need to grant a service account permission to query this table, but you must ensure that the service account can only see rows belonging to a specific set of customer_id values that it is responsible for.
What BigQuery security feature should you use to enforce this?
- A Authorized Datasets
- B Authorized Views
- C Row-level security
- D Column-level security
Xem giải thích
Đáp án
C — Row-level security (bảo mật ở cấp DÒNG).
Vì sao đúng
Yêu cầu là service account chỉ nhìn thấy các DÒNG có customer_id thuộc phạm vi được giao. Đó chính là định nghĩa của row-level security.
⚠ Điểm mấu chốt — bộ lọc gắn vào chính BẢNG:
CREATE ROW ACCESS POLICY loc_theo_khach
ON `du_an.giao_dich`
GRANT TO ('serviceAccount:sa-a@du-an.iam.gserviceaccount.com')
FILTER USING (customer_id IN ('KH001','KH002','KH003'));
↓
Service account chạy:
SELECT * FROM giao_dich
↓
⚠ BigQuery TỰ THÊM điều kiện lọc
→ chỉ trả về ba khách hàng đó
→ dòng khác coi như KHÔNG TỒN TẠI
↓
⚠ Kể cả COUNT(*) cũng chỉ đếm
phần được phép thấy
⚠ Cách viết bộ lọc động theo người truy cập:
CREATE ROW ACCESS POLICY loc_theo_nguoi_dung
ON `du_an.giao_dich`
GRANT TO ('group:doi-ban-hang@congty.com')
FILTER USING (
nguoi_phu_trach = SESSION_USER()
);
↓
SESSION_USER() trả về danh tính
của người đang chạy truy vấn
↓
→ MỘT chính sách phục vụ CẢ ĐỘI
→ mỗi người tự thấy phần của mình
↓
Hoặc JOIN với bảng ánh xạ
người dùng ↔ khách hàng
⚠ Ba cơ chế bảo mật chi tiết của BigQuery — phân biệt dứt điểm:
ROW-LEVEL SECURITY
→ lọc DÒNG ← đề này
COLUMN-LEVEL SECURITY (policy tag)
→ ẩn CỘT
DYNAMIC DATA MASKING
→ che GIÁ TRỊ của cột
↓
Dùng được ĐỒNG THỜI cả ba
Xem thêm câu #12961, #12963 và #12965 (cùng lô): cùng họ kiểm soát truy cập — chặn một BẢNG → deny policy; chia sẻ kết quả → authorized view; ẩn một CỘT → policy tag. Bốn khoá khác nhau theo phạm vi cần chặn — hoàn toàn nhất quán.
Vì sao các phương án khác sai
-
B (Authorized View) — đây là phương án gần nhất và cũng lọc dòng được bằng
WHEREtrong view, nhưng phải tạo và bảo trì MỘT VIEW cho MỖI nhóm quyền. Với nhiều service account phụ trách các tập khách hàng khác nhau, cách đó không mở rộng nổi. -
D (Column-level security) — ẩn CỘT, không lọc dòng.
-
A (Authorized Datasets) — cơ chế uỷ quyền cả một dataset truy cập dataset khác; không phải cơ chế lọc dòng.
Ghi nhớ
⚠ Ba cơ chế bảo mật chi tiết của BigQuery — bảng phải thuộc: | Cơ chế | Ẩn gì | Cấu hình bằng | |---|---|---| | Row-level security | DÒNG | CREATE ROW ACCESS POLICY | | Column-level security | CỘT | policy tag trong lược đồ | | Dynamic data masking | GIÁ TRỊ của cột | data policy trên policy tag | | Dùng chung được | có, cả ba cùng lúc |
Từ khoá nhận diện:
"chỉ thấy dòng của mình / của khách hàng được giao" → row-level security "ẩn cột lương" → column-level security "vẫn truy vấn được nhưng giá trị bị che" → dynamic data masking "chia sẻ kết quả, giấu bảng gốc" → authorized view "tất cả trừ một bảng" → IAM Deny policy
| Row access policy — điều cần nhớ | Nội dung |
|---|---|
| Nhiều chính sách trên một bảng | kết quả là HỢP (OR) của các bộ lọc |
| Không có chính sách nào áp dụng | → không thấy dòng nào |
GRANT TO |
user, group, service account, hoặc allAuthenticatedUsers |
FILTER USING |
biểu thức boolean |
SESSION_USER() |
danh tính người đang chạy truy vấn |
| Xem chính sách | SELECT * FROM <dataset>.INFORMATION_SCHEMA.ROW_ACCESS_POLICIES |
| Điều dễ gây bất ngờ | Nội dung |
|---|---|
COUNT(*) cũng bị lọc |
con số khác nhau tuỳ người chạy |
Người có bigquery.admin |
vẫn bị áp chính sách trừ khi được cấp riêng |
bq extract cũng bị lọc |
tốt cho bảo mật |
| Kết quả JOIN | dòng bị lọc không tham gia |
| Hiệu năng | bộ lọc phức tạp làm truy vấn chậm hơn |
| Thiết kế bộ lọc cho dễ bảo trì | Cách |
|---|---|
| BẢNG ÁNH XẠ người dùng ↔ phạm vi | thay vì liệt kê cứng trong chính sách |
| Bộ lọc | customer_id IN (SELECT customer_id FROM anh_xa WHERE nguoi = SESSION_USER()) |
| Ưu điểm | thêm người chỉ cần thêm dòng, không sửa chính sách |
| Nhược điểm | thêm một phép join vào mọi truy vấn |
| Với service account | liệt kê cứng cũng chấp nhận được nếu ít và ổn định |
| Khi nào row-level security KHÔNG đủ | Trường hợp |
|---|---|
| Cần ẩn cả sự tồn tại của bảng | → quyền ở cấp dataset |
| Cần chia sẻ ra ngoài tổ chức | → authorized view / Analytics Hub |
| Logic phân quyền rất phức tạp | → cân nhắc bảng riêng cho từng nhóm |
| Cần audit chi tiết ai xem gì | → Data Access log |
| Kết hợp | thường dùng cùng column-level security |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bảng có chính sách nào | INFORMATION_SCHEMA.ROW_ACCESS_POLICIES | | Service account thấy bao nhiêu dòng | chạy COUNT(*) dưới danh nghĩa tài khoản đó | | Có ai lách được không | Policy Analyzer và Data Access log |
Và một điều cần dặn trước với đội phân tích khi bật row-level security: cùng một truy vấn sẽ cho ra những con số khác nhau tuỳ người chạy. Đó là hành vi đúng và mong muốn, nhưng nếu không nói rõ, hai người so kết quả với nhau sẽ kết luận rằng dữ liệu bị lỗi — và đi tìm một vấn đề không hề tồn tại.
A company needs a tool to manage a complex daily workflow that involves a Dataproc job, a BigQuery query, and a cleanup task, ensuring each step runs only after the previous one succeeds.
What category of tool is required to automate this process?
- A A data storage service
- B A data processing engine
- C An orchestration tool
- D A business intelligence platform
Xem giải thích
Đáp án
C — Một công cụ ĐIỀU PHỐI (orchestration tool).
Vì sao đúng
Đề mô tả nhiều bước qua nhiều dịch vụ khác nhau, với ràng buộc bước sau chỉ chạy khi bước trước THÀNH CÔNG. Quản lý thứ tự và phụ thuộc giữa các bước chính là định nghĩa của điều phối.
⚠ Điểm mấu chốt — điều phối ↔ xử lý, hai việc khác nhau:
CÔNG CỤ XỬ LÝ (processing engine)
↓
BIẾN ĐỔI dữ liệu
→ Dataproc, Dataflow, BigQuery
→ "làm việc"
CÔNG CỤ ĐIỀU PHỐI (orchestration)
↓
QUYẾT ĐỊNH việc nào chạy, khi nào,
theo thứ tự nào, hỏng thì làm gì
→ Cloud Composer, Workflows
→ "chỉ huy"
↓
⚠ Điều phối KHÔNG tự xử lý dữ liệu
⚠ Ba đặc điểm bắt buộc phải có điều phối:
1. NHIỀU bước qua NHIỀU dịch vụ
2. PHỤ THUỘC: A xong mới tới B
3. Cần THỬ LẠI, theo dõi, cảnh báo
↓
Có đủ ba → cần orchestration tool
⚠ Trên Google Cloud, "công cụ điều phối" là những gì:
CLOUD COMPOSER (Apache Airflow)
→ DAG phức tạp, nhiều phụ thuộc,
backfill, hàng trăm operator
WORKFLOWS
→ luồng nhẹ, khai bằng YAML,
trả tiền theo bước
CLOUD SCHEDULER
→ chỉ kích hoạt theo giờ,
KHÔNG quản lý phụ thuộc
DATAFORM
→ điều phối các bước SQL
trong BigQuery
Xem thêm câu #12948 (cùng lô): mô tả gần như cùng một tình huống nhưng hỏi DỊCH VỤ NÀO → khoá là Cloud Composer. Câu này hỏi LOẠI công cụ → orchestration. Hai khoá khác nhau vì mức độ câu hỏi khác nhau, hoàn toàn nhất quán.
Vì sao các phương án khác sai
-
B (công cụ xử lý dữ liệu) — đây là phương án gần nhất vì luồng có chứa job Dataproc và truy vấn BigQuery, nhưng đó là các bước BÊN TRONG luồng. Thứ cần thêm là công cụ quản lý thứ tự và phụ thuộc giữa chúng.
-
A (dịch vụ lưu trữ dữ liệu) — nơi chứa dữ liệu, không điều khiển luồng công việc.
-
D (nền tảng BI) — trực quan hoá và báo cáo, ở cuối chuỗi chứ không điều phối.
Ghi nhớ
⚠ Bốn phạm trù công cụ dữ liệu — bảng phải thuộc: | Phạm trù | Việc | Ví dụ | |---|---|---| | Lưu trữ | chứa dữ liệu | Cloud Storage, BigQuery, Cloud SQL | | Xử lý | biến đổi dữ liệu | Dataflow, Dataproc, Data Fusion | | Điều phối | quản lý thứ tự và phụ thuộc | Cloud Composer, Workflows | | BI / trực quan hoá | hiển thị cho người dùng | Looker, Looker Studio | | Một pipeline hoàn chỉnh | thường có cả bốn |
Từ khoá nhận diện:
"bước sau chạy khi bước trước thành công" → điều phối "biến đổi, tổng hợp dữ liệu" → xử lý "nơi chứa" → lưu trữ "biểu đồ, dashboard" → BI "chạy đúng giờ, một việc" → lập lịch — nhẹ hơn điều phối
| Điều phối ↔ lập lịch — phân biệt | Nội dung |
|---|---|
| Lập lịch (scheduling) | kích hoạt MỘT việc theo thời gian |
| Điều phối (orchestration) | quản lý NHIỀU việc và quan hệ giữa chúng |
| Cloud Scheduler | lập lịch |
| Cloud Composer | điều phối |
| Thường kết hợp | Scheduler kích hoạt một Workflow hoặc DAG |
| Một công cụ điều phối tốt cần gì | Tính năng |
|---|---|
| Khai phụ thuộc (DAG) | rẽ nhánh, chạy song song |
| Thử lại có backoff | theo từng tác vụ |
| Theo dõi trạng thái | giao diện xem bước nào hỏng |
| Chạy lại quá khứ (backfill) | |
| Cảnh báo và SLA | |
| Truyền dữ liệu giữa các bước | XCom trong Airflow |
| Tích hợp sẵn | operator cho nhiều dịch vụ |
| Chọn công cụ điều phối trên GCP | Chọn |
|---|---|
| Phụ thuộc phức tạp, nhiều đội dùng | Cloud Composer |
| Luồng nhẹ, ít bước | Workflows — rẻ hơn nhiều |
| Chỉ toàn bước SQL trong BigQuery | Dataform |
| Chỉ trong Dataproc | Dataproc Workflow Template |
| Một việc theo giờ | Cloud Scheduler |
| Nguyên tắc thiết kế luồng điều phối | Nguyên tắc |
|---|---|
| Mỗi tác vụ làm MỘT việc | dễ chạy lại đúng chỗ hỏng |
| Tác vụ BẤT BIẾN | chạy lại an toàn |
| Không xử lý dữ liệu trong bộ điều phối | giao cho engine |
| Tham số hoá theo ngày chạy | backfill được |
| Cảnh báo khi luồng chậm, không chỉ khi hỏng |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bước nào hỏng | giao diện của công cụ điều phối | | Luồng có chậm dần không | so thời lượng theo ngày | | Có bước nào chạy trùng không | kiểm tra khoá chống chạy chồng |
Và một ranh giới đáng giữ nghiêm khi thiết kế: bộ điều phối ra lệnh, engine làm việc. Khi một tác vụ Airflow bắt đầu tự đọc và biến đổi vài triệu dòng dữ liệu, đó là dấu hiệu ranh giới đã bị vượt — và hệ quả thường là môi trường điều phối trở thành nút thắt cho toàn bộ hệ thống dữ liệu.