00:00
好,同学们,咱们接着来看一看咱们这一章的最后一个问题,叫淘宝数据库的这个主件啊,是如何设计的啊,那这个问题的话呢,呃,对大家来讲应该是非常有意义的了,因为呢,咱们在创建表的时候呢,是不是都要考虑这个主键的设置,对吧?尤其尤其呢,是当我们这个表的数据量比较大的情况下,甚至说呢,你面对的是一个分布式系统的情况下呢,我们这个表的主键呢,设计就非常具备讲究了。啊就非常有讲究了,那同时的话呢,如果你要是一个面试官的话呢,我觉得你也可以去问一下这个被面试者说呢,你啊在业务当中呢,涉及到的这个表表结构当中,主件呢,是如何设计的,看看他应该怎么说,通过这个问题呢,你也可以考察他实际的一个技术水平啊,如何他的理解,他的思考在这里边,对吧,相当于呢,给大家再去提供一个诶卷别人的一个非常好的一个问题啊一个题目。行,那这里边儿呢,就提到这个淘宝的数据库啊,为什么拿它的这个举例呢,大家应该也非常的心知肚明,呃,淘宝数据库呢,在咱们国内的,呃,乃至于说这个全球来讲的话呢,它的核心业务涉及到这个数据量呢,是非常庞大的,人家这个主件设置的好呢,是不是对于我们来讲的话呢,呃,人家都可以用,那咱们是不是就更可以去使用了啊OK,是这样子的,所以说在网上呢,就流传了很多关于啊淘宝也好,阿里也好,它相关的一些这个规范啊,啊就是所谓的形成的一些这个军规是吧?诶当然有一些呢,这个是呃,一些网络的这个。
01:23
呃,博主啊等等他们自己编的哈,并不是真正的阿里体系里边去使用的这样的一些规范啊,比如说呢,就涉及到这样一个点说呢,诶,这个淘宝的数据库当中啊,就是用八个次级的这个big int啊去做这个主键的啊,为了要确保呢,就是整个我们空间呢得够用,而没有选择用这个int对吧?啊听着很有道理,但事实情况呢,是错误的啊,不会这样的去做的,那真实的是什么情况的呢?诶当然呢,一方面我们可以呢去推理一下是吧?诶这一个点,另外一个点的话呢,其实这个淘宝的话呢,他自己呢,也会出相应的一些规范。啊,这个比如说Java开发手册啊,那么这些规范里边呢,就是便于他们内部体系的这些人呢,去呃,统一标准啊,另外的话呢,对于我们其他的一些业务场景的这个同事啊,你不是阿里体系的,是不是也可以做一个借鉴,对吧?OK。
02:09
好,那我们这块儿来看一看啊说呢,用八个字节呢,这个begin做这个主件的话呢,相当于呢,它只是站在数据库这一层呢去考虑问题没有呢,从这个业务的角度呢,去思考这个主见啊说主见呢,就只是一个自增的ID吗?啊说站在2020年啊,咱们马上呢就要这个过这个新年这个端口啊,这个档口了是吧?呃,今天呢,是27号啊,现在已经12点多了哈,呃,然后咱们录的这个视频,诶马上呢就是做这个,呃,这个过新年了是吧,这时候你还谈说我们提供这个主件的话呢,是一个自动的ID啊这个时候呢,恐怕呢。啊,这个面试官啊,这这都接受不了是吧,连几个呢都拿不到啊OK啊,架构设计上呢,来讲的话呢,更是如此啊,那我们该如何呢去理解呢?啊如何去设计呢?呃,首先的话呢,我们先考虑一下这个自增ID它的问题啊说自增ID的话呢,除了我们这个简单易懂啊设置方面之外呢,几乎其他的方面全是缺点,那有哪些缺点呢?来咱们看一看,第一个叫可靠性不高。
03:08
它呢还是存在这个ID是可以回溯的这种问题的啊,诶这个问题的话呢,到这个8.0呢才进行修复,这个呢其实还挺恶心的是吧?诶这是一个点,另外的话呢,我们叫这个安全性不高,它呢对外暴露的接口呢,很容易被猜测到对应的信息,比如我们暴露到呢叫U呢杠一啊这样一个接口,那很容的就猜到了用户这个ID的这个知识多少了,以及呢,我们这个用户量有多少,很容易被这个通过我们相关的这个爬虫工具呢,进行数据这个爬取啊这个呢不太靠谱是吧?诶这是一个点,另外的话呢,就是我们这个自增ID的,它的性能比较差,主要呢,就体现在我们需要在呃数据库这个服务端呢去生成。啊,所以它的性能呢,还是稍差一点,另外呢,叫交互比较多,比如我们想看一看,说最近呢,我们这个,呃,这个自增的这个ID呢,这个值现在是多少,我们还得需要呢,使用一个相关的函数呢,才进行一个查询啊,那么在海量并发这个系统当中,每多一条S扣呢,就要多一个开销啊交互比较多啊,再外再一点的话呢,这个点在实际业务场景当中呢,也是比较糟糕的啊,就是说呢,我们这个智能ID呢,它是一个举步唯一的。
04:10
啊,如果呢,我们在这种分布式的这种场景下的话呢,诶这个这个就很麻烦了,是吧?诶举一个实际中的例子呢,就是说比如说你是一个连锁的一个超市吧,诶在这个超市当中,我们记录一个表的数据啊,它是保证我们在这家呃这个分店当中,它是一个唯一的,那如果说我们这个连锁的超市呢,要把这个数据呢,在总部呢,做个汇总啊,那这时候就出问题了,我们这个ID值呢,它可能就不是哎在全局场景下的一个唯一性了。哎,那对于相同这个主键值的数据呢,那怎么办呢?麻烦了是吧,哎,这就不行的,所以局部微性啊,也是我们不能接受的点。这儿呢,我们就总结出来了这样的几个问题啊,基于这几个问题的话呢,我们看一看,那如果不用这种自增ID,那该怎么去办呢?诶这块我们再提到一下啊,用这个业务的字段呢,我们去做主见,哎上边这个呢,我们ID呢,就仅仅是为了表示一个主见,满足这个唯一的满足这种非控的特征是吧?哎,不是这种业务的这个字段了啊OK,那我们这块呢,可以考虑呢,说咱们要是用这个业务字段呢,做主键,诶可不可以呢?
05:10
是吧,诶那这个业务字段的话呢,咱们举个例子,比如说是一个会员的信息表啊,那这个会员信息表里边儿呢,你看我们有这样的这个信息啊,卡号名称,电话,诶身份证号,地址性别生日。对吧?诶那做主建的话呢,你像这个性别啊,生日啊,这这这这个包括这个姓名的话呢,这块大家就别想了,这都不太靠谱对吧?诶那包括这个地址北京上海写的这么范范的话呢,那有可能就都出现非唯一性的特征了,那我们目前能够考虑的话呢,是不是有这个卡号啊,身份证号啊,包括电话号码呀,是不是有这样的字段可以考虑对吧?行,那么首先呢,咱们来考虑一下这个卡号,诶靠不靠谱。啊卡号啊卡号的话呢,看似呢是比较靠谱的,哎,我们创建一下关于这个会员的这样一个表,里边呢,用这个卡号呢,来定义为一个主件,对吧?诶这样一个场景好,那用它行不行呢?诶看似的话呢,我们说每个会员的话呢,卡号都不一样啊这样呢,就有一个卡号跟会员的一个一一对应关系,感觉是没什么问题,但是这里边儿实际情况呢,我们说可能会出现这个卡号呢,重复使用的一个情况。
06:11
啊,比如说呢,这个张三呢,因为工作变动的情况呢,他就不在这个这个门店消费了啊,然后的话呢,我们把张三这张卡呢,为了能够复用啊,就把这张卡呢,又给了这个王五去使用了,哎,那你要给王五使用的话呢,在这个表当中,你是不是就应该把这个张三这个信息是不是改成这个王五的信息了。诶,你这个表中呢,就维护了这样的一些字段,诶改成万物信息,看似的话呢,问题不大啊,你比如说我们还有其他的一些这个具体的一些表啊,去记录,比如说这个消费记录啊等等其他一些表,然后我们跟这个表呢,在关联的时候呢,那说那那就是改成王五了呗,是吧?诶在查询的时候呢,看似呢没什么问题,实际上呢,是存在一个隐患的。什么隐患呀,诶你比如说我们现在还有一个叫销售的一个流水表啊销售流水表呢,是这样去建立的,其中的话呢,是不是有这个会员的卡号,对吧?诶这里边标注的就是一开始我们张三的这样的一个卡号,那么这个张三的话呢,在他还在的这个时候呢,他有一个消费,比如说这张三买了一本书,诶那么是在这个时间是吧,然后钱呢,是这么多啊,那当你把这个卡号呢,给了王五的时候呢,诶相当于呢,你是不是就把这个字段呢?诶把我们这个会员表中的这个张三的信息呢,就给抹掉了啊改成王五的了,然后呢,这个卡号呢,是没有变的,那这时候我们再去进行这个多宝的一个连接查询的时候呢,就发现出现问题了,这个时候呢,你查出来以后呢,是不是成了王五在这一天是不是买了一本书89块钱啊,这个显然呢是不行的,对吧。
07:33
啊,整个呢,就从业务场景上来讲,这个就是一个错误的情况。啊,这个呢不行啊好了,那所以说呢,我们不能够使用这个会员卡号呢,去做这个主建,那接着我们去考虑说用这个会员电话或者身份证号靠谱吗?那首先呢,我们说这个会员电话,呃电话呢做主建呢也不行,在实际操作当中,呃这个手机号呢,是不是也可能就呃这个会员呢就不用了,然后呢,这个运营商呢,是不是把这个号呢就发回给别人了,对吧,现在你这个主体这个人呢又变了啊这个呢也不太靠谱。
08:01
哎,那用身份证号呢,身份证号呢,呃,国家呢,就给每个人分配了唯一的一个啊,每个人呢,是不是也不会去变啊啊记得有时候还看过这个新闻,说这个,呃,有一个孩子的母亲呢,就是觉得他这个孩子的身份证号呢,给分配的就是不好是吧,寓意不好啊,算卦算过不行啊,怎么办呢,去找这个公安局说呢,你给我改一个啊,注意这个是改不了的啊,每个人这个身份证号一旦确定下来以后呢,就不能够去修改了。看似呢,说我们这个号呢挺好对吧,不会像你这个会员卡号或者这个手机号一样的就会换掉啊,诶但是的话呢,这毕竟属于一个个人的隐私啊,你这块呢,去登记的时候,有可能这个用户呢,根本就不愿意把这个号呢报给你,那不愿意报给你,这是个闹,那逐渐的还不能是闹那不行。对吧,诶那你这块呢,跟用户呢,去吵起来的话呢,用户可能根本连会员呢都不办了,所以呢,在实际情况当中,我们会看到在这表里边儿的身份证号啊,包括电话呀,甚至都有可能是空的,那那杨IG呢,就是我们现在呢,想用这个卡号,想用这个身份证号,想用这个电话号呢,诶都不太靠谱,也就是说呢,我们用这个业务字段呢,去作为我们这个主键值啊,就不是太合适的了。
09:07
啊,不是太合适的,因为呢,我们谁也无法预测在项目的整个生命周期当中,哪一个业务字段呢,会因为呃,项目的业务的需求呢,有重复了啊,或者说重用这样的情况。啊,有重复的话,那你你给他用成主见了,那就不让人家重复,这不行是吧?诶所以呢,我们就不能够考虑这个业务这个这个这个字段了啊,诶这块呢,提到一个实际的经验,说刚开始呢,使用这个MYQ的时候呢,很多人呢,容易犯的错误,就是喜欢呢用这个业务资源去做这个主见啊,想当然的认为了解业务需求啊,但是呢,实际情况呢,就是往往出乎意料,而更改我们这个主件的成本是非常高的,这句话呢,我不用多去解释吧,啊想想你这个索引,想想你底层存储数据的这个情况,你改一下你试试啊,表数据量很大的情况下呢,简直就崩溃了是吧。好,那么这时候呢,我们就诶回归到咱们一开始的这个头部的这个问题,说淘宝数据库呢,它的一个主件呢,是怎么设置的,来咱们看一看它的一个订单表的一个情况啊,这个订单表的话呢,罗列出来了几个呢?诶近期的这样的一个消费的订单的记录,然后呢,这个订单号啊,是不是就我们订单表里边呢,诶相当于是一个唯一的啊,我们可以理解成了这个呢,就是我们的这个主见。
10:17
对吧,诶这是我们主见好,那这个要是主见的话呢,那他这是怎么设计的呢?我们把这几个数据呢,抽取出来,诶一共呢,发现它是有这个19位,然后细节一观察呢,发现呢,我们后五位呢,看都是一样的。诶你说这块一样是吧,呃,这个恰好这块是一样了啊,诶我发现呢,后五位这块呢,都是一样的,都是这个诶08113啊呃,那么这个前14位的话呢,它还是一个这种单调递增的这样的一个场景,那我们就大胆的去猜测呢,说我们这个,诶淘宝的这个订单ID呢,它可能是这样设计的啊一个呢,涉及到这个时间段,然后呢,加上这个去重的这个字段,诶再加上用户的一个ID。啊,因为针对一个用户来讲呢,他后边这几个一样了,就是他的订单呢,哎,他的用户的ID啊,诶所以说呢,他这个,诶后缀呢,这个都一样了。
11:02
诶那么这样的话呢,其实我们说呢,诶比如能够保证呢,呃首先呢,它是唯一的对吧?呃,你比如说这个时间的话呢,呃时间的话呢,有可能说比如双11的场景啊,这个时间呢,极其一致了,然后的话呢,有多个用户呢同时去消费的,但是呢,对于一个用户来讲的话呢,基本上它这个时间呢,呃就不可能说这个。这个一个订单你跟下个订单呢,你这个时间是完全一样的,这不太可能对吧,所以对呃,把用户这块呢,首先我们考虑在内啊,当然这用户的订单ID呢,我们也不是完全取他这个完整ID,取他的尾数的这样几位啊,已经能够起到很好的一个区分的驱虫的这样一个作用了啊。呃,然后呢,在考虑它ID的情况下呢,把这个时间字段呢给它加上,然后呢,再考虑一个这个驱虫是吧?哎,考虑个驱虫OK,呃,这个呢还是不错的啊,这个设计的话呢,能够做到这个全局的一个唯一性啊,对我们分布式系统呢是比较友好的啊,那么大家呢,在设计你自己的这个表的这个主件的时候呢,可以考虑啊,用这样的方式去设计,当然这里边呢,关于这个去虫字段的话呢,诶大家也需要呢去考虑考虑啊,有个讲究,好,那这呢我们是诶做了一个猜测啊,那么除去淘宝的这样的一种我们猜测出来的它一种设计方案之外的话呢,我们还能不能自已呢再去啊做一个设置呢?啊其实这里边呢,就仁者见仁,智者见智了啊,下边的话呢,我们给大家一种方案啊,诶应该是不错的一种方案,首先的话呢,我明确一下,对于这种非核心的业务的话呢,我们对应的这个表的主件呢,大家选用这个自动ID呢,是可以的啊,是可以的哈,比如像我们这个告警啊,日志啊,监控啊等等是吧,你就放在你这个本地的啊,跟分布式呢,可能关系也不太大,诶然后呢,这个表数据量。
12:40
也没有那么大啊,这个呢,我们就是诶做一个不同条目的一个区分就可以了啊,你用这个自增的ID是OK的啊,那么对于这种核心业务的话呢,我们需要保证的,首先呢,叫全局的唯一性啊,这是主见的最基本的特征,对吧,那其次的话呢,叫单调递增。诶当然这个这呃单价递增的话呢,主要是为了我们在插入数据的时候呢,直接呢,是不是在我们这个呃B加B加数里边呢,右边去插入啊不要呢去这个进行这个表的这个页的一个分裂是吧?哎,保证我们插入一个性能哈,然后这个唯一的话呢,是这个主线啊,这个全局的话呢,是我们要应对这种分布式的这种场景啊,诶你涉及到呢,多个不同的数据呢,哎,我们要合并的时候呢,你一定要保证它全局是唯一的啊。
13:22
那么这里边儿呢,最简单的一种设计组件的方案呢,叫做UUID。啊,大家一想到UID呢,就很头疼,说呢不都说了不让用UUID嘛,诶咱们先从UUID入手,然后我们再去改造它啊那么UID的特点是什么呢?叫全局唯一,占用36个字节啊数据呢是无序的诶插入的性能比较差啊看似的话呢,感觉好像没什么好好的点是吧?诶那么首先的话呢,我们先对这个UID呢,咱们有一个认知,第一个啊说为什么UID呢,是诶这这也不是第一个了啊先分析一下这几个问题,第一个啊,为什么它是全局唯一的啊,第二呢,就是它为什么要占用36个字节啊,怎么去剖析的啊下一个它是啊无序的吗?诶这个我们来看一看关于这个MYSQL数据库的这个UID啊,当然了,这个在其他场景下,UID呢,通常也都是这样来定义的啊。
14:09
它这个定义的话呢,是由这样的一个构成,哎,大家网上可能去搜索说这UID呢,呃,这个占用多少个字节呢?诶很多同学搜出来呢,是占这个16个字节是吧?诶占用16个字节呢,是因为它是用这种二进制的方式来进行这个存储的啊,诶咱们现在的这个UID呢,在咱们MY当中呢,它是用这个字符串的方式来进行存储的,哎举个例子来说吧,哎,这个单单说的话呢,可能有点干啊,这是一个典型的一个UID。哎,这是一个典型的UID啊呃,这个的话呢,大家可以呢,去在这里边我们做一个操作也行啊,你比如说这样子,哎,我去set一个啊,这样其实是有一个具体的函数的啊嗯,或者我们直接先这样啊UUID,哎咱们这样做一个查询啊,From the door。好,这时候我们选中啊做个执行。嗯,辅让我倒啊,这个还不让我们这样去用,哎,这么着吧。诶,Select是吧,写错了啊。
15:03
Select来我们这块呢,做个执行这块呢,大家是不是就看到我们这样个情况了,是吧?好,那这就是他一个具体的一个格式啊,然后呢,我们拿到一个典型的一个UID,然后对它呢,先做一个说明啊,说它为什么是占用这个叫36个字节的啊,这呢是它具体的一个格式,大家你数每一个位置上,它其实呢是一个。呃,这就相当于用字符串来存了哈,字符串来存的话呢,我们这一个呢,字符其实它呢,就用一个字节来存就可以了,所以这一个呢,就相当于一个字节大,你就这块数,数完以后光数这个,呃,这个字母或数字的话呢,一共是有32个啊,然后呢,再加上呢,我们这样短横线啊,一个两个三个四个,这呢是不是有加上一个四就是36个字节对吧?哎,就是这样来构成的。啊,这是我们这样来构成的啊,啊,那一会儿的话呢,我再说一下这个二进制里边那个16啊,这是我们改进的时候呢,到时候给大家去讲啊好,那这是我们说的这个事儿啊,然后呢,在这样的一个格式当中啊,咱们首先说呢,它为什么是叫全局唯一的。
16:01
啊,这里边呢,诶,我们会看到它有这样的几个部分来构成啊,有这个时间啊,时间呢,又分成这个时间低位,时间中位和时间高位叭,如说这个小时啊分钟啊秒啊是吧?然后呢,接下来有这个UID的这个版本时钟序列,还有我们Mac的地址。啊,那广东这个时间上来考虑的话呢,它就占用了60个位。哎,占用了这个60个位啊,呃,那么它这个类似于我们这个呃,Time step啊这样一个时间戳来表示,哎,再加上的话呢,我们这块还有这样的这个结构合在一起的话呢,它能够保证它是一个唯一性的。啊,唯一性的对吧?啊这个比较好理解,说为什么是36个字节,刚才我解释了啊,它这个是用字符串来进行存储的啊,不是二进制,然后其次的话呢,它为什么是一个随机无序的。啊,随机无序的,呃,因为在这个设计当中,我们把这个时间低位呢,是放在这个前边了啊放在前边了,你比如说这个呃几点几分几秒,那这个秒的话呢,它是老变是吧,一会儿呢是呃这个比如十秒钟,我只是举个例子啊啊一会儿呢变成50秒了,一会儿呢又变成十秒了,诶它不是一个严格递增的啊,只要不是递增的话呢,相当于我们就是理解成它是一个呃像随机的啊这样的一个过程。
17:11
啊一直在变化,好,那么我们理解了这个UID以后的话呢,首先明确一点,咱们呢,是不是不会选择这个UID呢,去作为我们的主键,为什么呢,我们希望呢,它是不是应该叫单调递增啊,你刚才是随机的,就不是单调递增的啊,全局唯一的这个倒是能保证,但是这个呢,是不是不理想啊,啊那怎么办呢?我们就可以对它呢进行一个改造啊,那改造的话呢,我们希望让它变成一个单调递增了,怎么就单调递增呢?我们把这个时间的低位和高位呢互换一下。哎,低位和高位互换一下,也就是说呢,我们先考虑这个时分,再考虑秒啊,那你想想我们这时候呢,在添加的时候呢,你这个时间的话呢,它是不是当然还有这个年日的说法啊,诶我这块呢,只是简单这样一说,诶你考虑这个呃时间的时候,你把这个高位放在前边,然后呢,比如说某年某月某日,然后呢,某时某分某秒,然后呢,你再接着这样去走,那这个数据呢,它不就是始终是个递增的顺序吗?
18:02
哎,那这样的话呢,它是不是就变成单调递增了。对吧,哎就哎,我们用它做主键的话呢,就可以避免这个叶分裂啊。那MY8.0呢,可以更换这个时间低位和高位的这个存储方式,这样的话呢,就有序了,哇,8.0呢,这一点做的是非常的及时的。对吧,OK,然后呢,接着呢,这个麦呢,它还解决了UUID呢存储空间的一个问题。啊,8.0是吧,解决了一个存储空间的问题,它呢不再使用这个字符串来进行这个保存了,而是使用这个二进制的方式进行保存,那么这样的存储空间呢,就降低为16个字节。往前16个字节啊,原来我们是不是36个字节,现在改成了16个字节,降低的还挺多的,那么这个怎么去理解呢?哎,大家哎,你看啊,诶同学们是不知道这个16怎么算的,你看刚才我说到了直接呢,大家要光数这样的一个字符,别数这个短横线的话呢,是不是一共是32个呀。对吧,你就这样数一下就行啊,一共32个,扣去这四个这个短横线啊,36减四不就32嘛,那么每一个这个位置呢,是不是一个16进制啊,那一个16进制的话呢,大家应该知道,是不是我们要把它改成二进制的话呢,是不是需要呃四个比特来存呢。
19:11
对吧,四个比特,你比如说1234,我们这个要选写一的话呢,是不是恰好就是15啊对吧,15对应的我们16进制是不是就是F啊,所以呢,一个呢,呃,一个位置这个字符我们用四个bit来存,所以我们就乘以四是不是这个呢,就是128吧,好,那128个bit,然后一个字节的话呢,是不是占哎八个bit呀,那我们除以八是不是,哎,商个这个先这个写个一,这是八,这就48 48呢,这写个六是不是就哎。六八四十八啊,是不是就16个这个字节就可以了,是吧,这个短横线呢不要了。啊,十个字节好,那这时候我们这个存储空间的话呢,是不是也就给大家降下来了啊,那这时候说的很好是吧,说的很好听,那这时候我们MYSQ8.0是如何支持的呢?呃,这里边我们就提到这样的一个函数,刚才我们演示了,哎,然后呢,我们可以做这样的一个测试就行是吧?哎,我这块呢,就不写了啊,咱直接粘过来。
20:01
好大家看哎,我呢,首先呢,UID啊,把它呢,付给我们这样的一个用户定义的一个变量啊,咱们用一个这个圈呢,表示一个用户定义的变量,对吧?然后呢,放到这以后呢,我们这个提供的函数呢,叫u ID To Bin啊把它呢改成是一个二进制的,把这个变量放在这儿,然后再加上一个,诶这个函数我们后边呢,加了一个参数呢,叫做true,来我们做一个执行。啊,错了,咱们没有执行这个set是吧?哎,把这两个都选中,咱们做一个执行。好在这看着好像不太理想啊,那这么着吧,CTRLC一下,嗯,先这么着啊,CTRLC一下,咱们在咱们这块呢,来进行查看啊,注意这块呢,一定要在这个MYS8.0当中啊杠U啊root-PABC点三没问题是吧?哎,那咱们先选一个数据库吧,哎,D边。好,首先的话呢,把我们刚才这个语句粘过来,我们先呢,生成这样的一个呃函数,随机生成这个UID的值,给了我们这样一个变量,对吧?好,那接下来的话呢,我们是不是做这个select是吧?哎,首先呢,叫UUID啊,这是一个,然后呢,刚才提到这个函数呢,叫UID呢?哎,To是不是B呢。
21:04
然后呢,把我们这个变量的拿过来。啊,这是一个,然后呢,再啊,UUID。To B。UID,然后逗号一下,这来个处,哎这么着好回车一下,好这时候大家你会发现啊,这呢是咱们本身这个原始的这个UID,然后呢,这个操作呢,你看他把这个具体的短横线呢,现在给去了啊,其实这时候我们看到它呢,就是16个字节了,这个呢,还是36个这个字节的。啊,存储空间上呢,就变了,然后我们这块写个处的时候呢,其实呢,就做了个位数啊,相当于做了一个这个调整。呃,位数调整,这个我们还得稍微的细节,大家去看一看啊。就相当于这块呢,我们呃想说的这个事儿呢,你看我看是在哪啊,眼神还得好一点。这个我们从哪块就是这块这样啊,我们此时的话呢,诶这个位置呢是不变的,然后这个位置不变,把这三个的话呢,我们相当于是交换了位置,改成了是先高位后中位后低位。
22:04
嗯,这是几个呀。123456788个是吧,四个四个OK啊,我们这么去找。嗯,在这啊,1234。5678,哎,是不是这是一波,然后这是一波。没问题是吧,然后呢,这是一波。诶这没问题吧,好,那这块呢,我们去找,然后这个927这个呢,你看它是它就不变哈,927这块啊到这。诶大家看一下是不是后边没有变,然后的话呢,你看这三段的话呢,我们就交换了啊这幺幺啊这个ec,你看这个11EC是不是就到这了,然后666A啊66A,然后后边这个5A啊这个这个这个一直到我们这个五一,诶是不是就交换了,相当于呢,我们这个操作呢,不就是把这个呃高位中位低位,你看这样的去调整一下格式,调整完以后的话呢,我们要是再去随机升这1ID的,因为你前边这块呢,是时间的这样的一个高位中位和低位,所以能够保证呢,它就是一个有序的了。
23:00
言外之意呢,就是我们后边呢,就可以把这个啊得到这个结果,是不是充当我们的主见就可以了,既可以保证全局唯一性,又可以保证这个单调递增,而且呢,它占用的空间还小了,非常的完美,是吧?啊那这时候我们拿这个16个字节的UID呢,和之前我们要用八个字节的啊这个int类型去做一个自增的话呢,来添加这个1亿条数据,诶我们做了一个测试。诶,每条数据呢,占用的这个是500个字节啊,三个二级索引,整个呢,测试的结果呢,会发现呢,我们有序的这个UID比我们自增的这个呢,花的时间呢要短一些,当然了,在这个表大小方面呢,是我们这个相较于这个自增的这个呢,多了三个GB,当然了,在240这个基础上多了三个GB,呃,其实也就增加了百分之,呃不到1.5%。是吧,哎,这个增加的其实还是比较有限的啊,整个来讲的话呢,相当于我们用这个有序的UID呢,呃,还是比较不错的啊,也能够保证我们全局的一个唯一性是吧。OK,而且的话呢,在实际的业务当中,我们的有序的UID呢,还可以在业务端呢去生成。
24:03
啊,不用像这个智能ID呢,我们得在这个服务器端去生成是吧?哎,这个可以进一步的减少我们啊SQ的交互次数啊,会更好一些。好,那就意味着在咱们当今这个互联网环境当中啊,不推荐用自增ID作为这个组件来设计啊,大家呢,可以类似的用这种有序的UID,哎,这个去设计啊。呃,另外的话呢,在这个真实的业务当中呢,大家这个组件呢,还可以考虑呢,就是用这个业务和这个系统的这个呃属性,比如用户的尾号啊,机房的信息啊啊去设计,就是没有必要呢,说非得要用我们这个呃有序的UID,而且呢,这个有序的UID呢,你看我是不是在这个8.0当中提到了我们有这样的一个函数的使用了,对吧?哎,那就意味着话呢,如果要是不是8.0的时候怎么办呢?我们就需要呢,手动的去设置这个主键了。啊,那这时候呢,大家可以考虑的话,是不是就像我们这个淘宝一样的这样的一个方式呢,去做一个设置,对吧?诶你要记着呢,要保证这个全局的一个唯一性啊全局唯一性,那样回到我们上面提到这个点来讲的话呢,你用户呢,自己呢,是不是创建一个字段,那创业字段的话呢,呃,如果呢,涉及到这个多个啊,比如说连锁的这个超市啊,每个超市呢,这里边我们都有这个具体的ID了,那要合在一起的话呢,这个数据可能就不能保证全局的唯一性,那怎么办呢?诶我们在这个总部这块呢,比如维护一个用户的信息表,其中呢,我们有个字段呢,就是记录一下当前啊这样的一个主建ID的一个当前值,当前的最大值啊,然后哪个部门这块要用的时候,哪个这个分店要用的时候呢,把这个最大值呢取过来,然后呢,他做这个自增,自增完以后的话呢,把你得到这个当前的最大这个值呢,再上传到我们这个总部的这个字段上啊,再把它做个更新,然后其他再用的话,拿过来以后呢,再用,接着再去增长,然后呢,诶用到最后呢,是不是再还回来,诶再记录一下,更新一下我们最新的这个最大值,这样呢也能够保证它的一个全。
25:47
去唯一性啊,就是主键的设置的话呢,其实有很多的这个思路啊,很多这个思路啊,那么我们主要的这个思考的点的话呢,就是保证全局唯一性,然后单调递增啊,然后大家的话呢,诶可以实际情况呢去做一个思考,然后他适合做一个面试题的话呢,呃,主要原因呢,就在于说。
26:07
诶,你要看到这个被面试者他的一个思考在里边,他说的呢,可能不一定呢,说是呃,特别精准的啊,但是呢,你一定要跟他在这个交互当中呢,能看到他对这个问题是如何看待的啊,这个呢,反而来讲应该是更重要的。好,那么关于这一节讲完以后的话,咱们这一章呢,就告一段落啊,希望呢,这一章啊,有很多的这个内容呢,对于大家呢,实际生产环境当中啊,是起到这种帮助的作用的,好那么关于呢,我们叫索引化和查询化啊,咱们就说到这儿。
我来说两句