在 Redshift 中存储事件数据的最佳方式是什么?
What's the best way to store event data in Redshift?
我是 Redshift 的新手,正在寻找存储事件数据的最佳方式。数据由标识符、时间和有关当前状态的 JSON 元数据组成。
我正在考虑三种方法:
- 为每个事件类型创建一个 table,每个数据都有一个列。
- 为事件创建一个 table 并将元数据存储为 JSON 字段。
- 创建一个 table,其中包含我可能想要存储的每条可能数据的列。
#1 的优点是我可以对所有数据字段进行过滤,而且解决方案更加灵活。缺点是每次我想添加一个新事件我都必须创建一个新的 table.
#2 的优点是我可以将所有类型的事件放在一个 table 中。缺点是过滤元数据中的任何数据我需要在每一行上使用 JSON 函数。
#3 的优点是无需 运行 函数即可轻松访问所有字段,并且不必为每种类型创建新的 table。缺点是使用数据的人需要记住要忽略哪些列。
这些方法中的一种是否比其他方法更好,还是我完全遗漏了什么?
这是一个经典的困境。经过一段时间的思考,在我的公司,我们最终将事件的共同属性保留在单独的列中,并将独特的属性保留在 JSON 字段中。通用属性示例:
- 事件类型、时间戳(每个事件都有)
- URL(后端事件和移动应用程序事件将缺失,但所有前端事件都存在,值得在单独的列中包含)
- 客户端属性:设备、浏览器、OS(将在后端丢失,但会出现在移动应用程序事件和前端事件中)
独特属性示例(其他事件中没有此类属性):
- AB 测试事件中的测试名称和变体
- 购买事件中的产品名称或 ID
普通和独特之间的界限 属性 是您自己的判断,基于有多少事件共享此 属性 以及此 属性 在分析查询中用于过滤或过滤的频率组数据。如果一些 属性 只是 "nice-to-have" 并且它不涉及常规分析用例(是的,我们都喜欢存储任何可跟踪的东西以防万一)维护一个单独的列的负担是多余的.
此外,如果您有一些独特的 属性 并在查询中广泛使用,则有一种优化方法。您可以将此 属性 放在 JSON 列的开头(是的,在 Python JSON 中未排序,但在 Redshift 中它是一个字符串,因此键的顺序如果需要可以修复)并仅在字段末尾使用 LIKE 和通配符:
select *
from event_table
where event_type='Start experiment'
and event_json like '{"test_name":"my_awesome_test"%' -- instead of below
-- and json_extract_path_text(event_json,'test_name')='my_awesome_test'
LIKE 使用这种方式比 JSON 查找快得多(快 2-3 倍),因为它不需要扫描每一行、解码 JSON、找到密钥并检查值,但它只检查字符串是否以子字符串开头(操作成本低得多)。
我是 Redshift 的新手,正在寻找存储事件数据的最佳方式。数据由标识符、时间和有关当前状态的 JSON 元数据组成。
我正在考虑三种方法:
- 为每个事件类型创建一个 table,每个数据都有一个列。
- 为事件创建一个 table 并将元数据存储为 JSON 字段。
- 创建一个 table,其中包含我可能想要存储的每条可能数据的列。
#1 的优点是我可以对所有数据字段进行过滤,而且解决方案更加灵活。缺点是每次我想添加一个新事件我都必须创建一个新的 table.
#2 的优点是我可以将所有类型的事件放在一个 table 中。缺点是过滤元数据中的任何数据我需要在每一行上使用 JSON 函数。
#3 的优点是无需 运行 函数即可轻松访问所有字段,并且不必为每种类型创建新的 table。缺点是使用数据的人需要记住要忽略哪些列。
这些方法中的一种是否比其他方法更好,还是我完全遗漏了什么?
这是一个经典的困境。经过一段时间的思考,在我的公司,我们最终将事件的共同属性保留在单独的列中,并将独特的属性保留在 JSON 字段中。通用属性示例:
- 事件类型、时间戳(每个事件都有)
- URL(后端事件和移动应用程序事件将缺失,但所有前端事件都存在,值得在单独的列中包含)
- 客户端属性:设备、浏览器、OS(将在后端丢失,但会出现在移动应用程序事件和前端事件中)
独特属性示例(其他事件中没有此类属性):
- AB 测试事件中的测试名称和变体
- 购买事件中的产品名称或 ID
普通和独特之间的界限 属性 是您自己的判断,基于有多少事件共享此 属性 以及此 属性 在分析查询中用于过滤或过滤的频率组数据。如果一些 属性 只是 "nice-to-have" 并且它不涉及常规分析用例(是的,我们都喜欢存储任何可跟踪的东西以防万一)维护一个单独的列的负担是多余的.
此外,如果您有一些独特的 属性 并在查询中广泛使用,则有一种优化方法。您可以将此 属性 放在 JSON 列的开头(是的,在 Python JSON 中未排序,但在 Redshift 中它是一个字符串,因此键的顺序如果需要可以修复)并仅在字段末尾使用 LIKE 和通配符:
select *
from event_table
where event_type='Start experiment'
and event_json like '{"test_name":"my_awesome_test"%' -- instead of below
-- and json_extract_path_text(event_json,'test_name')='my_awesome_test'
LIKE 使用这种方式比 JSON 查找快得多(快 2-3 倍),因为它不需要扫描每一行、解码 JSON、找到密钥并检查值,但它只检查字符串是否以子字符串开头(操作成本低得多)。