如何在复合字段中使用 RLS
How to use RLS with compund field
在 Redshift 中,我们有一个 table (我们称它为 entity
),它在其他列中有两个重要的:hierarchy_id
& entity_timestampt
,hierarchy_id
是三个层级维度id的组合(A
, B
, C
;每一个与下一个是一对多的关系).
因此:hierarchy_id == A.a_id || '-' || B.b_id || '-' || C.c_id
此外 table 根据 DISTKEY(hierarchy_id)
分配并使用 COMPOUND SORTKEY(hierarchy_id, entity_timestampt)
.
排序
基于此table我们需要生成多个报告,其中一些固定在层次结构的最深处,而另一些将按较高部分过滤并按较低部分对结果进行分组。但是,层次结构的第一层 (A
维度) 定义了我们的安全模型,用户将永远无法访问除他们属于(这是我们的租户信息)。
当我们在普通 SQL 中制作报告原型时,当前的设计被证明对这件事很有用,因为我们可以为深度查询做这样的事情:
WHERE
entity.hierarchy_id = 'fixed_a_id-fixed_b_id-fixed_c_id' AND
entity.entity_timestampt BETWEEN 'start_date' AND 'end_data'
或者像这样按层次结构的其他点进行过滤:
WHERE
entity.hierarchy_id LIKE 'fixed_a_id-%' AND
entity.entity_timestampt BETWEEN 'start_date' AND 'end_data'
这仍然会利用 DISTKEY
和 SORTKEY
设置,即使我们只是针对层次结构的部分路径进行过滤。
现在我们想使用 QuickSight 通过嵌入功能创建和共享这些报告。但是我们还没有找到一种方法来按照我们的意愿过滤分析的数据。
我们尝试通过标签为匿名用户使用 RLS,但我们发现了两个问题:
- 如何在 API 中注入查询的
A.a_id
部分以安全的方式生成嵌入 URL (即用户不能更改它),同时允许他们配置层次结构的其他部分。最后在过滤器中组合这些独立的部分;无需在每次用户更改其他部分时生成新的 URL。
(但是,我们可能会忍受这个限制但是)
- 如何进行局部过滤;即,那些看起来像
LIKE 'fixed_a_id-fixed_b_id-%'
因为看起来 RLS 总是一个相等的条件。
有没有什么方法可以让 QuickSight 在我们当前的 table 设计中按照我们想要的方式工作?或者我们需要更改设计吗?
对于后者,我们考虑过将三个维度 id 保留为单独的列,这样我们可以为 A.a_id
列添加 RLS 并为其他列使用参数,问题在于按较低分组的报告部分层次结构,不清楚我们如何定义 DISTKEY
和 SORTKEY
以便正确优化查询。
COMPOUND SORTKEY(hierarchy_id, entity_timestampt)
您知道您只对 hierarchy_id
的前八个字节进行排序吗?并且区域地图区分块的能力完全基于字符串的前八个字节?
我怀疑如果有三个单独的栏你会做得更好。
Which would still take advantage of the DISTKEY & SORTKEY setup, even though we are filtering just for a partial path of the hierarchy.
我可能错了 - 我需要检查 - 但我认为如果你在排序键上使用任何类型的运算符(例如函数,或 LIKE
,甚至加法或减法),区域地图不运行,您读取了所有块。
同样在你的情况下,它可能是 - 我还没有尝试使用它 - 如果你启用了 AQUA,因为你正在使用 LIKE
,你的整个查询正在由 AQUA 处理。这对性能的影响,正面 and/or 负面,我完全不知道。
您是否一直在使用系统 table 来验证您对区域地图使用方面的查询的预期?
the problem would be for the reports that group by lower parts of the hierarchy, it is not clear how we could define the DISTKEY and SORTKEY so that the queries are properly optimized.
您现在面临的是排序列存储的基本性质;您选择的排序定义了您可以发出的查询,因此也定义了您不能发出的查询。
您可以通过某种方式改变您的数据设计,使您想要的成为可能,或者您可以复制有问题的 table,其中每个副本都有不同的排序顺序。
第一个是艺术,第二个有明显的成本。
顺便说一句,虽然我从未使用过 Quicksight,但我对所有 SQL 生成器的体验是它们完全不关心排序,因此它们发出的 SQL 不能用于大数据(因为排序是及时处理大数据的方法)。
如果你没有大数据,你会没事的,但问题是你为什么要使用 Redshift?
如果您确实拥有大数据,我知道的唯一解决方案是为每个仪表板创建一个聚合 table,大约 10 万行,并让给定的仪表板使用并且只使用那个 table.仪表板通常应该简单地读取整个 table,这很好,然后您可以避免它通常会产生的噩梦 SQL。
在 Redshift 中,我们有一个 table (我们称它为 entity
),它在其他列中有两个重要的:hierarchy_id
& entity_timestampt
,hierarchy_id
是三个层级维度id的组合(A
, B
, C
;每一个与下一个是一对多的关系).
因此:hierarchy_id == A.a_id || '-' || B.b_id || '-' || C.c_id
此外 table 根据 DISTKEY(hierarchy_id)
分配并使用 COMPOUND SORTKEY(hierarchy_id, entity_timestampt)
.
基于此table我们需要生成多个报告,其中一些固定在层次结构的最深处,而另一些将按较高部分过滤并按较低部分对结果进行分组。但是,层次结构的第一层 (A
维度) 定义了我们的安全模型,用户将永远无法访问除他们属于(这是我们的租户信息)。
当我们在普通 SQL 中制作报告原型时,当前的设计被证明对这件事很有用,因为我们可以为深度查询做这样的事情:
WHERE
entity.hierarchy_id = 'fixed_a_id-fixed_b_id-fixed_c_id' AND
entity.entity_timestampt BETWEEN 'start_date' AND 'end_data'
或者像这样按层次结构的其他点进行过滤:
WHERE
entity.hierarchy_id LIKE 'fixed_a_id-%' AND
entity.entity_timestampt BETWEEN 'start_date' AND 'end_data'
这仍然会利用 DISTKEY
和 SORTKEY
设置,即使我们只是针对层次结构的部分路径进行过滤。
现在我们想使用 QuickSight 通过嵌入功能创建和共享这些报告。但是我们还没有找到一种方法来按照我们的意愿过滤分析的数据。
我们尝试通过标签为匿名用户使用 RLS,但我们发现了两个问题:
- 如何在 API 中注入查询的
A.a_id
部分以安全的方式生成嵌入 URL (即用户不能更改它),同时允许他们配置层次结构的其他部分。最后在过滤器中组合这些独立的部分;无需在每次用户更改其他部分时生成新的 URL。
(但是,我们可能会忍受这个限制但是) - 如何进行局部过滤;即,那些看起来像
LIKE 'fixed_a_id-fixed_b_id-%'
因为看起来 RLS 总是一个相等的条件。
有没有什么方法可以让 QuickSight 在我们当前的 table 设计中按照我们想要的方式工作?或者我们需要更改设计吗?
对于后者,我们考虑过将三个维度 id 保留为单独的列,这样我们可以为 A.a_id
列添加 RLS 并为其他列使用参数,问题在于按较低分组的报告部分层次结构,不清楚我们如何定义 DISTKEY
和 SORTKEY
以便正确优化查询。
COMPOUND SORTKEY(hierarchy_id, entity_timestampt)
您知道您只对 hierarchy_id
的前八个字节进行排序吗?并且区域地图区分块的能力完全基于字符串的前八个字节?
我怀疑如果有三个单独的栏你会做得更好。
Which would still take advantage of the DISTKEY & SORTKEY setup, even though we are filtering just for a partial path of the hierarchy.
我可能错了 - 我需要检查 - 但我认为如果你在排序键上使用任何类型的运算符(例如函数,或 LIKE
,甚至加法或减法),区域地图不运行,您读取了所有块。
同样在你的情况下,它可能是 - 我还没有尝试使用它 - 如果你启用了 AQUA,因为你正在使用 LIKE
,你的整个查询正在由 AQUA 处理。这对性能的影响,正面 and/or 负面,我完全不知道。
您是否一直在使用系统 table 来验证您对区域地图使用方面的查询的预期?
the problem would be for the reports that group by lower parts of the hierarchy, it is not clear how we could define the DISTKEY and SORTKEY so that the queries are properly optimized.
您现在面临的是排序列存储的基本性质;您选择的排序定义了您可以发出的查询,因此也定义了您不能发出的查询。
您可以通过某种方式改变您的数据设计,使您想要的成为可能,或者您可以复制有问题的 table,其中每个副本都有不同的排序顺序。
第一个是艺术,第二个有明显的成本。
顺便说一句,虽然我从未使用过 Quicksight,但我对所有 SQL 生成器的体验是它们完全不关心排序,因此它们发出的 SQL 不能用于大数据(因为排序是及时处理大数据的方法)。
如果你没有大数据,你会没事的,但问题是你为什么要使用 Redshift?
如果您确实拥有大数据,我知道的唯一解决方案是为每个仪表板创建一个聚合 table,大约 10 万行,并让给定的仪表板使用并且只使用那个 table.仪表板通常应该简单地读取整个 table,这很好,然后您可以避免它通常会产生的噩梦 SQL。