认识数仓拉链表

数据仓库之拉链表

在数据仓库领域,拉链表是一种非常重要的数据结构,它能够对数据进行有效的组织和处理。本文将详细介绍拉链表的概念、应用、优缺点以及实现方法,帮助读者更好地理解和掌握数据仓库中的拉链表技术。

场景问题

在数据仓库的数据模型设计过程中,经常会遇到下面这种表的设计:

有一些表的数据量很大,比如一张用户表,大约有亿级别记录,几十个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。

表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。

需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。

表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。

那么对于这种表我该如何设计呢?下面有几种方案可选:

  1. 方案一:每天只留最新的一份,比如我们每天用Sqoop抽取最新的一份全量数据到Hive中。
  2. 方案二:每天保留一份全量的切片数据。
  3. 方案三:使用拉链表。

什么是拉链表

一、拉链表的概念

拉链表(Linked Chunked Blocks,简称 SCB)是一种数据存储方式,它可以将一块连续存储空间划分成多个块,每个块包含多个数据项。每个块都有一个头部和一个尾部,头部记录了该块的数据类型、大小等信息,尾部则记录了下一个块的地址。通过这种方式,拉链表可以实现数据的连续存储和非连续存储,从而满足不同场景下的需求。

二、拉链表的应用

拉链表作为一种高效的数据结构,在数据仓库领域有着广泛的应用。以下是几个典型的场景:

数据缓存:在数据仓库中,经常需要将大量数据加载到内存中进行处理。拉链表可以将数据按照块的方式组织,每个块包含多个数据项,从而减少内存的碎片化,提高数据加载和处理效率。
索引构建:在构建索引时,拉链表可以用来存储索引的倒排列表。通过将倒排列表分成多个块,每个块包含多个倒排项,可以实现对倒排列表的高效存储和查询。
数据分片:在分布式数据仓库中,需要将数据分成多个分片,存储在不同的节点上。拉链表可以将数据按照块的方式进行分片,每个块包含多个数据项,从而实现数据的分布式存储和处理。

三、拉链表的优缺点

拉链表作为一种常用的数据结构,具有以下优点:

高效的空间利用率:拉链表可以将一块连续的存储空间划分成多个块,每个块包含多个数据项,从而减少内存的碎片化,提高空间利用率。
高性能的数据加载和处理:由于拉链表可以将数据分成多个块,可以实现对数据的批量加载和处理,从而提高数据加载和处理效率。
灵活的数据组织方式:拉链表可以根据需要将数据分成不同的块大小和块数,从而实现数据的灵活组织和管理。
然而,拉链表也存在以下缺点:

写入性能问题:在写入数据时,需要将数据分成多个块,并维护每个块之间的链接关系,这会增加写入操作的复杂性,降低写入性能。
内存占用问题:由于拉链表需要维护每个块之间的链接关系,因此需要占用一定的内存空间。当数据量较大时,这些额外的内存开销可能会对系统性能产生影响。
数据访问限制:由于拉链表的每个块之间是通过链接关系相互连接的,因此在访问某个块的数据时,需要先加载该块的所有数据项。这可能会增加数据的访问延迟和系统负载。

四、拉链表的实现方法

下面介绍两种常见的实现方法:

内存实现:在内存中实现拉链表可以使用数组或链表来实现每个块的数据存储和链接关系。例如,可以使用一个数组来存储所有块的首地址,然后使用一个指针来指向当前块的下一个块。当需要访问某个块的数据时,可以首先加载该块的所有数据项,然后通过指针访问下一个块的数据项。
磁盘实现:在磁盘中实现拉链表可以使用文件或数据库来实现每个块的数据存储和链接关系。例如,可以使用一个文件来存储所有块的数据项和链接关系信息。当需要访问某个块的数据时,可以首先读取该块的头部信息,然后根据链接关系依次读取下一个块的数据项。

我们先看一个示例,这就是一张拉链表,存储的是用户的最基本信息以及每条记录的生命周期。我们可以使用这张表拿到最新的当天的最新数据以及之前的历史数据。

time_id用户编号手机号码start_dateend_datestate
2023-12-010011101202023-12-019999-12-310
2023-12-010021191202023-12-019999-12-310
2023-12-01003333332023-12-019999-12-310
2023-12-02004444442023-12-029999-12-310
2023-12-030011101202023-12-012023-12-031
2023-12-03005555552023-12-039999-12-310
2023-12-040044444442023-12-022023-12-041

我们能拿到历史状态用到的SQL

select state from model_aaa WHERE start_date <='查询日' and  end_date > '查询日'  -- 此处要好好理解,是拉链表比较重要的一块。)

拉链表在Hive中的实现

在现在的大数据场景下,大部分的公司都会选择以Hdfs和Hive为主的数据仓库架构。目前的Hdfs版本来讲,其文件系统中的文件是不能做改变的,也就是说Hive的表智能进行删除和添加操作,而不能进行update。基于这个前提,我们来实现拉链表。

在Hive中,拉链表可以通过使用视图来实现。视图是一个虚拟表,它可以根据一定的条件和规则从底层数据源中提取数据。在使用视图时,我们可以将拉链表的基本原理和更新策略以SQL语句的形式表达出来,从而实现拉链表的功能。

例如,我们可以创建一个名为“pivot_table”的视图,该视图根据时间戳对数据进行分组,并将最新版本的数据作为结果返回。具体SQL语句如下:

CREATE VIEW pivot_table AS
SELECT key, MAX(timestamp) AS timestamp, value
FROM (SELECT key, timestamp, value, ROW_NUMBER() OVER (PARTITION BY key ORDER BY timestamp DESC) AS row_numFROM table_name
) AS sorted
WHERE row_num = 1
GROUP BY key, value;

该SQL语句首先使用子查询将数据按照主键和时间戳进行排序,并给每个节点分配一个行号。然后,使用聚合函数MAX()和ROW_NUMBER()函数将最新版本的数据作为结果返回。最后,使用GROUP BY语句将结果按照主键和值进行分组。

通过使用视图,我们可以很方便地实现拉链表的功能,并大大提高数据仓库的效率和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/234615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决Edge浏览器问题的实用教程

学习目标&#xff1a; 掌握解决Edge浏览器常见问题的方法。提升对浏览器故障排除的能力。 学习内容&#xff1a; 常见Edge浏览器问题的识别和解决方法。例如页面加载慢、无法访问特定网站、崩溃或无响应等。更新Edge浏览器和操作系统&#xff0c;以确保拥有最新的安全补丁和功…

浅析:智能化视频安全监管系统的设计与实现步骤

关于智能化视频监管方案&#xff0c;小编已经和大家分享了很多&#xff0c;今天就和大家来探讨一下关于智能化视频安全监管系统的设计与实现步骤。 首先需要分析需求。要与使用者和业务部门合作&#xff0c;明确系统的功能和需求&#xff0c;例如&#xff0c;确定监控区域、安…

使用Vue customRef创建防抖 ref

customRef 用于创建一个自定义的ref&#xff0c;显式声明对其依赖追踪和更新触发的控制方式。 function customRef<T>(factory: CustomRefFactory<T>) : Ref<T>// customRef接受一个工厂函数作为参数&#xff0c;这个工厂函数接受track、trugger两个函数 //…

Tomcat介绍及使用:构建强大的Java Web应用服务器

引言&#xff1a; 在现代软件开发中&#xff0c;Web应用已经成为了不可或缺的一部分。而为了构建高效、稳定的Web应用服务器&#xff0c;选择合适的工具和技术至关重要。Tomcat作为一款开源的Java Web应用服务器&#xff0c;凭借其丰富的功能和灵活的配置&#xff0c;成为了开发…

C #define宏展开#与##

#include<stdio.h> //宏展开后解释成字符串&#xff1a;# #define fprint(expr) printf(#expr "%.1f\n",expr) #define strprint(expr) printf("%s\n",#expr) //宏展开后拼接变量&#xff1a;## #define strconcatprint(expr1,expr2) printf("%…

[C错题本]

1.int,short,long都是signed的 但是char可能是signed 也可能是unsigned的——《C Primer》 2.在16位的PC中 char类型占1个字节 int占2个字节 long int占4个字节 float占四个字节 double占八个字节 3.自增运算符和自减运算符即使是在判断条件中使用也会实际生效 int i 1; int…

MyBatis——MyBatis的原始Dao开发(了解)

MyBatis的原始Dao开发-了解 使用Mybatis开发Dao&#xff0c;通常有两个方法&#xff0c;即原始Dao开发方式和Mapper接口代理开发方式。而现在主流的开发方式是接口代理开发方式&#xff0c;这种方式总体上更加简便。在之前的文章已经给大家介绍了基于代理方式的dao开发&#x…

群聊中如何开启位置实时共享

如果需要在群聊中也加入该功能可在 RCConfig.plist 文件中添加如下内容&#xff1a; &#xff08;**注意&#xff1a;**群聊最多支持5人同时位置共享。&#xff09; 实时位置共享功能技术文档链接&#xff1a;融云开发者文档 2 <key>RealTimeLocationShare</key> &…

在scrapy 使用selenium模拟登录获取cookie

前言 最近有一点点爬虫需求&#xff0c;想总结一下scrapy框架的一些基本使用方法&#xff0c;加深印象&#xff0c;自己一直习惯使用一些脚本文件运行爬虫&#xff0c;面对数据量非常大&#xff0c;稳定性要求比较高的&#xff0c;效率需求比较高的情况下还是用scrapy较为合适…

Azure Machine Learning - 提示工程高级技术

本指南将指导你提示设计和提示工程方面的一些高级技术。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&#xff0c…

手动实现 Vue 3的简易双向数据绑定(模仿源码)

Vue 3 带来了许多令人兴奋的新特性和改进&#xff0c;其中之一就是其双向数据绑定的实现方式。与 Vue 2 使用 Object.defineProperty 不同&#xff0c;Vue 3 利用了 JavaScript 的 Proxy 特性来创建响应式数据。在这篇博客中&#xff0c;我们将探讨 Vue 3 中双向数据绑定的基础…

Python MySQL数据库连接实现增删改查

一、应用场景 python项目连接MySQL数据库时&#xff0c;需要第三方库的支持。这篇文章使用的是PyMySQL库&#xff0c;适用于python3.x。 二、安装 pip install PyMySQL三、使用方法 1.导入模块 import pymysql2.连接数据库 db pymysql.connect(hostlocalhost,usercode_s…

【Linux 驱动】Linux设备树(四)—— 设备树驱动LED

有了设备树以后&#xff0c;我们可以将寄存器信息保存到设备树&#xff0c;即便是更换了一个设备&#xff0c;我们也无需修改驱动文件&#xff0c;只需要修改设备树文件并重新编译。 下面介绍两种通过设备树驱动 LED 的最简单的方式&#xff0c;这两种方式的主要是设备树中 re…

什么是触控芯片?触控芯片有哪些?

一、什么是触控芯片&#xff1f; 触控芯片是一种用于感知人机交互行为的电子元器件&#xff0c;通过感应人体肌肉、电容电场和压力等多种信号&#xff0c;实现触摸屏幕、手势操作、手写输入等功能。二、触控芯片的工作原理 触控芯片的工作原理基于电容原理&#xff0c;当人体肌…

一文读懂PMP项目管理

PMP项目管理是什么 PMP&#xff08;Project Management Professional&#xff09;指项目管理专业人员资格认证&#xff0c;由美国项目管理协会&#xff08;Project Management Institute&#xff0c;简称PMI&#xff09;发起&#xff0c;目前已在全球206个国家和地区进行认证&…

小黑南京归来,参加部里的公务员培训,有点儿社死认识了好多小伙伴的leetcode之旅13. 罗马数字转整数

小黑代码 class Solution:def romanToInt(self, s: str) -> int:chars [M, CM, D, CD, C, XC, L, XL, X, IX, V, IV,I]nums [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]map_ dict((k, v) for k,v in zip(chars, nums))# 字符串长度n len(s)# 结果变量res …

Java集合转int数组

集合通过toArray()方法进行转换为数组&#xff0c;可以转换成为指定类型的数组&#xff0c; 【但是】这些类型都必须是object类型的子类&#xff0c;基本类型不可以。 可以通过stream流处理&#xff1a; Set<Integer> set new HashSet<>(); int[] result interSet…

Swagger2解放双手的API开发文档生成

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《MyBatis-Plus》。&#x1f3af;&#x1f3af; &am…

修改Mysql密码

ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY password

NFS原理详解

一、NFS介绍 1&#xff09;什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。 NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。 在本地的NFS客户端的机器看来&#xff0c;NFS服务器端共享的目录就好像自己的磁…