Ch 8 数据仓库设计(Redshift)¶
面包屑
本书主页 › Part II 架构设计 › Ch 8
项目第 0-1 年 · 架构设计期→核心建设期——数仓奠基
本章你将学到¶
- Redshift 集群架构与 Spectrum 外部表的设计
- 分层 schema 设计与 Kimball 维度建模在平台中的应用
- Redshift 行级安全(RLS)与列级安全(CLS)策略——数据仓库的安全基石
- Redshift vs Snowflake vs BigQuery 的工程取舍
数据湖解决了"存储"问题(Ch 7),但"分析查询"需要数据仓库。在数据湖上用 Athena 做 ad-hoc 查询可以,但 BI 报表的高频复杂查询、多表 join 和聚合计算,还是需要一个真正的列式 MPP 数据仓库。
选 Redshift 的过程在 Ch 2 已经讲过——四年前 Snowflake 未入华,Redshift 是 AWS China 上唯一靠谱的云数仓选项。但"选了 Redshift"只是开始,怎么用好它才是真正的工程挑战。
我在企业征信项目里用过 PostgreSQL 做数仓——能跑,但数据量到 TB 级后查询就慢得不可接受。PostgreSQL 是行式 OLTP 数据库,不适合大规模分析查询;Redshift 是列式 MPP(大规模并行处理)数据库,天然为分析场景设计。这个"行式 vs 列式"、"单机 vs MPP"的差别,是数仓设计的底层认知。
8.1 Redshift 集群架构与 Spectrum 外部表¶
集群架构¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
subgraph Redshift集群["Redshift 集群"]
LEADER@{ icon: "logos:aws-redshift", form: "rounded", label: "Leader Node<br/>查询规划与分发", pos: "b", h: 44 }
CN1[Compute Node 1<br/>数据存储+计算]
CN2[Compute Node 2]
CN3[Compute Node 3]
CN4[Compute Node 4]
end
CLIENT@{ icon: "codicon:person", form: "rounded", label: "BI / DaaS / 分析师", pos: "b", h: 40 } -->|SQL| LEADER
LEADER --> CN1 & CN2 & CN3 & CN4
CN1 -.->|Spectrum 查询| S3@{ icon: "logos:aws-s3", form: "rounded", label: "S3 数据湖", pos: "b", h: 40 }
CN2 -.->|Spectrum 查询| S3
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
class LEADER bpProcess
class CN1,CN2,CN3,CN4 bpProcess
class CLIENT bpExternal
class S3 bpData
linkStyle default stroke:#697077,stroke-width:2px
图 8-1 集群架构
Redshift 采用 MPP(大规模并行处理)架构:Leader Node 负责接收 SQL、生成执行计划并分发到 Compute Nodes;Compute Nodes 各自存储部分数据并并行执行。平台使用 RA3 节点类型——计算与存储分离架构,数据可缓存在本地 SSD,大量数据留在 S3。
选 RA3 而非 DC2,是我和企业征信教训对比后做的决策。企业征信时用 DC2(计算存储耦合)节点——数据全在本地 SSD,查询快,但扩容时要"加节点+重新分配数据",停机维护半天。到 Aurora 我选 RA3(计算存储分离)——数据主要在 S3,本地 SSD 只做缓存,扩容时"加节点即可",数据不用重分配,几分钟完成。这个差异在第二年业务域从 3 个涨到 6 个时兑现了价值:有次 BI 查询高峰导致集群负载告警,我加了 2 个 RA3 节点,5 分钟生效,全程无停机——如果用 DC2,同样的扩容要停机半天重分配数据。计算存储分离不是理论优势,是"在线扩容"的实操能力。
RA3 还有一个隐性好处——它和 Spectrum(下节)天然配合。RA3 的数据本就在 S3,Spectrum 查 S3 外部表时,数据不用"搬运",直接在 S3 上扫描。这让"本地表+外部表混合查询"的性能损耗降到最低。如果用 DC2,数据在本地 SSD,查外部表要从 S3 拉数据,跨存储层延迟显著。节点选型和数据湖集成是联动的决策,不能割裂考虑。
Spectrum:数据湖的"外部表"¶
Redshift Spectrum 让 Redshift 可以直接查询 S3 数据湖中的数据,无需先 COPY 入仓:
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
subgraph 数据湖["S3 数据湖"]
RAW[Raw 层 Parquet]
ENR[Enriched 层 Parquet]
end
subgraph Redshift["Redshift"]
EXT[外部 Schema<br/>Spectrum 外部表]
LOCAL[本地 Schema<br/>已 COPY 入仓的表]
RS_QUERY[SQL 查询引擎]
end
RAW -->|外部表映射| EXT
ENR -->|外部表映射| EXT
EXT --> RS_QUERY
LOCAL --> RS_QUERY
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
class RAW,ENR bpData
class EXT bpProcess
class LOCAL bpData
class RS_QUERY bpProcess
linkStyle default stroke:#697077,stroke-width:2px
图 8-2 Spectrum:数据湖的"外部表"
| 查询方式 | 数据位置 | 适合场景 |
|---|---|---|
| 本地表 | Redshift 内部存储 | 高频查询、复杂 join、性能敏感 |
| Spectrum 外部表 | S3 数据湖 | 低频查询、探索性分析、避免重复存储 |
表 8-1 Spectrum:数据湖的"外部表"
"Spectrum 外部表 vs COPY 入仓"的决策,我在项目第一年定了一个简单规则:高频查询的表 COPY 入仓,低频或大体量的表用 Spectrum。这个规则看起来简单,但判断"高频低频"需要数据——我在 Redshift 的 stl_query 系统表里跑了一个查询统计,发现 80% 的查询集中在 20% 的表上(经典的二八定律)。那 20% 的表 COPY 入仓(本地表,查询快),剩下 80% 用 Spectrum(省存储,按需查)。这个"按查询频率分流"的策略让存储成本降了约 40%,高频查询性能不受影响。
但 Spectrum 有一个我在初期低估的坑——它按扫描量计费。有一次分析师写了个 SELECT * 查了张 500GB 的外部表,单次查询费用几百块。从那以后我定了规则:外部表查询必须带分区过滤(WHERE date >= ...),并在 BI 工具层做了 SQL 审查拦截全表扫描。Spectrum 的"按需查询"是双刃剑——灵活但容易失控,必须有成本护栏(呼应 附录 G FinOps)。
引申
Spectrum 的价值是"按需查询数据湖而不必全量入仓"。比如某个历史归档表很大但很少查,放本地浪费存储,放 S3 用 Spectrum 按需查更经济。这是"湖仓一体"的雏形——数据湖和数据仓库通过外部表打通。
8.2 模式设计:分层 schema 与 Kimball 维度建模¶
Schema 分层¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
subgraph Redshift_Schema分层["Redshift Schema 分层"]
META[metadata schema<br/>运行元数据:审计日志/加载历史/变更日志]
STAGE[etl_stage schema<br/>暂存表:从 S3 COPY 的原始暂存]
SPECTRUM[外部 schema<br/>Spectrum 映射数据湖]
ENR[enriched_* schema<br/>加工后的维度/事实表]
end
S3[S3 Enriched] -->|COPY| STAGE
STAGE -->|加工| ENR
S3 -.->|外部表| SPECTRUM
ENR -->|记录| META
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
class META bpInfo
class STAGE bpProcess
class SPECTRUM bpData
class ENR bpSuccess
class S3 bpData
linkStyle default stroke:#697077,stroke-width:2px
图 8-3 Schema 分层
| Schema | 职责 | 谁写入 | 谁读取 |
|---|---|---|---|
metadata |
运行元数据(审计/加载历史/DDL 变更) | ETL 框架自动 | 运维/排障/合规 |
etl_stage |
暂存表(从 S3 COPY 的中间态) | ETL 框架 | 下游加工步骤 |
| 外部 schema | Spectrum 映射 S3 数据湖 | 数据目录 | 探索性查询 |
enriched_* |
各业务域的维度/事实表 | ETL 框架 | BI/DaaS/AI |
表 8-2 Schema 分层
这四层 schema 的划分,是我在企业征信"单 schema 大杂烩"教训基础上设计的。企业征信时所有表都在一个 public schema 里——ETL 暂存表、维度事实表、审计日志表全混在一起。后果是:BI 工具连上来看到几百张表,分不清哪些是"分析就绪"哪些是"中间垃圾";更糟的是,有个分析师误查了 ETL 暂存表,拿到的数据是半加工的,报表数字错了两天才发现。到 Aurora 我把 schema 分成四层,核心目的是让"表的状态"一目了然——etl_stage 是"加工中,别碰",enriched_* 是"加工完,可用",metadata 是"元数据,运维用",外部 schema 是"数据湖探索"。BI 工具只授权访问 enriched_*,从权限层杜绝了"误查暂存表"。
metadata schema 单独列出是我特别想强调的设计。很多团队的数仓没有独立的元数据 schema——审计日志、加载历史、DDL 变更散落各处或根本没记。我在企业征信时也犯过这个错,结果排障时"不知道这张表什么时候被谁改过",全靠猜。到 Aurora 我把 metadata 作为一等 schema,ETL 框架自动记录每次加载的批次、行数、耗时、状态——这个设计后来在 GxP 审计时被审计员评为"数据完整性可追溯性优秀"。元数据不是事后补的日志,是数仓的一等公民(M10 合规嵌入)。
Kimball 维度建模¶
enriched_* schema 内部采用 Kimball 维度建模:
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
erDiagram
DIM_HOSPITAL ||--o{ FACT_PRESCRIPTION : "医院维度"
DIM_DOCTOR ||--o{ FACT_PRESCRIPTION : "医生维度"
DIM_PRODUCT ||--o{ FACT_PRESCRIPTION : "产品维度"
DIM_DATE ||--o{ FACT_PRESCRIPTION : "日期维度"
DIM_HOSPITAL {
string hospital_key PK
string hospital_name
string region
string tier
}
FACT_PRESCRIPTION {
string prescription_key PK
string hospital_key FK
string doctor_key FK
string product_key FK
date date_key FK
int quantity
decimal amount
}
图 8-4 Kimball 维度建模
| 表类型 | 作用 | 特征 |
|---|---|---|
| 维度表(Dimension) | 描述业务实体 | 宽表、变化慢、用于过滤和分组 |
| 事实表(Fact) | 记录业务事件 | 窄表、增长快、包含度量值和外键 |
表 8-3 Kimball 维度建模
选 Kimball 而非 Data Vault 或 Inmon,是我在项目第一周和团队争论后拍板的。Data Vault 的拥护者认为它"更适合大规模集成、变更管理好"——这理论上成立,但有个代价:Data Vault 的查询性能差,需要在上面再建一层星型模型供 BI 查询——等于建了两层模型(Vault + Mart),工作量翻倍。对于 Aurora 这个规模(20000+ 表但分析查询为主),Kimball 的"一层星型模型直接服务 BI"更务实——建模成本是 Data Vault 的一半,查询性能更好。
但我要诚实地说 Kimball 的痛点——SCD(缓慢变化维)管理。医院的级别从"三甲"变成"三甲+专科"时,是覆盖旧值(SCD1)还是保留历史(SCD2)?SCD2 要加 effective_from/effective_to 字段,维度表行数膨胀,BI 查询要带时间条件——复杂度不低。我在第一年低估了这个复杂度,导致第二年初医院维度改了三次级别,SCD2 逻辑写错了,报表"历史某时间点的医院级别"全错。花了三天修。Kimball 的代价不在"建模型",而在"管变化"——如果数据域维度变化频繁,SCD 管理成本会吃掉 Kimball 的性能优势。这是选型时要权衡的。
Trade-off
Kimball 维度建模是数据仓库的经典方法论,优势是查询性能好、业务理解直观。代价是维度变更管理复杂(SCD 类型 1/2/3 的选择)和建模成本高。另一种选择是 Data Vault——更适合大规模集成但查询性能差,需要再建一层星型模型供查询。对于以分析查询为主的场景,Kimball 仍是务实选择——但要做好 SCD 管理的心理准备。
8.3 Redshift 行级安全(RLS)与列级安全(CLS)策略¶
这是数据仓库安全设计的核心。Redshift 提供两种细粒度安全策略,平台将其作为数据治理的基石。
引申:数据库安全的发展脉络
数据库安全经历了从粗到细的演进:最早只有"库级权限"(能/不能访问这个库)→ "表级权限"(能/不能访问这张表)→ "行级安全 RLS"(能访问表,但只看到特定行)→ "列级安全 CLS"(能访问行,但特定列不可见)→ "单元格级安全"(行×列交叉控制)。每一代都在前一代基础上增加粒度。Redshift 同时支持 RLS 和 CLS,这让平台能在不改变查询 SQL 的前提下实现细粒度数据隔离——用户写 SELECT * FROM fact_prescription,RLS 自动加 WHERE region='华东',CLS 自动隐藏 patient_id_card 列。用户无感,但数据安全了。这种"声明式安全"是现代数仓区别于传统数仓的重要能力。
RLS(Row-Level Security):行级安全¶
RLS 控制谁能看到哪些行。例如:华东区销售只能看到华东区的处方数据。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TD
USER[用户登录<br/>角色=华东销售] --> QUERY[查询 FACT_PRESCRIPTION]
QUERY --> RLS[RLS 策略引擎]
RLS -->|自动注入过滤| FILTER[WHERE region = '华东']
FILTER --> RESULT[仅返回华东区数据]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
class USER bpExternal
class QUERY bpProcess
class RLS bpDecision
class FILTER bpInfo
class RESULT bpSuccess
linkStyle default stroke:#697077,stroke-width:2px
图 8-5 RLS(Row-Level Security):行级安全
RLS 策略绑定到角色(Role),查询时自动注入行级过滤条件,用户无需(也无法)手动绕过。
选 RLS 而非"应用层过滤",是我在企业征信教训基础上做的决策。企业征信时数据隔离靠应用层——BI 工具查询时拼接 WHERE region=?,参数由应用传入。问题有三个:一是不可靠——开发者忘了拼 WHERE,或拼错了,数据就泄露了;二是难审计——安全审计员要检查"每个查询是否正确过滤",但过滤逻辑散落在各应用里,没法统一审计;三是重复——每个应用都要实现一遍过滤逻辑,维护成本高。到 Aurora 我选 RLS——过滤逻辑绑定在数据库层,应用层只管发 SELECT *,数据库自动注入过滤。安全责任从"每个应用开发者"收敛到"数据库管理员"——一处配置,全局生效,可审计。
RLS 还有一个我在第四年才意识到的战略价值——它是 Agentic BI 的安全基石。当 AI Agent 代用户查询数仓时(见 Ch 46 数据平面与 CDP 整合),Agent 用的数据库角色继承用户的 RLS 策略——华东用户的 Agent 只能查华东数据,即使 Agent 的 SQL 没带区域过滤,RLS 也会兜底。如果当时选了应用层过滤,Agent 时代就要重新给每条 SQL 拼过滤——而 RLS 让"安全策略"与"查询方式"解耦,AI 来了也不用改。好的安全设计是面向未来的——它不预测未来用什么查询,但保证任何查询都安全(M10 合规嵌入的长期回报)。
典型应用:
| 场景 | RLS 策略 |
|---|---|
| 区域隔离 | 华东销售只能看华东数据 |
| 业务域隔离 | SCI 团队只能看 SCI 域数据 |
| 租户隔离(AI 场景) | 不同租户的 Agent 只能查自己租户的数据 |
表 8-4 RLS(Row-Level Security):行级安全
CLS(Column-Level Security):列级安全¶
CLS 控制谁能看到哪些列。例如:普通分析师能看到处方数量但不能看到患者身份证号。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
subgraph FACT_PRESCRIPTION表["FACT_PRESCRIPTION 表"]
C1[处方编号<br/>所有人可见]
C2[医院名称<br/>所有人可见]
C3[处方数量<br/>所有人可见]
C4[患者身份证<br/>仅合规角色可见]
C5[患者姓名<br/>仅合规角色可见]
end
ANALYST@{ icon: "codicon:person", form: "rounded", label: "普通分析师", pos: "b", h: 40 } --> C1 & C2 & C3
COMPLIANCE@{ icon: "codicon:shield", form: "rounded", label: "合规角色", pos: "b", h: 40 } --> C1 & C2 & C3 & C4 & C5
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
class C1,C2,C3 bpSuccess
class C4,C5 bpError
class ANALYST bpExternal
class COMPLIANCE bpExternal
linkStyle default stroke:#697077,stroke-width:2px
图 8-6 CLS(Column-Level Security):列级安全
CLS 通过列级 GRANT 实现:对敏感列只授予特定角色,其他角色查询时会报权限错误(或看不到该列)。
CLS 的设计驱动力是 PIPL 的"最小必要"原则——分析师查处方数据时,需要看"处方数量、医院、产品"来做销售分析,但不需要看"患者身份证、患者姓名"。如果用视图(View)实现,要为每个角色建一个视图,视图数量爆炸(N 个表 × M 个角色 = N×M 个视图)。CLS 让我直接在表上做列级 GRANT——一个角色一个 GRANT 语句,不用建视图。CLS 是"声明式"的,视图是"命令式"的——声明式更简洁、更不容易出错。
我在第一年用 CLS 时踩过一个坑——SELECT * 的行为。普通分析师跑 SELECT * FROM fact_prescription 时,因为 patient_id_card 列没授权,Redshift 会报权限错误而不是"自动跳过该列"。这导致 BI 工具的 SELECT * 查询全挂。解决方案是改 BI 工具的查询为显式列名(SELECT prescription_id, hospital_name, quantity FROM ...),只查授权的列。这个调整花了一周——但长期收益是 BI 查询更规范了,不再有 SELECT * 的坏习惯。CLS 倒逼了查询规范化——这是个意外但正向的副作用。
RLS + CLS + 脱敏的协同分层¶
平台构建了三层纵深防御:
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
L1[第一层:RLS<br/>行级——控制能看到哪些行<br/>区域/租户/业务域隔离]
L2[第二层:CLS<br/>列级——控制能看到哪些列<br/>敏感字段隔离]
L3[第三层:脱敏 UDF<br/>值级——控制看到的值是什么<br/>mask/加密/哈希]
L1 --> L2 --> L3
QUERY[SQL 查询] --> L1
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
class L1 bpInfo
class L2 bpInfo
class L3 bpInfo
class QUERY bpProcess
linkStyle default stroke:#697077,stroke-width:2px
图 8-7 RLS + CLS + 脱敏的协同分层
| 层 | 粒度 | 防护对象 | 详见 |
|---|---|---|---|
| RLS | 行 | 防止跨区域/租户数据泄露 | 本章 |
| CLS | 列 | 防止敏感字段被未授权访问 | 本章 |
| 脱敏 UDF | 值 | 即使看到字段,值也是脱敏后的 | Ch 18 |
表 8-5 RLS + CLS + 脱敏的协同分层
引申
三层防护的关系是"纵深防御"(Defense in Depth)——即使某一层被绕过,其他层仍能兜底。比如 RLS 配置错了导致跨区域可见,CLS 仍能阻止敏感列被访问;CLS 漏配了某列,脱敏 UDF 仍能让值不可读。这是安全架构的核心原则:不依赖单一防线。
8.4 引申:Redshift vs Snowflake vs BigQuery 的工程取舍¶
| 维度 | Redshift | Snowflake | BigQuery |
|---|---|---|---|
| 架构 | MPP(计算存储分离 RA3) | 原生云数仓(多集群共享存储) | Serverless(无集群概念) |
| 计费 | 按节点小时 | 按仓库大小+使用时长 | 按查询扫描量 |
| 扩展 | 弹性集群(增减节点) | 多虚拟仓库独立扩展 | 自动弹性 |
| 数据湖集成 | Spectrum(外部表) | 外部表 + 原生 Iceberg | 外部表 + BigLake |
| 半结构化 | SUPER 类型 | VARIANT 类型(原生) | STRUCT/ARRAY(原生) |
| RLS/CLS | ✅ 原生支持 | ✅ 原生支持 | ✅ 原生支持 |
| 中国可用性 | ✅(AWS China) | ✅(已入华) | ❌(GCP China 有限) |
| 运维负担 | 中(需管集群) | 低(高度托管) | 最低(Serverless) |
表 8-6 引申:Redshift vs Snowflake vs BigQuery 的工程取舍
Trade-off
四年前选 Redshift 的核心原因是"AWS China 可用 + 与 S3/Glue 生态集成"。如果今天选,Snowflake 在托管体验和半结构化数据处理上更优,且已入华。但 Redshift 的优势是与 AWS 生态深度集成(Spectrum/IAM/Glue 原生协作)+ 成本可控(按节点而非按查询)。两者都是合理选择,取决于团队偏好和生态锁定容忍度。
本章小结¶
- Redshift 采用 MPP 架构,RA3 节点实现计算存储分离;Spectrum 外部表打通数据湖与数据仓库
- Schema 分四层:metadata(元数据)/ etl_stage(暂存)/ 外部 schema(Spectrum)/ enriched_*(维度建模)
enriched_*采用 Kimball 维度建模:维度表 + 事实表,查询性能好、业务直观- 安全基石:RLS(行级)+ CLS(列级)+ 脱敏 UDF(值级)三层纵深防御
- Redshift vs Snowflake vs BigQuery:各有优劣,四年前选 Redshift 是 AWS China 生态约束下的务实选择
下一章
Ch 9 计算与 ETL 设计(Glue + Lambda) —— 仓库设计好了,数据怎么加工?接下来看计算层的选型与控制面/数据面分离。