维度退化: 通过减少表的数量和提高数据的冗余来优化查询性能。
在维度退化中,相关的维度数据被合并到一个宽表中,减少了查询时需要进行的表连接操作。例如,在销售数据仓库中,客户信息、产品信息和时间信息等维度可能会被合并到一个单一的销售事实表中。这样,查询时只需访问一个表,而不必连接多个表,从而提高了查询效率。
做宽表的原因:
把多张表内容合并到一张表>>提升查询速度
弊端: 占更多的内存
数仓的本质>>用空间换时间
做主题宽表
1.业务人员告知需要的字段>>直接create table
2.业务人员没有告知
先确定需要用来做宽表的表>>事实表/与主题相关>>确认主表副表(left join)>>重复字段只保留主表的字段
很少选择第二种>>因为不能写注释; 只能建普通表,不能建分区表/分桶表
示例
步骤:
1.建DWB数据库
create database dwb;
2.建相应的主题宽表:(比如创建订单明细宽表)
先从事实表里面确认所需要的表(参照数据字典表了解表的实际内容)
t_goods_evaluation 订单评价表(主题相关)
t_goods_evaluation_detail 商品评价表(无关主题)
数据字典表(中英对照)
把订单主表(t_shop_order)确定为表连接的主表,其余为副表
主表的确定
业务需求分析
-
核心业务实体:明确业务需求,找出核心业务实体,如订单、客户、产品等。
-
高频查询:分析高频查询,确定哪些表最常被访问。
数据关系分析
-
主外键关系:通过主外键关系确定主表,通常主表包含核心业务数据,其他表通过外键关联。
-
数据粒度:选择粒度最细的表作为主表,确保宽表包含最详细的信息。
数据量分析
-
数据量大小:选择数据量较大的表作为主表,避免宽表数据量过大。
-
更新频率:选择更新频率较低的表作为主表,减少宽表维护成本。
工具支持
-
数据建模工具:使用数据建模工具分析表关系,辅助确定主表。
-
ETL工具:利用ETL工具自动化宽表构建,减少手动操作。
表字段的确定
主表字段全部保留
订单主表(t_shop_order)
副表字段
fact_shop_order_group (订单组表)
id是自增列,用来确保数据的唯一性(不保留)
order_id 用来和主表关联的字段,主表已存在(不保留)
其他字段,和主表重复(不保留)
t_shop_order_address_detail(订单副表)
id是和主表的关联字段(不保留)
其余字段,和主表重复(不保留)
t_order_pay(订单支付表)
t_refund_order (退款订单表)
t_order_settle(订单结算表)
t_shop_order_goods_details(订单商品快照表)
id自增列主键(不保留)
order_id 主表关联字段, 主表已经存在(不保留)
shop_store_id 店铺id, buyer_id 买家id 在主表中已存在(不保留)
其他字段, 主表中已经存在(不保留)
t_goods_evaluation(订单评价表)
user_id 评论人id=主表的buyer_id 买家id; 主表已经存在(不保留)
t_order_delievery_item(配送信息表 )
id 自增列(不保留)
shop_order_id 订单id, 和主表关联的字段, 主表已经存在(不保留)
refund_order_id 在副表t_shop_order_goods_details(订单商品快照表)已经存在(不保留)
shop_store_id 店铺id, buyer_id 买家id 在主表已经存在(不保留)
circle_master_user_id 在副表t_order_settle(订单结算表)已经存在(不保留)
dispatcher_user_id 在副表t_order_settle(订单结算表)已经存在(不保留)
sql
create table dwb.dwb_order_detail
as
selecto.id,o.order_num,o.buyer_id,o.store_id,o.order_from,o.order_state,o.create_date,o.finnshed_time,o.is_settlement,o.is_delete,o.evaluation_state,o.way,o.is_stock_up,o.create_user,o.create_time,o.update_user,o.update_time,o.is_valid,og.group_id,og.is_pay,od.order_amount,od.discount_amount,od.goods_amount,od.is_delivery,od.buyer_notes,od.pay_time,od.receive_time,od.delivery_begin_time,od.arrive_store_time,od.arrive_time,op.order_pay_amount,ro.apply_date,ro.modify_date,ro.refund_reason,ro.refund_amount,ro.refund_state,ro.refuse_refund_reason,ro.refund_goods_type,ro.refund_shipping_fee,os.settlement_create_date,os.settlement_amount,os.dispatcher_user_id,os.dispatcher_money,os.circle_master_user_id,os.circle_master_money,os.plat_fee,os.store_money,os.status,os.note,os.settle_time,os.first_commission_user_id,os.first_commission_money,os.second_commission_user_id,os.second_commission_money,ogd.goods_id,ogd.buy_num,ogd.goods_price,ogd.total_price,ogd.goods_name,ogd.goods_image,ogd.goods_specification,ogd.goods_weight,ogd.goods_unit,ogd.goods_type,ogd.refund_order_id,ogd.goods_brokerage,ogd.is_refund,e.geval_scores,e.geval_scores_speed,e.geval_scores_service,e.geval_isanony,odi.dispatcher_order_type,odi.dispatcher_order_state,odi.order_goods_num,odi.delivery_fee,odi.distance,odi.dispatcher_code,odi.receiver_name,odi.receiver_phone,odi.sender_name,odi.sender_phone
from dwd.fact_shop_order o
left join dwd.fact_shop_order_group ogon o.id = og.order_id
left join dwd.fact_shop_order_address_detail odon o.id = od.id
left join dwd.fact_order_pay opon og.group_id = op.group_id
left join dwd.fact_refund_order roon o.id = ro.order_id
left join dwd.fact_order_settle oson os.order_id = o.id
left join dwd.fact_shop_order_goods_details ogdon ogd.order_id = o.id
left join dwd.fact_goods_evaluation eon e.order_id = o.id
left join dwd.fact_order_delievery_item odion odi.shop_order_id = o.id;
宽表查询
select * from dwb.dwb_order_detail;