比對使用者提供的資料

比對使用者提供的資料 (UPDM) 功能會彙整您收集的使用者第一方資料 (例如來自網站、應用程式或實體商店的資訊),以及該使用者在所有 Google 廣告資料 (包括 Google 自有及經營的資料) 中的登入活動記錄。這包括透過 Google Marketing Platform (GMP) 產品購買的資料,例如使用 Display & Video 360 購買的 YouTube 廣告。不支援其他非 Google 擁有及經營的 GMP 產品。

廣告事件必須連結到 Google 廣告資料中的登入使用者,才能比對使用者提供的資料。

本文件將說明使用者提供的資料比對功能,並提供設定和使用指南。

總覽

要取得有價值的廣告洞察資料,通常需要將來自多個來源的資料拼接在一起。自行建構解決方案來解決這個資料管道問題,需要大量時間和工程投資。廣告資料中心的「連結」頁面提供逐步操作說明,可讓您將資料匯入、轉換及比對至 BigQuery,藉此簡化這項程序,並在廣告資料中心查詢或從 BigQuery 讀取資料的任何其他產品中使用這些資料。使用第一方資料讓查詢內容更豐富,不僅可帶來更豐富的客戶體驗,也更能因應整個產業的廣告追蹤變化。

「連結」頁面內建的工具可讓您以以隱私為優先的方式,與合作夥伴加密及分享個人識別資訊 (PII)。選取含有 PII 的資料欄後,廣告資料中心會對資料進行加密,確保只有有權限的使用者才能匯出或讀取您的第一方資料。要瞭解評估或啟用用途需要哪些第一方資料,可能不太容易,因此廣告資料中心會提供預先定義用途的完整清單,然後引導您完成資料的擷取、轉換和載入作業。雖然您可以建立多種連線,但本文件假設您會使用「連線」頁面比對使用者提供的資料。

支援的第一方資料來源

您可以從下列資料來源匯入資料:

  • BigQuery
  • Cloud Storage
  • 安全檔案傳輸通訊協定 (SFTP)
  • 雪花
  • MySQL
  • PostgreSQL
  • Amazon Redshift
  • Amazon S3

由於「比對使用者提供的資料」功能只會比對 Google 自有自營廣告空間的登入使用者,因此不會受到第三方 Cookie 即將淘汰的影響。比第三方資料更能適應業界變遷,因此能提供更豐富的洞察資料,進而提高顧客參與度。

認識術語

  • 使用者提供的資料連結:設定使用者提供的資料連結,以便匯入及比對資料、排定資料匯入作業、轉換資料,以及使用使用者 ID 比對廣告資料。廣告事件必須連結到 Google 廣告資料中的登入使用者。需要多個 Google Cloud 專案。
  • 第一方資料連結:將第一方資料連結設為資料準備工具,無須使用 UPDM 的進階功能,即可排定資料匯入作業並轉換資料。這類連線只需要一個 Google Cloud 專案。
  • 資料來源:已連結的產品、匯入的檔案或第三方整合服務,例如 BigQuery。
  • 目的地:用途;通常是指 Google 產品或產品功能 (已啟用匯入的資料),例如廣告資料中心的使用者提供的資料比對。
  • 管理專案:含有原始格式專屬廣告資料的 Google Cloud 專案。
  • 輸出資料集:廣告資料中心寫入的 BigQuery 資料集。根據預設,這是管理員專案中的資料集。如要將其變更為其他 Google Cloud 專案,請參閱「設定服務帳戶」一文。

程序摘要

  1. 設定資料攝入和比對
    • 必須為管理員專案中的服務帳戶授予必要權限。請參閱「設定資料擷取」一文。
  2. 第一方資料擷取和比對
    • 可以將第一方資料格式化並上傳至 BigQuery 資料集。如要簡化設定程序,請使用管理員專案。不過,您可以使用自己擁有的任何 BigQuery 資料集。
    • 可以透過建立連線並設定匯入時間表,啟動資料比對要求。
    • Google 會彙整您專案與 Google 自有資料之間的資料,其中包含 Google 的使用者 ID 和經雜湊處理的使用者提供資料,以建立及更新比對表。
    • 請參閱「擷取第一方資料
  3. 廣告資料中心中,以比對資料為依據的持續性查詢
    • 對對照表執行查詢的方式,與在廣告資料中心執行一般查詢的方式相同。請參閱「查詢相符的資料」。

瞭解隱私權規定

收集客戶資料

使用「比對使用者提供的資料」功能時,您必須上傳第一方資料。這可能是您從網站、應用程式、實體商店收集的資訊,或是顧客直接提供給您的任何資訊。

須遵循的規定如下:

  • 確實在隱私權政策中聲明您會與第三方共用客戶資訊,以便第三方代為提供服務,且您按照法律規定向使用者徵求共用資訊的同意聲明。
  • 僅使用 Google 核准的 API 或介面上傳顧客資料
  • 遵守所有適用法律和法規,包括任何適用的自我規範或業界準則

確認已取得第一方同意聲明

為確保能在廣告資料中心使用第一方資料,請務必確認您已根據歐盟地區使用者同意授權政策廣告資料中心政策,取得適當的同意聲明,能與 Google 分享歐洲經濟區使用者的資料。這項規定適用於每個廣告資料中心帳戶,且您每次上傳新的第一方資料時,都必須更新同意聲明。任一使用者都可代表整個帳戶確認已取得同意聲明。

請注意,適用於分析查詢的 Google 服務查詢規則,同樣也適用於 UPDM 查詢。例如,建立對照表時,您無法對歐洲經濟區使用者執行跨服務查詢。

請參閱歐洲經濟區同意聲明規定,瞭解如何在廣告資料中心確認已取得同意聲明。

資料大小

為保護使用者隱私,使用者提供的資料比對功能會強制執行以下資料大小相關規定:

  • 您必須上傳至少 1,000 筆使用者名單記錄。
  • 每次成功更新比對表時,都必須納入一定數量的新比對使用者。這項行為類似於差異檢查
  • 清單中的記錄數量不得超過上限。如要瞭解資料上限,請洽詢 Google 代表。

設定資料攝入

開始之前,請先設定廣告資料中心帳戶,建立資料連線,以便建立資料比對管道。這些步驟只需執行一次。

在「Connections」頁面中,按一下「Begin setup」,在 UPDM 啟用階段開啟帳戶設定精靈。

前往「連線」

系統會授予 BigQuery 和 Cloud Storage 哪些權限?

如果您設定比對使用者提供的資料功能,以便與 BigQuery 或 Cloud Storage 搭配使用,請參閱這份參考資料,瞭解授予廣告資料中心服務帳戶的權限。

BigQuery

Datafusion 服務帳戶
目的 Data Fusion 服務帳戶可用於在廣告資料中心使用者介面中,顯示來源欄位清單。
格式 service-some-number@gcp-sa-datafusion.iam.gserviceaccount.com
需要的存取權
BigQuery Data Viewer
roles/bigquery.dataViewer
針對資料來源目的地專案中的特定資料集
Storage Admin
roles/storage.admin
資料來源專案,或專屬的儲存空間值區
Dataproc 服務帳戶
目的 Dataproc 服務帳戶負責在背景執行資料管道。
格式 some-number-compute@developer.gserviceaccount.com
需要的存取權
BigQuery Data Viewer
roles/bigquery.dataViewer
針對資料來源目的地專案中的特定資料集
BigQuery Data Editor
roles/bigquery.dataEditor
針對目的地專案中的特定資料集
BigQuery Job User
roles/bigquery.jobUser
適用於資料來源目的地專案
Storage Admin
roles/storage.admin
適用於資料來源目的地專案,或專用儲存值區
UPDM 服務帳戶
目的 UPDM 服務帳戶用於執行相符的工作。
格式 service-some-number@gcp-sa-adsdataconnector.iam.gserviceaccount.com
需要的存取權
BigQuery Data Viewer
roles/bigquery.dataViewer
針對「Destination」專案
BigQuery Job User
roles/bigquery.jobUser
針對「Destination」專案

Cloud Storage

Datafusion 服務帳戶
目的 Data Fusion 服務帳戶可用於在廣告資料中心使用者介面中,顯示來源欄位清單。
格式 service-some-number@gcp-sa-datafusion.iam.gserviceaccount.com
需要的存取權
Storage Object Viewer
roles/storage.objectViewer
針對「Data Source」專案中的特定儲存值區
BigQuery Data Viewer
roles/bigquery.dataViewer
資料來源專案,或專屬的儲存空間值區
Storage Admin
roles/storage.admin
資料來源專案,或專屬的儲存空間值區
Dataproc 服務帳戶
目的 Dataproc 服務帳戶負責在背景執行資料管道。
格式 some-number-compute@developer.gserviceaccount.com
需要的存取權
Storage Admin
roles/storage.admin
適用於資料來源目的地專案,或專用儲存值區
BigQuery Job User
roles/bigquery.jobUser
針對「Destination」專案
UPDM 服務帳戶
目的 UPDM 服務帳戶用於執行相符的工作。
格式 service-some-number@gcp-sa-adsdataconnector.iam.gserviceaccount.com
需要的存取權
BigQuery Data Viewer
roles/bigquery.dataViewer
針對「Destination」專案
BigQuery Job User
roles/bigquery.jobUser
針對「Destination」專案

其他資料來源

其他資料來源不需要

擷取及比對第一方資料

設定輸入資料的格式

資料必須符合下列格式規定,才能正確比對:

  • 請在下列輸入欄位說明中指定的位置,使用 SHA256 雜湊處理上傳。
  • 輸入欄位必須以字串格式輸入。舉例來說,如果您要使用 BigQuery 的 SHA256 雜湊函式搭配 Base16 編碼函式 (TO_HEX),請使用以下轉換:TO_HEX(SHA256(user_data))
  • UPDM 支援 Base16 和 Base64 編碼。您必須將第一方資料的編碼與廣告資料中心查詢中使用的解碼方式保持一致。如果您變更第一方資料編碼,請務必更新廣告資料中心查詢,以便從相同的基礎進行解碼。以下範例使用 Base16 編碼。

使用者 ID

  • 純文字
  • 雜湊:無

電子郵件

  • 移除空白字元
  • 全部使用小寫字元
  • 為所有電子郵件地址加上網域名稱 (例如 gmail.com 或 hotmail.co.jp)
  • 移除重音符號,例如將 è、é、ê 或 ë 改為 e
  • 雜湊:以 Base16 編碼的 SHA256

有效: TO_HEX(SHA256("jeffersonloveshiking@gmail.com"))

無效: TO_HEX(SHA256("JéffersonLôvesHiking@gmail.com"))

電話

  • 移除空白字元
  • 請使用 E.164 格式,例如美國的例子:+14155552671,英國的例子:+442071838750
  • 包含國家/地區代碼 (包括美國)
  • 移除所有特殊字元,但國家/地區代碼前面的「+」除外
  • 雜湊:以 Base16 編碼的 SHA256

有效: TO_HEX(SHA256("+18005550101"))

無效: TO_HEX(SHA256("(800) 555-0101"))

名字

  • 移除空白字元
  • 全部使用小寫字元
  • 移除所有前置字元,例如「Mrs.」
  • 請勿移除重音符號,例如 è、é、ê 或 ë
  • 雜湊:以 Base16 編碼的 SHA256

有效: TO_HEX(SHA256("daní"))

無效: TO_HEX(SHA256("Daní"))

姓氏

  • 移除空白字元
  • 全部使用小寫字元
  • 移除所有前置字元,例如 Jr.
  • 請勿移除重音符號,例如 è、é、ê 或 ë
  • 雜湊:以 Base16 編碼的 SHA256

有效: TO_HEX(SHA256("delacruz"))

無效: TO_HEX(SHA256("de la Cruz, Jr."))

國家/地區

  • 即使所有顧客數位資料的國家/地區代碼皆相同,仍須納入
  • 請勿對國家/地區資料進行雜湊處理
  • 使用 ISO 3166-1 alpha-2 國家/地區代碼
  • 雜湊:無

有效: US

無效: United States of AmericaUSA

郵遞區號

  • 請勿對郵遞區號資料進行雜湊處理
  • 美國與國際郵遞區號皆可使用
  • 美國:
    • 可使用 5 碼郵遞區號,例如 94043
    • 也可使用 5 碼後加 4 碼額外編碼的郵遞區號,例如 94043-1351 或 940431351
  • 所有其他國家/地區:
    • 不需要設定格式 (不需要將字母改為小寫,也不需要移除空格和特殊字元)
    • 移除郵遞區號的額外編碼
  • 雜湊:無

雜湊驗證和資料編碼

您可以使用下列雜湊驗證指令碼,確保資料格式正確無誤。

JavaScript

Base16

/**
 * @fileoverview Provides the hashing algorithm for User-Provided Data Match, as
 * well as some valid hashes of sample data for testing.
*/

async function hash(token) {
  const formattedToken = token.trim().toLowerCase();
  const hashArrayBuffer = await crypto.subtle.digest(
      'SHA-256', (new TextEncoder()).encode(formattedToken));
  return Array.from(new Uint8Array(hashArrayBuffer))
      .map((b) => b.toString(16).padStart(2, '0'))
      .join('');
}

function main() {
  // Expected hash for test@gmail.com:
  // 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  hash('test@gmail.com').then(result => console.log(result));

  // Expected hash for +18005551212:
  // 61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  hash('+18005551212').then(result => console.log(result));

  // Expected hash for John:
  // 96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  hash('John').then(result => console.log(result));

  // Expected hash for Doe:
  // 799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
  hash('Doe').then(result => console.log(result));
}

main()

Base64

/**
 * @fileoverview Provides the hashing algorithm, as well as some valid hashes of
 * sample data for testing.
*/

async function hash(token) {
  const formattedToken = token.trim().toLowerCase();
  const hashBuffer = await crypto.subtle.digest(
      'SHA-256', (new TextEncoder()).encode(formattedToken));
  const base64Str = btoa(String.fromCharCode(...new Uint8Array(hashBuffer)));
  return base64Str;
}

function main() {
  // Expected hash for test@gmail.com:
  // h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  hash('test@gmail.com').then(result => console.log(result));

  // Expected hash for +18005551212:
  // YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  hash('+18005551212').then(result => console.log(result));

  // Expected hash for John: ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  hash('John').then(result => console.log(result));

  // Expected hash for Doe: eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
  hash('Doe').then(result => console.log(result));
}

main()

Python

Base16

"""Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Supports: Python 2, Python 3

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
"""

import base64
import hashlib

def updm_hash(token):
  return hashlib.sha256(token.strip().lower().encode('utf-8')).hexdigest()

def print_updm_hash(token):
  print('Hash: "{}"\t(Token: {})'.format(updm_hash(token), token))

def main():
  print_updm_hash('test@gmail.com')
  print_updm_hash('+18005551212')
  print_updm_hash('John')
  print_updm_hash('Doe')

if __name__ == '__main__':
  main()

Base64

"""Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Supports: Python 2, Python 3

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
"""

import base64
import hashlib

def hash(token):
  return base64.b64encode(
      hashlib.sha256(
          token.strip().lower().encode('utf-8')).digest()).decode('utf-8')

def print_hash(token, expected=None):
  hashed = hash(token)

  if expected is not None and hashed != expected:
    print(
        'ERROR: Incorrect hash for token "{}". Expected "{}", got "{}"'.format(
            token, expected, hashed))
    return

  print('Hash: "{}"\t(Token: {})'.format(hashed, token))

def main():
  print_hash(
      'test@gmail.com', expected='h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=')
  print_hash(
      '+18005551212', expected='YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=')
  print_hash('John', expected='ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=')
  print_hash('Doe', expected='eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=')

if __name__ == '__main__':
  main()

Go

Base16

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
*/
package main

import (
  "crypto/sha256"
  "fmt"
  "strings"
)

// Hash hashes an email, phone, first name, or last name into the correct format.
func Hash(token string) string {
  formatted := strings.TrimSpace(strings.ToLower(token))
  hashed := sha256.Sum256([]byte(formatted))
  encoded := fmt.Sprintf("%x", hashed[:])
  return encoded
}

// PrintHash prints the hash for a token.
func PrintHash(token string) {
  fmt.Printf("Hash: \"%s\"\t(Token: %s)\n", Hash(token), token)

}

func main() {
  PrintHash("test@gmail.com")
  PrintHash("+18005551212")
  PrintHash("John")
  PrintHash("Doe")
}

Base64

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
*/
package main

import (
  "crypto/sha256"
  "encoding/base64"
  "fmt"
  "strings"
)

// Hash hashes an email, phone, first name, or last name into the correct format.
func Hash(token string) string {
  formatted := strings.TrimSpace(strings.ToLower(token))
  hashed := sha256.Sum256([]byte(formatted))
  encoded := base64.StdEncoding.EncodeToString(hashed[:])
  return encoded
}

// PrintHash prints the hash for a token.
func PrintHash(token string) {
  fmt.Printf("Hash: \"%s\"\t(Token: %s)\n", Hash(token), token)

}

func main() {
  PrintHash("test@gmail.com")
  PrintHash("+18005551212")
  PrintHash("John")
  PrintHash("Doe")
}

Java

Base16

package updm.hashing;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Ascii;
import com.google.common.hash.Hashing;

/**
 * Example of the UPDM hashing algorithm using hex-encoded SHA-256.
*
* <p>This uses the Guava Hashing to generate the hash: https://github.com/google/guava
*
* <p>Sample valid hashes:
*
* <ul>
*   <li>Email "test@gmail.com": "87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674"
*   <li>Phone "+18005551212": "61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44"
*   <li>First name "John": "96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a"
*   <li>Last name "Doe": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f"
* </ul>
*/
public final class HashExample {

  private HashExample() {}

  public static String hash(String token) {
    String formattedToken = Ascii.toLowerCase(token).strip();
    return Hashing.sha256().hashString(formattedToken, UTF_8).toString();
  }

  public static void printHash(String token) {
    System.out.printf("Hash: \"%s\"\t(Token: %s)\n", hash(token), token);
  }

  public static void main(String[] args) {
    printHash("test@gmail.com");
    printHash("+18005551212");
    printHash("John");
    printHash("Doe");
  }
}

Base64

package updm.hashing;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
* Example of the hashing algorithm.
*
* <p>Sample hashes:
*
* <ul>
*   <li>Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
*   <li>Phone '+18005551212': YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
*   <li>First name 'John': ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
*   <li>Last name 'Doe': eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
* </ul>
*/
public final class HashExample {

private HashExample() {}

public static String hash(String token) {
  String formattedToken = token.toLowerCase().strip();

  byte[] hash;
  try {
    hash = MessageDigest.getInstance("SHA-256").digest(formattedToken.getBytes(UTF_8));
  } catch (NoSuchAlgorithmException e) {
    throw new IllegalStateException("SHA-256 not supported", e);
  }

  return Base64.getEncoder().encodeToString(hash);
}

public static void printHash(String token) {
  System.out.printf("Hash: \"%s\"\t(Token: %s)\n", hash(token), token);
}

public static void main(String[] args) {
  printHash("test@gmail.com");
  printHash("+18005551212");
  printHash("John");
  printHash("Doe");
}
}

SQL

Base16

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

The following code uses Google Standard SQL and can be run on BigQuery to generate match tables from unhashed data.

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f

The unhashed input table schema is assumed to be:

- Column name: UserID, Type: String
- Column name: Email, Type: String
- Column name: Phone, Type: String
- Column name: FirstName, Type: String
- Column name: LastName, Type: String
- Column name: PostalCode, Type: String
- Column name: CountryCode, Type: String
*/

CREATE TABLE `your_project_name.your_dataset_name.output_hashed_table_name`
AS
SELECT
  UserID,
  TO_HEX(SHA256(LOWER(Email))) AS Email,
  TO_HEX(SHA256(Phone)) AS Phone,
  TO_HEX(SHA256(LOWER(FirstName))) AS FirstName,
  TO_HEX(SHA256(LOWER(LastName))) AS LastName,
  PostalCode,
  CountryCode,
FROM
  `your_project_name.your_dataset_name.input_unhashed_table_name`;

Base64

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

The following code uses Google Standard SQL and can be run on BigQuery to generate match tables from unhashed data.

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=

The unhashed input table schema is assumed to be:

- Column name: UserID, Type: String
- Column name: Email, Type: String
- Column name: Phone, Type: String
- Column name: FirstName, Type: String
- Column name: LastName, Type: String
- Column name: PostalCode, Type: String
- Column name: CountryCode, Type: String
*/

CREATE TABLE `your_project_name.your_dataset_name.output_hashed_table_name`
AS
SELECT
  UserID,
  TO_BASE64(SHA256(LOWER(Email))) AS Email,
  TO_BASE64(SHA256(Phone)) AS Phone,
  TO_BASE64(SHA256(LOWER(FirstName))) AS FirstName,
  TO_BASE64(SHA256(LOWER(LastName))) AS LastName,
  PostalCode,
  CountryCode,
FROM
  `your_project_name.your_dataset_name.input_unhashed_table_name`;

加入鍵值

有些使用者提供的資料組合比其他組合更強大。以下列出不同使用者提供的資料組合,並依據相對強度進行排名。如果您使用地址,則必須提供:名字、姓氏、國家/地區和郵遞區號。

  1. 電子郵件、電話、地址 (最強)
  2. 電話、地址
  3. 電子郵件、地址
  4. 電子郵件、電話
  5. 地址
  6. 電話
  7. 電子郵件 (最弱)

建立對照表

  1. 依序點選「連線」>「建立連線」>「比對使用者提供的資料」
  2. 選擇資料來源,然後按一下「連結」
  3. 如有提示,請進行驗證,然後點選「下一步」

    BigQuery

    按一下「套用」即可授予 BigQuery 存取權。

    Cloud Storage

    按一下「套用」授予 Cloud Storage 存取權。

    MySQL

    輸入 MySQL 資料庫位置、通訊埠、使用者名稱和密碼。

    S3

    輸入 Amazon S3 私密存取金鑰

    PostgreSQL

    輸入 PostgreSQL 資料庫位置、通訊埠、使用者名稱、密碼和資料庫。

    Redshift

    輸入 Redshift 資料庫位置、通訊埠、使用者名稱、密碼和資料庫。

    sFTP

    輸入 sFTP 伺服器位置、使用者名稱和密碼。

    雪花

    輸入 Snowflake 帳戶 ID、使用者名稱和密碼。

  4. 設定資料來源,然後點選「下一步」

    BigQuery

    選取要匯入的 BigQuery 資料表。

    Cloud Storage

    輸入 gsutil 路徑 (例如 gs://my-bucket/folder/),然後選取檔案格式。

    如果這是您第一次連結這項資源,系統會顯示快訊。按一下「套用」授予存取權,然後點選「下一步」。注意:您必須具備相關權限,才能為相關值區委派 storage.buckets.setIamPolicy

    MySQL

    選取要使用的 MySQL 資料庫和資料表。

    S3

    輸入要上傳檔案的 URI (相對於主機位址)。

    PostgreSQL

    輸入 PostgreSQL 結構定義和資料表 (或檢視表) 名稱。

    Redshift

    輸入 Redshift 結構定義和資料表 (或檢視畫面) 名稱。根據預設,Redshift 使用的資料庫位置網址會採用下列範本:cluster-identifier.account-number.aws-region.redshift.amazonaws.com

    sFTP

    輸入檔案路徑和名稱,格式為 /PATH/FILENAME.csv

    雪花

    輸入要使用的 Snowflake 資料庫、結構定義和資料表 (或資料檢視)。

  5. 選取要用來做為中介目的地的 BigQuery 資料集,然後按一下「Next」。這個步驟可確保資料格式正確無誤。
  6. 選用步驟:修改資料格式。轉換作業包括計算雜湊、小寫/大寫格式設定,以及合併/分割欄位。
    1. 依序點選「動作」 >「」>「轉換」
    2. 在彈出的面板中,按一下「新增轉換」或「新增其他轉換」
    3. 從下拉式選單中選擇轉換類型,然後輸入相關規定。
    4. 按一下 [儲存]
  7. 請至少選擇一個聯結鍵,並對應要使用的欄位。廣告資料中心會自動對應名稱相同的欄位,並以 表示。進行必要的編輯,然後按一下「下一步」
  8. 設定時間表:
    1. 為連線命名。
    2. 設定頻率,指定資料要多久匯入一次您在前一個步驟中選取的資料集。每次執行時,系統都會覆寫目的地資料表中的資料。
    3. 指定您要如何處理使用者 ID 衝突。您可以選擇保留現有的相符項目,或使用新資料覆寫。
  9. 按一下「完成」。對照表通常會在建立後 12 小時內準備好供查詢。

查看連線詳細資料

連結詳細資料頁面會提供特定連結最近執行的次數和錯誤資訊。如要查看特定連線的詳細資料,請按照下列步驟操作:

  1. 按一下「連線」
  2. 按一下連線名稱即可查看詳細資料。
  3. 您現在可以查看連線的詳細資料和最近執行的情況。每個資料表都會顯示兩種可能的錯誤類型:連線層級 (連線未執行) 和資料列層級錯誤 (未匯入資料列)。
    1. 「Failed」狀態表示整個連線無法執行 (例如服務帳戶權限問題)。按一下錯誤狀態,即可查看哪些錯誤影響了連線。
    2. 「Completed」狀態表示連線已順利執行。不過,資料列可能仍有錯誤,這可從「含有錯誤的列數」欄中的非零值判斷。按一下該值,即可進一步瞭解哪些記錄失敗。

編輯連線

你可以編輯下列詳細資料:

  • 連線名稱
  • 排程
  • 目標資料表
  • 欄位對應

不支援編輯資料來源。如要變更資料來源,請建立新的連結並刪除舊連結。

如要編輯連結詳細資料,請按照下列步驟操作:

  1. 按一下「連線」
  2. 按一下要編輯的連線名稱。
  3. 編輯要變更的詳細資料:
    • 連線名稱:按一下「編輯」,輸入新名稱,然後按下 Enter 鍵。
    • 時間表:按一下「編輯」,設定新的時間表,然後按一下「儲存」
    • 目的地表格:按一下「編輯」,輸入新的目的地名稱,然後按一下「儲存」
    • 欄位對應:按一下 ,變更欄位,然後按一下「儲存」
  4. 按一下 []

查詢相符的資料

查詢對照表

如果對照表包含足夠的資料,可以滿足隱私權檢查的條件,您就能針對資料表執行查詢。

第一方資料 (1PD) 的原始表格會以 my_data 表示。這包括個人識別資訊 (PII) 和非 PII 資料。與比對表相比,使用原始表格可讓報表提供更多洞察資料,因為原始表格代表範圍內的所有 1PD 資料。

廣告資料中心結構定義中,每個包含 user_id 欄位的資料表,都會附帶一個對照表。以 adh.google_ads_impressions 資料表為例,廣告資料中心會產生名為 adh.google_ads_impressions_updm 的對照表,其中包含 User-ID。如果是政策排除資料表,系統會建立個別的對照表。舉例來說,廣告資料中心也會為 adh.google_ads_impressions_policy_isolated_youtube 資料表,產生名為 adh.google_ads_impressions_policy_isolated_youtube_updm 的對照表,其中包含 User-ID。

這些資料表包含原始資料表的一部分使用者,user_id 會有相符項目。舉例來說,如果原始資料表包含使用者 A 和使用者 B 的資料,但只有使用者 A 成功比對,那麼使用者 B 就不會出現在對照表。

對照表包含另一個名為 customer_data_user_id 的資料欄,該欄會以位元組形式儲存使用者 ID。

編寫查詢時,請務必考慮欄位的類型。SQL 比較運算子會認為您要比較的常值類型相同。視第一方資料表儲存 user_id 的方式而定,您可能需要先為資料表中的值編碼,才能比對資料。您必須將彙整鍵轉換為位元組,才能成功比對:

JOIN ON
  adh.google_ads_impressions_updm.customer_data_user_id = CAST(my_data.user_id AS BYTES)

另外,在 SQL 中比較字串時會區分大小寫,因此您可能需要為比較兩方的字串編碼來提高比較準確度。

查詢範例

計算相符的使用者

這項查詢會計算 Google Ads 曝光表中的比對成功使用者人數。

/* Count matched users in Google Ads impressions table */

SELECT COUNT(DISTINCT user_id)
FROM adh.google_ads_impressions_updm

這項查詢會顯示如何彙整第一方資料與 Google Ads 資料:

/* Join first-party data with Google Ads data. The customer_data_user_id field
contains your ID as BYTES. You need to cast your join key into BYTES for
successful matches. */

SELECT
  inventory_type,
  COUNT(*) AS impressions
FROM
  adh.yt_reserve_impressions_updm AS google_data_imp
LEFT JOIN
  `my_data`
ON
  google_data_imp.customer_data_user_id = CAST(my_data.user_id AS BYTES)
GROUP BY
  inventory_type

UPDM 媒合率常見問題

如需 UPDM 媒合率的常見問題清單,請參閱 UPDM 媒合率常見問題