Injeksi derau

Penyisipan derau adalah teknik yang digunakan untuk melindungi privasi pengguna saat membuat kueri database. Metode ini berfungsi dengan menambahkan derau acak ke klausa SELECT penggabungan kueri. Derau ini melindungi privasi pengguna sekaligus memberikan hasil yang cukup akurat dengan nilai minimum agregasi yang diperlukan untuk output. Sebagian besar kueri yang ada dapat dieksekusi dalam mode bising,dengan beberapa batasan.

Mempelajari manfaat penggunaan injeksi derau

Pemecahan masalah lebih sederhana: Baris hanya dihilangkan karena persyaratan agregasi, sehingga pemecahan masalah dan penyesuaian kueri lebih sederhana.

Tidak ada sintaks baru yang perlu dipelajari: Anda tidak perlu mempelajari sintaks kueri baru atau memahami konsep privasi untuk menggunakan derau.

Akurasi hasil dilaporkan: Tugas yang berhasil menunjukkan total persentase data yang mungkin terpengaruh oleh derau.

Mempelajari pengaruh kebisingan terhadap persyaratan privasi

Persyaratan agregasi: Penyisipan derau menghasilkan data tayangan iklan yang diwakili oleh sekitar 20 pengguna unik atau lebih, dan data klik atau konversi yang diwakili oleh sekitar 10 pengguna unik atau lebih.

Pemeriksaan statis: Tidak ada dampak.

Anggaran dan batas kueri: Penyisipan derau membatasi berapa kali kueri yang sama dapat dijalankan pada set data yang sama. Saat menghitung ulang hasil gabungan yang sama dalam satu kueri atau di beberapa eksekusi kueri, hasil Anda mungkin diblokir. Hal ini dapat terjadi jika Anda menjalankan kueri jendela geser, atau jika Anda membuat permintaan yang sama beberapa kali. Untuk mengetahui informasi selengkapnya, lihat Hasil berulang.

Pelajari lebih lanjut pemeriksaan privasi.

Memahami pengaruh penyisipan derau terhadap hasil

Ads Data Hub menyisipkan derau untuk mengurangi risiko pengungkapan—risiko bahwa seseorang dapat mempelajari informasi tentang pengguna perorangan. Fitur ini menyeimbangkan privasi dengan utilitas.

Penyisipan derau di Ads Data Hub mengubah hasil kueri sebagai berikut:

  • Fitur ini membatasi kontribusi pengguna yang tidak biasa dalam hasil gabungan. Layanan ini menjumlahkan setiap kontribusi pengguna dalam setiap agregasi, lalu membatasi setiap kontribusi dengan batas penjepitan minimum dan maksimum.
  • Menggabungkan kontribusi per pengguna yang dijepit.
  • Fungsi ini menambahkan derau ke setiap hasil agregat—hasil setiap panggilan fungsi agregasi di setiap baris. Skala derau acak ini sebanding dengan batas yang dijepit.
  • Layanan ini menghitung jumlah pengguna berderau untuk setiap baris dan menghilangkan baris dengan jumlah pengguna yang terlalu sedikit (sekitar 20 pengguna per baris). Karena derau, tugas yang berjalan di dataset yang sama dapat menghapus baris yang berbeda. Persyaratan ini dapat dihindari dengan menggunakan grup publik.

Hasil akhirnya adalah set data di mana setiap baris memiliki hasil agregat berderau dan kelompok kecil telah dieliminasi. Hal ini menyamarkan pengaruh pengguna perorangan terhadap hasil yang ditampilkan.

Tentang pembatasan agregasi

Penyisipan derau di Ads Data Hub menggunakan pembatasan agregasi implisit atau eksplisit untuk membatasi kontribusi pencilan. Anda dapat memilih jenis pembatasan yang akan digunakan, bergantung pada kasus penggunaan Anda.

Penjepitan implisit

Anda tidak memerlukan sintaks SQL khusus untuk menggunakan pembatasan implisit, yang diterapkan secara default. Batas implisit berasal dari data itu sendiri dan ditentukan untuk setiap agregasi. Jika beberapa agregasi memiliki rentang nilai yang lebih luas daripada yang lain, pembatasan implisit dapat menyimpulkan batas yang berbeda untuk agregasi yang berbeda sesuai kebutuhan. Hal ini biasanya menghasilkan lebih sedikit error. Perhatikan bahwa COUNT(DISTINCT user_id) otomatis membatasi kontribusi per pengguna hingga 1.

Penjepitan eksplisit

Pembatasan eksplisit membatasi total kontribusi dari setiap pengguna ke rentang yang ditentukan. Batas eksplisit diterapkan secara seragam ke semua agregasi dan harus berupa nilai literal. Pembatasan eksplisit dapat memberikan hasil yang lebih baik jika batas umumnya diketahui. Misalnya, membatasi usia antara 0 dan 100 mencerminkan informasi publik karena usia sebagian besar orang umumnya berada dalam rentang ini.

Ads Data Hub menyediakan fungsi agregasi ADH.ANONtambahan untuk pembatasan eksplisit. Untuk menggunakan pembatasan eksplisit, tetapkan batas untuk setiap fungsi agregat yang didukung dengan menambahkan bilangan bulat yang merepresentasikan batas bawah dan batas atas. Contoh:

SELECT
campaign_name,
-- Set lower and upper bounds to 0 and 1, respectively
ADH.ANON_COUNT(*, contribution_bounds_per_group => (0,1))
FROM data
GROUP BY 1

Menjalankan kueri menggunakan penyisipan derau

  1. Buka laporan.
  2. Klik tombol Setelan derau privasi ke posisi Gunakan derau.
  3. Jalankan kueri.
  4. Tinjau dampak derau yang ditambahkan.
  5. Opsional: Sesuaikan kueri untuk mengurangi dampak derau.

Meninjau dampak kebisingan

Setelah tugas berhasil diselesaikan, Ads Data Hub akan menampilkan keandalan hasil dalam ringkasan privasi. Keandalan didasarkan pada persentase sel dalam output yang mungkin sangat terpengaruh oleh derau. Nilai dalam tabel hasil dianggap terpengaruh jika skala derau yang ditambahkan lebih besar dari 5% hasil dalam sel.

Untuk set data output yang terpengaruh, ringkasan privasi mencantumkan sepuluh kolom paling bising dari dampak tertinggi hingga terendah dan kontribusinya terhadap noise. Berikut adalah perincian label dampak kebisingan.

% hasil yang terpengaruh Warna indikator Dampak
<5% Hijau Berdampak rendah
5%-15% Kuning Dampak sedang
15%-25% Orange Berdampak tinggi
>25% Merah Dampak sangat tinggi

Anda juga dapat melihat pratinjau ringkasan privasi untuk tugas pelaporan terbaru di halaman Beranda. Untuk melihat pratinjau privasi pekerjaan tertentu, tahan kursor di atas ikon tips privasi privacy_tip di kartu pekerjaan di bagian Aktivitas terbaru.

Menyesuaikan kueri

Agregasi lebih mungkin terpengaruh oleh derau jika hanya sedikit pengguna yang berkontribusi pada hasil. Hal ini dapat terjadi saat agregasi dihitung dari set pengguna kecil atau saat beberapa pengguna tidak memengaruhi hasil, yang dapat terjadi, misalnya, dengan fungsi COUNTIF. Berdasarkan laporan derau, Anda mungkin perlu menyesuaikan kueri untuk mengurangi persentase hasil yang terpengaruh.

Berikut adalah panduan umum:

  • Perluas rentang tanggal.
  • Tulis ulang kueri untuk mengurangi perincian data, seperti dengan mengelompokkan menurut lebih sedikit parameter atau mengganti COUNTIF dengan COUNT.
  • Hapus kolom yang tidak relevan.
  • Coba penjepitan eksplisit jika batas yang wajar dapat dipilih.

Fungsi agregat yang didukung

Fungsi agregat berikut didukung dengan derau:

  • SUM(...)
  • COUNT(*)
  • COUNT(...)
  • COUNTIF(...)
  • COUNT(DISTINCT ...)
  • APPROX_COUNT_DISTINCT(...)
  • AVG(...)

Kata kunci DISTINCT hanya didukung dengan fungsi COUNT. Jika digunakan dengan referensi langsung ke kolom user_id dari tabel Ads Data Hub atau ekspresi yang menampilkan user_id atau NULL, seperti COUNT(DISTINCT IF(..., user_id, NULL)), fungsi COUNT DISTINCT dan APPROX_COUNT_DISTINCT(...) dihitung dengan membatasi kontribusi per pengguna ke 1. Jika COUNT DISTINCT mereferensikan kolom non-user_id, COUNT DISTINCT diperkirakan menggunakan APPROX_COUNT_DISTINCT dengan pembatasan implisit.

Fungsi agregat tambahan

Selain mendukung pengagregasi reguler, Ads Data Hub memperkenalkan fungsi agregasi ADH.ANON tambahan yang mendukung pembatasan eksplisit. Agregator ini memiliki sintaksis yang sama dengan fungsi agregasi privasi diferensial BigQuery, tetapi tidak memerlukan klausa WITH DIFFERENTIAL_PRIVACY:

  • ADH.ANON_SUM( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )

  • ADH.ANON_COUNT( *, [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )

  • ADH.ANON_COUNT( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )

  • ADH.ANON_AVG( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )

  • ADH.ANON_PERCENTILE_CONT( ..., percentile, contribution_bounds_per_row => (lower_bound, upper_bound) )

  • ADH.ANON_COUNT_DISTINCT( ..., [ max_contributions_per_group => upper_bound ] )

Parameter ADH.ANON_SUM, ADH.ANON_COUNT, dan ADH.ANON_AVG:

  • contribution_bounds_per_group: Kontribusi per pengguna di-clamp untuk setiap partisi yang ditentukan oleh kunci GROUP BY. Batas atas dan bawah diterapkan pada nilai per grup setelah nilai diagregasi per pengguna.
  • lower_bound: Literal numerik yang merepresentasikan nilai terkecil yang akan disertakan dalam agregasi.
  • upper_bound: Literal numerik yang merepresentasikan nilai terbesar yang akan disertakan dalam agregasi.

Parameter ADH.ANON_PERCENTILE_CONT:

  • percentile: Persentil yang akan dihitung, literal dalam rentang [0, 1].
  • contribution_bounds_per_row: Kontribusi per pengguna dibatasi berdasarkan per baris (per data). Perhatikan bahwa batas penjepitan eksplisit diperlukan untuk persentil dan oleh karena itu, persentil hanya didukung sebagai fungsi tambahan.
  • lower_bound: Literal numerik yang merepresentasikan nilai terkecil yang akan disertakan dalam agregasi.
  • upper_bound: Literal numerik yang merepresentasikan nilai terbesar yang akan disertakan dalam agregasi.

Parameter ADH.ANON_COUNT_DISTINCT:

  • max_contributions_per_group: Kontribusi per pengguna di-clamp untuk setiap partisi yang ditentukan oleh kunci GROUP BY. Batas atas membatasi kontribusi pengguna maksimum per grup setelah nilai diagregasi per pengguna.
  • upper_bound: Literal numerik yang merepresentasikan nilai terbesar yang akan disertakan dalam agregasi.

Menghitung MIN dan MAX

Fungsi MIN dan MAX tidak didukung secara langsung dalam agregasi derau, tetapi sering kali ada metode alternatif untuk menghitung hasil ini.

Jika Anda memiliki MIN atau MAX nilai yang dapat digunakan sebagai kunci pengelompokan, seperti tanggal peristiwa, Anda dapat mengelompokkan menurut nilai tersebut terlebih dahulu, lalu menghitung MIN/MAX setelahnya. Fungsi ini menampilkan nilai minimum atau maksimum yang melewati penerapan batas nilai agregasi.

Contoh:

WITH campaign_date_ranges AS (
  SELECT campaign_id, MIN(event_date) AS min_date, MAX(event_date) AS max_date
  FROM (
    # Aggregation thresholding will be applied here
    SELECT DISTINCT
      campaign_id,
      DATE(query_id.time_usec, @time_zone) AS event_date
    FROM adh.google_ads_impressions
  )
)
SELECT campaign_id, num_impressions, min_date, max_date
FROM (
  # Noise and aggregation thresholding will be applied here
  SELECT campaign_id, COUNT(*) AS num_impressions
  FROM adh.google_ads_impressions
)
JOIN campaign_date_ranges USING(campaign_id)

Atau, jika Anda memiliki MIN atau MAX nilai perincian dengan batas yang diketahui, Anda dapat menggunakan PERCENTILE_CONT dengan batas eksplisit untuk hasil perkiraan.

Contoh:

SELECT
  campaign_id,
  COUNT(*) AS num_impressions,
  ADH.ANON_PERCENTILE_CONT(
    query_id.time_usec, 0,
    contribution_bounds_per_row => (@min_timestamp, @max_timestamp))
    AS min_timestamp,
  ADH.ANON_PERCENTILE_CONT(
    query_id.time_usec, 1,
    contribution_bounds_per_row => (@min_timestamp, @max_timestamp))
    AS max_timestamp
FROM adh.google_ads_impressions

Tentang hasil bilangan bulat

Meskipun Ads Data Hub akan otomatis menyisipkan derau untuk fungsi agregat ini, tanda tangan fungsi tidak berubah. Karena fungsi seperti COUNT atau SUM dari INT64 menampilkan INT64, setiap bagian desimal dari hasil yang diberi derau dibulatkan. Hal ini biasanya dapat diabaikan dibandingkan dengan ukuran hasil dan noise.

Jika Anda memerlukan perincian desimal dalam hasil, hindari penulisan fungsi yang menampilkan INT64–misalnya, dengan menggunakan SUM dengan inputnya yang di-cast ke FLOAT64.

Tentang hasil negatif

Pada prinsipnya, derau dengan nilai yang sangat kecil dapat menghasilkan angka negatif, meskipun secara semantik hal ini tidak mungkin terjadi untuk kueri. Untuk mempertahankan perilaku yang diharapkan, semua bentuk COUNT dan COUNTIF otomatis dibatasi pada nol, sehingga tidak pernah memberikan hasil negatif. Jika Anda menginginkan perilaku yang sama dengan fungsi lain, seperti SUM, Anda dapat membatasi hasil secara manual menggunakan GREATEST(0, SUM(...)).

Perubahan ini biasanya dapat diabaikan, tetapi akan menimbulkan sedikit bias positif pada hasil keseluruhan.

Grup publik

Dengan klausa GROUP BY, hasil kueri anonim digabungkan di seluruh grup. Nilai minimum agregasi diterapkan untuk memastikan bahwa ada cukup banyak pengguna dalam grup sehingga data pengguna individu terlindungi. Proses penentuan grup mana yang dapat dirilis disebut "pemilihan partisi".

Dalam banyak kasus, grup mungkin merupakan pengetahuan publik. Misalnya, pengelompokan menurut versi browser, hari dalam seminggu, atau wilayah geografis tidak bergantung pada data pengguna jika nilai kunci pengelompokan diketahui sebelumnya. Dalam hal ini, pemilihan partisi dapat dihilangkan, karena ada atau tidaknya grup dalam output tidak memberikan informasi baru tentang pengguna.

Ads Data Hub mengidentifikasi kueri yang memenuhi syarat untuk grup publik dan tidak menerapkan penerapan nilai minimum agregasi pada kueri ini. Artinya, tidak ada baris output yang dikecualikan. Perhatikan bahwa hasil yang dihitung dari sejumlah kecil pengguna dapat sangat terpengaruh oleh derau.

Agar memenuhi syarat untuk grup publik, kueri harus disusun untuk memastikan bahwa semua kunci pengelompokan diketahui sebelumnya. Kolom pengelompokan harus memenuhi kondisi berikut:

  • Data tersebut berasal dari tabel publik (tabel atau klausa SELECT tanpa data pengguna Ads Data Hub).
  • Kolom tersebut memiliki SELECT DISTINCT yang diterapkan untuk menerapkan nilai unik.
  • Kolom tersebut digabungkan ke dalam kueri dengan OUTER JOIN di semua kolom individual.

Jika kueri memenuhi syarat untuk grup publik, UI Ads Data Hub akan menampilkan pesan validasi berikut: 'Gabung mendukung grup publik dan tidak tunduk pada penerapan nilai minimum agregasi.'

Contoh kueri grup publik:

SELECT age_group_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT age_group_id FROM adh.age_group)
ON demographics.age_group = age_group_id
GROUP BY age_group_id
SELECT age_group_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT * FROM UNNEST([1, 2, 3]) AS age_group_id)
ON demographics.age_group = age_group_id
GROUP BY age_group_id

Pada contoh pertama, adh.google_ads_impressions table yang dilindungi digabungkan dengan tabel adh.age_group yang tidak berisi data pengguna di kolom age_group_id. Kolom tabel publik yang sama age_group_id muncul di klausa GROUP BY.

Demikian pula, dalam contoh kedua, tabel adh.google_ads_impressions yang dilindungi digabungkan dengan tabel publik, yang disediakan secara eksplisit sebagai UNNEST([1, 2, 3]). Perhatikan bahwa dalam kedua contoh, kunci pengelompokan age_group_id berasal dari tabel publik.

Beberapa item pengelompokan juga dapat diberikan, misalnya:

SELECT campaign_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT campaign_id, customer_id FROM adh.google_ads_campaign)
USING (campaign_id, customer_id)
GROUP BY campaign_id, customer_id
SELECT p.campaign_id, p.browser, COUNT(*) FROM adh.google_ads_impressions AS i
RIGHT OUTER JOIN (
  SELECT DISTINCT * FROM UNNEST([1, 2]) AS campaign_id
  CROSS JOIN UNNEST(['Chrome', 'Other']) AS browser
) AS p
  ON i.campaign_id = p.campaign_id AND i.browser = p.browser
GROUP BY campaign_id, browser;

Untuk menyusun RIGHT OUTER JOIN dengan benar menggunakan subkueri yang menentukan grup publik, pastikan pernyataan SELECT DISTINCT dalam subkueri hanya menyertakan kolom yang digunakan dalam klausa ON dari JOIN. Kolom yang sama ini juga harus ada dalam klausa GROUP BY kueri utama. Misalnya, kueri berikut tidak memenuhi syarat untuk grup publik:

SELECT age_group_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (
  SELECT DISTINCT * -- Incorrect: May include fields not in the JOIN/GROUP BY
  FROM adh.age_group
)
  ON demographics.age_group = age_group_id
GROUP BY age_group_id

Tidak adanya pemfilteran dalam kueri grup publik dapat bermanfaat untuk kueri yang dijalankan berulang kali, karena output selalu ditampilkan untuk nilai kunci pengelompokan tetap yang sama. Hal ini dapat sangat berguna, misalnya, untuk membuat dasbor berkala.

Peringatan: jika tabel publik menyediakan sejumlah besar nilai kunci pengelompokan, maka Anda mungkin mendapatkan banyak baris dengan sedikit atau tanpa data, dan semua baris ini akan dilaporkan sebagai memiliki dampak derau yang tinggi. Dalam hal ini, Anda harus mempertimbangkan untuk memberikan daftar kunci yang lebih kecil secara eksplisit dengan hanya nilai yang Anda minati.

GROUP BY ROLLUP

GROUP BY ROLLUP memperluas klausa GROUP BY untuk menyertakan baris tambahan yang merepresentasikan subtotal dan total keseluruhan berdasarkan hierarki yang ditentukan dalam daftar pengelompokan. Di Ads Data Hub, GROUP BY ROLLUP hanya tersedia saat menggunakan penyisipan derau. Sintaksis mengikuti spesifikasi BigQuery standar.

Total yang Konsisten dengan Grup Publik

Saat injeksi derau digunakan, derau diterapkan secara independen di setiap tingkat agregasi. Artinya, total tidak selalu memiliki konsistensi yang sempurna, sehingga subtotal tidak sama dengan total keseluruhan (misalnya, jumlah kota mungkin tidak sama dengan total wilayah).

Saat menggunakan GROUP BY ROLLUP bersama dengan grup publik Ads Data Hub akan menghilangkan inkonsistensi ini dalam hasil. Hal ini dapat terjadi karena tidak ada hasil yang difilter karena penerapan nilai minimum. Artinya, misalnya, jumlah kota akan dijumlahkan dengan jumlah wilayah masing-masing. (Catatan: Untuk hasil bilangan bulat, kemungkinan ada sedikit perbedaan karena error pembulatan floating-point.)

Manfaat Menggunakan Grup Publik dengan ROLLUP

  1. Agregat yang konsisten: Memastikan subtotal dan total keseluruhan selaras.
  2. Peningkatan akurasi: Proses konsistensi meningkatkan akurasi data secara keseluruhan. Tingkat yang lebih tinggi dalam hierarki rollup (seperti agregat tingkat negara) didasarkan pada set data yang lebih besar dan cenderung memiliki dampak derau relatif yang lebih kecil. Informasi yang lebih stabil dari tingkat yang lebih tinggi ini digunakan untuk menyesuaikan dan meningkatkan kualitas tingkat yang lebih terperinci dan lebih bising (seperti gabungan tingkat kota).

Sangat disarankan untuk menggunakan GROUP BY ROLLUP dengan grup publik jika memungkinkan untuk mendapatkan manfaat dari keunggulan ini.

Contoh ROLLUP dengan grup publik:

ROLLUP dengan satu tombol:

Menggunakan tabel:

SELECT country_code, COUNT(1) AS count
FROM adh.google_ads_impressions
RIGHT OUTER JOIN
 (SELECT DISTINCT country_code FROM adh.city)
 ON location.country = country_code
GROUP BY ROLLUP (country_code);

Menggunakan daftar inline:

SELECT country_code, COUNT(1) AS count
FROM adh.google_ads_impressions
RIGHT OUTER JOIN
 (SELECT DISTINCT * FROM UNNEST(['US', 'CA', 'CN', 'MX']) AS country_code)
 ON location.country = country_code
GROUP BY ROLLUP (country_code);

Contoh hasil:

country_code count
CN 6155
CA 16439
US 256695
MX 10780
null 290067

Baris dengan NULL untuk country_code menunjukkan total keseluruhan. Jumlah jumlah masing-masing negara, 290069, sangat mendekati baris total keseluruhan, 290067, dengan sedikit perbedaan yang muncul dari pembulatan.

ROLLUP dengan beberapa Kunci pengelompokan:

SELECT p.campaign_id, p.browser, COUNT(*) as count
FROM adh.google_ads_impressions AS i
RIGHT OUTER JOIN (
 SELECT DISTINCT * FROM UNNEST([1, 2]) AS campaign_id
 CROSS JOIN UNNEST(['Chrome', 'Other']) AS browser
) AS p
 ON i.campaign_id = p.campaign_id AND i.browser = p.browser
GROUP BY ROLLUP (campaign_id, browser);

Contoh hasil:

campaign_id browser count catatan
1 Chrome ...
1 Lainnya ...
2 Chrome ...
2 Lainnya ...
1 null ... Subtotal untuk campaign_id = 1
2 null ... Subtotal untuk campaign_id = 2
null null ... Total keseluruhan

ROLLUP dengan set item yang dapat dikelompokkan:

Untuk memperlakukan beberapa kolom sebagai satu unit dalam hierarki penggabungan, sertakan kolom tersebut dalam tanda kurung, misalnya: ROLLUP ((column1, column2), column3). Pasangan ini digabungkan menurut pasangan (campaign_id, browser) sebagai satu entitas.

GROUP BY ROLLUP ((campaign_id, browser)) akan menghasilkan subtotal untuk:

  • (campaign_id, browser) - paling terperinci
  • () - total keseluruhan

Subtotal perantara tidak akan dibuat hanya untuk (campaign_id).

SELECT p.campaign_id, p.browser, COUNT(*) AS count
FROM adh.google_ads_impressions AS i
RIGHT OUTER JOIN (
 SELECT DISTINCT * FROM UNNEST([1, 2]) AS campaign_id
 CROSS JOIN UNNEST(['Chrome', 'Other']) AS browser
) AS p
 ON i.campaign_id = p.campaign_id AND i.browser = p.browser
GROUP BY ROLLUP ((campaign_id, browser));

Contoh hasil:

campaign_id browser count catatan
1 Chrome ...
1 Lainnya ...
2 Chrome ...
2 Lainnya ...
null null ... Total keseluruhan

Perhatian: Menggunakan ROLLUP dengan banyak tingkat hierarki atau sejumlah besar nilai unik dalam kunci pengelompokan dapat menghasilkan sejumlah besar baris output. Hal ini berpotensi menyebabkan error karena batas Ads Data Hub pada hasil berulang. Sebaiknya jumlah tingkat hierarki dan kardinalitas kunci pengelompokan tetap relatif kecil.


Pola kueri yang didukung

Penting: Sebagian besar praktik terbaik standar Ads Data Hub masih berlaku untuk kueri yang menggunakan penyisipan derau. Secara khusus, sebaiknya Anda meninjau panduan tentang kueri berulang kali pada data yang sama.

Bagian ini menjelaskan pola kueri yang didukung saat menjalankan kueri menggunakan injeksi derau.

Agregat tingkat pengguna

Derau hanya disisipkan dalam agregasi yang menggabungkan data dari beberapa pengguna. Agregasi yang secara eksplisit mengelompokkan atau mempartisi menurut user_id tidak menerima derau apa pun atau membatasi penggunaan fungsi. Agregasi tingkat pengguna yang tidak secara eksplisit dikelompokkan menurut user_id, misalnya GROUP BY impression_id, diperlakukan sebagai agregasi lintas pengguna, sehingga derau ditambahkan.

Pengelompokan menurut external_cookie saja tidak cukup. Meskipun external_cookie dapat digunakan untuk menggabungkan tabel *_match dengan tabel milik pelanggan, setiap agregasi pengguna tunggal harus dikelompokkan secara eksplisit menurut kolom user_id, bukan hanya kolom external_cookie.

Contoh fungsi agregat:

WITH user_paths AS (
  # Grouping by user_id, no noise needed, all functions allowed
  SELECT user_id, STRING_AGG(campaign_id, ">" ORDER BY query_id.time_usec) AS path
  FROM adh.google_ads_impressions
  GROUP BY 1
)
# Noise applied here to num_users
SELECT path, COUNT(*) AS num_users
FROM user_paths
GROUP BY 1;

Contoh fungsi analisis:

WITH events AS (
  # Partitioning by user_id, no noise needed, all functions allowed
  SELECT
    campaign_id,
    ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY query_id.time_usec) AS index
  FROM adh.google_ads_impressions
)
# Noise applied here to first_impressions
SELECT campaign_id, COUNT(*) AS first_impressions
FROM events
WHERE index = 1
GROUP BY 1;

Agregat paralel

Setiap agregasi lintas pengguna menerima derau secara independen. Anda dapat menjalankan beberapa agregasi tersebut dalam satu pernyataan, menggabungkan hasil ke dalam satu tabel menggunakan JOIN atau UNION.

Contoh:

WITH result_1 AS (
  # Noise applied here to num_impressions
  SELECT campaign_id, COUNT(*) AS num_impressions
  FROM adh.google_ads_impressions
  GROUP BY 1
), result_2 AS (
  # Noise applied here to num_clicks
  SELECT campaign_id, COUNT(*) AS num_clicks
  FROM adh.google_ads_creative_conversions
  GROUP BY 1
)
SELECT * FROM result_1 JOIN result_2 USING(campaign_id)

Data gabungan yang digabungkan dengan data yang tidak digabungkan

Karena Ads Data Hub hanya mendukung jendela analisis yang dipartisi menurut user_id, solusi umum untuk mengatasi hal ini adalah dengan menggabungkan hasil ini secara terpisah dan melakukan self-join sebelum menggabungkan lagi.

Contoh:

WITH campaign_totals AS (
  # Noise applied here to campaign_imps
  SELECT campaign_id, COUNT(*) AS campaign_imps
  FROM adh.google_ads_impressions
  GROUP BY 1
)
# Noise applied here to imps
SELECT campaign_id, demographics, campaign_imps, COUNT(*) AS imps
FROM adh.google_ads_impressions JOIN campaign_totals USING(campaign_id)
GROUP BY 1,2,3

Mode derau mencegah penggabungan ulang hasil gabungan, seperti AVG(campaign_imps).


Pola kueri yang tidak didukung

Bagian ini menjelaskan pola kueri yang tidak didukung saat menjalankan kueri menggunakan injeksi derau.

Hasil berulang

Dalam mode derau, Ads Data Hub membatasi frekuensi pengulangan agregasi yang sama. Jika Anda mencapai batas ini, kueri mode derau Anda akan kehilangan akses ke tanggal yang sering dikueri dalam set data. Berikut adalah contoh bagaimana hal ini dapat terjadi.

Pengulangan kueri terjadi saat kueri yang sama dijalankan beberapa kali dengan parameter yang sama atau parameter yang sangat mirip, seperti rentang tanggal yang tumpang-tindih. Anda dapat menghindari hal ini dengan menggunakan data yang sudah diekspor ke project BigQuery Anda.

Perhatikan bahwa jika dua tugas mengkueri rentang tanggal yang tumpang-tindih, tugas tersebut dapat menghasilkan pengulangan jika melakukan komputasi yang sama pada pengguna yang sama. Misalnya, kueri berikut, yang dijalankan pada rentang tanggal yang tumpang-tindih, membuat pengulangan karena dipartisi menurut tanggal:

SELECT DATE(TIMESTAMP_MICROS(event.event_time)) AS date,
COUNT(*) AS cnt
FROM adh.cm_dt_clicks
GROUP BY 1

Dalam hal ini, Anda harus menjalankan kueri pada segmen tanggal yang tidak berurutan.

Contoh lain pengulangan terjadi saat data agak tidak bergantung pada tanggal. Kueri berikut menghasilkan pengulangan saat dijalankan pada tanggal yang tumpang-tindih, dengan kedua tugas mencakup seluruh masa aktif kampanye:

SELECT campaign_id, COUNT(*) AS cnt
FROM adh.google_ads_impressions
GROUP BY 1

Dalam hal ini, Anda hanya perlu menjalankan kueri ini satu kali karena hasilnya tidak berubah.

Pengulangan agregasi terjadi saat agregasi yang sama diulang beberapa kali dalam kueri:

SELECT COUNT(*) AS cnt1, COUNT(*) AS cnt2
FROM table

Dalam hal ini, Anda harus menghapus salah satu pengulangan.

Perhatikan bahwa meskipun agregasi berbeda secara sintaksis, tetapi menghitung nilai yang sama, hal ini akan dihitung sebagai pengulangan. Dengan kata lain, jika nilai condition1 dan condition2 sama untuk semua pengguna dengan beberapa nilai key, kueri berikut akan memiliki pengulangan:

SELECT key, COUNTIF(condition1) AS cnt1, COUNTIF(condition2) AS cnt2
FROM table
GROUP BY key

Jika Anda memiliki kondisi yang sangat mirip untuk beberapa grup pengguna, Anda dapat mempertimbangkan untuk menulis ulang kueri agar hanya memiliki satu COUNT.

Duplikasi baris terjadi saat tabel Ads Data Hub digabungkan dengan tabel BigQuery sedemikian rupa sehingga setiap baris dari tabel Ads Data Hub cocok dengan beberapa baris dalam tabel BigQuery. Misalnya, kueri berikut menghasilkan pengulangan jika ada beberapa baris dengan ID kampanye yang sama di bq_table:

SELECT r.campaign_id, COUNT(*) AS cnt
FROM adh_table
INNER JOIN bq_table ON l.campaign_id = r.campaign_id

Dalam hal ini, Anda harus menyusun ulang kueri sehingga bq_table hanya memiliki satu baris per nilai kunci gabungan (campaign_id, dalam hal ini).

Perhatikan bahwa memisahkan array dari tabel Ads Data Hub dapat menghasilkan efek yang sama jika sebagian besar pengguna memiliki array nilai yang sama:

SELECT in_market_id, COUNT(*)
FROM adh.dv360_youtube_impressions,
UNNEST(in_market) AS in_market_id
GROUP BY 1

Sebagai aturan umum, Anda harus membatasi komputasi hasil yang sama hingga 10 kali atau kurang. Saat Anda mendekati nilai minimum, Ads Data Hub akan menampilkan peringatan. Jika hasil yang sama terus dihitung di luar nilai minimum, tugas Anda akan mulai diblokir dengan error.

Pelajari praktik terbaik kueri lainnya.

Tentang Periode Lihat Balik

Beberapa pola kueri menghasilkan laporan dalam jangka waktu yang lama, yang secara berkala dibuat ulang untuk menyertakan hasil baru. Kueri ini mungkin perlu disesuaikan agar berfungsi dalam mode derau karena jika menghitung ulang hasil sebelumnya, kueri akan diblokir. Sebaliknya, setiap tugas hanya boleh menghasilkan hasil baru, lalu hasil baru dapat digabungkan dengan hasil dari tugas sebelumnya untuk laporan lengkap.

Misalnya, jika Anda membuat laporan metrik menurut tanggal, yang diperbarui setiap hari:

SELECT
  campaign_id,
  DATE(TIMESTAMP_MICROS(query_id.time_usec), @time_zone) AS event_date,
  COUNT(*) AS impressions
FROM adh.google_ads_impressions
GROUP BY 1,2

Anda tidak boleh menjalankan kueri ini dengan rentang tanggal yang besar karena akan menghitung ulang hasil hari-hari sebelumnya. Sebagai gantinya, Anda harus menjalankan setiap tugas hanya pada hari terbaru, yang memiliki data baru, lalu menggabungkannya dengan hasil dari tugas sebelumnya. Jika Anda ingin mengumpulkan semua hasil dalam satu tabel di banyak tugas, pertimbangkan untuk menggunakan pernyataan MERGE.

Anda masih dapat menghitung ulang rentang tanggal sebelumnya untuk memperbarui hasil (misalnya, untuk memperhitungkan data yang terlambat tiba), tetapi Anda harus menghindari penghitungan ulang satu hasil terlalu sering, seperti yang dijelaskan sebelumnya.

Penggabungan ulang langsung

Derau diterapkan pada lapisan pertama agregasi lintas pengguna dalam kueri. Kueri dengan beberapa lapisan agregasi akan menggabungkan hasil yang bising, sehingga agregat akhir mungkin memiliki derau yang jauh lebih tinggi. Kueri ini menerima peringatan saat validasi:

WITH layer_1 AS (
  # Noise applied here to partial_result
  SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
  FROM adh.google_ads_impressions
  GROUP BY 1,2,3
  HAVING partial_result > 5
)
# Reaggregation of partial_result with no user-level data, will be rejected
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1

Untuk mendapatkan hasil terbaik dari derau, hitung semua operasi lintas pengguna dalam satu agregasi. Misalnya, ambil SUM peristiwa, bukan SUM jumlah perantara.

Jika agregasi multi-layer tidak dapat dihindari, Anda dapat menyelesaikan peringatan dengan mengekspor hasil langsung dari layer pertama. Untuk melakukannya dalam satu tugas tanpa mengubah hasil skrip, buat tabel sementara (atau tabel yang diekspor ke project BigQuery Anda) dengan sintaksis OPTIONS(privacy_checked_export=true). Contoh:

CREATE TEMP TABLE layer_1 OPTIONS(privacy_checked_export=true) AS (
  # Noise applied here to partial_result
  SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
  FROM adh.google_ads_impressions
  GROUP BY 1,2,3
  HAVING partial_result > 5
);
# Reaggregation of privacy checked data, no noise needed
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1

Pelajari tabel sementara lebih lanjut.

Jika lapisan agregasi pertama terlalu terperinci untuk pemeriksaan privasi, pertimbangkan untuk menulis ulang kueri dengan agregat tingkat pengguna. Jika hal ini tidak memungkinkan, maka kueri ini tidak didukung dalam mode derau.

ID pengguna yang tidak tergabung

Kueri dalam mode derau tidak boleh menggabungkan data dari pengguna terpisah ke dalam satu baris, kecuali saat melakukan agregasi dengan derau. Akibatnya, gabungan data Ads Data Hub yang tidak diagregasi harus digabungkan secara eksplisit pada kolom user_id.

Kueri ini tidak secara eksplisit menggabungkan kolom user_id, yang menghasilkan peringatan validasi:

SELECT 
FROM adh.google_ads_impressions
JOIN adh.google_ads_creative_conversions USING(impression_id)

Penggabungan seperti ini mungkin tidak berperilaku seperti yang diharapkan karena hanya baris dengan nilai user_id yang sama yang akan cocok. Hal ini dapat diperbaiki dengan menyesuaikan klausa USING agar secara eksplisit menyertakan user_id – misalnya, USING(impression_id, user_id).

Perhatikan bahwa batasan ini hanya berlaku untuk gabungan antara tabel Ads Data Hub (kecuali tabel dimensi). Kebijakan ini tidak berlaku untuk tabel milik pelanggan. Misalnya, hal berikut diizinkan:

SELECT 
FROM adh.google_ads_impressions
JOIN bigquery_project.dataset.table USING(any_column)

Gabungan kanan Ads Data Hub-BigQuery

Outer join dengan data milik pelanggan dapat menghasilkan baris dengan ID pengguna yang tidak ada, sehingga mencegah derau berfungsi dengan baik.

Kedua kueri ini menghasilkan peringatan validasi karena memungkinkan baris yang tidak cocok dengan ID pengguna yang tidak ada di sisi Ads Data Hub:

SELECT 
FROM adh.google_ads_impressions
RIGHT JOIN bigquery_project.dataset.table USING(column)
SELECT 
FROM bigquery_project.dataset.table
LEFT JOIN adh.google_ads_impressions USING(column)

Perhatikan bahwa gabungan mana pun akan berfungsi jika urutan tabel dibalik. Ada juga pengecualian untuk tabel RDID yang bergabung langsung di device_id_md5. Misalnya, kueri berikut akan berfungsi tanpa peringatan:

SELECT 
FROM bigquery_project.dataset.table
LEFT JOIN adh.google_ads_impressions_rdid USING(device_id_md5)

Ringkasan Baris yang Difilter

Spesifikasi ringkasan baris yang difilter tidak didukung dalam mode derau. Fitur ini paling sering tidak diperlukan dengan derau karena rasio pemfilteran yang lebih rendah dan kurangnya pemfilteran dari pemeriksaan perbedaan.

Jika Anda mengamati pemfilteran data yang signifikan dalam hasil derau, tingkatkan data gabungan. Anda dapat melakukan agregasi paralel pada seluruh set data untuk membandingkan perkiraan total menggunakan ROLLUP atau agregasi terpisah, misalnya:

SELECT campaign_name, COUNT(*)
FROM data
GROUP BY 1
UNION ALL
SELECT 'Total', COUNT(*)
FROM data
GROUP BY 1

Perhatikan bahwa jumlah total diberi derau secara terpisah dan total nilai mungkin tidak sama, tetapi jumlah total sering kali lebih akurat daripada mengambil jumlah baris yang diberi derau.

Tabel yang dibuat lintas mode

Tabel yang tidak diekspor di Ads Data Hub hanya dapat digunakan dengan mode privasi yang sama dengan tempat tabel tersebut dibuat. Anda tidak dapat membuat tabel dalam mode agregasi normal dan menggunakannya dalam mode derau, atau sebaliknya (kecuali jika tabel tersebut diekspor ke BigQuery terlebih dahulu).