Python面试-DB相关

昨日回顾:

面试

Python综述

  设计哲学

  版本变迁及发展

  GIL

  内存管理及垃圾回收

  并发并行

昨日作业一:Python是否存在内存泄露

 

作业二:过往的项目中有没有出现过性能问题?

作业三:什么是协程?

 

 

一、数据库

     今天的主要内容集中在面试过程中的数据库部分;互联网公司Python相关岗位面试中大多数会有数据库相关的面试问题。

     大家认为什么是数据库呢?

     数据库简而言之是一种电子化的文件柜,用户可以对文件中的数据进行增删改查;当前互联网中,最常见的数据模型主要有两种:关系型数据库和非关系型数据库。

     关系型数据库常见的有MySQL,Oracle, Postgrel, MariaDB, SQL Server等;非关系型数据库(nosql, not only sql)Redis, Memcached, MongoDB, Hbase等。

     1. 关系型数据库

     关系型数据库优点主要在三方面:易用性(都是使用表结构,格式一致),使用方便(SQL语言),支持复杂查询(多表之间复杂查询);其缺陷在于三块:读写性能较差,尤其是海量数据的高并发读写;二是因为是固定的表结构导致其灵活度不高,三是高并发的情况下硬盘IO容易成为瓶颈;

    2. 非关系型数据库

    非关系型数据库主要的优势如下:

     1) 格式灵活:存储数据格式支持key-value,文档,图片等;

     2) 高扩展性:很容易进行集群扩展,适应海量数据增减;

     3) 速度快:nosql可以使用硬盘和随机存储器作为存储介质,同时其设计理念之初一般便适合海量数据的高并发读写;

     4) 成本低:nosql数据库部署简单,基本都是开源软件;

 

二、MySQL

     关系型数据库中大家应该mysql接触的比较多。mysql面试中一般会有几大类易考点:

     1. 存储引擎

  查看MySQL支持哪些存储引擎可以在登录mysql后执行show engines

     当前常用的mysql存储引擎有InnoDB, MyIsam, Merge, Memory等。

     其中使用最为广泛的是InnoDB存储引擎,InnoDB是一种事务性的存储引擎,一般如果需要事务支持,并且需要较高的读写频率,推荐使用InnoDB

    MyIsam不支持事务,也不支持外键,但访问速度很快,每个MyIsam表在磁盘上存储有三个文件(.frm存储表定义,.myd存储数据,.myi存储索引);

    Merge存储引擎是一种MyIsam表的集合,这些MyIsam表结构必须完全一致,说白了,merge表只是一堆MyIsam表的集合器,merge表中并没有数据,对merge表的增删改查操作实际上是对MyIsam表的操作;删除merge表时,只是删除merge表的定义,对内部数据没有影响;

    Memory存储引擎的逻辑存储介质是内存,但memory表中存储的数据必须是长度不变的格式,同时由于内存介质特性,当宕机或出现其他故障时,很容易出现数据损失的情况;在实际的公司生产线上使用很少;

 

  2. 索引

    大家应该都去过图书馆,比如深圳图书馆藏书400万册,我们怎么在这海量的图书中找到自己真正想找的书呢?首先通过系统关键词搜索找到书的索引号,如T520.13等;而在计算机中也是一样,随着数据的增多,如果表中没有合适索引,单表的查询性能基本也就万这个级别了,每一次查询都需要进行全表扫描(即扫描该表中所有的记录),效率低下;在MySQL中索引根据存储的方式区分又分为聚集索引和非聚集索引两种;聚集索引数据的存放顺序于索引顺序是一致的。即只要索引是相邻的,那么索引所对应的数据也一定是相邻的存放在磁盘上。这样做的好处是什么呢?设想一下做范围查询时,比如查询1000-10000的主键ID,又或者以a,b,c开头的用户名,如果是聚集索引的话,实际情况只需要一次磁盘IO

    而非聚集索引的逻辑顺序与磁盘上的物理顺序不同,非聚集索引的数据在逻辑上也是连续的,但其记录的逻辑顺序和磁盘上记录的物理顺序没有任何直接联系。有点类似于大家以前使用新华字典时根据偏旁部首查字典,查偏旁部首对应的连着的两个字时目录部分是连续的,但详情页实际的字却很有可能是不挨着的。

    根据唯一性区分又分为:

    a. 普通索引

    这是最基本的索引,它没有任何限制,比如上文中为title字段创建的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引

    CREATE INDEX index_name ON table(column(length))

    b. 唯一索引

     与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。

    CREATE UNIQUE INDEX indexName ON table(column(length))

    c. 组合索引(最左前缀)

     平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。例如上表中针对titletime建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:

    –title,time

    –title

    为什么没有time这样的组合索引呢?这是因为MySQL组合索引最左前缀的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引,如下面的几个SQL所示:

    SELECT * FROM article WHREE title='测试' AND time=1234567890;

    SELECT * FROM article WHREE utitle='测试';

    SELECT * FROM article WHREE time=1234567890;

 

    3. 索引底层存储

    mysql索引底层存储机制是使用B+树进行实现;B+树数据结构是B-树实现的增强版本。尽管B+树支持B-树索引的所有特性,它们之间最显著的不同点在于B+树中底层数据是根据被提及的索引列进行排序的。B+树还通过叶子节点之间的附加引用来优化扫描性能。

     B树(m=4)结构图如下:

  B+树结构如下:

     

 

      B+搜索和B-搜索不同,区别是B+树只有达到叶子节点才命中(B-树可以在非叶子节点命中),其性能等价于关键字全集做一次二分搜索。

      B+树的特性:

     1)所有关键字都出现在叶子节点的链表中,叶子节点相当于存储数据的数据层。

     2)不可能在非叶子节点上命中。

     3)非叶子节点相当于是叶子节点的索引,叶子节点相当于数据层。

 

 4. 版本变迁及特性

    有时面试过程中会谈到mysql版本特性问题,此时如果我们队mysql版本变迁有比较深入的了解便比较容易给面试官留下好的印象记忆点,也代表着我们自身关注着行业相关技术的最新发展,不与时代脱节。

    目前市场上mysql存在的版本基本是5.65.78.0三个大版本。5.6稳定版本在13年发布,5.7版本15年发布,8.0稳定版本18年初;我们需要了解5.7版本相对于5.6版本、8.0相对于5.7版本有哪些重要特性变化;

    Mysql5.7新变化特性有:

    a. 灵活性上开始支持json串格式字段;mysqljson的支持是在server层;server层提供了一堆便于操作JSON的函数,至于存储,就是简单地将JSON编码成BLOB,然后交由存储引擎层进行处理,也就是说,MySQL 5.7JSON支持与存储引擎没有关系,MyISAM 存储引擎也支持JSON 格式mysqljson格式可以混合存储结构化数据和非结构化数据,同时拥有关系型数据库和非关系型数据库的优点

 

 

    b. generated column. 即数据库中的这一列由其他列计算而得。例如,知道直角三角形的两条直角边,要求直角三角形的面积。很明显,面积可以通过两条直角边计算而得,那么,这时候就可以在数据库中只存放直角边,面积使用generated column.

    CREATE TABLE triangle (sidea DOUBLE, sideb DOUBLE, area DOUBLE AS (sidea * sideb / 2);

    insert into triangle(sidea, sideb) values(3, 4);

     在这个例子中,如果我们需要根据面积创建索引以加快查询,就无法在用户代码里面实现,使用generate column就变得非常简单: 
alter table triangle add index ix_area(area);

    c. 性能提升。

   

    Mysql8.0新版本特性如下:

    a. mysql8开始支持文档存储。开发人员可以将无模式 JSON 文档集合与关系表放在一起使用(文档是一堆键值对的集合,表现为 JSON 结构)

    b. 性能大幅提升。速度比5.7快两倍,在读写工作负载、IO密集型工作负载、高竞争工作负载;

    c. 默认字符编码改为了utf8mb4.

 

 5. 事务隔离

   任何支持事务的数据库必须满足四个特性:原子性(automicity), 一致性(consistency),隔离性(isolation)、持久性(durability

   ⑴ 原子性(Atomicity

 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

   ⑵ 一致性(Consistency

 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

 拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管AB之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

  ⑶ 隔离性(Isolation

 隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

 即要达到这么一种效果:对于任意两个并发的事务T1T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

 关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。

  ⑷ 持久性(Durability

 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

 

   事务隔离相关的几个问题如下:

   a. 脏读

 脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

 当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

    update account set money=money+100 where name=’B’;  (此时A通知B)

    update account set money=money - 100 where name=’A’;

  当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

   b. 不可重复读

  不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

  例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

  不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

  在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据AB依次查询就可能不同,AB就可能打起来了……

   c. 虚读(幻读)

  幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

  幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

 

    现在来看看MySQL数据库为我们提供的四种隔离级别:

   ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

   ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

   ③ Read committed (读已提交):可避免脏读的发生。

   ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

 

    以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)

 

   6. MVCC

    基本原理

   MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。

    基本特征

  • 每行数据都存在一个版本,每次数据更新时都更新该版本。
  • 修改时Copy出当前版本随意修改,各个事务之间无干扰。
  • 保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copyrollback

     InnoDB存储引擎中MVCC的实现策略:

     在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空,其实还有一列称为回滚指针,用于事务回滚,不在本文范畴)。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。

每个事务又有自己的版本号,这样事务内执行CRUD操作时,就通过版本号的比较来达到数据版本控制的目的。

 

补充:

1). MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read.

2). Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.

   原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。

3). 串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。

4). 通过以上总结,可知,MVCC主要作用于事务性的,有行锁控制的数据库模型。

 

关于MysqlMVCC的总结

客观上,我们认为他就是乐观锁的一整实现方式,就是每行都有版本号,保存时根据版本号决定是否成功。

但由于Mysql的写操作会加排他锁(前文有讲),如果锁定了还算不算是MVCC

了解乐观锁的小伙伴们,都知道其主要依靠版本控制,即消除锁定,二者相互矛盾,so从某种意义上来说,MysqlMVCC并非真正的MVCC,他只是借用MVCC的名号实现了读的非阻塞而已。

 

面试题一:知道mysql的事务隔离吗?/事务隔离分哪几个级别?/事务隔离性怎么保证/...

   回答思路:

   空间线:

   事务ACID概念

   事务隔离四个级别(概念及优缺点)

   MySQL事务隔离性和其他DB区别

   

   思路串联:事务ACID-> 事务隔离四个级别 ->MVCC/GAP问题引子

 

   示例答案:

    数据库支持事务本身需要有具备四个特性:原子性、一致性、隔离性和持久性,也即ACID。其中事务的隔离性简单来说就是并发执行的多个事务之间互不干扰。

    事务隔离总体分为四个级别:第一个是RU(未提交读),该级别事务内容易出现脏读的情况,即事务A读到了事务B没有提交的数据;为了解决脏读问题,可以提高事务隔离级别到RC(提交读),此时事务A不会读到其他事务未提交的数据,但又产生了一个新的现象:事务A执行的过程中,有可能另外一个事务B提交了数据,此时事务读取的数据和之前不一致,即出现了不可重复读的问题;所以mysql的InnoDB本身默认采用了第三个事务隔离级别RR(可重复读),该级别使用MVCC(多版本并发控制)解决重复读的问题,一般的RR级别会出现幻读的问题,及同一个事务多次执行同一个select,读取到的数据行发生了改变,这是因为数据行发生了行数减少或者新增;而最高的事务隔离级别是SE(可序列化),该方式下事务相当于串行执行,解决了脏读、不可重复读、幻读等问题,但对性能和效率的影响很大,生产环境中很少会使用该隔离级别;

    具体到mysql中,mysql默认的RR级别有一些特别,因为其引入了GAP LOCK(间隙锁)的概念,可在RR级别即可解决幻读的问题;另外一个特性是mysql里的MVCC只解决读-写的阻塞问题,写-写依然还是阻塞的。

 

 

 

三、MongoDB

     1. 存储引擎

    MMAP:

    MongoDB MMAPv1 引擎的扩展规则是,每次存储文件容量翻倍,直至增加到 2G 大小

     缺点:

  1) 库级锁,在3.0版本时有提升到collection锁,但粒度仍然很大;

     2) 删除元素时存储空间未真正释放;

 

   Wiredtiger:

   20153.0版本发布后,引入wiredtiger存储引擎,3.2版本默认存储引擎都改为了wiredtiger

      特点

     a. 文档级别锁,解决了锁粒度过大的问题;

     b. 磁盘数据压缩,支持对所有集合和索引进行Block压缩和前缀压缩(如果数据库启用了journaljournal文件一样会压缩),已支持的压 缩选项包括:不压缩、Snappy压缩和Zlib压缩。

     c.  删除数据时,数据会立即删除;

     d. MongoDB3.0在多线程、批量插入场景下较之于MongoDB2.6有大约4-7倍的增长

 

   Rocksdb

   RocksDB 是基于 LSM tree 结构组织数据,其针对写入做了优化,将随机写入转换成了顺序写入,能保证持续高效的数据写入。

   写场景较多时刚开始 Wiredtiger 的写入性能远超 RocksDB,而随着数据量越来越大,WT的写入能力开始下降,而 RocksDB 的写入一直比较稳定。

 

   2. 版本变迁及特性

    MongoDB历史变化中,有两个大的版本变化节点,分别是:

    a. MongoDB 3.0版本可能是MongoDB诞生以来最重要的一个版本,该版本引入了插件式的存储引擎架构,允许第三方根据实际项目的需要开发存储引擎,类似于MySql中的分层存储引擎架构。随同这种架构发布的新的存储引擎为WiredTiger,在随后的3.2版本中,默认的存储引擎改为了wiredtiger

    b. MongoDB 4.0版本添加了一个极为重要的功能:多文档事务支持,支持复制集内部跨一或多个集合的多文档事务,保证针对多个文档的更新的原子性。而在未来的 MongoDB 4.2 版本,还会支持分片集群的分布式事务。

 

  3. 底层存储机制(B树)

    MongoDB的索引底层存储采用的是B-tree进行存储,为什么MongoDB底层使用B-TREEMySQL使用B+tree呢?

     空间局部性原理:如果一个存储器的某个位置被访问,那么将它附近的位置也会被访问

     传统用来搜索的平衡二叉树有很多,如 AVL 树,红黑树等。这些树在一般情况下查询性能非常好,但当数据非常大的时候它们就无能为力了。原因当数据量非常大时,内存不够用,大部分数据只能存放在磁盘上,只有需要的数据才加载到内存中。一般而言内存访问的时间约为 50 ns,而磁盘在 10 ms 左右。速度相差了近 5 个数量级,磁盘读取时间远远超过了数据在内存中比较的时间。这说明程序大部分时间会阻塞在磁盘 IO 上。

 

     为什么 MongoDB 使用B-树:

    MongoDB 是一种 nosql,也存储在磁盘上,被设计用在 数据模型简单,性能要求高的场合。性能要求高,看看B/B+树的区别第一点:

    B+树内节点不存储数据,所有 data 存储在叶节点导致查询时间复杂度固定为 log n。而B-树查询时间复杂度不固定,与 key 在树中的位置有关,最好为O(1)

我们说过,尽可能少的磁盘 IO 是提高性能的有效手段。MongoDB 是聚合型数据库,而 B-树恰好 key data 域聚合在一起。

 

     为什么 Mysql 使用B+树:

    Mysql 是一种关系型数据库,区间访问是常见的一种情况,而 B-树并不支持区间访问(可参见上图),而B+树由于数据全部存储在叶子节点,并且通过指针串在一起,这样就很容易的进行区间遍历甚至全部遍历。见B/B+树的区别第二点:

    B+树叶节点两两相连可大大增加区间访问性,可使用在范围查询等,而B-树每个节点 key data 在一起,则无法区间查找。

     其次B+树的查询效率更加稳定,数据全部存储在叶子节点,查询时间复杂度固定为 O(log n)

     最后第三点:

    B+树更适合外部存储。由于内节点无 data 域,每个节点能索引的范围更大更精确。

 

    4. 和关系型数据库MySQL对比

    随着数据库本身的飞速发展,MySQLMongoDB作为关系型数据库和非关系型数据中的一种常见数据库,他们之间表现出来的特性越来越类似,已经很难去通过是否支持事务、性能等方面的过往的评判标准来定位选型。

    大体上一般如果数据量规模不是特别大,同时关系性结构比较多,应用场景事务要求较多,此时mysql可能较为适用;如果是海量数据存储,读取和写入频率极高,则推荐适用MongoDBnosql数据库。

    当然在实际的企业项目开发过程中,DB的选型情况远比上面复杂;除了业务场景的特性,还需要考虑到成本(运维成本、学习成本)、成员意愿、公司技术栈等情况;

    5. 集群及扩展

    当数据量规模达到亿级以上时,单一的collection已经很难独自承担整体的存取需求,此时便需要进行db扩展,常用的数据扩展方法有:

    a. 水平扩展:分库,分collection

    b. 垂直扩展:分片

 

四、Redis相关

     1. 用途及使用场景

    Redis是一个开源的key-value数据库,支持stringlistsetzsethash类型数据。其存储介质是内存。在实际的企业开发中,一般在以下几类场景中会用到:

    a. 缓存高频次访问的数据,降低数据库io

    b. 分布式架构,做session共享

    c. 利用zset类型可以存储排行榜

    d. 利用list做简易MQ或存储最新的n个数据

 

     2. redis底层存储机制(ziplist, skiplist

     redis常规键的底层实现如下:

     list键:双向链表

     hash键:字典dict

     zset键:跳跃表zskiplist

      但是当list键里包含的元素较少、并且每个元素要么是小整数要么是长度较小的字符串时,redis将会用ziplist作为list键的底层实现。同理hashzset在这种场景下也会使用ziplist

      既然已有底层结构可以实现listhashzset键,为什么还要用ziplist?

      当然是为了节省内存空间,由于时间原因此处暂不深入ziplist的内部实现;

   

    3. redis集群

    redis的集群化方案 目前有三种 

  (1Twitter开发的twemproxy

  (2)豌豆荚开发的codis

  (3redis官方的redis-cluster

     相较而言,当前redis-cluster功能更为强大;

 

    4. bloom算法

    redis本身是基于内存的nosql数据库,在实际开发过程中,随着业务的扩展,需要redis进行缓存的数据可能越来越庞大,使用redis,memcache等内存数据库进行缓存时,需要的内存空间可能需要几十个G甚至几百G的内存,对于大多数中小型公司而言,这是一笔巨大的成本,比如垃圾邮箱地址数目达到十亿数量级时,传统方式存储需要的内存可能需要几十个G,此时便可以引入bloom算法,采用基于bloom算法的开源数据库;

     那么何为bloom算法呢?

    Bloom Filter算法就是对于有n个元素的集合S={x1, x2,……,xn},我们用k个哈希函数(h1,h2,……,hn),分别将S中的每一个元素映射到一个m位的位数组(bm-1bm-2……b1b0)中。该位数组在初始化时所有置为0,每当用哈希函数映射到该位时则将该位置为1。对于已经置为1的位则不在反复置1

比如。将S={x1,x2,x3}这个集合用3个哈希函数映射到一个14位的位数组中,如图所看到的:

 

 

     使用Bloom Filter我们能够推断一个元素是否在某一个集合中。假设这个集合是使用线性结构存储的话。其查找的时间复杂度是O(n);使用像二叉树或B-tree这种树形结构存储的话其查找的时间复杂度是O(logn)。而使用Bloom Filter在能够容忍一定错误率的情况下,其时间复杂度是O(1)。因此,与传统的权衡空间或时间的算法不同,Bloom Filter 极其巧妙。通过引入一定的错误率来换取时间和空间,在某些应用大大提高了性能。

 

五、列式数据库

     列式数据库我简单的和大家过一遍基础知识。

 

    怎么来理解或区分数据库和数据仓库的关系

 

    业界经常说的术语是OLTP,这是on-line transaction processing的简写。联机事务处理。

    OLAP是On-Line Analytical Processing 翻译成联机分析处理。

 

    从名字来看,可以看出一个侧重事务处理。一个侧重分析处理。事务处理,就是交易数据。如订单、商品等数据的增删查改。分析处理,要对这些数据分析出统计结果。分析处理,就要使用数据仓库来存储数据了,要与业务数据库分开,而数据来自于业务数据库。

 

    联机事务处理使用的是交易型数据库,即行式存储关系型数据库如oraclesqlservermysql

    联机分析处理使用的是分析型数据库,即列式关系型数据库hbasehiveclickhouse等。

    数据仓库只是一个概念,至于用什么数据库,随自己。对数据的分析处理,得到统计结果,归到数据仓库里面去,以提供在线查询

    为什么数据仓库喜欢使用列式关系型储数据库?

    数据仓库使用的技术方案,有很多种。可以使用关系型数据库mysql,目前,业界一般使用列存储。

 

    为什么不用mysql等行存储关系数据库来做数据仓库? 而一般使用列存储数据库, 是考虑到数据仓库的以下特点: 

    1)数据仓库的数据来源多个系统。可能是文件、可能是其他关系型数据库中的交易数据。 

    2)需要多个维度建立数据统计模型。 

    3)存储数据量。历史的,存档的,归纳的,计算的数据。

    4)需要访问大量的记录才能统计出结果。如果统计性能上不能很慢,无法出统计结果。就满足不了分析统计的需求。涉及到复杂的聚合统计查询,这类系统就比较难以处理了,比如要查询某一些类型的用户过去三个月购买最多的商品,因为同一时间需要查询大量数据,OLTP(关系数据库) 系统并不擅长处理这类需求。

    5)更新数据很少。都是添加数据、查询数据。于是对查询速度要求高。

 

    列式型关系数据库,使用上与mysql一样,都是sql语句操作,也是关系表设计。唯独底层存储原理不一样。下面解释。

 

     对比行存储和列存储

    下面来看网上找的一张图,对比行存储和列存储

    

 

      行存储的一行数据(此行的所有数据)都在一起,紧接着就是第二行数据,依次下去。

      列存储不同的是,一列的所有数据都放在一起了。

    

    作业1 为什么用Mysql/MysqlMongoDB差别在哪?/mysql索引这块了解吗/...

    作业2 什么时候使用Redis/ 你们之前Redis使用多吗?/...

   

转载于:https://www.cnblogs.com/jamon/p/10830053.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值