拉链表流水表

  1. 1. 全量表:每天的所有的最新状态的数据,
  2. 2. 增量表:每天的新增数据,增量数据是上次导出之后的新数据。
  3. 3. 拉链表:维护历史状态,以及最新状态数据的一种表,拉链表根据拉链粒度的不同,实际上相当于快照,只不过做了优化,去除了一部分不变的记录而已,通过拉链表可以很方便的还原出拉链时点的客户记录。
  4. 4. 流水表: 对于表的每一个修改都会记录,可以用于反映实际记录的变更。
  5. 拉链表通常是对账户信息的历史变动进行处理保留的结果,流水表是每天的交易形成的历史;
  6. 流水表用于统计业务相关情况,拉链表用于统计账户及客户的情况
  7. 数据仓库之拉链表(原理、设计以及在Hive中的实现)
  8. 在有些情况下,为了保持历史的一些状态,需要用拉链表来做,这样做目的在可以保留所有状态的情况下可以节省空间。
  9. 拉链表适用于以下几种情况吧
  10. 数据量有点大,表中某些字段有变化,但是呢变化的频率也不是很高,业务需求呢又需要统计这种变化状态,每天全量一份呢,有点不太现实,
  11. 不仅浪费了存储空间,有时可能业务统计也有点麻烦,这时,拉链表的作用就提现出来了,既节省空间,又满足了需求。
  12. 一般在数仓中通过增加begin_date,en_date来表示,如下例,后两列是start_date和end_date.
  13. 1  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  14. 1  2016-08-20  2016-08-21  支付 2016-08-21  2016-08-21
  15. 1  2016-08-20  2016-08-22  完成 2016-08-22  9999-12-31
  16. 2  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  17. 2  2016-08-20  2016-08-21  完成 2016-08-21  9999-12-31
  18. 3  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-21
  19. 3  2016-08-20  2016-08-22  支付 2016-08-22  9999-12-31
  20. 4  2016-08-21  2016-08-21  创建 2016-08-21  2016-08-21
  21. 4  2016-08-21  2016-08-22  支付 2016-08-22  9999-12-31
  22. 5  2016-08-22  2016-08-22  创建 2016-08-22  9999-12-31
  23. begin_date表示该条记录的生命周期开始时间,end_date表示该条记录的生命周期结束时间;
  24. end_date = ‘9999-12-31’表示该条记录目前处于有效状态;
  25. 如果查询当前所有有效的记录,则select * from order_his where dw_end_date = ‘9999-12-31′
  26. 如果查询2016-08-21的历史快照,则select * from order_his where begin_date <= ‘2016-08-21′ and end_date >= ‘2016-08-21’
  27. 再简单介绍一下拉链表的更新:
  28. 假设以天为维度,以每天的最后一个状态为当天的最终状态。
  29. 以一张订单表为例,如下是原始数据,每天的订单状态明细
  30. 1   2016-08-20  2016-08-20  创建
  31. 2   2016-08-20  2016-08-20  创建
  32. 3   2016-08-20  2016-08-20  创建
  33. 1   2016-08-20  2016-08-21  支付
  34. 2   2016-08-20  2016-08-21  完成
  35. 4   2016-08-21  2016-08-21  创建
  36. 1   2016-08-20  2016-08-22  完成
  37. 3   2016-08-20  2016-08-22  支付
  38. 4   2016-08-21  2016-08-22  支付
  39. 5   2016-08-22  2016-08-22  创建
  40. 根据拉链表我们希望得到的是
  41. 1  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  42. 1  2016-08-20  2016-08-21  支付 2016-08-21  2016-08-21
  43. 1  2016-08-20  2016-08-22  完成 2016-08-22  9999-12-31
  44. 2  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  45. 2  2016-08-20  2016-08-21  完成 2016-08-21  9999-12-31
  46. 3  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-21
  47. 3  2016-08-20  2016-08-22  支付 2016-08-22  9999-12-31
  48. 4  2016-08-21  2016-08-21  创建 2016-08-21  2016-08-21
  49. 4  2016-08-21  2016-08-22  支付 2016-08-22  9999-12-31
  50. 5  2016-08-22  2016-08-22  创建 2016-08-22  9999-12-31
  51. 可以看出 1,2,3,4每个订单的状态都有,并且也能统计到当前的有效状态。
  52. 本例以hive为例,只考虑到实现,与性能无关
  53. 首先创建表
  54. CREATE TABLE orders (
  55. orderid INT,
  56. createtime STRING,
  57. modifiedtime STRING,
  58. status STRING
  59. ) row format delimited fields terminated by ‘\t‘
  60. CREATE TABLE ods_orders_inc (
  61. orderid INT,
  62. createtime STRING,
  63. modifiedtime STRING,
  64. status STRING
  65. ) PARTITIONED BY (day STRING)
  66. row format delimited fields terminated by ‘\t‘
  67. CREATE TABLE dw_orders_his (
  68. orderid INT,
  69. createtime STRING,
  70. modifiedtime STRING,
  71. status STRING,
  72. dw_start_date STRING,
  73. dw_end_date STRING
  74. ) row format delimited fields terminated by ‘\t‘ ;
  75. 首先全量更新,我们先到2016-08-20为止的数据。
  76. 初始化,先把2016-08-20的数据初始化进去
  77. INSERT overwrite TABLE ods_orders_inc PARTITION (day = ‘2016-08-20‘)
  78. SELECT orderid,createtime,modifiedtime,status
  79. FROM orders
  80. WHERE createtime < ‘2016-08-21‘ and modifiedtime <‘2016-08-21‘;
  81. 刷到dw中
  82. INSERT overwrite TABLE dw_orders_his
  83. SELECT orderid,createtime,modifiedtime,status,
  84. createtime AS dw_start_date,
  85. ‘9999-12-31‘ AS dw_end_date
  86. FROM ods_orders_inc
  87. WHERE day = ‘2016-08-20‘;
  88. 如下结果
  89. select * from dw_orders_his;
  90. OK
  91. 1  2016-08-20  2016-08-20  创建 2016-08-20  9999-12-31
  92. 2  2016-08-20  2016-08-20  创建 2016-08-20  9999-12-31
  93. 3  2016-08-20  2016-08-20  创建 2016-08-20  9999-12-31
  94. 剩余需要进行增量更新
  95. INSERT overwrite TABLE ods_orders_inc PARTITION (day = ‘2016-08-21‘)
  96. SELECT orderid,createtime,modifiedtime,status
  97. FROM orders
  98. WHERE (createtime = ‘2016-08-21‘  and modifiedtime = ‘2016-08-21‘) OR modifiedtime = ‘2016-08-21‘;
  99. select * from ods_orders_inc where day=‘2016-08-21‘;
  100. OK
  101. 1  2016-08-20  2016-08-21  支付 2016-08-21
  102. 2  2016-08-20  2016-08-21  完成 2016-08-21
  103. 4  2016-08-21  2016-08-21  创建 2016-08-21
  104. 先放到增量表中,然后进行关联到一张临时表中,在插入到新表中
  105. DROP TABLE IF EXISTS dw_orders_his_tmp;
  106. CREATE TABLE dw_orders_his_tmp AS
  107. SELECT orderid,
  108. createtime,
  109. modifiedtime,
  110. status,
  111. dw_start_date,
  112. dw_end_date
  113. FROM (
  114. SELECT a.orderid,
  115. a.createtime,
  116. a.modifiedtime,
  117. a.status,
  118. a.dw_start_date,
  119. CASE WHEN b.orderid IS NOT NULL AND a.dw_end_date > ‘2016-08-21‘ THEN ‘2016-08-21‘ ELSE a.dw_end_date END AS dw_end_date
  120. FROM dw_orders_his a
  121. left outer join (SELECT * FROM ods_orders_inc WHERE day = ‘2016-08-21‘) b
  122. ON (a.orderid = b.orderid)
  123. UNION ALL
  124. SELECT orderid,
  125. createtime,
  126. modifiedtime,
  127. status,
  128. modifiedtime AS dw_start_date,
  129. ‘9999-12-31‘ AS dw_end_date
  130. FROM ods_orders_inc
  131. WHERE day = ‘2016-08-21‘
  132. ) x
  133. ORDER BY orderid,dw_start_date;
  134. INSERT overwrite TABLE dw_orders_his
  135. SELECT * FROM dw_orders_his_tmp;
  136. 在根据上面步骤把2016-08-22号的数据更新进去,最后结果如下
  137. select * from dw_orders_his;
  138. OK
  139. 1  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  140. 1  2016-08-20  2016-08-21  支付 2016-08-21  2016-08-21
  141. 1  2016-08-20  2016-08-22  完成 2016-08-22  9999-12-31
  142. 2  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-20
  143. 2  2016-08-20  2016-08-21  完成 2016-08-21  9999-12-31
  144. 3  2016-08-20  2016-08-20  创建 2016-08-20  2016-08-21
  145. 3  2016-08-20  2016-08-22  支付 2016-08-22  9999-12-31
  146. 4  2016-08-21  2016-08-21  创建 2016-08-21  2016-08-21
  147. 4  2016-08-21  2016-08-22  支付 2016-08-22  9999-12-31
  148. 5  2016-08-22  2016-08-22  创建 2016-08-22  9999-12-31
  149. 至此,就得到了我们想要的数据。

值得注意的是,订单表中数据同一天有多次状态更新,应以每天的最后一个状态为当天的最终状态。比如一天之内订单状态创建,支付,完成都有,应拉取最终的状态进行拉练表更新,否则后面的数据可能就会出现异常,比如

[sql] view plain copy

  1. 6  2016-08-22  2016-08-22  创建 2016-08-22  9999-12-31
  2. 6  2016-08-22  2016-08-22  支付 2016-08-22  9999-12-31
  3. 6  2016-08-22  2016-08-22  完成 2016-08-22  9999-12-31

http://www.cnblogs.com/wujin/p/6121754.html

http://www.jianshu.com/p/799252156379

http://lxw1234.com/archives/2015/04/20.htm

版权声明:本文为博主原创文章,未经博主允许随机转载。 https://blog.csdn.net/mtj66/article/details/78019370

原文地址:https://www.cnblogs.com/wzlbigdata/p/9217418.html

时间: 2024-11-09 04:50:07

拉链表流水表的相关文章

流水表

是数据仓库中记录数据的一个方式 她是记录数据的明细信息. 流水表对于表每修改都会记录用于反映实际记录变更而拉链表根据拉链粒度同实际上相当于快照只过做了优化去除了部分变记录而已通过拉链表方便还原出拉链时点客户记录而流水表虽也能做得效率行或者需要人工参与 提问者评价两者间最重要的区别在于,在首次添加信息时拉链表会添加全量信息,之后的每次都是和首次做比较. 流水表

数仓1.4 |业务数仓搭建| 拉链表| Presto

电商业务及数据结构 SKU库存量,剩余多少SPU商品聚集的最小单位,,,这类商品的抽象,提取公共的内容 订单表:周期性状态变化(order_info) id 订单编号 total_amount 订单金额 order_status 订单状态 user_id 用户id payment_way 支付方式 out_trade_no 支付流水号 create_time 创建时间 operate_time 操作时间 订单详情表:(order_detail) order_detail.order_id 是要一

hive 中的拉链表 1

hive中拉链表 在有些情况下,为了保持历史的一些状态,需要用拉链表来做,这样做目的在可以保留所有状态的情况下可以节省空间. 拉链表适用于以下几种情况吧 数据量有点大,表中某些字段有变化,但是呢变化的频率也不是很高,业务需求呢又需要统计这种变化状态,每天全量一份呢,有点不太现实, 不仅浪费了存储空间,有时可能业务统计也有点麻烦,这时,拉链表的作用就提现出来了,既节省空间,又满足了需求. 一般在数仓中通过增加begin_date,en_date来表示,如下例,后两列是start_date和end_

使用kettle制作拉链表

拉链表是在数据仓库中常见的表,主要用还存储不按时间变化的表,比如客户基本信息表. 下面先建两个实例表,user_info和user_info_l,其中user_info_l为拉链表. user_info表及数据: user_info_l表及转换后的数据: kettle的设计其实很简单,就一个“表输入”一个“维度查询/更新 下面来看一下表输入的配置: 这个很简单,但是一定要有个基本表的数据日期 下面几个是“维度查询/更新”的配置: 下面介绍一下设置中的关键地方,依次如下: 1.不钩选的话变化的数据

拉链表

拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史.记录一个事物从开始,一直到当前状态的所有变化的信息. 优点:为了节省数据库的空间 用处:记录一个事物从开始到现在所有的状态信息. 1采集原系统的全量数据到表new1. 2从历史表中获取昨日全量数据到表new2. 3从new1和new2中比较出新增和改变的数据,也就是增量数据到表new3. 4从new1和new2中比较出来改变的数据,到表new4. 5将new3的数据插入到历史表中,这些是新增记录,startda

极限存储--历史拉链表(上)

在数据仓库的数据模型设计过程中,经常会遇到这样的需求: 1. 数据量比较大;2. 表中的部分字段会被update,如用户的地址,产品的描述信息,订单的状态等等;3. 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态,   比如,查看某一个用户在过去某一段时间内,更新过几次等等;4. 变化的比例和频率不是很大,比如,总共有1000万的会员,每天新增和发生变化的有10万左右;5. 如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极

基于hive的拉链表设计实现

参考http://lxw1234.com/archives/2015/08/473.htm 测试数据 order_2015-08-21 1 2015-08-18 2015-08-18 创建2 2015-08-18 2015-08-18 创建3 2015-08-19 2015-08-21 支付4 2015-08-19 2015-08-21 完成5 2015-08-19 2015-08-20 支付6 2015-08-20 2015-08-20 创建7 2015-08-20 2015-08-21 支付

nginx代理服务器时,如何验证多个客户拉同一个流时,是拉一路还是多路

学生1 | 老师  --> 服务器A -->  服务器B  --> 学生2 | 学生3 如图,老师向服务器A推流,学生从服务器B拉流,当有学生向B去拉流时,B向A去pull 对于老师来说,只推了一路流,对于三个学生来说,拉的是同一路流 那么,如何判断这三个 学生是拉了一路流还是三路流 (1)首先,要配置服务器B的nginx为多个worker. (2)其次,三个学生拉流,在服务器B使用下面命令查看是同一个进程还是多个进程拉流 netstat -anop | grep 1935 | grep

Hive拉链表实现

拉链表测试: 有如下测试数据 --2019/12/1号订单的全量数据 id status create_time operation_time 1 待支付 2019-12-01 2 待支付 2019-12-01 3 已支付 2019-12-01 --2019/12/2号订单的全量数据 id status create_time operation_time 1 待支付 2019-12-01 2 已支付 2019-12-01 2019-12-02 3 已支付 2019-12-01 4 待支付 20