---
code: track_update_and_track_overwrite
name: "可更新事件"
wikiToken: P5ryw0zcmi9CJBk5S0LclWSEnlh
parentWikiToken: Ljs3w406DiyDLnktFuAcHogInvg
updateTime: 1745309946000
sourceUrl: https://docs-v2.thinkingdata.cn/?version=v5.0&lan=zh-CN&code=track_update_and_track_overwrite
---
# 可更新事件

本章节将介绍 AE 系统的特殊数据结构——可更新事件的使用方法。可更新事件是一种**特殊的事件数据**，可以对数据中的事件属性值进行更新，适合记录包含可变状态值或者可变累计值的事件数据，例如成本事件，可随时间推移对属性`成本金额`进行更新。

::: warning

 可更新事件的存储以及处理的性能开销很大，为了保证数据处理效率以及查询性能，只适用于事件量较少、且在特殊业务场景下有较强的更新需求的事件，强烈建议在 AE 工作人员的协助下进行使用

 :::

### 一、数据结构

<!-- unsupported block: 34 -->

使用 AE 客户端 SDK 或服务端 SDK，可查看对应 SDK 的接入指南，指南中“可更新事件”及“可重写事件”章节将会提供详细的接口调用方法

使用”可更新事件“特性，需要在数据中进行两个调整：

1. 将标识数据类型的字段`#type`设置为`track_update`或`track_overwrite`，这两种数据类型分别表示两种事件的更新方式：更新部分属性与重写所有属性
1. 增加字段`#event_id`，该字段是事件的唯一标识；在更新属性时，会根据`#event_name`与`#event_id`查找对应的事件数据，并对该条数据进行更新；不同事件的`#event_id`互相独立，因此每个可更新事件拥有一套单独的唯一标识体系
以下是一条数据样例，可以关注`#event_id`的所在位置：

```
{
  "#account_id": "ABCDEFG-123-abc",
  "#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#type": "track_update",
  "#event_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#time": "2020-08-18 14:37:28.527",
  "#event_name": "test_event",
  "properties": {
    "argString": "abc"
  }
}
```

### 二、数据处理逻辑

可更新事件在处理逻辑上和普通的事件数据有很大的差异：**请注意，如果一条事件数据的**`#type`**为**`track`**，则该条数据无法在之后被更新**；如果一条事件数据的`#type`为`track_update`或`track_overwrite`，就会被视为可更新事件，则之后可以使用两类数据中的任意一类对属性进行更新。

AE 系统收到`track_update`或`track_overwrite`时会有不一样的处理方式，本节将会详细描述这两类数据的处理逻辑。

#### 2.1 track_update 的处理逻辑

数据中的`#type`为`track_update`时，数据的处理逻辑为事件属性更新。当系统收到该类型数据时，会根据`#event_id`字段查找对应事件数据在是否存在，如果存在，则会更新对应的字段，具体的处理逻辑如下：

1. 若该事件下不存在`#event_id`对应的数据，该数据视为新增数据，将会直接入库
1. 若`#event_id`存在，则新传入数据中的事件属性将会更新先前值，如果有新属性，也会将新属性加入进来，新传入数据中不包含的属性将不会被更新，因此只需要传入要被更新的属性即可
1. 此外`#time`即事件时间也会被新数据更新，因此需根据实际业务场景，对新传入数据中的时间进行合理设置
#### 2.2 track_overwrite 的处理逻辑

数据中的`#type`为`track_overwrite`时，数据的处理逻辑为事件重写。当系统收到该类型数据时，会根据`#event_id`字段查找对应事件数据在是否存在，如果存在，则会删除该条数据，并且将新的事件数据写入到系统内（相当于替换了被删除的那条数据），具体的处理逻辑如下：

1. 若该事件下不存在`#event_id`对应的数据，该数据视为新增数据，将会直接入库
1. 若`#event_id`存在，则该条事件数据的所有内容都会重写，如需更新部分属性，可使用`track_update`
1. 此外`#time`即事件时间也会被新数据更新，因此需根据实际业务场景，对新传入数据中的时间进行合理设置
### 三、最佳实践

#### 广告成本

在广告成效分析时，往往需要计算广告位或素材的 ROI 投入产出比，也就是用户价值与用户成本的比值。用户的价值，即直接付费与其它方式产生价值的总和，是容易记录的；而成本数据，则会依赖于广告投放端的数据规则，一般成本金额会持续更新，不适合用一般的事件数据进行记录。

由于成本数据会持续变化，广告成本数据很适合通过可更新数据的方式来进行记录，首次记录广告成本数据时，可以上传如下数据：

```
{
  "#account_id": "admin",
  "#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#type": "track_update",
  "#event_id": "2020-09-01_google_7-Tier1-0527_adset1_adname1",
  "#time": "2020-09-01 00:00:00.000",
  "#event_name": "ad_cost",
  "properties": {
    "channel": "google",
    "campaignid": "7-Tier1-0527",
    "adset": "adset1",
    "adname": "adname1",
    "cost": 100
  }
}
```

以上数据将会新增一条成本的可更新事件，其中`#event_id`由日期、渠道、活动名、广告组、广告名的拼接而成，作为成本的唯一 ID，从数据逻辑上而言，这也是成本事件可更新的最细粒度；`cost`字段记录此时广告的成本 100 元。

随着时间推移，广告投放渠道的推送了新的成本数据，新的广告成本为 200，则可以发送如下数据，其中`#event_id`需要和之前的数据保持一致，代表更新先前的那条数据；更新的是`cost`字段，传入新成本值 200；由于`#time`也会被新数据更新，此处需要和之前保持一致，传入的是成本的日期（转化为时间类型）。其它字段如渠道、活动、广告位，由于没有不需要更新，所以数据中可以不填写。

```
{
  "#account_id": "admin",
  "#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#type": "track_update",
  "#event_id": "2020-09-01_google_7-Tier1-0527_adset1_adname1",
  "#time": "2020-09-01 00:00:00.000",
  "#event_name": "ad_cost",
  "properties": {
    "cost": 200
  }
}
```

当系统收到该条事件时，会查询该`#event_id`是否已经存在，发现存在后，会将原始数据（也就是第一条样例数据）中的`#time`以及`cost`字段进行更新，即完成了成本事件成本金额的更新操作。
