0

Google BigQuery - Bài học 5: Cấu trúc phân cấp tài nguyên – Quản lý Organization, Project, Dataset, Table và View chuẩn doanh nghiệp

Chào anh em! Qua 4 bài học đầu tiên, chúng ta đã "mổ bụng" toàn bộ phần lõi kỹ thuật đáng sợ nhất của Google BigQuery: từ Colossus, Capacitor cho đến Dremel, Jupiter và Borg. Giờ là lúc chúng ta bước từ phòng thí nghiệm của Google ra chiến trường thực tế của doanh nghiệp!

Khi anh em dựng một con MySQL hay PostgreSQL ở local hoặc trên VPS, mọi thứ rất đơn giản: Cài Database Server →\rightarrow Gõ CREATE DATABASE ecommerce; →\rightarrow Gõ CREATE TABLE orders;. Xong!

Nhưng khi bước lên Google BigQuery ở quy mô công ty (có nhiều phòng ban như Logistics, Kho vận, Marketing, Kế toán; có nhiều môi trường Dev, Staging, Prod), nếu bạn cứ hồn nhiên gom tất cả bảng vào chung một chỗ, chỉ sau 6 tháng hệ thống của bạn sẽ biến thành một "Đầm lầy dữ liệu" (Data Swamp):

  • Bảng orders_temp_v2_final nằm cạnh bảng orders_prod.

  • Nhân viên thực tập chạy một câu lệnh SELECT quét nhầm bảng 50 TB làm bay màu ngân sách của cả phòng IT nhưng không biết quy trách nhiệm cho bộ phận nào.

  • Bạn muốn cho đội Kế toán xem bảng doanh thu nhưng lại lỡ tay cấp quyền cho họ thấy luôn cả bảng thông tin cá nhân (SĐT, Địa chỉ) của khách hàng.

Để không bao giờ rơi vào cảnh hỗn loạn đó, bài học hôm nay sẽ giúp anh em nắm vững Cấu trúc phân cấp tài nguyên (Resource Hierarchy) của BigQuery và cách thiết kế kiến trúc Data Mesh / Multi-Project chuẩn chỉnh nhất!

1. Bức tranh toàn cảnh: Hệ thống phân cấp trên Google Cloud & BigQuery

Trong MySQL, địa chỉ của một bảng có 2 cấp: database_name.table_name.

Còn trong BigQuery, mọi bảng hoặc View đều được định danh duy nhất trên toàn cầu bởi 3 cấp độ được viết cách nhau bằng dấu chấm:

SQL

SELECT * FROM `project_id.dataset_name.table_name`;

Nếu nhìn rộng ra toàn bộ hệ sinh thái Google Cloud Platform (GCP) của một doanh nghiệp, cấu trúc phân cấp từ đỉnh xuống đáy sẽ trông như thế này:

Plaintext

[ Organization ] (Ví dụ: congtycuaanh-em.vn)
       |
       +--- [ Folder: Môi trường Production ]
       |         |
       |         +--- [ Project 1: Storage / Data Warehouse (Lưu trữ dữ liệu) ]
       |         |         |
       |         |         +--- [ Dataset: raw_ecommerce (Vùng Tokyo - asia-northeast1) ]
       |         |         |         +--- Table: orders
       |         |         |         +--- Table: users
       |         |         |
       |         |         +--- [ Dataset: mart_finance (Vùng Singapore - asia-southeast1) ]
       |         |                   +--- View: v_daily_revenue
       |         |                   +--- Materialized View: mv_monthly_kpi
       |         |
       |         +--- [ Project 2: Compute - Team Marketing (Chỉ dùng để chạy Query) ]
       |         +--- [ Project 3: Compute - Team Logistics (Chỉ dùng để chạy Query) ]
       |
       +--- [ Folder: Môi trường Staging / Dev ]

Hãy cùng đi sâu vào vai trò thực sự của từng tầng để hiểu tại sao Google lại chia như vậy!

2. Giải phẫu từng tầng: Project và Dataset khác gì Database truyền thống?

2.1. Organization & Folders (Tầng Quản trị Doanh nghiệp)

  • Organization: Đại diện cho toàn bộ công ty của bạn (gắn liền với tên miền Google Workspace hoặc Cloud Identity).

  • Folders: Giống như các thư mục con để gom nhóm các phòng ban (Khối E-commerce, Khối Chuỗi cửa hàng) hoặc gom theo môi trường (Prod, Dev). Mọi chính sách bảo mật (IAM Policy) áp đặt ở tầng Folder sẽ tự động chảy (kế thừa) xuống toàn bộ các Project bên dưới.

2.2. Project – Ranh giới của Tiền bạc (Billing) và Tài nguyên tính toán (Compute)

Rất nhiều anh em mới làm quen với GCP lầm tưởng rằng: "Một công ty chỉ cần tạo 1 Project duy nhất là đủ". Đây là sai lầm chí mạng!

Trong BigQuery, Project chính là nơi gắn thẻ tín dụng (Billing Account) và cấp phát CPU (Slots).

Vì BigQuery tách rời hoàn toàn Storage và Compute (như chúng ta đã học ở Bài 2), nên một kiến trúc sư dữ liệu giỏi sẽ tách Project Lưu trữ và Project Tính toán ra riêng biệt:

  • Data/Storage Project (Ví dụ: company-data-warehouse): Chỉ dùng để chứa dữ liệu (Datasets & Tables). Hoá đơn của Project này 100% là tiền ổ cứng Colossus (Storage cost).

  • Compute/Query Projects (Ví dụ: bq-compute-marketing, bq-compute-logistics): Các Project này không chứa bất kỳ bảng dữ liệu nào cả! Nhân sự đội Marketing sẽ đăng nhập vào Project bq-compute-marketing để viết câu lệnh SELECT chọc sang bảng nằm ở Project company-data-warehouse:

    SQL

    -- Chạy từ Project [bq-compute-marketing], nhưng đọc dữ liệu của [company-data-warehouse]
    SELECT campaign_id, SUM(revenue) 
    FROM `company-data-warehouse.mart_marketing.orders`
    GROUP BY campaign_id;
    
    
  • Điểm ăn tiền: Khi câu lệnh này chạy, tiền quét dữ liệu (Query Cost) và giới hạn Quota sẽ tính vào ví của Project bq-compute-marketing! Cuối tháng, sếp hỏi phòng nào xài tốn tiền Cloud nhất, bạn chỉ cần mở Billing của từng Project ra là rõ trắng đen, không ai đổ lỗi cho ai được!

2.3. Dataset – Ranh giới của Vị trí địa lý (Location) và Phân quyền (Access Control)

Nếu Project quản lý tiền bạc, thì Dataset tương đương với khái niệm Database hoặc Schema trong MySQL/PostgreSQL. Nó là chiếc hộp dùng để chứa các Tables, Views, Routines (Stored Procedures/UDFs) và ML Models.

Có 2 quy tắc sống còn về Dataset mà bạn bắt buộc phải nhớ:

  1. Dataset quyết định Vị trí địa lý vật lý (Geographic Location) của dữ liệu:

    Khi tạo một Dataset, bạn phải chọn nơi lưu trữ (ví dụ: Multi-region như US, EU hoặc Region cụ thể như asia-southeast1 - Singapore). Một khi đã tạo Dataset, bạn KHÔNG THỂ đổi Location của nó!

  2. Luật bất thành văn về JOIN khác vùng (Cross-region JOIN):

    Bạn không thể viết một câu lệnh SQL JOIN trực tiếp một bảng nằm ở Dataset vùng US với một bảng nằm ở Dataset vùng asia-southeast1 (Singapore). Tại sao? Vì mạng lưới Jupiter siêu tốc chỉ nằm trong nội bộ cụm Data Center của vùng đó. Kéo hàng Terabyte dữ liệu xuyên Thái Bình Dương qua cáp quang biển để JOIN sẽ phá vỡ hoàn toàn cam kết tốc độ của Dremel! Do đó, hãy thống nhất chọn 1 Region duy nhất (ví dụ asia-southeast1 cho khu vực Đông Nam Á) cho toàn bộ các Dataset cần liên kết với nhau.

3. Thế giới của Bảng (Tables) và Khung nhìn (Views) trong BigQuery

Bên trong một Dataset, không phải cái bảng nào cũng giống nhau. BigQuery cung cấp cho bạn 5 loại đối tượng dữ liệu cực kỳ linh hoạt:

Loại đối tượng Nơi lưu trữ thực tế Chi phí Lưu trữ (Storage) Đặc điểm & Khi nào nên sử dụng?
1. Standard (Native) Table Trong Colossus (chuẩn Capacitor) Có tính phí ($0.02/GB) Bảng tiêu chuẩn của BigQuery. Tốc độ nhanh nhất, hỗ trợ đầy đủ Partitioning, Clustering, Time Travel.
2. External Table (Bảng ngoài) Nằm ở Google Cloud Storage (GCS), S3, Google Drive, hoặc Bigtable Không tốn phí lưu trữ của BigQuery (Tính phí bên GCS/S3) BigQuery chỉ lưu cấu trúc (Schema) và trỏ thẳng xuống đọc file Parquet/CSV/ORC trên GCS khi bạn chạy query. Tốc độ chậm hơn Native Table nhưng cực tiện để đọc Raw Data hoặc Data Lake (BigLake).
3. Logical View (View thường) Không lưu dữ liệu (Chỉ lưu câu lệnh SQL) 0 đồng (Miễn phí) Là một bảng ảo. Mỗi lần bạn SELECT từ View, BigQuery sẽ chạy lại câu lệnh SQL gốc bên dưới. Dùng để ẩn giấu logic JOIN phức tạp hoặc che giấu cột nhạy cảm.
4. Materialized View Trong Colossus (Lưu kết quả đã tính toán sẵn) Có tính phí (nhưng rất nhỏ) Tự động tính toán trước các hàm SUM, COUNT, GROUP BY và tự động cập nhật ngầm khi bảng gốc có dữ liệu mới. Giúp tăng tốc Dashboard lên gấp hàng chục lần!
5. Table Snapshot / Clone Trong Colossus (Cơ chế Zero-copy) Miễn phí cho phần dữ liệu không đổi Dùng để backup bảng hoặc tạo môi trường test. Chỉ tính phí cho những byte dữ liệu bị thay đổi (Delta) so với bảng gốc.

4. Thiết kế Kiến trúc Medallion (Bronze - Silver - Gold) trên BigQuery

Bây giờ, giả sử bạn được giao nhiệm vụ thiết kế kho dữ liệu BigQuery cho một hệ thống E-commerce & Giao vận lớn. Bạn sẽ chia các Datasets và đặt tên Tables như thế nào cho chuẩn Best Practices thế giới?

Câu trả lời được hơn 90% các đội ngũ Data Engineering hiện đại áp dụng chính là Kiến trúc Medallion (3 tầng dữ liệu) kết hợp với quy ước đặt tên theo tiền tố:

Plaintext

[Hệ thống Backend: MySQL / PostgreSQL / Kafka / Logs]
                         |
                         v (Đẩy thô qua CDC / Debezium / Streaming)
+-----------------------------------------------------------------------+
| 1. TẦNG ĐỒNG (BRONZE) - Dataset: `raw_ecommerce`, `raw_logistics`     |
|    - Giữ nguyên bản 100% dữ liệu từ nguồn đẩy sang (kể cả dữ liệu trùng|
|      hoặc JSON thô). Không sửa xóa để luôn có thể chạy lại (Replay).   |
|    - Ví dụ bảng: `raw_ecommerce.orders_cdc_log`                       |
+-----------------------------------------------------------------------+
                         |
                         v (Làm sạch, khử trùng lặp bằng ROW_NUMBER/MERGE)
+-----------------------------------------------------------------------+
| 2. TẦNG BẠC (SILVER) - Dataset: `core_dwh` hoặc `staging`             |
|    - Dữ liệu đã được làm sạch (Cleaned), chuẩn hóa kiểu dữ liệu,      |
|      chuyển múi giờ chuẩn, khử trùng lặp (Deduplicated).              |
|    - Ví dụ bảng: `core_dwh.dim_users`, `core_dwh.fact_orders`         |
+-----------------------------------------------------------------------+
                         |
                         v (Tổng hợp theo nghiệp vụ cho từng phòng ban)
+-----------------------------------------------------------------------+
| 3. TẦNG VÀNG (GOLD) - Dataset: `mart_finance`, `mart_operations`      |
|    - Dữ liệu đã được gom nhóm sẵn (Aggregated), chứa các bảng báo cáo |
|      hoặc Materialized Views phục vụ trực tiếp cho Looker/PowerBI.    |
|    - Ví dụ bảng: `mart_operations.daily_warehouse_sla`                |
+-----------------------------------------------------------------------+

Tại sao cách chia Dataset theo 3 tầng này lại "vô đối"?

  1. Phân quyền bảo mật (Security) cực dễ: Bạn khóa chặt Dataset raw_* và core_dwh (chỉ có tài khoản Service Account của hệ thống ETL và Data Engineer mới được đụng vào). Với đội Kế toán, bạn chỉ cấp quyền đọc (BigQuery Data Viewer) đúng vào cái hộp Dataset mart_finance. Họ hoàn toàn không nhìn thấy và không thể chọc ngoáy vào dữ liệu gốc của hệ thống!

  2. Thiết lập thời gian tự hủy dữ liệu (Default Table Expiration): Ở các Dataset nháp như dev_sandbox hoặc staging_temp, bạn có thể cấu hình thuộc tính Default Table Expiration = 7 days ngay ở cấp độ Dataset. Bất kỳ anh em dev nào tạo bảng nháp trong đó để test, sau 7 ngày BigQuery sẽ tự động xóa sạch mà bạn không cần viết một dòng cronjob dọn rác nào!

5. Tuyệt chiêu "Authorized Views": Cho xem báo cáo mà không cần cấp quyền đọc bảng gốc!

Đây là một tình huống thực tế mà chắc chắn anh em sẽ gặp:

  • Bạn có bảng gốc core_dwh.fact_orders chứa đầy đủ thông tin đơn hàng của toàn quốc (bao gồm cả số điện thoại khách hàng và giá vốn nhập hàng).

  • Đội vận hành khu vực TP.HCM cần xem danh sách đơn hàng của riêng TP.HCM để điều phối giao hàng, nhưng theo quy định bảo mật, họ tuyệt đối không được phép xem đơn hàng của Hà Nội và không được thấy cột giá vốn.

Nếu trong MySQL hoặc các hệ thống cũ, nếu bạn tạo một cái View lọc dữ liệu TP.HCM nhưng không cấp quyền SELECT trên bảng gốc fact_orders, người dùng truy vấn vào View sẽ bị báo lỗi Access Denied ngay lập tức. Mà nếu cấp quyền SELECT trên bảng gốc, họ lại tự gõ câu lệnh SELECT * FROM fact_orders để xem trộm dữ liệu Hà Nội!

Trên BigQuery, Google giải quyết bài toán này cực đẹp bằng tính năng Authorized Views (hoặc Authorized Datasets):

  1. Bạn tạo bảng gốc fact_orders nằm ở Dataset core_dwh (Khóa kín, không cho đội vận hành quyền truy cập vào Dataset này).

  2. Bạn tạo một cái View v_hcm_orders nằm ở một Dataset khác tên là mart_hcm_ops:

    SQL

    CREATE VIEW `my-project.mart_hcm_ops.v_hcm_orders` AS
    SELECT order_id, created_at, shipping_address, status
    FROM `my-project.core_dwh.fact_orders`
    WHERE city = 'Ho Chi Minh'; -- Không lấy cột giá vốn, chỉ lọc TP.HCM
    
    
  3. Bạn cấp quyền cho đội vận hành TP.HCM chỉ được đọc Dataset mart_hcm_ops.

  4. Cuối cùng, bạn vào cài đặt của Dataset core_dwh và ủy quyền (Authorize) cho cái View v_hcm_orders được phép đọc dữ liệu của mình.

Kết quả: Nhân viên vận hành chạy SELECT * FROM mart_hcm_ops.v_hcm_orders mượt mà, nhưng nếu họ cố tình gõ SELECT * FROM core_dwh.fact_orders, BigQuery sẽ chặn đứng ngay lập tức với lỗi 403 Access Denied!

Tổng kết Bài học 5

Một hệ thống dữ liệu mạnh mẽ bắt đầu từ một khung xương tổ chức ngăn nắp. Trước khi viết dòng code đầu tiên đổ dữ liệu vào BigQuery, hãy luôn nhớ 4 nguyên tắc vàng:

  1. Tách biệt Storage Project và Compute Project nếu công ty bạn có nhiều phòng ban cùng truy vấn dữ liệu để quản lý chi phí (Chargeback) và Quota minh bạch.

  2. Chọn đúng Region cho Dataset ngay từ đầu (ví dụ asia-southeast1) vì dữ liệu khác Region không thể JOIN trực tiếp với nhau.

  3. Tổ chức Datasets theo mô hình 3 tầng (Raw/Bronze →\rightarrow Core/Silver →\rightarrow Mart/Gold) và bật tính năng tự động xóa bảng (Expiration) cho các Dataset môi trường Dev/Test.

  4. Sử dụng Authorized Views ở tầng Mart để chia sẻ dữ liệu an toàn mà không bao giờ phải mở quyền truy cập trực tiếp vào bảng gốc.

Khi đã quy hoạch xong "đất đai và sổ đỏ" (Projects & Datasets), câu hỏi tiếp theo khiến mọi ông chủ doanh nghiệp và Tech Lead phải đau đầu là: Google tính tiền BigQuery như thế nào? Khi nào nên trả tiền theo từng câu lệnh (On-Demand), và khi nào nên thuê bao trọn gói CPU (Editions/Slots) để không bị "cháy túi" cuối tháng?

Hẹn gặp lại anh em ở Bài học 6: Cơ chế tính phí (Pricing Model) – Phân biệt On-Demand và Editions/Slots (Autoscaling Compute) – Tránh "đốt tiền" oan!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.