数据仓库(Data Warehouse,DW)是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。与传统的业务数据库不同,数据仓库主要用于数据分析和决策支持,而非日常事务处理。
数据仓库的核心价值在于:
为了更好地组织和管理数据,现代数据仓库通常采用分层架构,常见的分层包括ODS、DWD、DWS和ADS四层。这种分层设计既可以提高数据处理效率,又能保证数据质量和一致性。
ODS层是数据仓库的数据准备区,也是数据仓库的数据缓冲层。其主要职责是将来自不同源系统的原始数据进行简单清洗后存储,保持数据的原貌,为后续的数据加工提供基础。
主要特点:
示例代码(Hive建表):
CREATE EXTERNAL TABLE ods_user_info (
user_id STRING COMMENT '用户ID',
username STRING COMMENT '用户名',
gender STRING COMMENT '性别',
age INT COMMENT '年龄',
register_time STRING COMMENT '注册时间',
update_time STRING COMMENT '更新时间'
) COMMENT '用户信息表'
PARTITIONED BY (dt STRING COMMENT '日期分区')
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS ORC
LOCATION '/warehouse/gmall/ods/ods_user_info';
DWD层是在ODS层基础上,对数据进行清洗转换,并按照业务过程进行划分的明细层。在这一层,数据开始具有业务含义,并且经过了数据质量保障处理。
主要特点:
示例代码(数据清洗和转换):
-- 从ODS层加载数据并进行清洗转换后加载到DWD层
INSERT OVERWRITE TABLE dwd_user_info PARTITION(dt='2023-06-01')
SELECT
user_id,
username,
CASE gender
WHEN 'M' THEN '男'
WHEN 'F' THEN '女'
ELSE '未知'
END as gender,
age,
TO_DATE(register_time) as register_date,
current_timestamp() as etl_time
FROM ods_user_info
WHERE dt='2023-06-01'
AND user_id IS NOT NULL;
DWS层基于DWD层进行轻度汇总,形成主题宽表。这一层主要面向业务主题进行聚合,通常包含特定时间周期(如天、周、月)的汇总数据。
主要特点:
示例代码(主题宽表构建):
-- 构建用户主题日汇总表
INSERT OVERWRITE TABLE dws_user_stats_day PARTITION(dt='2023-06-01')
SELECT
user_id,
MAX(username) as username,
MAX(gender) as gender,
MAX(age) as age,
COUNT(DISTINCT order_id) as order_count,
SUM(order_amount) as total_amount,
AVG(order_amount) as avg_amount
FROM dwd_order_detail
WHERE dt='2023-06-01'
GROUP BY user_id;
ADS层是数据仓库的输出层,直接面向业务应用和分析需求,提供各类报表、仪表盘和分析指标数据。
主要特点:
示例代码(构建销售分析报表):
-- 构建销售分析报表
CREATE TABLE ads_sales_report AS
SELECT
dt,
region_name,
COUNT(DISTINCT user_id) AS user_count,
COUNT(order_id) AS order_count,
SUM(order_amount) AS total_sales,
SUM(order_amount) / COUNT(order_id) AS avg_order_value,
SUM(CASE WHEN is_new_user = 'Y' THEN order_amount ELSE 0 END) AS new_user_sales
FROM dws_sales_stats_day
WHERE dt BETWEEN '2023-06-01' AND '2023-06-30'
GROUP BY dt, region_name
ORDER BY dt, total_sales DESC;
ODS层常用工具:
// Sqoop导入数据示例
public class SqoopImportExample {
public static void main(String[] args) {
String command = "sqoop import " +
"--connect jdbc:mysql://db-server:3306/source_db " +
"--username user --password pass " +
"--table user_info " +
"--target-dir /warehouse/gmall/ods/ods_user_info " +
"--fields-terminated-by '\\t' " +
"--where \"update_time >= '2023-06-01'\" " +
"--m 4";
try {
Process process = Runtime.getRuntime().exec(command);
// 处理执行结果...
} catch (Exception e) {
e.printStackTrace();
}
}
}
DWD和DWS层常用工具:
# PySpark数据处理示例
from pyspark.sql import SparkSession
from pyspark.sql.functions import *
# 创建SparkSession
spark = SparkSession.builder \
.appName("DWD Data Processing") \
.enableHiveSupport() \
.getOrCreate()
# 读取ODS层数据
ods_df = spark.sql("""
SELECT * FROM ods_user_info
WHERE dt = '2023-06-01'
""")
# 数据清洗和转换
dwd_df = ods_df.select(
col("user_id"),
col("username"),
when(col("gender") == "M", "男")
.when(col("gender") == "F", "女")
.otherwise("未知").alias("gender"),
col("age"),
to_date(col("register_time")).alias("register_date"),
current_timestamp().alias("etl_time")
).filter(col("user_id").isNotNull())
# 写入DWD层
dwd_df.write \
.format("orc") \
.mode("overwrite") \
.partitionBy("register_date") \
.saveAsTable("dwd_user_info")
DWS和ADS层常用工具:
-- ClickHouse查询示例
SELECT
toYYYYMM(dt) AS month,
region_name,
SUM(order_amount) AS total_sales,
COUNT(DISTINCT user_id) AS user_count,
total_sales / user_count AS arpu
FROM ads_sales_report
WHERE dt BETWEEN '2023-01-01' AND '2023-06-30'
GROUP BY month, region_name
ORDER BY month, total_sales DESC
LIMIT 10;
ADS层常用工具:
跨层常用工具:
# Great Expectations数据质量检查示例
import great_expectations as ge
# 加载数据
df = ge.read_csv("dwd_user_data.csv")
# 定义期望
expectation_suite = df.expect_column_values_to_not_be_null("user_id")
expectation_suite = expectation_suite.expect_column_values_to_be_between("age", 0, 120)
expectation_suite = expectation_suite.expect_column_values_to_match_regex("email", r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
# 验证数据
validation_result = df.validate(expectation_suite=expectation_suite)
# 输出验证结果
print(validation_result.success)
数据在各层之间流动时,通常遵循以下规则:
数据质量问题:
性能优化:
数据一致性保障:
数据仓库的分层架构(ODS、DWD、DWS、ADS)是大数据领域的经典设计,它通过逐层处理和转换,将原始数据逐步加工为高价值的业务分析资产。不同层次的数据既满足了不同粒度的分析需求,又保障了数据处理的灵活性和可维护性。
随着技术的发展,现代数据仓库架构也在不断演进,出现了数据湖、湖仓一体等新概念。但无论架构如何变化,分层处理的核心思想依然适用。企业在构建数据仓库时,应根据自身业务特点和技术能力,选择合适的架构和工具,打造能真正支撑业务决策的数据平台。