00:00
这页PPT呢,是我们去制作拉链表的这个核心啊,把这页PPT咱们得好好看一下啊,看怎么做拉链表。嗯。来,我们一起看一下。嗯。来一起看一下这个拉链表的形成过程啊。呃,现在呢,我们来看这边先啊,这个图全出来了,咱们先不用看啊,咱们先看这看这看这一部分就行,呃,这边假设,假设什么呢?说2019年1月1日的全量的这个用户表是以下的这个表啊,什么例子啊,举个例子啊,在这儿呢,他想说的是这个啊,就是在2019年1月1号的时候。我们买SQ当中,就是业务系统当中啊,我们是不是就呃已经有一个这个用户表了呀,用户表当中是不是已经有一部分的历史数据了呀,然后咱们数仓是从哪天开始搭建的呢。是从1月1号开始搭建的啊,就是1月1号之前,咱们业务系统已经跑了有好几年了,是不是已经积累了一部分的历史用户了啊,然后呢,咱们出仓才开始搭建,那且以后大家到公司之后呢,哎,大部分的情况也是这样啊,就一般情况咱们数仓跟这个业务系统一般情况下不是同步展开的,那都是到到公司之后呢,都是业务系统早就有了,然后你去了再重新开始拉出仓啊,是不是都是这种情况啊啊就是在历史数系统的业务系统当中已经有一部分的历史数据了啊,那我们现在假如说已经有历史数据了,然后呢,我要做拉链表对吧,咱们得保证拉链表里边得有什么。
01:28
是不是得有全部的这个用户啊,是不是得有全量用户,因为我们去使用拉链表的时候,我有一个使用场景,就是获取全量的什么最新和全量的历史数据,对不对,得有全量用户才行,那所以说我们这儿需要怎么做呀?需要做一个初始化导入,需要做一个初始化导入,因为如果说你不做初始化导入啊,不做初始化导入,那你说我们拉链表每天这个同步方式是什么样,是每日新增及变化对不对?那你是不是第一天只能把它的新增和变化的那部分数据用户拿到对不对?那其他的老用户没变的那些你能拿到吗?
02:04
拿不到,那你这个拉链表是不是用起来就有问题啊,所以说呢,我们做拉链表呢,我们需要做一步这个数据的初始化啊,其实这个所谓的初始化应该怎么做呀。初化怎么做,很简单啊,初始化呢,就是我们需要啊,将买SQL当中,也就我们业务系统当中啊,那个存储用户的那个信息的那张表里边儿就是用户表呗,从用户表里边把它所有的数据。啊,全部一次性的导入到我们这个拉链表里。啊,做一次全量同步相当于。啊,那当然这个全量同步这个任务,咱们是不是单独走一次就行了呀,因为初始化是不是只需要做一次啊,就是在呃,你搭出仓的第一天啊,把我们这个呃用户表的全部数据给它拿到我们出仓里边啊,那拿回来之后呢,你要知道啊,咱们这个数仓里边,呃,这个拉链表呢,有一个特点,我们要比这个普通的用户表是不是多俩字段呀,一开始一个结束,那这俩时间咱们怎么去处理呢?
03:05
呃,先说结束吧,结束肯定都是啥。都是999,为什么?因为业务系统当中我们保存的是不是就是最新状态,就那肯定都是九九,那关键是这个开始时间怎么办。看时间咋整。说实话,这个开始时间不太好找。为什么不太好找啊,你要知道这个开始时间指的是什么的开始时间是不是每个状态的开始时间呀,对不对,那你知道张三是从什么时候开始叫张三,李四什么时候开始叫的吗?不知道对不对,因为业务系统当中我一般不会去记录这些历史数据的,对吧?啊,那没有的话,那这怎么办呢?你获取不到,那就没办法了,除非你业务系统那边,那边有流水记录,有记录的话你可以获取到,那要没有的话,我们只能是怎么做呀啊,给他随意的指定一个,但也不能太随意啊,那一般情况下我们就把开始时间指定成啥呀,只能咱们数仓第一天开始运行的时间啊,只能是这样去做了,因为你获取不到嘛,啊,这个没有办法啊,那所以说这样呢,我们需要做一个这个初始化啊,这个初始化怎么做呀,问一下大家要让你做的话。
04:09
怎么做呀?写S库脚本呗,对不对,S库写做来一个全量导入给导到HS上hfs呢,再给它导到咱们的用户拉链表里,是不是这样一个过程啊,这是初始化导入,这个我们要搞清楚啊行,那这个第一天初始化完了,接下来时间来到第二天是不是就是9月2号了呀,9月2号了啊9月2号了,那9月2号呃,不是九月,是1月2号,2019年1月2号啊啊1月2号,那来到1月2号之后呢,你看我们买买SQ当中这张用户表发生了一些变化。啊,这个变化具体是什么呀,你看一下。是不是多了俩用户,这相当于是新增用户对不对?那还有什么,是不是还有一一个用户信息改了呀,这是不是相当于发生了新增及变化对吧?信息变化啊,那新增级变化之后呢?我们需要怎么做呀?是不是需要把MY当中的新增级变化是不是得导到我们的数据仓库当中,对不对?那这个下边是不是就是我们获取到的新增级变化呀?咱们怎么去获取的我们那个用户表的新增级变化呀?
05:12
怎么就过去的?是不是根据创建时间和那个操作时间就是create time oper time啊呃,Create time等于今天,Op time等于今天,那就是今天的新增级变化,对吧?那也就是说我们通过他俩就能达到李四的这个就是二号用户以及四号和五号用户的这个信息能看懂吧,这就是新增级变化,那咱们接下来要干什么呀?接下来咱们是要将这个新增级变化得整合到这个拉链表里边啊对不对?来咱们看看这个整合。具体应该怎么做?这个整合应该怎么做?啊,这个整合怎么做。啊,这个很显然,这是我们现在最终得到的结果,对吧?啊,那咱们具体怎么实操呢?咱们需要做哪些工作呀。首先我们需要做第一件事儿啊,第一件什么事呢?需要先将我们拿到的这个新增及变化呀,是不是得处理一下呀,所以你得给他补上俩字段。
06:06
哪俩字段,一个是开始,一个是结束日期,那开始日期应该是哪一天?今天对不对,那就是他是不是就从今天开始才叫李小四,那这个是不从今天开始才新增啊啊就是那那结束日期呢,9999对吧,不管是新增还是修改,它的结束日期和新增日期是不都是相同的啊不不是结束日期不是,呃,结束日期和这个这个开始日期啊,开始日期都是今天结束日期都是9999,没错吧?啊OK,处理好了,那对今天的新增及变化你处理好了。那你还得对什么处理一下?是不是还得对咱们这个原来的拉链表也得给他处理一下呀,处理谁在咱们这儿处理谁。处理出二号用户的之前的李四那个状态呀,对不对,因为在今天之前李四是他的最新状态,但最新状态已经是李小四了,那是不是999就得改一下呀,这个改成什么呀?注意啊,咱们一般是改成昨天的日期。
07:05
昨天哎,我们必须得保证什么,保证我们一个用户的所有的状态之间啊,它那个时间是不能重合的。对不对啊,你比如说第一个状态二号到三号,那第二一个呢,就得是四号到,哎五号或者是到多少号能理解吧,你不能第一个是一号到二号,第二是二号的三号,那我要获取二号的数据,那你是不是就获取俩状态了呀,那那就有歧义了啊,所以说不能重复啊,不能重复啊,不能重合啊,那所以说我们需要将这个9999改成昨天的日期,那今天是不是1月2号,昨天日期就是多少,就是1月1号呗,啊1月1号啊,哎,得改了,那OK,那新的数据咱们也处理好了,那旧的数据也处理好了,对不对。这部分数据和这部分数据应该怎么样放到一块儿啊。咱别放在一块啊。是不是直接这俩东西上下一合并就完事了呀?
08:03
对不对啊,上下一合并完事,那上下一合并咱们这用啥对,是不是用妖精就行啊,那最终呢,就得到了咱们最新的拉链表了。啊,这是咱们这个拉链表的这个制作过程,那其实大家要知道啊,我们其实以后每天重复要做的工作,应该都是什么工作呀。第一天我们需要做一个初始化,对吧,那后续每天重复咱们要做的工作是哪部分呀。是不要是获取新增级变化啊,然后呢,修改这个开始和结束日期,然后呢,把这个原来那张拉链表里边的结束日期改几个,对不对,这俩东西合并,说每天重复做的工作应该是这部分呀啊,新的数据拿过来跟原来的比,旧表进行一个进行一个整合,每天重复的工作就是这个整合。啊,每天整合,每天整合啊,然后呢,初始化呢,就第一天做一次就可以了啊,这是咱们这个拉链表的制作过程。啊好,那接下来呢,我们来继续往下思考啊,咱们就思考哪啊思考这你看啊,这会儿咱是不是需要去改9999,那这又涉及到了什么,又涉及到了修改have当中的数据了吧,对不对,那have当中数据怎么修改来着,是不是查出来查了过程当中进行判断啊,改完之后再放过去啊,是不是这样一个过程,那他这儿也是这么去做的啊来往下翻。
09:20
来看一下,还有一个PPT啊,这个再看一下吧啊。呃,这个PPT呢,先看左边啊,左边这。嗯,左边这呢,这儿说了一个这个,这就就看括号里边啊,这就解决了have中数据不能更新的问题,其实have当中数据实际上也是能更新的,对吧?咱们说了你只要做那个呃,分通表是不是就能更新了呀,对不对,就能更新了啊,这边假定说是不可能更新啊,那这个怎么解决的呀,其实就是刚才咱们说的啊,就是把数据查出来,查出来修改再放回去,这就修改了啊,这说的就这个事儿,这个文字就不用看了啊,咱们看右边的图。这边右边这个图呢,哎,帮我们把我们每天需要重复执行的这个工作呢,又给我们总结了一下啊,咱们看这个图啊,看怎么做的啊,首先做拉链表,第一天我需要做一个初始化导入,对吧,就是初始化导入首日嘛,啊初始导入,然后从第二天开始,我就怎么做,从MYSQ当中获取变动数据,里边是不是包括新增,包括修改。
10:18
对不对,拿过来,拿过来之后呢,我需要怎么做呀?哎,把开始和结束日期是不是给它加上啊,完之后呢,我还得怎么做,是不是还得从原来就是昨天那个拉链表,是不是把那个数据查出来呀,查来之后呢,我得怎么做,我是不是得把那个日期9999该改的得改呀,对不对,改完之后,那这个今天的跟原来的这个俩这俩表应该怎么做,是不是优念到一块儿啊对不对,UN念到一块之后怎么办?是不是正常情况下咱们直接insert over right回这个拉力表就行了。对不对,但是他这你看他怎么做了,他说并没有直接insert or回去啊,他放到哪去了,给他放到一个临时表里边去了。那临时表之后呢,什么都没做,然后又从临时表是不是又给他insert到allright到用户栏里表里边去了呀,那是不是这他看着相当于是多做了一步啊对不对,他多做这一步是干什么事的呀,他在干什么呀,为什么要多做这一步?
11:15
就是在这儿呢,他考虑的是什么?考虑的是这个数据的安全问题。啊啊,什么安全问题呢?哎,大家这个得考虑一个这样的问题啊,就是大家了解不了解我们have当中这个insert overri啊,就是这个操作,它底层的这个执行顺序是什么样的。啊,因此而大家都知道我会把这个原来的数据给覆盖掉,对吧,用新的数据对不对,那这个具体的,诶这个操作是什么样的呢。啊,他是先上来就把这个表当中原来的数据给删掉,然后再把新的数据写进来吗?是这个顺序吗?是不是这个顺序。啊,不知道对吧,那咱们假如说它是这个顺序啊,假如说我因此而外的就是先把这张表的数据删掉,然后呢,再把新数据给它写进来,假如说是这个顺序啊,那你看一看,如果说我们这没有这个临时表,你看它会不会有什么问题啊,如果没有临时表,按照我们刚才那个呃分析,你看怎么做啊,这是今天的新变化数据对不对,那这是我们这个老数据啊,那我现在呢,把这个数据是不是拿出来了对不对,然后我现在如果直接insert o right回去,那刚才说了音色OS,假如咱们是先删后斜对不对,那现在我我怎么做。
12:29
我是不是直接删了呀,对不对,结果删了之后,我再往里边写的时候,我给失败了,报错了。对不对,这个集群出问题了,那是不是这个数据原来的也被你删了,然后新数据也没写进去,那是不是拉里面的数据全没了呀,对不对,哎,他其实是考虑到这一点啊,考虑到一点,那如果说那咱们考虑到这一点之后,我加一个临时表呢,那你看这个现象能不能解决啊,这个问题能不能解决,你看啊新数据旧数据啊,查出来啊,查出来之后我放在哪,我先放临时表。
13:02
啊,那这边这表里的数据还有没有有啊,我先放临时表对不对,然后我把临时表的数据啊,我写到临时表之后呢,那这个相当于是我这个数据是不是就写完了对不对,那写完了之后我再往这里边写。啊,再往这里边写,哎,那这时候咱们还怕他丢吗?哎,不怕了,为什么,你想想啊,假如说我在往临时表写,是不是也是先删后写呀,对不对,那我先删了,结果写都是写失败了,哎,那这个你怕不怕,怕吗?不怕,为啥还有。我再来一遍是不是就行了,对不对,这个这样来的话能安全一点啊,它其实出于这个考虑,但其实这个考虑呢,是是多余的,是多余的啊,为什么多余的呢?因为人家have,人家没那么傻啊,In inside allright,人家没那么傻,他不是先删后写的。啊,不是先上后写,你要是仔细去观察那个have insert or right这个任务啊,你仔细去观察你会发现啊,它是怎么做的呀,它是先往啊先往哪先往一个临时路径斜咱们这个结果。
14:03
对不对,因此会先往一个临时路径写咱们的数据,OK,写完之后怎么做呀,再把再把你写完的这个临时文件的数据啊,给它改名为真正的这个文件,就改一下路径的事儿。对不对啊,那这样一来,原来那个数据呢,才会被删掉。嗯,也就他应该是怎么做的呀,是不是应该是先写完,哎没问题了,我是不是再把原来的给删掉啊,啊实际上是这样一个过程,其实那个临时路径就有点类似于谁呀。是不是就类似于咱们这个临时表这个作用啊,啊是这样的,那当然因为咱们本身have就有这个临时路径这个机制,所以临时表这个东西你建不建无所谓啊,那在这儿呢,其实这个步这一步呢,可以完全就不做了,那直接在俩合并啊,完了之后怎么办?直接到下一个拉链表里边啊,直接写回就行了,你像我们之前咱们DWD仓啊,DW层咱们那个累计型快照师表,咱们是不是也是直接in字偶尔的回去了呀,对不对,那也没有问题啊啊,那咱们知道这回事儿就行了啊。
15:03
啊,那这边呢,相当于给大家看了一下啊,就是每天呃重复这个每天首次导入,然后每天重复做的事呢,就是诶把这个新数据跟旧数据合并,再放回拉链表就完事了,这是咱们这个制作流程啊。好,视频录一下。
我来说两句