在 Redshift 中存储事件数据的最佳方式是啥?

Posted

技术标签:

【中文标题】在 Redshift 中存储事件数据的最佳方式是啥?【英文标题】:What's the best way to store event data in Redshift?在 Redshift 中存储事件数据的最佳方式是什么? 【发布时间】:2017-07-23 04:19:07 【问题描述】:

我是 Redshift 新手,正在寻找存储事件数据的最佳方式。数据由标识符、时间和有关当前状态的 JSON 元数据组成。

我正在考虑三种方法:

    为每种事件类型创建一个表,并为每条数据创建一个列。 为事件创建单个表并将元数据存储为 JSON 字段。 为我可能要存储的每条可能的数据创建一个包含一列的表。

#1 的优点是我可以过滤所有数据字段,并且解决方案更加灵活。缺点是每次我想添加一个新事件时,我都必须创建一个新表。

#2 的优点是我可以将所有类型的事件放在一个表中。缺点是过滤元数据中的任何数据,我需要在每一行上使用 JSON 函数。

#3 的优点是我可以轻松访问所有字段而无需运行函数,并且不必为每种类型创建新表。缺点是使用数据的人需要记住要忽略哪些列。

是其中一种方式比其他方式更好,还是我完全错过了什么?

【问题讨论】:

你考虑过雅典娜还是迪纳摩? @Henry 据我所知,我会遇到与非结构化数据相同的问题 + 我希望拥有 Redshift 的灵活性。 纯粹从数据库的角度来看,3是最好的,1是最差的。有趣的是,稀疏列上的这个 sn-p 建议选项 2。forums.aws.amazon.com/thread.jspa?threadID=134407 数据输入的速度以及需要报告的速度有多快?这提供了一些线索,即 JSON 是否应该在进入(即成无数列)或退出时被切碎。你的 JSON 是扁平的还是分层的?如果它是分层的,那么很难在单行上放入一堆扁平列 红移有什么“灵活性”? 【参考方案1】:

这是一个典型的困境。经过一段时间的思考,在我的公司中,我们最终将事件的公共属性保留在单独的列中,并将唯一属性保留在 JSON 字段中。常用属性示例:

事件类型,时间戳(每个事件都有) URL(后端事件和移动应用事件将缺少该 URL,但所有前端事件都存在,值得在单独的列中使用) 客户端属性:设备、浏览器、操作系统(后端会缺失,但会出现在移动应用事件和前端事件中)

独特属性示例(其他事件中没有此类属性):

AB 测试事件中的测试名称和变体 购买事件中的产品名称或 ID

通用属性和唯一属性之间的界限是您自己的判断,具体取决于有多少事件共享该属性以及该属性在分析查询中用于过滤或分组数据的频率。如果某些属性只是“不错的”并且它不涉及常规分析用例(是的,我们都喜欢存储任何可跟踪的东西以防万一)维护单独列的负担是过度的。

此外,如果您有一些在查询中广泛使用的独特属性,那么还有一种优化方法。您可以将此属性放在 JSON 列的开头(是的,在 Python 中 JSON 没有排序,但在 Redshift 中它是一个字符串,因此可以根据需要固定键的顺序)并仅在字段结束:

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 中存储事件数据的最佳方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

AWS中ETL流程的最佳方式是啥

在反应器内存储事件处理程序的最佳方式是啥

在数据库中表示“重复事件”的最佳方式是啥?

Redshift 的最佳加载路径是啥?

在数据库中存储货币价值的最佳方式是啥?

在数据库中存储货币价值的最佳方式是啥?