跳转至

Vertica 访问策略最佳实践

原文:Best Practices for Using Access Policies

概述

Vertica 访问策略(Access Policies)提供了一种灵活且强大的方式来控制用户对数据库中数据的访问。通过列级和行级安全策略,您可以实现细粒度的数据隔离,而无需为每个用户创建单独的视图。

Vertica 支持两种类型的访问策略:

  • 列访问策略(Column Access Policy):限制用户对特定列的访问
  • 行访问策略(Row Access Policy):限制用户对特定行的访问

这两种策略可单独使用,也可组合使用,以满足复杂的多租户和合规性需求。

列访问策略 (Column Access Policy)

列访问策略允许您控制用户对表中特定列的查询能力。当用户无权访问某列时,Vertica 会返回如下结果之一:

  • NULL 值
  • 掩码后的值(通过自定义掩码函数)
  • 完全隐藏该列

创建列访问策略

CREATE ACCESS POLICY ON table_name FOR COLUMN column_name 
    CASE 
        WHEN ENABLED('role_name') THEN column_name
        ELSE NULL
    END
    ENABLE;

最佳实践:

  • 为不同角色创建差异化的列访问策略,而非逐个用户设置
  • 对敏感数据列(如身份证号、手机号、薪资)使用掩码函数而非直接返回 NULL
  • 列访问策略应在表创建后、数据加载前配置完毕

列掩码示例

-- 创建掩码函数
CREATE FUNCTION mask_phone(phone VARCHAR) RETURN VARCHAR AS
BEGIN
    RETURN CONCAT(SUBSTR(phone, 1, 3), '****', SUBSTR(phone, 8, 4));
END;

-- 应用列访问策略
CREATE ACCESS POLICY ON customers FOR COLUMN phone 
    CASE 
        WHEN ENABLED('admin') THEN phone
        ELSE mask_phone(phone)
    END
    ENABLE;

行访问策略 (Row Access Policy)

行访问策略允许您控制用户对表中特定行的可见性。通过定义行级过滤条件,Vertica 会在查询执行时自动添加过滤条件,确保用户只能访问符合条件的数据。

创建行访问策略

CREATE ACCESS POLICY ON table_name FOR ROWS
    CASE 
        WHEN ENABLED('admin') THEN true
        ELSE tenant_id = CURRENT_USER()
    END
    ENABLE;

最佳实践:

  • 行访问策略应基于用户属性(如角色、租户 ID)而非固定值
  • 确保管理员角色具有不受限制的访问权限
  • 对于多租户场景,使用 tenant_id 字段作为行级过滤条件

多租户行过滤示例

CREATE ACCESS POLICY ON sales_data FOR ROWS
    CASE 
        WHEN ENABLED('sysadmin') THEN true
        WHEN ENABLED('regional_manager') THEN region = get_user_region(CURRENT_USER())
        ELSE tenant_id = get_user_tenant(CURRENT_USER())
    END
    ENABLE;

组合列与行访问策略

列访问策略和行访问策略可以同时应用于同一张表,提供双向的数据安全保护。组合使用时,Vertica 先应用行级过滤,再应用列级掩码,确保数据在两个维度上都受到控制。

组合策略示例

-- 行级别:按租户过滤
CREATE ACCESS POLICY ON orders FOR ROWS
    CASE 
        WHEN ENABLED('admin') THEN true
        ELSE customer_id IN (SELECT id FROM customers WHERE tenant_id = CURRENT_TENANT())
    END
    ENABLE;

-- 列级别:对金额列脱敏
CREATE ACCESS POLICY ON orders FOR COLUMN amount
    CASE 
        WHEN ENABLED('finance') THEN amount
        ELSE ROUND(amount, -2)
    END
    ENABLE;

最佳实践: - 先设计行级策略,再设计列级策略 - 测试组合策略下的查询性能,特别是当行级策略涉及子查询时 - 谨慎使用复杂的行级过滤条件,以免影响查询优化器的执行计划

查询重写 (Query Rewriting)

当 Vertica 执行查询时,访问策略通过查询重写机制生效。Vertica 优化器会自动将访问策略中的过滤条件注入查询计划中,用户无需修改查询语句。

访问策略重写的工作流程:

  1. 用户提交 SQL 查询
  2. Vertica 解析查询并检查访问策略
  3. 优化器根据用户角色和策略注入适当的过滤条件或列掩码
  4. 执行重写后的查询计划

查询重写的影响

  • 行级策略:优化器会在查询的 WHERE 子句中自动追加过滤条件
  • 列级策略:优化器会替换用户访问的列为掩码后的表达式
  • 两种策略均在优化阶段处理,运行时无额外开销

性能测试 (Performance Testing)

在生产环境中启用访问策略前,应进行充分的性能测试。

测试要点

  1. 查询延迟对比:对比启用和未启用访问策略时相同查询的执行时间
  2. 并发负载测试:模拟多用户并发访问场景,验证行级过滤条件下的吞吐量
  3. 复杂策略测试:测试涉及子查询的行级策略对性能的影响
  4. JOIN 操作影响:测试包含 JOIN 的查询在访问策略下的执行计划变化

性能监控 SQL

-- 查看访问策略相关的查询性能
SELECT 
    user_name, 
    request_type, 
    transaction_id, 
    statement_id,
    schema_name, 
    table_name, 
    access_policy_used
FROM query_requests 
WHERE access_policy_used IS NOT NULL 
ORDER BY start_time DESC;

-- 检查执行计划中是否包含访问策略过滤
EXPLAIN SELECT * FROM orders WHERE customer_id = 1001;

最佳实践: - 在测试环境中完成性能验证后再部署到生产 - 对行级策略中使用的子查询创建合适的投影,确保过滤条件能高效下推 - 监控 resource_usage 系统表,观察访问策略引入后的资源消耗变化 - 定期审查访问策略的使用频率和有效性,移除不再需要的策略

扩展阅读