ODS 完成
This commit is contained in:
2
tmp/doc_extracted.txt
Normal file
2
tmp/doc_extracted.txt
Normal file
File diff suppressed because one or more lines are too long
286
tmp/doc_lines.txt
Normal file
286
tmp/doc_lines.txt
Normal file
@@ -0,0 +1,286 @@
|
||||
台球厅数仓 DWD 层数据库说明书
|
||||
本说明书详细列出了台球厅经营系统的 DWD 层表结构。
|
||||
每张表都包含字段名称、数据类型、来源、含义、是否属于主键/外键、业务重要性、未知作用标记,以及枚举值解释。说明书依据《*-Analysis.md》中提供的字段说明整理完成,未出现省略号,确保字段信息完整可追溯。
|
||||
因业务需求,将一个表拆成主数据表和扩展数据表(Ex为后缀),如:维度表的门店数据表分为主表dim_site 和扩展表dim_site_Ex,主键相同,作为唯一关联标识。在业务代码处理的读和写时,使用统一处理方式,将数据视为一个表格。注意,极少数表,没有扩展表。
|
||||
注意:考虑到后期分布式部署,以及测试的便利性。所有的“外键”的处理,使用业务处理,不在数据库中强制约束。
|
||||
维度表(DIM)
|
||||
dim_site
|
||||
门店维度表,提取自各 ODS 中的 siteProfile 对象,如table_fee_transactions。记录门店的基本信息和配置,是其他事实表的外键。
|
||||
dim_site_Ex
|
||||
dim_table
|
||||
台桌维度表,来自 site_tables_master。每行代表一张球台或包厢,包含区域和业务角色信息。
|
||||
dim_table_Ex
|
||||
dim_assistant
|
||||
助教档案维表,对应 assistant_accounts_master。每行代表一位助教账号及其人事/账号状态。
|
||||
dim_assistant_Ex
|
||||
dim_member
|
||||
会员档案维表,对应 member_profiles。每行记录租户内某会员的主档信息,包括等级、状态、注册信息等。
|
||||
dim_member_Ex
|
||||
dim_member_card_account
|
||||
已开通的会员卡账户视图,来自 member_stored_value_cards。每行代表一张会员卡账户的快照,记录卡种、持卡人、余额、有效期及各种折扣/扣款配置。
|
||||
重要说明:本视图不仅包含储值卡,还囊括活动抵用券、台费卡、酒水卡、月卡等多种卡种。
|
||||
大多数折扣/扣款字段在当前数据中保持默认值(如 10.0 表示不打折、100.0 表示全额抵扣、0 表示不启用),业务上暂未使用,但为系统预留能力。
|
||||
dim_member_card_account_Ex
|
||||
dim_tenant_goods
|
||||
租户级商品档案,来自 tenant_goods_master。每行代表一款商品标准定义。
|
||||
dim_tenant_goods_Ex
|
||||
dim_store_goods
|
||||
门店级商品档案,来自 store_goods_master.json。每行代表门店自定义的商品 SKU,包括售价和折扣。关联到 dim_tenant_goods 和分类维度。
|
||||
dim_store_goods_Ex
|
||||
dim_goods_category
|
||||
商品分类索引树,来自 stock_goods_category_tree.json。每行是一个分类节点。
|
||||
categoryBoxes 是“某个分类节点下面的子分类列表”,整个文件里只有两层:根节点 + 子节点两级,不存在孙节点。
|
||||
每个 categoryBoxes 里的元素结构与根节点完全一致(同样的 11 个字段),只是 pid 指向父节点的 id,categoryBoxes 为空。
|
||||
同一个分类树在 JSON 里分页返回了两次,goodsCategoryList 和每个 categoryBoxes 在两个 page 中完全重复,真正的不同分类节点一共只有 26 个。
|
||||
从数仓角度,树结构的“真实关系”完全由 id 和 pid 就可以表达,categoryBoxes 更像是前端为了直接画树而准备的冗余展开结果,在 DWD 里不需要原样存这一坨结构,只需要被“打散”成一行一个节点。
|
||||
下面我把完整的 categoryBoxes 结构按业务和数据的视角展开给你看。
|
||||
一、整体结构:categoryBoxes 是子分类数组,深度只有两层
|
||||
stock_goods_category_tree.json 顶层是一个分页数组 pages,每个元素形如:
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"total": 9,
|
||||
"goodsCategoryList": [ 根分类1, 根分类2, ... 共9个 ]
|
||||
}
|
||||
}
|
||||
每个“根分类”对象都有这些字段:
|
||||
id
|
||||
tenant_id
|
||||
category_name
|
||||
alias_name
|
||||
pid
|
||||
business_name
|
||||
tenant_goods_business_id
|
||||
open_salesman
|
||||
categoryBoxes
|
||||
sort
|
||||
is_warehousing
|
||||
其中:
|
||||
pid = 0 表示根分类。
|
||||
categoryBoxes 是一个数组,里面放的是子分类节点对象。
|
||||
子分类对象和根分类字段完全一样,只是:
|
||||
pid = 父节点 id
|
||||
categoryBoxes = []
|
||||
两个 page 的 goodsCategoryList 完全相同,所以你看到的 18 个“根”其实是相同的 9 个重复了两次,categoryBoxes 里的子节点也重复了两次。按照去重后的真实结构:
|
||||
根节点 9 个。
|
||||
子节点 17 个。
|
||||
总共 26 个不同的 id。
|
||||
所以“完整的 categoryBoxes”其实就是:9 个根节点各自带着若干子节点。
|
||||
二、逐个根节点把 categoryBoxes 展开给你看
|
||||
下面按“根分类 → categoryBoxes 子分类”的树形方式列一遍,便于你直观看到完整结构。
|
||||
1. 根:槟榔
|
||||
根节点:
|
||||
id = 2790683528350533
|
||||
category_name = 槟榔
|
||||
business_name = 槟榔
|
||||
pid = 0
|
||||
categoryBoxes 只有一个子分类:
|
||||
子分类 1:
|
||||
id = 2790683528350534
|
||||
category_name = 槟榔
|
||||
business_name = 槟榔
|
||||
pid = 2790683528350533
|
||||
categoryBoxes = []
|
||||
其它字段:tenant_id、tenant_goods_business_id、is_warehousing、open_salesman、sort 与父节点一致。
|
||||
可以理解为:业务线“槟榔”,下面只有一个细分类“槟榔”。
|
||||
2. 根:器材
|
||||
根节点:
|
||||
id = 2790683528350535
|
||||
category_name = 器材
|
||||
business_name = 器材
|
||||
pid = 0
|
||||
categoryBoxes 子分类 3 个:
|
||||
子分类 1:
|
||||
id = 2790683528350536
|
||||
category_name = 皮头
|
||||
pid = 2790683528350535
|
||||
子分类 2:
|
||||
id = 2790683528350537
|
||||
category_name = 球杆
|
||||
pid = 2790683528350535
|
||||
子分类 3:
|
||||
id = 2790683528350538
|
||||
category_name = 其他
|
||||
pid = 2790683528350535
|
||||
这条业务线代表所有“器材相关商品”,细分为皮头、球杆、器材其他。
|
||||
3. 根:酒水
|
||||
根节点:
|
||||
id = 2790683528350539
|
||||
category_name = 酒水
|
||||
business_name = 酒水
|
||||
pid = 0
|
||||
categoryBoxes 子分类 6 个:
|
||||
子分类 1:饮料
|
||||
id = 2790683528350540
|
||||
category_name = 饮料
|
||||
pid = 2790683528350539
|
||||
子分类 2:酒水
|
||||
id = 2790683528350541
|
||||
category_name = 酒水
|
||||
pid = 2790683528350539
|
||||
子分类 3:茶水
|
||||
id = 2790683528350542
|
||||
category_name = 茶水
|
||||
pid = 2790683528350539
|
||||
子分类 4:咖啡
|
||||
id = 2790683528350543
|
||||
category_name = 咖啡
|
||||
pid = 2790683528350539
|
||||
子分类 5:加料
|
||||
id = 2790683528350544
|
||||
category_name = 加料
|
||||
pid = 2790683528350539
|
||||
子分类 6:洋酒
|
||||
id = 2793221553489733
|
||||
category_name = 洋酒
|
||||
pid = 2790683528350539
|
||||
这里是最典型的一棵分类树:业务线“酒水”,细分成饮料、普通酒水、茶水、咖啡、加料、洋酒。
|
||||
4. 根:果盘(业务线:水果)
|
||||
根节点:
|
||||
id = 2790683528350545
|
||||
category_name = 果盘
|
||||
business_name = 水果
|
||||
pid = 0
|
||||
categoryBoxes 子分类 1 个:
|
||||
子分类:
|
||||
id = 2792050275864453
|
||||
category_name = 果盘
|
||||
business_name = 水果
|
||||
pid = 2790683528350545
|
||||
这里有个有意思的点:
|
||||
分类名称用的是“果盘”,而业务大类 business_name 是“水果”,说明业务线从“水果”角度管理,这个店真正卖的具体品类是“果盘”。
|
||||
5. 根:零食
|
||||
根节点:
|
||||
id = 2791941988405125
|
||||
category_name = 零食
|
||||
business_name = 零食
|
||||
pid = 0
|
||||
categoryBoxes 子分类 2 个:
|
||||
子分类 1:
|
||||
id = 2791948300259205
|
||||
category_name = 零食
|
||||
pid = 2791941988405125
|
||||
子分类 2:
|
||||
id = 2793236829620037
|
||||
category_name = 面
|
||||
pid = 2791941988405125
|
||||
这说明“面”类商品也被算在零食这条业务线里(这完全是你们的门店本地习惯)。
|
||||
6. 根:雪糕
|
||||
根节点:
|
||||
id = 2791942087561093
|
||||
category_name = 雪糕
|
||||
business_name = 雪糕
|
||||
pid = 0
|
||||
categoryBoxes 子分类 1 个:
|
||||
子分类:
|
||||
id = 2792035069284229
|
||||
category_name = 雪糕
|
||||
pid = 2791942087561093
|
||||
7. 根:香烟
|
||||
根节点:
|
||||
id = 2792062778003333
|
||||
category_name = 香烟
|
||||
business_name = 香烟
|
||||
pid = 0
|
||||
categoryBoxes 子分类 1 个:
|
||||
子分类:
|
||||
id = 2792063209623429
|
||||
category_name = 香烟
|
||||
pid = 2792062778003333
|
||||
8. 根:其他
|
||||
根节点:
|
||||
id = 2793217944864581
|
||||
category_name = 其他
|
||||
business_name = 其他
|
||||
pid = 0
|
||||
categoryBoxes 子分类 1 个:
|
||||
子分类:
|
||||
id = 2793218343257925
|
||||
category_name = 其他2
|
||||
pid = 2793217944864581
|
||||
可以理解为“杂项类商品”的一级和二级拆分。
|
||||
9. 根:小吃
|
||||
根节点:
|
||||
id = 2793220945250117
|
||||
category_name = 小吃
|
||||
business_name = 小吃
|
||||
pid = 0
|
||||
categoryBoxes 子分类 1 个:
|
||||
子分类:
|
||||
id = 2793221283104581
|
||||
category_name = 小吃
|
||||
pid = 2793220945250117
|
||||
三、categoryBoxes 元素的字段与含义
|
||||
无论是在 goodsCategoryList 还是 categoryBoxes 里,每个分类节点的字段集合完全一致:
|
||||
id:分类节点主键,唯一。
|
||||
tenant_id:租户 ID,本文件所有节点相同。
|
||||
category_name:分类名,见上面的各种名称。
|
||||
alias_name:分类别名,当前全部为空字符串。
|
||||
pid:父级分类 ID,根节点为 0,子节点为父节点 id。
|
||||
business_name:业务大类名,用于业务线聚合。
|
||||
tenant_goods_business_id:业务大类 ID,对应 business_name,根节点与子节点在同一业务线中取值相同。
|
||||
open_salesman:营业员开关,当前所有值为 2,表示没启用分类级差异。
|
||||
categoryBoxes:子分类数组,只有根节点非空,子节点都是空数组。
|
||||
sort:排序,小部分为 1,大部分为 0,目前排序未精细化使用。
|
||||
is_warehousing:是否走库存,本文件全部为 1。
|
||||
这一点很重要:categoryBoxes 里的元素不是“别的结构”,就是一套完整分类节点,只是挂在父节点下面而已。
|
||||
四、从 DWD 建模角度怎么看 categoryBoxes
|
||||
结合上面的完整展开,可以得出几个明确结论和建议:
|
||||
真实树关系靠的是 id 和 pid
|
||||
子节点的 pid 永远等于父节点的 id。
|
||||
即使没有 categoryBoxes,你也完全可以自下而上拼出整棵树。
|
||||
categoryBoxes 是前端友好的结构,不是建模必要字段。
|
||||
当前树只有两层
|
||||
根节点的 categoryBoxes 非空,子节点的 categoryBoxes 全为空。
|
||||
对应 DWD 可以直接用一个 category_level 字段区分 1、2 层,再配一个 is_leaf 字段。
|
||||
JSON 有分页重复
|
||||
同一套分类树出现在两个 page 中,goodsCategoryList 与 categoryBoxes 内容重复。
|
||||
ETL 时必须按 id 去重,否则维表会重复插入相同分类。
|
||||
在 DWD 的 dim_goods_category 里,categoryBoxes 本身不需要落列
|
||||
只保留每个节点一行:category_id、category_name、parent_category_id、category_level、is_leaf、tenant_goods_business_id、business_name 等即可。
|
||||
如果你特别想保留源结构,可以另开一个 raw_json 字段存原始节点 JSON,日后排错用,但不建议在分析建模中依赖它。
|
||||
dim_goods_category_Ex
|
||||
dim_groupbuy_package
|
||||
团购套餐定义,来自 group_buy_packages。每行代表一种团购套餐及其使用规则。
|
||||
dim_groupbuy_package_Ex
|
||||
事实表(DWD)
|
||||
以下事实表均以“业务事件”为粒度,不做聚合。字段来源包括原始 JSON(或ODS) 中的明细数组以及对象属性。时间单位均统一为秒,并保留原始字段以备检查。金额按照源系统保持符号规则,不做符号转换。
|
||||
dwd_settlement_head(结账记录)
|
||||
来自 settlement_records的内层 settleList 对象,每行代表一次结账。该表在业务上是其他明细事实表的汇总头,用于串联台费、商品、助教、券等明细。
|
||||
dwd_settlement_head_Ex(结账记录扩展)
|
||||
dwd_table_fee_log(台费流水)
|
||||
来自 table_fee_transactions的 siteTableUseDetailsList,忽略siteProfile(已在dim_site实现)。粒度为一次台费使用记录(包括包厢)。该表连结订单结账头、桌台、会员等维度。
|
||||
dwd_table_fee_log_Ex(台费流水扩展)
|
||||
dwd_table_fee_adjust(台费折扣/调整)
|
||||
来自 table_fee_discount_records的table_fee_discount_records.data.taiFeeAdjustInfos. 路径下字段路径。每行代表一次台费打折或减免操作。由于结构相对简单,字段说明如下:
|
||||
dwd_table_fee_adjust_Ex(台费折扣/调整扩展)
|
||||
dwd_store_goods_sale(商品销售明细)
|
||||
来自 store_goods_sales_records的 orderGoodsLedgers。每行代表订单中的一条商品销售明细。字段较多,以下列出关键字段及其作用。
|
||||
dwd_store_goods_sale_Ex(商品销售明细扩展)
|
||||
dwd_assistant_service_log(助教服务流水)
|
||||
来自 assistant_service_records的 assistant_service_records.data.orderAssistantDetails.。每行表示一次助教提供服务的记录,包括服务时长、金额、助教与会员关联等。
|
||||
dwd_assistant_service_log_Ex(助教服务流水扩展)
|
||||
dwd_assistant_trash_event(助教废除事件)
|
||||
来自 assistant_cancellation_records 的 abolitionAssistants。每行代表一次助教服务被废除的事件,无法直接与结算记录或助教流水关联,只能通过门店+台桌+助教+时间窗口软关联。
|
||||
dwd_assistant_trash_event_Ex(助教废除事件扩展)
|
||||
dwd_member_balance_change(会员余额变动)
|
||||
来自 member_balance_changes.json,粒度为一次储值卡账户余额变动。此表是分析会员资金往来的核心事实表。
|
||||
dwd_member_balance_change_EX(会员余额变动扩展)
|
||||
dwd_groupbuy_redemption(团购券核销)
|
||||
来自 group_buy_redemption_records.json 中各条记录。每行代表一次团购券使用/核销事件。
|
||||
dwd_groupbuy_redemption_Ex(团购券核销扩展)
|
||||
来自 group_buy_redemption_records.json 中各条记录。每行代表一次团购券使用/核销事件。
|
||||
dwd_platform_coupon_redemption(第三方平台券核销)
|
||||
来自 platform_coupon_redemption_records.json。每条记录代表一次第三方团购券的核销,用于追踪渠道引流和兑换。
|
||||
dwd_platform_coupon_redemption_Ex(第三方平台券核销扩展)
|
||||
dwd_recharge_order(充值结算)
|
||||
来自 recharge_settlements.json的settleList.settleList.。每行是一条充值订单,记录充值金额、赠送金额及是否首充。
|
||||
dwd_recharge_order_Ex(充值结算扩展)
|
||||
dwd_payment(支付流水)
|
||||
来自 payment_transactions.json。每行代表一笔支付或收款流水,与结算单、充值单等关联。只有 pay_status=2 的支付成功记录被导出。
|
||||
dwd_refund(退款流水)
|
||||
来自 refund_transactions.json。每行代表一笔退款,对应原支付流水。退款金额以负数存储在 pay_amount 字段;字段 refund_amount 全部为 0,实际退款金额需取 pay_amount 的绝对值。
|
||||
dwd_refund(退款流水)
|
||||
来自 refund_transactions.json。每行代表一笔退款,对应原支付流水。退款金额以负数存储在 pay_amount 字段;字段 refund_amount 全部为 0,实际退款金额需取 pay_amount 的绝对值。
|
||||
总结
|
||||
本说明书列出了经营数据仓库 DWD 层的主要维度表和事实表的字段结构及说明,尽可能在每个字段上标注其来源、含义及业务重要性。对于未在 MD 文档中解释的字段标记为 作用未知,在建模时建议保留字段但谨慎使用;对业务逻辑影响较小的展示类字段标记为 不重要。枚举字段均列出了观测到的取值和推断的含义,便于后续 ETL 做值域映射和数据清洗。随着业务扩展和数据补充,可继续完善枚举信息、用途说明和字段分类。
|
||||
2610
tmp/dwd_tables.json
Normal file
2610
tmp/dwd_tables.json
Normal file
File diff suppressed because it is too large
Load Diff
6188
tmp/dwd_tables_full.json
Normal file
6188
tmp/dwd_tables_full.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user