用户提供的数据匹配

用户提供的数据匹配 (UPDM) 会将您收集的关于用户的第一方数据(例如来自您的网站、应用或实体店的信息)与该用户在所有 Google 广告数据(包括 Google 自有自营的数据)中的登录活动相联接。这包括通过 Google Marketing Platform (GMP) 产品购买的数据,例如使用 Display & Video 360 购买的 YouTube 数据。不支持非 Google 自有自营的其他 GMP 产品。

若要使用用户提供的数据匹配这一功能,广告事件必须与 Google 广告数据涉及的已登录用户相关联。

本文档介绍了用户提供的数据匹配功能,并提供了有关设置和使用方面的指南。

概览

若要获得有价值的广告数据分析,通常需要将来自多个来源的数据整合在一起。若要自行构建解决此数据流水线问题的解决方案,需要投入大量时间和工程资源。广告数据中心的“关联”页面提供了一个分步引导式界面,可用于将数据导入、转换和匹配到 BigQuery,从而简化此流程,以便您在广告数据中心查询或其他任何从 BigQuery 读取的产品中使用这些数据。使用第一方数据丰富查询可以带来更丰富的客户体验,并且更能抵御整个行业的广告跟踪更改。

借助“关联”页面中提供的工具,您可以以注重隐私保护的方式加密个人身份信息 (PII) 并与合作伙伴分享。选择包含个人身份信息 (PII) 的列后,广告数据中心会对数据进行加密,确保只有有权限的用户才能导出或读取您的第一方数据。确定衡量或启用用例需要哪些第一方数据可能很困难,因此广告数据中心提供了预定义用例的完整列表,并引导您完成数据提取、转换和加载的整个流程。虽然您可以创建多种类型的连接,但本文档假定您使用“关联”页面进行用户提供的数据匹配。

您可以从以下数据源导入数据:

  • BigQuery
  • Cloud Storage
  • 安全 FTP (sFTP)
  • Snowflake
  • 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 分享从欧洲经济区 (EEA) 最终用户那里收集的数据。此要求适用于每个广告数据中心账号,且每次上传新的第一方数据时都必须更新意见征求结果。任何一个用户都可以代表整个账号进行这项确认。

请注意,适用于分析查询的 Google 服务查询规则,同样也适用于 UPDM 查询。例如,创建匹配表时,您不能对欧洲经济区 (EEA) 境内用户运行跨服务查询。

若要了解如何在广告数据中心内确认用户同意情况,请参阅欧洲经济区用户意见征求要求

数据大小

为保护最终用户的隐私,用户提供的数据匹配功能会强制执行以下与数据大小有关的要求:

  • 您必须在用户名单中上传至少 1,000 条记录。
  • 每次成功更新匹配表都必须包含一定数量的新匹配用户。此行为类似于差异检查
  • 您的列表不得超过记录数量上限。如需了解最高数据流量上限,请与您的 Google 代表联系。

设置数据提取

在开始之前,您需要配置广告数据中心账号以创建数据关联,这是建立数据匹配流水线的方法。您只需执行这些步骤一次。

连接页面中,点击开始设置,以在 UPDM 启用阶段打开账号设置向导。

前往关联

如果您将 UPDM 设置为与 BigQuery 或 Cloud Storage 搭配使用,请参阅此参考文档,了解向广告数据中心服务账号授予的权限。

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 项目
Datafusion 服务账号
用途 Data Fusion 服务账号用于在广告数据中心界面中显示来源字段列表。
格式 service-some-number@gcp-sa-datafusion.iam.gserviceaccount.com
所需的访问权限
Storage Object Viewer
roles/storage.objectViewer
数据源项目中的特定存储分区
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 编码。
  • 纯文本
  • 哈希处理:无
  • 去除空格
  • 所有字符均须采用小写格式
  • 所有电子邮件地址都必须有域名,例如 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
  • 对于所有其他国家/地区:
    • 无需格式设置(无需转换为小写,也不必移除空格和特殊字符)
    • 请勿添加扩展邮编
  • 哈希处理:无

哈希验证和数据编码

您可以使用以下哈希验证脚本确保数据格式正确无误。

Base16Base64
/**
 * @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()
/**
 * @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()
Base16Base64
"""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()
"""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()
Base16Base64
/*
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")
}
/*
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")
}
Base16Base64
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");
  }
}
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");
}
}
Base16Base64
/*
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`;
/*
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 的访问权限。

    点击“应用”以授予对 Cloud Storage 的访问权限。

    输入您的 MySQL 数据库位置、端口、用户名和密码。

    输入您的 Amazon S3 私有访问密钥

    输入您的 PostgreSQL 数据库位置、端口、用户名、密码和数据库。

    输入您的 Redshift 数据库位置、端口、用户名、密码和数据库。

    输入您的 sFTP 服务器位置、用户名和密码。

    输入您的 Snowflake 账号标识符、用户名和密码。

  4. 配置数据源,然后点击下一步

    选择要导入的 BigQuery 表。

    输入 gsutil 路径(例如 gs://my-bucket/folder/),然后选择文件的格式。

    如果这是您首次关联此资源,系统会显示一条提醒。点击“应用”以授予访问权限,然后点击“下一步”。注意:您的角色必须有权为相关存储分区委托 storage.buckets.setIamPolicy

    选择要使用的 MySQL 数据库和表。

    输入要上传的文件相对于主机地址的 URI。

    输入 PostgreSQL 架构和表(或视图)名称。

    输入 Redshift 架构和表(或视图)名称。默认情况下,Redshift 使用遵循以下模板的数据库位置网址:cluster-identifier.account-number.aws-region.redshift.amazonaws.com

    输入文件路径和名称,格式为 /PATH/FILENAME.csv

    输入您要使用的 Snowflake 数据库、架构和表(或视图)。

  5. 选择要用作中间目标位置的 BigQuery 数据集,然后点击下一步。这一步可确保数据格式正确无误
  6. 可选:修改数据格式。转换包括计算哈希、小写/大写格式设置以及合并/拆分字段。
    1. 依次点击操作 > > 转换
    2. 在随即弹出的面板中,点击添加转换添加其他转换
    3. 从下拉菜单中选择转换类型,然后输入要求。
    4. 点击保存
  7. 选择至少一个联接键,然后映射要使用的字段。 广告数据中心会自动映射名称相同的字段(以 表示)。进行必要的修改,然后点击下一步
  8. 设置时间表:
    1. 为连接命名。
    2. 设置频率,以指定将数据导入您在上一步中选择的数据集的频率。每次运行都会覆盖目标表中的数据。
    3. 指定您希望如何处理用户 ID 冲突。您可以选择保留现有匹配项,也可以使用新数据覆盖现有匹配项。
  9. 点击完成。匹配表通常在创建 12 小时后即可进行查询。

查看连接详细信息

通过连接详情页面,您可以了解给定连接的近期运行情况和错误。如需查看特定连接的详细信息,请执行以下操作:

  1. 点击连接
  2. 点击连接名称以查看其详细信息。
  3. 现在,您可以查看关联的详细信息和近期运行情况。每个报告都显示两种可能的错误类型:连接级错误(连接未运行)和行级错误(未导入行)。
    1. “失败”状态表示整个连接运行失败(例如服务账号权限问题)。点击错误状态,查看哪些错误影响了连接。
    2. 已完成状态表示连接已成功运行。不过,可能仍存在行级错误,这由“出错的行数”列中的非零值表示。点击该值可详细了解哪些记录失败。

修改连接

您可以修改以下详细信息:

  • 连接名称
  • 时间表
  • 目标表
  • 字段映射

不支持修改数据源。如需更改数据源,请创建新连接并删除旧连接。

如需修改连接详情,请执行以下操作:

  1. 点击连接
  2. 点击要修改的关联的名称。
  3. 修改您要更改的详细信息:
    • 连接名称:点击修改,输入新名称,然后按 Enter 键。
    • 时间表:点击修改,设置新时间表,然后点击保存
    • 目标表:点击修改,输入新的目标表名称,然后点击保存
    • 字段映射:点击 ,更改字段,然后点击保存
  4. 点击

查询匹配的数据

查询匹配表

如果匹配表包含的数据足以满足隐私权检查要求,就可以针对该表运行查询。

第一方数据 (1PD) 的原始表由 my_data 表示。 这包括个人身份信息 (PII) 和非个人身份信息数据。与匹配表相比,使用原始表可以让报告包含更多数据洞见,因为它代表了范围内的所有 1PD 数据。

广告数据中心架构中包含 user_id 字段的每个表都附带一个匹配表。例如,对于 adh.google_ads_impressions 表,广告数据中心还会生成一个名为 adh.google_ads_impressions_updm 的匹配表,其中包含您的用户 ID。对于因政策而隔离的表,系统会创建单独的匹配表。例如,对于 adh.google_ads_impressions_policy_isolated_youtube 表,广告数据中心还会生成一个名为 adh.google_ads_impressions_policy_isolated_youtube_updm 的匹配表,其中包含您的用户 ID。

这些表都包含原始表中在 user_id 方面匹配的一部分用户。例如,如果原始表包含用户 A 和用户 B 的数据,但只有用户 A 是匹配项,那么用户 B 将不会出现在匹配表中。

匹配表包含一个额外的列,名为 customer_data_user_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 匹配率常见问题解答