# 数据规则
本章节将会详细介绍 TA 后台的数据结构、数据类型以及数据限制。通过本章节,您将了解如何构建符合规则的数据,排查数据传输问题。
如果您使用的是 LogBus 或 RESTful API 上传数据,需要按照本章节中的数据规则对数据进行格式处理。
# 一、数据结构
TA 后台接受的是符合规则的 JSON 数据:如果使用的是 SDK 接入,则数据将会被转化成 JSON 数据进行传输。如果使用 LogBus 或 POST 方法上传数据,则数据需要是符合规则的 JSON 数据。
JSON 数据以行为单位:即一行一条 JSON 数据,对应物理意义上的一条数据,数据意义上对应的是用户产生一次行为,或者是设置一次用户属性。
数据格式及要求如下(为了方便阅读,数据经过排版,真实环境下请勿换行):
- 以下是事件数据的样例:
{
"#account_id": "ABCDEFG-123-abc",
"#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
"#type": "track",
"#ip": "192.168.171.111",
"#uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"#time": "2017-12-18 14:37:28.527",
"#event_name": "test",
"properties": {
"argString": "abc",
"argNum": 123,
"argBool": true
}
}
- 以下是用户属性设置的样例:
{
"#account_id": "ABCDEFG-123-abc",
"#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
"#type": "user_set",
"#uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"#time": "2017-12-18 14:37:28.527",
"properties": {
"userArgString": "abc",
"userArgNum": 123,
"userArgBool": true
}
}
"#type"的值可以替换为"user_setOnce"、"user_add"、"user_unset"、"user_append"、"user_del"
从结构和功能上,可以将一条 JSON 数据分为两个部分:
properties 的同层其他字段,组成了该条数据的基本信息,其中只包括以下几项:
- 表示触发用户的账号 ID
#account_id
与访客 ID#distinct_id
- 表示触发时间
#time
,可精确到秒或毫秒 - 表示数据类型(事件还是用户属性设置)的
#type
- 表示事件名称的
#event_name
(仅事件数据带有) - 表示用户 IP 的
#ip
- 表示数据唯一性的
#uuid
请注意,除以上几项外,其余以“#”开头的属性都需要放在 properties 的内层
properties 的内层,是该条数据的内容,也就是事件中的属性,或者需要设置的用户属性,在后台分析时作为属性或分析对象被直接使用。
从结构上来看,这两部分与报文头(Header)和报文体(Content)有些类似,接下来将会详细介绍这两部分各字段的含义。
# 1.1 数据信息部分
如下图红框标识,与"properties"同层的数个字段组成了该条数据的信息部分:
这些字段包含了这条数据的触发用户、触发时间等数据信息,其特点是所有字段都以“#”开头,本节将会梳理各字段的意义以及如何配置。
# 1.1.1 用户信息(#account_id与#distinct_id)
#account_id
与#distinct_id
是 TA 后台用来识别用户的两个字段,其中#account_id
为用户在登录状态下的 ID,#distinct_id
为用户在未登录状态下标识,TA 后台会根据这个两个字段判断该行为的触发用户,其中优先根据#account_id
进行判断,具体规则参见用户识别规则一章。
#account_id
与#distinct_id
至少要传入一个,如果所有事件都是在用户登录状态下触发的,则只传入#account_id
是可行的,如果有事件是在未登录状态(包括注册前)触发的,则建议将两个字段都填入。
# 1.1.2 数据类型信息(#type与#event_name)
#type
决定了该条数据的类型,是用户的行为记录、还是修改用户属性的操作处理,每一条数据都需要配置#type
字段。#type
的取值分为两类,track
代表这条数据是用户行为记录,以user_
开头代表对用户属性进行操作,具体意义如下:
- track:向事件表传入一个事件,事件的上传都为 track
- user_set:对用户表进行操作,覆盖一个或多个用户属性,如果该属性已有值存在,覆盖先前值
- user_setOnce:对用户表进行操作,初始化一个或多个用户属性,如果该属性已有值存在,则忽略本次操作
- user_add:对用户表进行操作,为一个或多个数值型用户属性做累加计算
- user_unset:对用户表进行操作,清空该名用户的一个或多个用户属性的属性值
- user_del:对用户表进行操作,删除该名用户
- user_append:对用户表进行操作,为用户的列表类型属性值添加元素
- user_uniq_append: 对用户表进行操作,为用户的列表类型属性值添加元素,并会进行一次全列表去重(去重保证前后原有的元素顺序不变)
当#type
的取值为track
时,即该条数据是行为记录时,必须配置事件的名称#event_name
,必须以字母开头,只能包含:字母(区分大小写)、数字和下划线“_”,长度最大为 50 个字符。请注意配置时不要带有空格。如果该条数据是修改用户属性的操作,则不需要#event_name
字段。
需要注意的是,用户属性是用户具有节点意义的属性,不建议在短时间内进行频繁修改,对于需要频繁变更的属性,建议放在事件中作为事件属性
# 1.1.3 触发时间(#time)
#time
为事件产生的时间,必须要配置,格式必须是精确到毫秒("yyyy-MM-dd HH:mm:ss.SSS")或秒("yyyy-MM-dd HH:mm:ss")的字符串
尽管对 User 表的操作数据也需要配置#time
,但对于用户属性的操作会按照后台收到数据的先后顺序进行操作。
比如用户重传了过去某天的 User 表操作数据,则无论是属性的覆盖还是初始化都会照常进行,并不会根据#time 字段进行判断
# 1.1.4 触发地点(#ip)
#ip
是设备的 IP 地址,可选配置,TA 将会根据 IP 地址计算用户的地理位置信息,如果您在"properties"中传入了#country、#province、#city 等地理位置属性,则会以您传入的值为准
# 1.1.5 数据唯一 ID(#uuid)
#uuid
是用以表示数据唯一性的字段,可选配置,格式必须为 uuid 的标准格式。TA 将会根据数据量,将会在一段时间内,在接收端校验是否短时间内出现相同#uuid
的数据(即重复数据),并将重复数据直接抛弃,不再入库
需注意,通过#uuid
进行的接收端校验只会对近几个小时接收到的数据进行校验,主要解决因网络抖动问题造成的短时数据重复,无法将接收到的数据与全量数据进行校验。如需对数据进行去重,请联系 TA 工作人员。
# 1.2 数据主体部分
数据的另一部分,则是properties
内层所包含的数据,properties
是一个 JSON 对象,里面的数据以键值对的形式表示。如果是用户行为数据,其代表了该行为的属性及指标(相当于行为表中的字段),这些属性及指标可在分析时直接使用;如果是用户属性的操作处理,则代表需要设置的属性内容。
key 值为该属性的名称,类型是字符串,自定义的属性必须以字母开头,只能包含:字母(忽略大小写)、数字和下划线“_”,且长度最大只能 50 个字符;另外还存在以#
开头的 TA 预置属性,您可以在预置属性一章中了解更多信息,但需要注意,大多数情况下建议只使用自定义的属性,不使用#。
value 值为该属性的值,可以是数值、文本、时间、布尔、列表、对象、对象组,数据类型的表示方式如下表所示:
TA 数据类型 | 取值样例 | 取值说明 | 数据类型 |
---|---|---|---|
数值 | 123,1.23 | 数据范围是-9E15 至 9E15 | Number |
文本 | "ABC","上海" | 字符的默认上限是 2KB | String |
时间 | "2019-01-01 00:00:00","2019-01-01 00:00:00.000" | "yyyy-MM-dd HH:mm:ss.SSS"或"yyyy-MM-dd HH:mm:ss",如需表示日期,可使用"yyyy-MM-dd 00:00:00" | String |
布尔 | true,false | - | Boolean |
列表 | ["a","1","true"] | 列表中的元素都会转变为字符串类型 ,列表内最多500个元素 | Array(String) |
对象 | {"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false} | 对象内的每个子属性(Key)都有自己的数据类型,取值说明请参考上面对应类型的普通属性 对象内最多100个子属性 | Object |
对象组 | [{"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false}, {"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false}] | 对象组内的每个子属性(Key)都有自己的数据类型,取值说明请参考上面对应类型的普通属性 对象组内最多500个对象 | Array(Object) |
需要注意,所有属性的类型会根据第一次收到该属性值的类型所决定,后续数据的类型必须与相应属性的类型一致,类型不匹配的属性将被丢弃(该条数据其余符合类型的属性将保留),TA 不会进行类型的兼容转换。
# 二、数据处理规则
TA 服务器在收到数据之后,会进行一些处理,本节将会结合实际使用场景,TA 后台的处理规则:
# 2.1 收到新事件数据
在收到新增事件的数据后,TA 后台会自动地创建新增事件与其属性的关联模型;如果收到了新的属性,则首次收到该属性时的属性类型将会设置为该属性的类型,属性的类型之后将不能修改。
# 2.2 增添事件的属性
如果需要对已有事件增添属性,只需要在上传数据时将新增属性一并传入即可,TA 后台将会动态地关联事件与新增属性,不需要进行其他配置。
# 2.3 属性不一致的处理
当收到一条事件数据,其中某属性的类型与后台已存的该属性的类型不一致,则该属性的值将会被抛弃(即取值为 null)。
# 2.4 弃用事件属性
如果需要弃用事件某个属性,则只需要在 TA 后台的元数据管理中将该属性隐藏即可,后续传输的数据可不传该属性。TA 后台不会删除该属性的数据,隐藏操作也是可逆的,如果在属性被隐藏后仍传输该属性,该属性的值仍会被保留。
# 2.5 多事件共有属性
不同事件的同名属性被视为是同一属性,类型一致,因此需要保证所有同名属性的类型一致,以避免由于类型不一致而导致的属性值被抛弃。
# 2.6 用户表操作逻辑
修改用户在用户表中的数据,也就是上报数据中#type
字段为user_set
、user_setOnce
、user_add
、user_unset
、user_append
或user_del
的数据,本质上可以看作是一条指令,也就是对该条数据所指用户的用户表数据进行操作,操作的类型由#type
字段决定,而操作的内容以properties
中的属性所决定。
以下是主要的用户表属性操作的具体逻辑:
# 2.6.1 覆盖用户属性(user_set)
根据数据中的用户 ID 确定进行操作的用户,再根据properties
中的属性,覆盖所有属性,如果某个属性不存在则新建该属性。
# 2.6.2 初始化用户属性(user_setOnce)
根据数据中的用户 ID 确定进行操作的用户,再根据properties
中的属性,对未赋值(为空)的属性进行设置,如果该用户的某需要设置的属性已经有值,则不会进行覆盖,如果某个属性不存在则新建该属性。
# 2.6.3 累加用户属性(user_add)
根据数据中的用户 ID 确定进行操作的用户,再根据properties
中的属性,对数值型的属性进行累加操作,如果传入负值相当于原属性值减去传入值,如果该用户的某需要设置的属性未赋值(为空),则会默认设置为 0 后再进行累加操作,如果该属性不存在则新建该属性。
# 2.6.4 清空用户属性值(user_unset)
根据数据中的用户 ID 确定进行操作的用户,再根据properties
中的属性,清空其中的所有属性(即设置成 NULL),如果某个属性不存在不会新建该属性。
# 2.6.5 添加列表型用户属性的元素(user_append)
根据数据中的用户 ID 确定进行操作的用户,再根据properties
中的属性,对列表型的属性进行添加元素操作
# 2.6.6 删除用户(user_del)
根据数据中的用户 ID 确定进行操作的用户,将该用户从用户表中删除,该用户的事件数据不会被删除。
# 三、数据限制
- 事件类型及属性数量限制
出于性能考虑,TA 后台会默认地对项目的事件类型及属性的数量进行限制:
限制 | 事件种类上限 | 事件属性上限 | 用户属性上限 |
---|---|---|---|
建议不超过 | 100 | 300 | 100 |
硬件上限 | 500 | 1000 | 500 |
管理员可以进入“项目管理”页面,可查询各项目已经使用的事件类型以及属性数,联系 TA 工作人员可申请上调事件种类、属性属性的上限。
- 账号 ID(#account_id)、访客 ID(#distinct_id)长度限制
* 3.1版本之前创建的项目:64个字符;如需扩大至128个字符,请联系TA工作人员
* 3.1版本及之后创建的项目:128个字符
- 事件、属性名称限制
* 事件名:`String`类型,以字母开头,可包含数字,大小写字母和下划线“\_”,长度最大为50个字符
* 属性名:`String`类型,以字母开头,可包含数字,字母(忽略大小写)和下划线“\_”,长度最大为50个字符。只有预置属性能以#号开头。
- 文本、数值、列表、对象、对象组类型属性数据范围
* 文本:字符串上限是2KB
* 数值:数据范围是-9E15至9E15
* 列表:最多包含500个元素;每个元素为字符串类型,且上限为255字节
* 对象:最多包含100个子属性;
* 对象组:最多包含500个对象;
- 数据接收时限
* 服务端数据接收事件上限:相对服务器时间的前三年至后3天
* 客户端数据接收事件上限:相对服务器时间的前10天至后3天
# 四、其他规则
- 请以 UTF-8 对数据进行编码,以避免乱码问题
- TA 后台的属性名不区分大小写,建议使用"_"作为分词分隔符
- TA 后台默认只接收最近三年的数据,超过三年的数据将无法录入,如需录入三年之前的数据,可联系 TA 工作人员放宽时限
# 五、常见问题
本节总结了由于数据不符合数据规则而引起的常见问题,如果出现了数据传输问题,可以先根据本节内容进行排查
# 5.1 TA 后台没有收到数据
如果使用的是 SDK 传输:
- 请确认 SDK 是否被成功集成
- 排查 APPID 与传输的 URL 是否设置正确,传输端口号及传输方式对应后缀有无遗漏
如果使用的是 LogBus 或 POST 方法传输:
- 请确认 APPID 与传输的 URL 是否设置正确,传输端口号及传输方式对应后缀有无遗漏
- 请检查数据是否以 JSON 格式传输,并确保一行一条 JSON 数据
- 请检查数据信息部分的 key 值是否以"#"开头,是否遗漏了必要字段
- 请检查数据信息部分的 value 值的类型与格式(时间格式)是否正确
- 请检查"#event_name"的 value 值是否符合规范,不包含汉字,空格等字符
- "properties"请不要以"#"开头
- 另外,请注意用户属性设置并不会产生行为记录,因此如果只上传了
user_set
等数据,在后台的行为分析模型(除 SQL 查询外)中无法直接查询到数据 - 请注意上传数据的时间,过早时间(超过三年)的数据将不会录入;如果上传数据为历史数据,则可能是查询时段没有涵盖上传数据的时间,请调整查询时段
# 5.2 数据有缺失,某些属性没有收到
- 请确认数据主体部分的属性 key 值符合规范,不包含汉字,空格等字符
- 请确认数据主体部分的属性中,以"#"开头 key 值属于预置属性
- 请检查缺失属性在上传时的类型是否与后台该属性的类型一致,可在后台的元数据管理中查看已收到属性的类型
# 5.3 数据传输有误,希望删除数据
- 私有化服务的用户,可使用数据删除工具自助式的删除数据;如果是云服务的用户,可联系 TA 工作人员进行数据删除
- 如果数据有较大改动,建议直接新建项目,建议用户在正式传输数据之前先在测试项目下进行完备的数据测试