在Redshift中存储事件数据的最佳方法是什么?

时间:2017-07-23 04:19:08

标签: database amazon-web-services amazon-redshift data-warehouse bigdata

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

我正在考虑三种方法:

  1. 为每个事件类型创建一个表,其中包含每个数据的列。
  2. 为事件创建一个表,并将元数据存储为JSON字段。
  3. 为我可能想要存储的每个可能的数据创建一个包含列的表。
  4. #1的优点是我可以过滤所有数据字段,解决方案更灵活。缺点是每次我想添加一个新事件时我都要创建一个新表。

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

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

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

1 个答案:

答案 0 :(得分:3)

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

  • 事件类型,时间戳(每个事件都有)
  • URL(对于后端事件和移动应用程序事件,这将丢失,但是对于所有前端事件都存在,并且值得在单独的列中显示)
  • 客户端属性:设备,浏览器,操作系统(后端将丢失,但会出现在移动应用事件和前端事件中)

唯一属性的示例(在其他事件中没有此类属性):

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

公共属性和唯一属性之间的边界是您自己的判断,基于共享此属性的事件数量以及在分析查询中使用此属性来过滤或分组数据的频率。如果某些房产只是“很好”,那就是#34;并且它不涉及常规分析用例(是的,我们都喜欢存储任何可跟踪的内容以防万一)维护单独列的负担是过度的。

此外,如果您在查询中广泛使用了一些独特的属性,那么有一种优化的hacky方法。您可以将此属性放在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,找到密钥并检查值,但它只检查字符串以子字符串开头(操作便宜得多)。