精华内容
下载资源
问答
  • 数据库存储原理 据库存储原理 存储原理 数据库存储原理 数据库存储原理
  • 数据库存储原理.pdf
  • 列存储数据库原理

    列式数据库是以列方式存储数据,主要适合于即时查询和批量数据处理

    行式数据库是以行方式存储数据,主要适合于联机事物处理和小批量数据处理。


    举个栗子

    1.事实数据如下



    2.在传统数据库行数据库中的存储方法



    3.在列存储数据库中的逻辑结构



    4.在列存储数据中的压缩

    因为列的集中存储,方便采用多种高效的数据压缩技术。行程编码压缩就是将数据值、数据出现的起始位置和持续长度保存为一个三元组。行程压缩适合于重复数据较多的场景。


    词典编码压缩是生成一个原始值的符合对照词典,符合的长度小于原始值的长度。位向量压缩是将每一个不同的取值生成一个位向量。字典压缩和位向量压缩仅适合取值空间比较小的场景。对于取值空间比较大的场景,Sybase IQ中的BitWise索引可以并行化范围求值操作。



    5.列存储数据库的查询

    举个栗子:商家BAiPhone6s的双十一销量


    依据查询条件依次标定向量,标定日期中=2015/11/11,标定订单类型=Sale,标定商家=BA,标定商品=iPhone6s,无关列无需扫描。


    将标定后的向量求交后,根据目标向量延迟物化目标列,然后根据物化后的列完成后续的求和计算SUM(1+1+1)=3



    6.行存储和列存储数据库的对比

    随着大数据的发展,列存储数据库也越来越受到欢迎。高效的压缩比大大节省了硬盘和内存。全字段索引后的数据即是索引,使得数据库管理员彻底告别针对应用场景反复调优索引结构。列存储数据库使得大数据即时分析成为可能。也有许多混合型的设计方案,举个栗子:SQL Server2014中的RowGroup+ColumnSegments。



    展开全文
  • 数据库~clickhouse 底层存储原理

    千次阅读 2018-08-15 14:43:00
    简介:今天介绍数据库的一些基本原理 一 数据目录 Data目录 数据存储目录,数据按照part分成多个文件夹,每个文件夹下存储相应数据和对应的元信息文件 Metadata 表定义语句,存储所有表的建表语句 二 基本原理...

    简介:今天介绍列式数据库的一些基本原理

    一  数据目录

          Data目录 数据存储目录,数据按照part分成多个文件夹,每个文件夹下存储相应数据和对应的元信息文件

          Metadata 表定义语句,存储所有表的建表语句

    二  基本原理

         记录方式:每隔8192行数据,是1个block,主键会每隔8192,取一行主键列的数据,同时记录这是第几个block 

         查找过程:如果有索引,就通过索引定位到是哪个block,然后找到这个block对应的mrk文件,mrk文件里记录的是某个block的数据集,在整列bin文件的哪个物理偏移位,加载数据到内存,之后并行化过滤

         构成图如下

         

              主键本身也符合最左原则,下面是查找图,所以查询时最好利用好主键条件

              

     

    转载于:https://www.cnblogs.com/danhuangpai/p/9481325.html

    展开全文
  • 数据库原理习题

    万次阅读 2020-09-07 18:39:47
    数据库原理是每个计算机专业的学生必须掌握的课程之一,所以学好数据库原理对日后实际工作和项目十分重要。这篇博客通过总结广州大学数据库原理课程和教材中的例题,希望能够对数据库原理加深理解。

    数据库是存放数据的仓库。数据库原理是每个计算机专业的学生必须掌握的课程之一,所以学好数据库原理对日后实际工作和项目十分重要。这篇博客通过总结广州大学数据库原理课程和教材中的例题,希望能够对数据库原理加深理解。

    选择

    1.数据库系统中的数据模型通常由( A )三部分组成。 
    A. 数据结构、数据操作和完整性约束 
    B. 数据定义、数据操作和安全性约束 
    C. 数据结构、数据管理和数据保护 
    D. 数据定义、数据管理和运行控制
    【分析】:数据模型中一种重要的模型——关系模型
    数据结构:二维表格,用“键”导航数据
    数据操作:集合操作,存取路径隐蔽
    完整性约束:保证数据和语义的正确有效。包括实体完整性、参照完整性和用户定义完整性


    2.五种基本关系代数运算是( A )。 
    A. ∪,-,×,π和σ  
    B. ∪,-,∞,π和σ 
    C. ∪,∩,×,π和σ  
    D. ∪,∩,∞,π和σ
    【分析】:五种基本运算
    并、差、笛卡尔积、投影、选择
    关系代数运算:
    并、差、交、笛卡尔积、投影、选择、连接、除
    (交、连接、除可以用5种基本运算来表达。引进它们并不增加语言的能力,但可以简化表达。)


    3.在关系R和关系S进行自然联接时,只把S中原该舍弃的元组保存到新关系中,这种操作称为( D )。 
    A. 外联接 B. 内联接  C. 左外联接  D. 右外联接
    【分析】:自然连接时舍弃的元组也保存在结果关系中,而在其他属性上填空值


    4.下列聚合函数中不忽略空值(null)的是( C )。
    A. SUM(列名) B. MAX(列名) C. COUNT( * )   D. AVG(列名)
    【分析】:在聚集函数中遇到空值时,除了COUNT(*)外,都跳过了空值而去处理非空值


    5.现有一个关系:借阅(书号,书名,库存数,读者号,借期,还期),假如同一本书允许一个读者多次借阅,但不能同时对一种书借多本,则该关系模式的主码是( D )。
    A. 书号  B. 读者号   C. 书号 + 读者号  D. 书号 + 读者号 + 借期
    【分析】:主码是可以唯一标识元组的,也就是说,可以通过主码中的属性,来推出非主属性。


    6.有关系模式R(A, B, C, D, E),根据语义有如下函数依赖集:F={A→B, B→A, (A,C)→D, D→E},下列属性组中的哪一个(些)是R的候选码( B )。
    Ⅰ. (A, C) Ⅱ. (A, B) Ⅲ. (B, C) Ⅳ. (A, D) Ⅴ. (A, C, D)A. 只有Ⅰ B. Ⅰ和ⅢC. 只有Ⅴ D. Ⅲ和Ⅳ
    【分析】:候选码:若关系中的一个属性或属性组的值能够唯一地标识一个元组,且他的真子集不能唯一的标识一个元组,则称这个属性或属性组做候选码。


    7.接6题,关系模式R的规范化程度最高达到( B )。
    A. 1NF B. 2NF C. 3NF D. BCNF
    【分析】:
    在这里插入图片描述


    8.下列说法正确的是 ( B )
    A. 视图是观察数据的一种方法,只能基于基本表建立。
    B. 视图是虚表,观察到的数据是实际基本表中的数据。
    C. 索引查找法一定比表扫描法查询速度快。
    D. 索引的创建只和数据的存储有关系
    【分析】:虚表,是从一个或几个基本表(或视图)导出的表;
    只存放视图的定义,不存放视图对应的数据;
    基表中的数据发生变化,从视图中查询出的数据也随之改变。


    9.若事务T对数据R已加排他锁(X锁),则其他事务对R(  D  )
    A. 可以加共享锁(S锁),不能加X锁
    B. 不能加S锁,可以加X锁
    C. 可以加S锁,也可以加X锁
    D. 不能加任何锁
    【分析】:封锁就是事务T在对某个数据对象(例如表、记录等)操作之前,先向系统发出请求,对其加锁
    加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。
    基本封锁类型

    • 排它锁(X锁)/写锁
      • 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。**如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。**获准排他锁的事务既能读数据,又能修改数据。
    • 共享锁(S锁)/读锁
      • 共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

    10.设有T1和T2两个事务,其并发操作如下所示,下面评价中正确的是( C )

    T1T2
    (1) 读A=10,B=5
    (2) 求和A+B=15
    (3)读A=10,A=A*2写回
    (4) 读A=20,B=5
    (5) 求A+B=25,验证错

    A. 该操作不存在问题 B. 该操作丢失修改
    C. 该操作不能重复读 D. 该操作读“脏数据”
    【分析】:

    • 丢失数据
      • 针对一个事务提交后会覆盖另一个事务提交的结果
    • 脏读
      • 针对未提交数据如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
    • 不可重复读
      • 针对其提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的。
    • 幻读
      • 针对其提交前后,读取数据条数的对比) 幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。

    区分不可重复读和幻读:
    不可重复读:某人读自己的工资1000,(操作还没有完成)后来管理员将其工资改为2000,他再读工资的时候就变成2000了。
    幻读:读取发现工资1000的有2个人,此时管理员又插入一个工资为1000的人,再次读取发现工资1000的人为3个。


    11.在数据库系统中死锁属于( C )。
    A. 系统故障   B. 程序故障   C. 事务故障  D. 介质故障
    【分析】:事务故障分类

    • 事务故障:死锁
    • 系统故障:特定类型的硬件错误(如CPU故障)、操作系统故障、DBMS、代码错误、系统断电
    • 介质故障:系统在运行过程中,由于某种硬件故障,使存储在外存上的数据部分损失或全部损失。
    • 计算机病毒:一种可以繁殖和传播的人为的故障或破坏的计算机程序。

    12.解决并发操作带来的数据不一致问题普遍采用( A )技术。
    A. 封锁   B. 存取控制   C. 恢复  D. 协商


    13.数据库系统中,单个用户使用的数据视图用______描述,它是用户与数据库系统之间的接口。( A )
    A.外模式 B.存储模式 C.内模式 D.概念模式


    14.以下关系数据库的基本数据操作中,不能同时操作两个关系的是( B )
    A.交 B.选择C.连接 D.并


    15.数据库系统中产生数据不一致性的根本原因是( C )
    A.没有严格保护数据 B.未对数据进行完整性控制C.数据冗余 D.数据存储量大
    【分析】:由于数据冗余,有时修改数据时,一部分数据修改,而另一部分没有修改,造成同一种数据有多个值,产生数据不一致。


    16.在数据库设计中,当合并局部E-R图时,学生在某一局部应用中被当作实体,而在另一局部应用中被当作属性,那么被称之为( D )
    A.属性冲突 B.命名冲突C.联系冲突 D.结构冲突
    【分析】:合并局部E—R图时,主要有三类冲突:属性冲突、命名冲突和结构冲突

    • 属性冲突:属性值的类型不同、属性的取值范围不同或属性取值单位不同。
    • 命名冲突:异名同义,如对于科研项目,财务科称为项目,科研处称为课题,生产管理处称为工程;同名异义,即不同意义的对象在不同的局部E-R图中具有相同的名字。
    • 结构冲突:同一对象在不同E-R图中具有不同的抽象意义,例如题中“职工”在某一局部应用中被当做实体,而在另一局部应用中被当做属性;同一实体在不同的局部E-R图中所包含的属性个数和属性排列次序不完全相同;实体间联系的类型在不同E-R图中不相同,例如,实体E1、E2在一个局部E-R图中是多对多联系,而在另一个局部E-R图中是一对多联系。

    17.如果要求学生关系S(SNO,NAME,SEX,AGE)中存储的学生信息满足下列条件:男生(SEX=‘F’)的年龄在15-60岁之间,女生(SEX=‘M’)的年龄在15-55岁之间。那么在关系S的定义中加入的检查子句正确的是( B )
    A.CHECK(AGE>=15 AND((SEX=‘M’ AND AGE<=60)AND(SEX=‘F’ AND AGE<=55)))
    B.CHECK(AGE>=15 AND((SEX=‘M’AND AGE<=60)OR(SEX=‘F’AND AGE<=55)))
    C.CHECK(AGE>=15 OR((SEX=‘M’AND AGE<=60)OR(SEX=‘F’AND AGE<=55)))
    D.CHECK(AGE>=15 OR((SEX=‘M’AND AGE<=60)AND(SEX=‘F’AND AGE<=55)))


    18.公司中有多个部门和多名职员,每个职员只能属于一个部门,一个部门可以有多名职员,从职员到部门的联系类型是( C )。
    A.多对多 B.一对一
    C.多对一 D.一对多


    19.数据库系统中,使用宿主语言和DML编写应用程序的人员是( C )。
    A.数据库管理员 B.专业用户C.应用程序员 D.最终用户
    【分析】:宿主语言,是开发宿主环境的程序语言,也被称作系统开发语言。 DML:数据操纵语言。


    20.关系代数表达式σ3<′4′(S)表示( C )。
    A.表示从S关系中挑选3的值小于第4个分量的元组
    B.表示从S关系中挑选第3个分量值小于4的元组
    C.表示从S关系中挑选第3个分量值小于第4个分量的元组
    D.表示从S关系中挑选第4个分量值大于3的元组


    21.关系代数中的π运算符对应SELECT语句中的以下哪个子句?( A )
    A.SELECT B.FROM C.WHERE D.GROUP BY


    22.子模式DDL用来描述 (B)。
    A.数据库的总体逻辑结构
    B.数据库的局部逻辑结构
    C.数据库的物理存储结构
    D.数据库的概念结构
    【分析】:数据库管理系统提供外模式数据描述语言描述外模式。外模式也称为子模式或用户模式,是对数据库用户看见和使用的局部数据逻辑结构及特征的描述。


    23.在DBS中,DBMS和OS之间的关系是 ( )
    A. 相互调用 B. DBMS调用OS C. OS调用DBMS D. 并发运行
    【分析】:操作系统是计算机系统在软件上的第一层扩充,DBMS是构筑在操作系统的基础上来管理数据库的,DBMS的很多功能性实现都需要多操作系统的调用。


    24.DBMS中实现事务持久性的子系统是 ( D )
    A. 安全性管理子系统 B. 完整性管理子系统 C. 并发控制子系统 D. 恢复管理子系统


    25.SQL的全局约束是指基于元组的检查子句和( C )。
    A.非空值约束
    B.域约束子句
    C.断言
    D.外键子句
    【分析】:SQL的全局约束包括基于元组的检查子句(CHECK)和断言(CREATE ASSERTION断言名CHECK条件)。
    SQL中,可以使用 CREATE ASSERTION语句,通过声明性断言来指定更具一般性的约束。
    可以定义涉及多个表的或聚集操作的比较复杂的完整性约束。
    断言创建以后,任何对断言中所涉及的关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值的操作都会被拒绝执行。


    26.下列SQL语言的定义语句中,哪一(些)组包含了不正确的定义语句?(C)
    I.CREATETABLE…CREATEVIEW…CREATEINDEX…
    II.DROPTABLE…DROPVIEW…DROPINDEX…
    III.ALTERTABLE…ALTERVIEW…ALTERINDEX…
    A只有I BI和II C只有III DII和III
    【分析】:由于视图是基于基本表的虚表,索引是依附于基本表的,因此SQL通常不提供修改视图定义和修改索引定义的操作。
    表 CREATE TABLE DROP TABLE ALTER TABLE
    视图 CREATE VIEW DROP VIEW
    索引 CREATE INDEX DROP INDEX


    27、设有两个事务T1、T2,其并发调度如下图所示。下列说法正确的是(B)
    A该调度不存在问题 B该调度丢失修改C该调度不能重复读 D该调度读“脏”数据
    在这里插入图片描述

    【分析】:很明显的,T1对于A的修改被T2对A的修改覆盖掉了。


    28、下列哪一个不是日志文件中应该记录的内容?(D)
    A事务开始 B事务交换 C事务对数据的修改 D事务对数据的查询
    【分析】:日志是日志记录的序列,它记录了数据库中所有更新活动。数据查询并没有涉及到数据更新,所以事务对数据的查询并不是日志记录的内容。


    29、下列哪个不属于数据库对象:(D)
    A.存储过程 B.角色 C.视图 D.日志
    【分析】:数据库的主要组成部分就是数据库对象。很明显的,日志并不是数据库的主要组成部分。


    30、下列叙述不正确的是( D )
    A. 创建索引是加快表的查询速度的有效手段
    B. 可以根据需要在基本表上建立一个或多个索引
    C. 用户可以在最频繁查询的列上建立索引以提高查询效率
    D. 可以根据需要在基本表上建立一个或多个聚簇索引
    【分析】:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关。正式因为如此,所以一个表最多只能有一个聚簇索引。


    31、关系模式R中若没有非主属性,则( C )
    A. R属于2NF,但R不一定属于3NF B. R属于BCNF,但R不一定属于4NF
    C. R属于3NF,但R不一定属于BCNF D. R属于4NF


    32、SQL语言是(B) 的语言,易学习。
    A.过程化 B.非过程化 C.格式化 D.导航式


    33、SQL语言具有(B) 的功能。
    A.关系规范化、数据操纵、数据控制 B.数据定义、数据操纵、数据控制
    C.数据定义、关系规范化、数据控制 D.数据定义、关系规范化、数据操纵
    【分析】:分别是DDL,DML,DCL


    34、SQL语言具有两种使用方式,分别称为交互式SQL和(C) 。
    A.提示式SQL B.多用户SQL C.嵌入式SQL D.解释式SQL


    35、下面哪个不是数据库系统必须提供的数据控制功能 (B) 。
    A.安全性 B.可移植性 C.完整性 D.并发控制


    36、数据库的(B) 是指数据的正确性和相容性。
    A.安全性 B.完整性 C.并发控制 D.恢复


    37、在数据系统中,对存取权限的定义称为(B)。
    A.命令 B.授权 C.定义 D.审计


    38、在SQL Server 中删除触发器用( B )。
    A.ROLLBACK B. DROP C.DELALLOCATE D. DELETE


    39、数据库恢复的基础是利用转储的冗余数据。这些转储的冗余数据包括 (C) 。
    A.数据字典、应用程序、审计档案、数据库后备副本
    B.数据字典、应用程序、日志文件、审计档案
    C.日志文件、数据库后备副本
    D.数据字典、应用程序、数据库后备副本


    40、关于“死锁”,下列说法中正确的是(D)。
    A.死锁是操作系统中的问题,数据库操作中不存在
    B.在数据库操作中防止死锁的方法是禁止两个用户同时操作数据库
    C.当两个用户竞争相同资源时不会发生死锁
    D.只有出现并发操作时,才有可能出现死锁


    41、对并发操作若不加以控制,可能会带来(D)问题。
    A.不安全 B.死锁 C.死机 D.不一致


    填空

    1.数据库设计分为六个阶段分别是:需求分析、概念结构设计 、逻辑结构设计 、物理结构设计 、数据库实施、数据库运行和维护


    2.事务具有四个特性,分别为:原子性、一致性 、隔离性 和持久性(ACID)


    3.在关系数据库中,任何不含多值依赖的二元关系模式的最高范式必是 BC 范式。


    4、在并发控制中,事务 是数据库的逻辑工作单位,是用户定义的一组操作序列,是并发控制的单位


    5、一个SQL语句原则上可产生或处理一组记录,而主语言一次只能处理一个记录,为此必须协调两种处理方式,这是通过使用游标 机制来解决的


    6、保护数据安全性的一般方法是 设置用户标识和存取权限控制


    7、安全性控制的一般方法有①、②、③、④和视图的保护五级安全措施。【答案】:①用户标识鉴定 ②存取控制 ③审计 ④数据加密


    8、存取权限包括两方面的内容,一个是 ① ,另一个是 ②。
    【答案】:①要存取的数据对象 ②对此数据对象进行操作的类型


    9、在数据库系统中对存取权限的定义称为授权


    10、DBMS存取控制机制主要包括两部分:自主存取控制,强制存取控制


    11、数据库恢复是将数据库从 ① 错误 状态恢复到 ② 某一已知的正确状态 的功能


    12、数据库系统在运行过程中,可能会发生故障。故障主要有事务故障、 系统故障 、介质故障和计算机病毒四类。


    13、DBMS的基本工作单位是事务,它是用户定义的一组逻辑一致的程序序列;并发控制的主要方法是封锁机制


    判断

    1、经常更新的属性列上不适合建立聚簇索引。(√)


    2、若R.(B,C)→R.A,则R.B→R.A,R.C→R.A。(×)


    3、可以先修改相应的数据库,然后把日志记录写到外存的日志文件中。(×)


    4、若视图的字段来自聚集函数,则此视图不允许更新。(√)


    5、模式也称为逻辑模式,一个数据库可以有多个模式。(×)
    【分析】:模式也称为逻辑模式,一个数据库只能有一个模式


    6、delete from mytable; 该语句可以删除mytable表中的所有元组,但是表的定义仍然存在。(√)


    7、数据库不允许存在数据冗余。(×)


    8、设置惟一约束的列可以为空。(√)


    简答

    1、简述视图的作用。所有的视图是否都可以更新?为什么?
    答:( 1 )视图能够简化用户操作
    ( 2 )视图机制可以使用户以不同的方式看待同一数据
    ( 3 )视图为数据库重构提供一定的逻辑独立性
    ( 4 )视图可以对机密的数据提供安全保护
    不是所有的视图都可以更新。若视图的更新不能唯一地、有意义地转换成对相应基本表的更新,则这些视图不允许更新。


    2.今有3个事务的一个调度:r3 (B) r1 (A) w3 (B) r2 (B) r2 (A) w2 (B) r1 (B) w1 (A)该调度是冲突可串行化的调度吗?为什么?
    答:该调度是冲突可串行化的调度。
    Sc1= r3 (B) r1 (A) w3 (B) r2 (B) r2 (A) w2 (B) r1 (B) w1 (A)
    交换r1 (A) 和w3 (B)得到:
    r3 (B) w3 (B)r1 (A) r2 (B) r2 (A) w2 (B) r1 (B) w1 (A)
    再交换r1 (A) 和r2 (B) r2 (A) w2 (B)得到:
    Sc2= r3 (B) w3 (B) r2 (B) r2 (A) w2 (B) r1 (A) r1 (B) w1 (A)
    由于Sc2是串行的,而且两次交换都是基于不冲突操作的
    所以Sc1= r3 (B) r1 (A) w3 (B) r2 (B) r2 (A) w2 (B) r1 (B) w1 (A)是冲突可串行化的调度。
    【分析】:
    冲突可串行化:一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务的次序可以得到另一个调度Sc‘,如果Sc’是串行化的,称调度Sc是冲突可串行化调度。
    一个调度是冲突可串行化的,一定是可串行化的调度。
    可以交换的情况

    • 不同事务,同一数据,读读操作可以交换
    • 不同事务,不同数据,无论读写都可以交换

    3.试述关系模型的完整性规则。在参照完整性中,为什么外部码属性的值也可以为空?什么情况下才可以为空?
    答:关系模型的完整性规则是对关系的某种约束条件。关系模型中可以有3类完整性约束:实体完整性、参照完整性和用户定义的完整性。
    实体完整性规则:主属性不能取空值。
    参照完整性规则:外部码要么取空值,要么等于被参照关系中的某个主码值。
    参照关系中外部码可以为空,表示该属性的值尚不确定。但前提条件是外部码本身不是所在关系的主属性。


    4.设有两个关系R (A,B,C) 和S (C,D,E),试用SQL查询语句表达下列关系代数表达式πA,E (σB = D (R∞S))。
    select A,E
    from R,S
    where R.B=S.D;


    5.设有关系R和S,其中R为参照关系,S为信赖关系。为了实现完整性约束,SQL规定可以对R的删除操作采取哪三种措施?
    【答】:三种措施:

    • Restrict(或约束删除)拒绝执行或拒绝操作
    • cascade(或级联删除)
    • set null(或外键值置空)

    6.设有关系数据库:
    职工关系EMPLOYEE (职工号,职工名,街道,城市)
    工作关系WORKS (职工号,公司号,工资)
    公司关系COMPANY (公司号,公司名,城市)
    假设职工可在多个公司兼职,请用关系代数表达式写出至少在公司号为‘C2’和‘C5’公司兼职的职工的职工号。
    【答】:
    首先建立一个临时关系K:
    在这里插入图片描述

    π职工号,公司号(工作关系)÷K

    依据上面的关系数据库,试用SQL语句写出下列操作:
    将所有在“联华公司”工作的职工加薪5﹪。

    update 工资
    set 工资=工资*105%
    where 公司号 in(
    	select 公司号
    	from 公司关系
    	where 公司名='联华公司'
    );

    7、设有关系模式R (A,B,C,D),F是R上成立的FD集,F = {D→A,D→B},试写出关系模式R的候选键,并说明理由。
    【答】:①R的候选键是CD
    ②理由:从已知的F,可导出D→ABD,再根据增广律,可得出CD→ABCD,即CD值可决定全部属性值。


    8、SQL中表达完整性约束的规则主要有哪几种?
    【答】:有主键约束、外键约束、属性值约束和全局约束等。


    综合

    1.已知职工数据库中有三个数据表,分别是职工基本信息表、工资表和部门信息表,表结构如下表所示。
    “职工基本信息”表

    字段名职工编号姓名性别出生日期部门编号
    类型及说明char(5),主码char(10), 不允许为空char(2)datetimechar(3),引用部门表的部门编号

    “工资”表

    字段名职工编号基本工资奖金实发工资
    类型及说明char(5),主码,引用职工基本信息表中的职工编号moneymoneymoney

    “部门信息”表

    字段名部门编号部门名称部门简介
    类型及说明char(3),主码char(20), 不允许为空varchar(50)

    1、 使用alter table语句向“职工基本信息”表中添加一列,列名称为“职称”,类型为char,长度为10。
    答:alter table 职工信息表 add 职称 char(10);
    2、现在需向数据库中添加数据,已知要添加的数据如下,请使用insert语句完成,注意添加的先后顺序。
    在这里插入图片描述

    【注意:要考虑到外码,注意需要先创建哪一个表】
    insert into 部门信息(部门编号,部门名称) values(‘01’,‘计算机’);
    insert into 部门信息(部门编号,部门名称) values(‘02’,‘数学’);

    insert into 职工基本信息(‘0101’,‘孙华’,‘女’,‘1970-10-3’,‘01’,‘副教授’);
    insert into 职工基本信息 values(‘0201’,‘陈明’, ‘男’, ‘1965-8-5’,‘02’,‘教授’);

    insert into 工资 values(‘0101’, 2000, 2500, 4500);

    3、用update语句把“工资”表中所属部门编号为“01”的职工的奖金增加10%。
    update 工资
    set 奖金=奖金*1.1
    where 职工编号 in
    (select 职工编号
    from 职工基本信息
    where 部门编号=‘01’);

    4、查询所属部门名称为“数学”的所有职工的工资信息。
    select *from 工资
    where 部门编号 in
    (select 部门编号
    from 部门信息,职工基本信息
    where 部门名称=‘学习’ and 部门信息.部门编号=职工基本信息.部门编号);

    5、查询部门编号和该部门的总人数。
    select 部门编号,count(*)
    from 职工基本信息
    group by 部门编号;

    6、查询所有姓“孙”的女职工的基本信息。
    select *
    from 职工基本信息表
    where 姓名 like ‘孙%’ and 性别=‘女’;

    7、在职工数据库中完成以下操作:
    1)定义变量prof_quali,类型为char,长度为10
    2)声明一个游标CS_cursor,该游标保存所有“职称”等于prof_quali变量值的职工基本信息和工资信息
    3)打开CS_cursor游标,使用该游标逐行修改结果集中职工的基本工资和实发工资的值,使他们的值都在原来的基础上增加5004)关闭和释放CS_cursor游标
    【答】DECLARE CS_cursor CURSOR FOR
    SELECT 职工基本信息.职工编号, 职称, 基本工资 FROM 职工基本信息, 工资
    WHERE 职工基本信息.职称=‘副教授’ and 职工基本信息.职工编号=工资.职工编号
    OPEN CS_cursor
    – Perform the first fetch.
    FETCH NEXT FROM CS_cursor
    – Check @@FETCH_STATUS to see if there are any more rows to fetch.
    WHILE @@FETCH_STATUS = 0
    BEGIN
    – This is executed as long as the previous fetch succeeds.
    UPDATE 工资
    SET 基本工资=基本工资+500, 实发工资=实发工资+500
    WHERE CURRENT OF CS_cursor
    FETCH NEXT FROM CS_cursor
    END
    CLOSE CS_cursor
    DEALLOCATE CS_cursor
    GO


    设计题

    1、欲为某图书馆建立一个图书借阅管理系统,请仔细阅读以下需求描述,设计合理的数据库:
    1) 图书信息的录入:要求能够将图书信息录入到数据库中,图书的基本信息包括书号、书名、作者、出版社、价格、类型、封面等。
    2) 图书信息的修改:根据需要修改、删除图书信息。
    3) 借阅证件信息录入:可以输入不同类型的借阅者信息,并根据需要修改、删除借阅证信息。不同类型的借阅证借书时,借书的数量时间以及续借的时间不同。
    4) 借阅证管理:包括借阅证丢失、过期等管理。
    5) 借阅管理:包括借书、还书、过期还书与书籍丢失处罚等管理。
    6) 图书查询:包括按图书类别、书名、作者、出版社等的查询。
    7) 借阅查询:可以查询当前所借图书和历史所借图书。
    8) 用户登录:根据用户权限登录此系统。用户分为普通用户和超级用户,超级用户能实现上述1)~5)的管理功能,普通用户只能通过登录该系统进行图书查询和借阅。
    9) 系统用户管理:可以管理系统的用户,包括添加、修改和删除用户。
    根据需求描述,完成以下3题:
    依据以上需求描述,设计系统的E-R图;
    在这里插入图片描述

    2、将该E-R图转换为关系模型,并指出每个关系模式的主码、外码以及相互间的参照关系;
    带黑体的属性或属性组为主码
    图书类别(类别号,类别名)
    图书(书号,书名,作者,出版社,价格,类别号,封面,简介)
    类别号为外码,引用图书类别表的类别号

    读者类型(类型号,类型名,借阅本数,借阅天数,续借天数)
    读者(借阅证号,姓名,工作单位,身份证,类型号,办证日期,借阅证状态)
    类型号为外码,引用读者类型表的类型号

    借阅(借阅证号,书号,借书日期,续借日期,归还日期,罚金,借阅状态)
    借阅证号,书号为外码,分别引用读者表的借阅证号和图书表的书号

    用户(用户名,密码,用户类型,借阅证号)
    借阅证号为外码,引用读者表的借阅证号

    3、根据关系模型设计数据库,以表格的形式给出每个数据表的结构。
    数据表结构示例:
    表名:Order,描述:订单信息表,管理订单信息
    在这里插入图片描述

    我设计的数据表结构如下:
    表名: BookType 描述: 图书分类信息表
    在这里插入图片描述

    表名: BookInfo 描述: 图书基本信息表
    在这里插入图片描述

    表名: CardType 描述: 借阅证件类型
    在这里插入图片描述

    表名: CardInfo 描述: 借阅证信息表
    在这里插入图片描述

    表名: UserInfo 描述: 用户信息表
    在这里插入图片描述

    表名: BorrowInfo 描述: 借阅信息表
    在这里插入图片描述


    2、设学生课程数据库中有三个关系:
    学生关系S(S#,SNAME,AGE,SEX)
    学习关系SC(S#,C#,GRADE)
    课程关系C(C#,CNAME)
    其中S#、C#、SNAME、AGE、SEX、GRADE、CNAME分别表示学号、课程号、姓名、年龄、性别、成绩和课程名。
    用SQL语句表达下列操作:
    (1)检索选修课程名称为“MATHS”的学生的学号与姓名

    select S#,SNAME
    from S,CNAME,C
    where C.C#=SC.C#
    AND S.S#=SC.S
    AND CNAME='MATHS';

    (2)检索至少学习了课程号为“C1”和“C2”的学生的学号

    select S# 
    from SC
    WHERE SC.C#='C1'
    AND S# IN(
    	SELECT S# 
    	FROM SC
    	WHERE C#='C2'
    );

    (3)检索年龄在18到20之间(含18和20)的女生的学号、姓名和年龄

    SELECT S#,SNAME,SAGE
    FROM S
    WHERE SAGE BETWEEN 18 AND 20;

    (4)检索平均成绩超过80分的学生学号和平均成绩

    SELECT S#,AVG(GRADE) '平均成绩'
    FROM SC
    GROUP BY S#
    HAVING AVG(GRADE)>80

    (5)检索选修了全部课程的学生姓名

    /*
    理解:
    1.拿出Student表的第一行数据
    2.拿出Course表的第一行数据
    3.拿出SC表的第一行数据 (其实这个表就是用来与前两个表进行对比判断的)
    
    for(循环从Student表拿一行学生数据){
      for(循环从Course表拿一行课程信息){
        for(循环在SC表拿一行进行比对){
          SC表中的这条数据判断:
            SC.Sno == Student.Sno , SC.Cno == Course.Cno;
          是否SC表中的学号 = Student表中的学号 且
           SC表中的Cno = Course表中的Cno
        }
      }
    }
    */
    select SNAME
    FROM S
    WHERE NOT EXISTS(
    	SELECT * 
    	FROM COURSE 
    	WHERE NOT EXISTS(
    		SELECT * 
    		FROM SC
    		WHERE SC.S#=S.S#
    		AND SC.C#=C.C#
    	)
    );
    
    #另外一种写法
    select SNAME
    from S
    where S# in(
    	select S# 
    	from SC 
    	Group by S#
    	having count(*)=(  /*该学生的选修的课程门数 =  所有课程的门数*/
    		select count(*)  /*所有课程的门数*/
    		from C
    	)
    );

    (6)检索选修了三门课以上的学生的姓名

    select SNAME 
    FROM FROM S
    WHERE S# IN (
    	SELECT S# 
    	FROM SC
    	GROUP BY S#
    	HAVING COUNT(*)>3
    );

    3、设学生-课程数据库中包括三个表:
    学生表:Student (Sno,Sname,Sex,Sage,Sdept)
    课程表:Course(Cno,Cname,Ccredit)
    学生选课表:SC(Sno,Cno,Grade)
    其中Sno、Sname、Sex、Sage、Sdept、 Cno、Cname、Ccredit 、Grade分别表示学号、姓名、性别、年龄、所在系名、课程号、课程名、学分和成绩。
    试用SQL语言完成下列项操作:
    (1)查询选修课程包括“1042”号学生所学的课程的学生学号

    (2)创建一个计科系学生信息视图S_CS_VIEW,包括Sno学号、Sname姓名、Sex性别;

    create view S_CS_VIEW 
    as 
    select Sno 学号,Sname 姓名,Sex 性别
    from Student 
    where Sdept='计科';

    (3)通过上面第2题创建的视图修改数据,把王平的名字改为王慧平

    update S_CS_VIEW 
    set Sname='王慧平'
    where Sname='王平';

    (4)创建一选修数据库课程信息的视图,视图名称为datascore_view,包含学号、姓名、成绩。

    create view datascore_view 
    as 
    select Sno,Sname,Grade
    from Student,SC,Course
    where Student.Sno=SC.Sno
    and Course.Cno=SC.Cno
    and Cname='数据库';

    3、设有如下实体:
    学生:学号、单位、姓名、性别、年龄、选修课程名
    课程:编号、课程名、开课单位、任课教师号
    教师:教师号、姓名、性别、职称、讲授课程编号
    单位:单位名称、电话、教师号、教师名
    上述实体中存在如下联系:
    (1)一个学生可选修多门课程,一门课程可为多个学生选修;
    (2)一个教师可讲授多门课程,一门课程可为多个教师讲授;
    (3)一个单位可有多个教师,一个教师只能属于一个单位。
    试完成如下工作:
    (1)分别设计学生选课和教师任课两个局部信息的结构E-R图。
    在这里插入图片描述

    在这里插入图片描述

    (2)将上述设计完成的E-R图合并成一个全局E-R图。
    在这里插入图片描述

    为避免图形复杂,下面给出各实体属性:
    单位:单位名、电话
    学生:学号、姓名、性别、年龄
    教师:教师号、姓名、性别、职称
    课程:编号、课程号
    (3)将该全局E-R图转换为等价的关系模型表示的数据库逻辑结构。
    单位(单位名,电话)
    教师(教师号,姓名,性别,职称,单位名)
    课程(课程编号,课程名,单位名)
    学生(学号,姓名,性别,年龄,单位名)
    讲授(教师号,课程编号)
    选修(学号,课程编号)

    展开全文
  • 文章目录分布式NoSQL列存储数据库Hbase_列族的设计(五)知识点01:课程回顾知识点02:课程目标知识点03:Hbase设计:列族的设计知识点04:聊天系统案例:需求分析知识点05:聊天系统案例:Hbase表设计知识点06:...

    分布式NoSQL列存储数据库Hbase_列族的设计(五)

    知识点01:课程回顾

    1. Hbase存储原理

      • 存储架构
        • Hbase:对外提供分布式内存
          • Master:集群管理
          • RegionServer:数据管理
        • HDFS:提供分布式磁盘
          • DataNode
        • Zookeeper:实现辅助选举、实现元数据存储
      • 存储结构
        • Table:分布式表,一张表划分了多个Region
        • RegionServer:分布式集群节点,管理所有表的region
          • Region:每张表的每个分区,对表的数据进行划分
            • region的划分规则:按照范围划分,从-oo 到+oo进行有序划分
            • 数据的划分规则:按照Rowkey或者Rowkey前缀,Rowkey属于哪个范围,写入对应的region
            • Store:对分区内部的数据再次划分,按照列族进行划分Store
              • MemStore:内存区域,用于存储刚写入的数据,使用的RegionServer的JVM内存
                • 如果到达一定的阈值,就会写入HDFS,变成文件
              • StoreFile:逻辑上属于Store,物理上存储在HDFS【HFILE】
      • HDFS存储关系
        • Hbase目录:/hbase
        • Hbase数据:/hbase/data
          • NS目录
            • Table的目录
              • Region的目录
                • 列族的目录
    2. 热点问题

      • 现象:大量的读写请求全部集中在某个Region或者某个RegionServer上

      • 原因:数据分配的不均衡

        • 情况一:表只有一个分区
        • 情况二:表有多个分区,但是Rowkey是连续的,或者与分区的划分不匹配
          • Rowkey是连续,写入同一个Region
          • 分区都是按照数字划分的,但是Rowkey是字母开头
      • 解决

        • 实现预分区

          • 方式一:创建表时候:SPLITS => [10,30……]
          • 方式二:指定分区的个数,根据数字和字母的Hash组合
            • 应用:Rowkey的前缀是字母和数字组合
          • 方式三:Java API
        • 合理的设计Rowkey,根据Rowkey的前缀或者完整的Rowkey来划分分区

          • Rowkey的设计规则

          • 业务原则:尽量用最常用的查询条件作为Rowkey的前缀

            • 目的:尽量走索引查询
          • 唯一原则:每条Rowkey是不能重复

            • 目的:唯一标识一条数据
          • 组合原则:将最常用的几个查询条件组合构建Rowkey

            • 目的:尽量大部分查询都走索引
          • 散列原则:Rowkey整体或者前缀不能是连续的,需要构建随机的散列

            • 目的:避免热点问题
          • 长度原则:在满足业务需求情况下,越短越好

            • 目的:提高性能

              • Rowkey本身每列都会存储:存储占用的空间越大

              • Rowkey会构建索引:内存的占用越大,比较就越慢

    知识点02:课程目标

    1. 聊天系统案例

      • 目标
        • 掌握基于业务需求场景的Hbase表的设计
        • 熟练Hbase JavaAPI
      • 实现
        • 写:保存【重点】
          • Rowkey构建的代码
          • 数据写入的代码
        • 读:查询【重点】
          • 过滤器代码
    2. 二级索引【重点】

      • 问题:如果查询数据的条件,不是rowkey的前缀,怎么解决查询效率的问题?

        • Hbase只支持RowKey作为唯一索引,不支持创建索引

        • 与MySQL不一样

          id		name		age		sex		addr		phone
          主键
          select * from table where id = 1
          select * from table where name=‘zhangsan’
          |
          create index name on table(name);
          
      • 本质:基于Rowkey索引之上,自己构建一层索引

    知识点03:Hbase设计:列族的设计

    • 设计目的

      • Hbase特点:按列存储,允许存储一行有非常多的列

      • 工作中主要处理的场景:对列进行处理

        select name,count(*) from table group by name;
        
      • 列族的设计:将列进行分组

      • 列族的规则:将拥有相似IO属性的列划分为同一列族

        • 要读一起读,要写一起写
    • 底层实现

      • Store:每个Region中根据列族将不同列族的列存储在不同的Store
    • 设计规则

      • 个数原则:Hbase列族的个数有一定的要求,大部分情况下建议给2个
      • 如果列的个数比较多:30列以上
        • 2 ~ 3
      • 如果列的个数比较少,数据量不大
        • 1个
      • 长度原则 :能满足业务需求的情况下,越短越好
      • 名称没有其他功能,只要有标示性即可
    • Hbase底层数据结构:KV结构,按列存储

      • K:rowkey+列族+列名+Timestamp
      • V:value

    知识点04:聊天系统案例:需求分析

    • 目标

      • 掌握Hbase表的设计:Rowkey设计、列族设计
      • 熟练应用Hbase Java API
    • 需求

      • 基于Hbase来设计聊天系统的数据存储

      • 需求1:当用户聊天时,将用户的聊天的信息写入Hbase

        • A发送消息给B

          发送人ID	接受者ID	时间		内容……
          
        • 写入Hbase

      • 需求2:允许用户查询聊天记录:指定时间查询两个用户的聊天信息

        • 查询某个时间当前用户与其他用户的聊天记录
        • 时间戳
        • 发送人ID
        • 接收人ID
    • 数据

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m51LYFsL-1616666919956)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322092911806.png)]

      消息时间发件人昵称发件人账号发件人性别发件人IP发件人系统发件人手机型号发件人网络制式发件人GPS收件人昵称收件人IP收件人账号收件人系统收件人手机型号收件人网络制式收件人GPS收件人性别消息类型双方距离消息
      msg_timesender_nickynamesender_accountsender_sexsender_ipsender_ossender_phone_typesender_networksender_gpsreceiver_nickynamereceiver_ipreceiver_accountreceiver_osreceiver_phone_typereceiver_networkreceiver_gpsreceiver_sexmsg_typedistancemessage
      2020/05/08 15:11:33古博易1474787719448.147.134.255Android 8.0小米 Redmi K304G94.704577,36.247553莱优97.61.25.5217832829395IOS 10.0Apple iPhone 104G84.034145,41.423804TEXT77.82KM天涯海角惆怅渡,牛郎织女隔天河。佛祖座前长顿首,只求共度一百年。

    知识点05:聊天系统案例:Hbase表设计

    • NameSpace的设计

      create_namespace 'MOMO_CHAT'
      
    • 表的设计

      • Rowkey设计:每一条聊天记录都是一个Rowkey的数据,Rowkey怎么设计?

        • 业务原则

        • 唯一原则

        • 散列原则

        • 组合原则

        • 长度原则

        • 需求:根据时间戳、发件人ID、收件人ID查询数据

        Rowkey:MD5【发件人_收件人_时间戳】取8位_发件人_收件人_时间戳

        
        

        发件人_收件人_时间戳

        
        
        
        
      • 列族设计

        • 个数原则

        • 长度原则

        • 需求:存储聊天记录所有列,列的个数不多,给定1个列族

          C1
          
      • 列的设计

        • 直接使用数据中的每一列即可
      • 预分区

        • 规则:划分多个分区,根据Rowkey的设计划分

        • Hbase中提供了数字与字母组合的指定分区个数的方式:HexStringSplit

      • 建表语句

        create 'MOMO_CHAT:MSG', {NAME => "C1", COMPRESSION => "GZ"}, { NUMREGIONS => 6, SPLITALGO => 'HexStringSplit'}
        
        • COMPRESSION:压缩

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fa0jBwS0-1616666919959)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322094757899.png)]

    知识点06:聊天系统案例:环境准备

    • 参考附录一导入Maven依赖

    • 构建以下包,并依次添加代码

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AdmYCQsN-1616666919960)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210321214639429.png)]

    • entity:实体类,JavaBean

      • Msg:用于将每一条消息封装为一个对象

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kRiU1ypz-1616666919961)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322101623133.png)]

    • service:应用层

      • ChatMessageService:用于实现用户数据查询的接口

        public interface ChatMessageService {
            //根据条件进行查询方法
            List<Msg> getMessage(String date, String sender, String receiver) throws Exception;
            //关闭资源方法
            void close();
        }
        
      • 给定时间、发送人、接收人、返回所有聊天记录

    • tool:工具类

      • ExcelReader:用于读取Excel表中的数据,从每一列中随机选择一个值,模拟生成用户之间的聊天数据

        • readXlsx:用于接收Excel文件地址和要读取的表名,将每一列和这一列的所有数据构建一个KV

          //参数一:Excel文件的地址
          //参数二:指定读取哪个表格
          

      //返回值:Map集合
      K:String:列名称
      V:List:这一列对应的所有数据
      public static Map<String, List> readXlsx(String path, String sheetName)
      ```

    • randomColumn:随机的从某一列总取某一个值

          //参数一:Excel中的所有数据
          //参数二:指定获取的列名
          //返回值:从指定列名中随机返回一个值
      public static String randomColumn(Map<String, List<String>> resultMap, String columnName)
          ```
        
        - getOneMsg:用于从整张Excel表中让每一列都随机产生一个值,构建一条消息数据
        
          ```java
          //参数:Excel中的所有数据
          //返回值:模拟的数据对应的Msg对象
          public static Msg getOneMsg(Map<String, List<String>> resultMap)
          ```
        
        - 运行测试,得到一条数据
        
          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aHK6cHg-1616666919962)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322103055968.png)]
      
      
      
      

    知识点07:聊天系统案例:模拟生成数据

    • 目标

      • 模拟产生用户聊天数据,将每条聊天数据写入Hbase表中
    • 路径

      • step1:读取Excel文件,读取指定表格
      • step2:从表格的每一列中随机生成一条数据,构建一条模拟数据
      • step3:将模拟数据封装在一个Msg对象中
    • 实现

      • 读取Excel文件

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPxKWFGg-1616666919964)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322105117623.png)]

      • 随机取某一列的一个值

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9a9g0u0B-1616666919964)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322105145249.png)]

      • 随机生成一条数据

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hm39BwML-1616666919965)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322105206464.png)]

    • 总结

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GvWhnY47-1616666919965)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322103055968.png)]

    知识点08:聊天系统案例:构建Rowkey

    • 目标

      • 基于表的设计构建Rowkey

      • HbaseJava API

        • step1:构建连接

        • step2:构建Table对象

        • step3:写入数据

          table.put(Put)
          
    • 路径

      • step1:根据每条模拟数据,获取时间、发送人ID、接收人ID
      • step2:基于时间戳、发送人ID、接收人ID构建MD5编码
      • step3:使用MD5前8位+发送人ID+接收人ID+时间戳,构建Rowkey返回
    • 实现

      //构建rowkey,根据每条数据的内容来生成rowkey:ROWKEY = MD5Hash8位_发件人账号_收件人账号_时间戳
          private static String getRowKey(Msg msg) throws Exception {
              //构建一个动态字符串,用于拼接Rowkey
              StringBuilder stringBuilder = new StringBuilder(msg.getSender_account());
              stringBuilder.append("_");
              stringBuilder.append(msg.getReceiver_account());
              stringBuilder.append("_");
              //转换时间戳
              stringBuilder.append(input.parse(msg.getMsg_time()).getTime());
              //构建MD5前缀
              byte[] orginkey = Bytes.toBytes(stringBuilder.toString());
              String md5AsHex = MD5Hash.getMD5AsHex(orginkey).substring(0, 8);
              //返回最终rowkey
              return md5AsHex + "_"+stringBuilder.toString();
          }
      
    • 总结

      • Rowkey必须根据需求提前设计
      • 在构建Put等DML操作时,提前基于数据构建Rowkey即可

    知识点09:聊天系统案例:测试写入代码

    • 目标

      • 将每条模拟数据写入Hbase
    • 路径

      • step1:基于Rowkey构建Put对象
      • step2:获取模拟数据中每一列,添加到Put对象中
      • step3:对表执行Put操作,将每条模拟数据,构建一个Put,写入hbase表中中,观察结果
    • 实现

      //写入Hbase表
          private static void writeToHbase(Table table) throws Exception {
              for(int i = 0;i<100 ;i++){
                  //step1:先获取要写入的数据
                  Map<String, List<String>> maps = ExcelReader.readXlsx("datas/momo/测试数据集.xlsx", "陌陌数据");
                  Msg msg = ExcelReader.getOneMsg(maps);
                  //测试
      //            System.out.println(msg);
                  //step2:构建rowkey
                  String rowkey = getRowKey(msg);
      //            System.out.println(rowkey);
                  //step3:写入Hbase,构建Put对象
                  Put put = new Put(Bytes.toBytes(rowkey));
                  //添加每一列到put对象中
      //            put.addColumn(列族、列、值)
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_time), Bytes.toBytes(msg.getMsg_time()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_nickyname), Bytes.toBytes(msg.getSender_nickyname()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_account), Bytes.toBytes(msg.getSender_account()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_sex), Bytes.toBytes(msg.getSender_sex()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_ip), Bytes.toBytes(msg.getSender_ip()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_os), Bytes.toBytes(msg.getSender_os()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_phone_type), Bytes.toBytes(msg.getSender_phone_type()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_network), Bytes.toBytes(msg.getSender_network()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_sender_gps), Bytes.toBytes(msg.getSender_gps()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_nickyname), Bytes.toBytes(msg.getReceiver_nickyname()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_ip), Bytes.toBytes(msg.getReceiver_ip()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_account), Bytes.toBytes(msg.getReceiver_account()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_os), Bytes.toBytes(msg.getReceiver_os()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_phone_type), Bytes.toBytes(msg.getReceiver_phone_type()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_network), Bytes.toBytes(msg.getReceiver_network()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_gps), Bytes.toBytes(msg.getReceiver_gps()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_receiver_sex), Bytes.toBytes(msg.getReceiver_sex()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_msg_type), Bytes.toBytes(msg.getMsg_type()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_distance), Bytes.toBytes(msg.getDistance()));
                  put.addColumn(Bytes.toBytes(cf_name), Bytes.toBytes(col_message), Bytes.toBytes(msg.getMessage()));
                  //让表执行Put操作
                  table.put(put);
              }
      
          }
      
    • 总结

      • 写入hbase只要设计好rowkey,构建Put,添加列,执行即可

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jaacGobF-1616666919966)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322110352464.png)]

    知识点10:聊天系统案例:查询需求分析

    • 目标

      • 根据时间【日期】、发送人ID、接收人ID查询用户在指定时间的聊天记录

      • Hbase JavaAPI

        • step1:构建连接

        • step2:构建Table

        • step3:读分为两种

          • Get:给定rowkey,只返回一条数据

          • Scan:基于各种条件的复杂查询,返回多条数据

    • 路径

      • step1:指定时间[2021-03-22]、发送人ID、接收人ID查询条件,构建Scan

      • step2:根据条件构建过滤器

        ff98a62c_17351912952_17742251415_1616381252000
        
        • Rowkey前缀范围过滤:startrow,stoprow
        • Rowkey前缀过滤:PrefixFIlter
        • 列值过滤:SingleColumnValueFilter
          • 发送人ID = 给定的发送人ID
          • 收件人ID = 给定的收件人ID
          • 开始时间:2021-03-22 00:00:00【闭区间】
          • 结束时间:2021-03-23 00:00:00【开区间】
          • 四个条件:并且:and
        • 列的过滤:MultipleColumnPrefixFilter
      • step3:在Scan中加载过滤器

    • 实现

      //构建返回值
              List<Msg> msgs = new ArrayList<>();
              //step1:先构建连接
              Configuration conf = HBaseConfiguration.create();
              conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");
              conn = ConnectionFactory.createConnection(conf);
              //step2:构建表的对象
              Table table = conn.getTable(tbName);
              //step3:构建Scan + Filter
              Scan scan = new Scan();
              String startTime = date+" 00:00:00";
              String endTime = date+" 23:59:59";
              SingleColumnValueFilter valueFilter1 = new SingleColumnValueFilter(
                      Bytes.toBytes(cf_name),
                      Bytes.toBytes("msg_time"),
                      CompareOperator.GREATER_OR_EQUAL,
                      Bytes.toBytes(startTime));
              SingleColumnValueFilter valueFilter2 = new SingleColumnValueFilter(
                      Bytes.toBytes(cf_name),
                      Bytes.toBytes("msg_time"),
                      CompareOperator.LESS_OR_EQUAL,
                      Bytes.toBytes(endTime));
              SingleColumnValueFilter valueFilter3 = new SingleColumnValueFilter(
                      Bytes.toBytes(cf_name),
                      Bytes.toBytes("sender_account"),
                      CompareOperator.EQUAL,
                      Bytes.toBytes(sender));
              SingleColumnValueFilter valueFilter4 = new SingleColumnValueFilter(
                      Bytes.toBytes(cf_name),
                      Bytes.toBytes("receiver_account"),
                      CompareOperator.EQUAL,
                      Bytes.toBytes(receiver));
              FilterList list = new FilterList();
              list.addFilter(valueFilter1);
              list.addFilter(valueFilter2);
              list.addFilter(valueFilter3);
              list.addFilter(valueFilter4);
              scan.setFilter(list);
      
    • 总结

      • step1:分析需求,使用哪种过滤器
      • step2:构建Scan和过滤器即可

    知识点11:聊天系统案例:测试查询代码

    • 目标

      • 将查询结果,输出打印
    • 路径

      • step1:将返回的每条Rowkey的数据中的每一列取出
      • step2:将每一列赋值为Msg对象的对应属性
      • step3:输出每一条Msg数据
    • 实现

      ResultScanner scanner = table.getScanner(scan);
              //step5:将每个rowkey的数据取出转换为Msg对象,放入集合中
              for (Result result : scanner) {
                  //每个rowkey构建一个Msg对象
                  Msg msg = new Msg();
                  //读取Rowkey中每一列的数据赋值给msg的属性
      //            result.getValue(列族,列)
                  msg.setSender_nickyname(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_nickyname))));
                  msg.setSender_account(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_account))));
                  msg.setSender_sex(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_sex))));
                  msg.setSender_ip(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_ip))));
                  msg.setSender_os(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_os))));
                  msg.setSender_phone_type(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_phone_type))));
                  msg.setSender_network(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_network))));
                  msg.setSender_gps(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_sender_gps))));
                  msg.setReceiver_nickyname(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_nickyname))));
                  msg.setReceiver_account(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_account))));
                  msg.setReceiver_sex(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_sex))));
                  msg.setReceiver_ip(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_ip))));
                  msg.setReceiver_os(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_os))));
                  msg.setReceiver_phone_type(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_phone_type))));
                  msg.setReceiver_network(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_network))));
                  msg.setReceiver_gps(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_receiver_gps))));
                  msg.setDistance(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_distance))));
                  msg.setMsg_type(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_msg_type))));
                  msg.setMessage(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_message))));
                  msg.setMsg_time(Bytes.toString(result.getValue(Bytes.toBytes(cf_name),Bytes.toBytes(col_msg_time))));
                  //将msg放入集合
                  msgs.add(msg);
              }
              return msgs;
      
    • 总结

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OteMzxhZ-1616666919966)(20210322_分布式NoSQL列存储数据库Hbase(五).assets/image-20210322112127417.png)]

      • step1:执行Scan,得到所有符合条件的数据
      • step2:迭代每条数据进行处理即可

    知识点12:聊天系统案例:查询问题

    • 问题

      • 根据当前Rowkey的设计以及当前的需求,无法实现基于索引查询,性能较差,如何解决?
    • 原因

      • Rowkey的设计:MD58位+发件人+收件人+消息时间戳

      • 索引查询:只有根据Rowkey或者Rowkey的前缀查询,才走索引查询

        • 必须:发件人+收件人+消息时间戳
      • 查询条件:发件人、收件人、时间【天】

      • 问题:即使Rowkey中包含了我们经常查询的列,但凡查询条件不在Rowkey中,不能做索引查询,怎么解决?

      • 假设

        rowkey:id_name_age		id			name	age		addr		phone
        
        • 走索引
          • 查询id等于001的所有信息
          • 查询id等于001名字为张三的所有信息
          • 查询id等于001名字为张三,并且年龄为18的所有信息
        • 不走索引:全表扫描
          • 查询张三的所有信息
          • 查询18岁的所有信息
          • 查询上海的所有数据信息
          • 查询号码为110的所有信息
    • 解决

      • 二级索引

    知识点13:二级索引

    • 目标

      • 基于一级索引之上,构建一层索引,通过走两次索引来代替全表扫描
      • Hbase中的唯一索引是Rowkey
      • 目标:得到所有符合条件的数据
      • 思考:能不能先得到所有符合条件的rowkey,再通过rowkey得到所有符合条件的数据
    • 路径

      • step1:先构建原始数据表
      • step2:根据查询需求,构建索引表
      • step3:先查询索引表,再查询原始数据表
    • 实现

      • 原始数据表

        rowkey:name_id			id			name			age			sex			addr
        zhangsan_001			001			zhangsan		18			male		shanghai
        lisi_002				002			lisi			18			female		beijing
        zhangsan_003			003			zhangsan		20			male		
        ……
        
      • 哪些查询走索引?

        • name
        • name + id
      • 哪些查询不走索引?

        • id
        • age
        • sex
        • addr
      • 需求:根据id查询对应id的所有数据

        • 不走索引
      • 解决方案:构建二级索引

        • 原始数据表:记录所有原始数据

          rowkey:name_id			id			name			age			sex			addr
          zhangsan_001			001			zhangsan		18			male		shanghai
          lisi_002				002			lisi			18			female		beijing
          zhangsan_003			003			zhangsan		20			male		
          
        • 数据索引表:记录查询条件与原表Rowkey的映射关系

          rowkey:id_name			col:原表的rowkey
          001_zhangsan			zhangsan_001
          002_lisi				lisi_002
          003_zhangsan			zhangsan_003
          ……
          
        • 查询过程:查询id = 003

          • step1:先根据条件查询索引表,获取所有符合条件的原表的rowkey

            • 根据索引表的前缀匹配

              003_zhangsan			zhangsan_003
              
          • step2:根据原表的rowkey获取数据

            zhangsan_003			003			zhangsan		20			male		
            
    • 总结

      • 在原表之上构建索引表
      • 先查询索引表,再查询原表
    • Hive的问题

      • Hive中能否执行create index

        • 可以
        • 要求:0.7 ~ 3.x
        • 原因:Hive中索引表不会自动同步原始数据表,必须手动通过MapReduce同步索引表
    • Hbase问题:索引表如何与原表保持一致的问题

      • 方案一:当客户端往Hbase原表写入时,在客户端中也往索引表写一份

        • 不会用的
        • 优点:最简单
        • 缺点:Hbase无法保证不同表不同的rowkey的事务性,不能实现同时成功或者同时失败,性能很差
      • 方案二:协处理器,类似于Hive中的UDF

        • 自定义开发代码,让Hbase实现监听原表,如果原表的数据发生变化,索引自动发生变化
        • 优点:Hbase原生发生,可以满足原子性包括性能
        • 缺点:开发比较麻烦
      • 方案三:第三方工具

        • Phoenix:专门为Hbase所设计的工具,底层通过大量协处理器来实现,提供SQL接口

          create index 
          
          • 自动创建索引表,维护索引同步
        • ES:ElasticSearch / Solr

    附录一:Maven 依赖

        <repositories>
            <repository>
                <id>aliyun</id>
                <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            </repository>
        </repositories>
        <properties>
            <hbase.version>2.1.2</hbase.version>
        </properties>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client -->
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-client</artifactId>
                <version>${hbase.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-server</artifactId>
                <version>${hbase.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <!-- Xml操作相关 -->
            <dependency>
                <groupId>com.github.cloudecho</groupId>
                <artifactId>xmlbean</artifactId>
                <version>1.5.5</version>
            </dependency>
            <!-- 操作Office库 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.0.1</version>
            </dependency>
            <!-- 操作Office库 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.0.1</version>
            </dependency>
            <!-- 操作Office库 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>4.0.1</version>
            </dependency>
            <!-- 操作JSON -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.62</version>
            </dependency>
            <!-- phoenix core -->
            <dependency>
                <groupId>org.apache.phoenix</groupId>
                <artifactId>phoenix-core</artifactId>
                <version>5.0.0-HBase-2.0</version>
            </dependency>
            <!-- phoenix 客户端 -->
            <dependency>
                <groupId>org.apache.phoenix</groupId>
                <artifactId>phoenix-queryserver-client</artifactId>
                <version>5.0.0-HBase-2.0</version>
            </dependency>
        </dependencies>
    
       <!-- 操作Office库 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- 操作JSON -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <!-- phoenix core -->
        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>5.0.0-HBase-2.0</version>
        </dependency>
        <!-- phoenix 客户端 -->
        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-queryserver-client</artifactId>
            <version>5.0.0-HBase-2.0</version>
        </dependency>
    </dependencies>
    
    
    
    展开全文
  • 文章目录分布式NoSQL列存储数据库Hbase(三)知识点01:课程回顾知识点02:课程目标知识点03:Java API:DML:Table知识点04:Java API:DML:Put知识点05:Java API:DML:Get知识点06:Java API:DML:Delete知识...
  • 数据库存储

    千次阅读 2010-03-30 15:32:00
    首先看下WIKI上对数据库的解释: 数据库是以相关存储架构进行数据存储数据库,主要适合与批量数据处理和即席查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合与小批量
  • 数据库原理

    2017-10-25 22:05:33
    数据库简介文件存储对数据的存储需求一直存在。保存数据的方式,经历了手工管理、文件管理等阶段,直至数据库管理阶段。 文件存储方式保存数据的弊端:- 缺乏对数据的整体管理,数据不便修改; - 不利于数据分析和...
  • 数据库原理概论Ⅰ-关系数据库

    千次阅读 多人点赞 2019-02-17 15:52:38
    数据库原理概论Ⅰ-关系数据库 数据库原理是一门不难,但是各种形式化的语言比较难以理解的课,大三的时候数据库是全英文授课,鄙人不才,仿佛身处巫山之中。重新学习数据库,我这次以《数据库系统概论》 王珊著 这...
  • 什么是存储数据库

    万次阅读 多人点赞 2018-03-14 10:52:46
    列存储不同于传统的关系型数据库,其数据在表中是按行存储的,列方式所带来的重要好处之一就是,由于查询中的选择规则是通过列来定义的,因此整个数据库是自动索引化的。按列存储每个字段的数据聚集存储,在查询只...
  • 数据库的三级模式结构中,描述数据库中数据的全局逻辑结构和特征的是 A、 外模式 B、 内模式 C、 存储模式 D、 模式 我的答案:D 2【单选题】 公司中有多个部门和多名职员,每个职员只能属于一...
  • 数据库原理实验

    2020-07-09 13:37:47
    数据库原理实验存在的问题 存在的问题 1这一条显示好像有点问题 INNER JOIN 的用法 注意top 3 的用法
  • 数据库

    2016-09-19 14:54:34
    数据库介绍数据库是以相关存储架构进行数据存储数据库,主要适合与批量数据处理和即席查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合与小批量的数据处理,常用于联机...
  • Oracle数据库原理

    千次阅读 2017-08-18 14:02:00
    1. 数据库简介1.1文件存储 文件存储方式保存数据的弊端:1)缺乏对数据的整体管理,存取不方便,数据不便修改。2)不利于数据分析和分享,安全性不高。3)存储数据量较小,但数据量急剧增长时,大量数据不可长期...
  • 数据库种类及关系型数据库原理

    千次阅读 2017-09-14 08:02:25
    一、数据库种类及关系型数据库原理1.1数据库种类:按照早期的数据库理论,比较流行的数据库模型有三种: 层次式数据库 网络式数据库 关系型数据库 在当今互联网中,最常用的数据库模型: 关系型数据库 非关系型...
  • MS SQL Server数据库原理

    千次阅读 2019-01-23 11:24:09
    MS SQL Server数据库原理 一、 数据库基本概念 数据库系统(DBS):采用数据库技术的计算机系统,由数据库(数据)、数据库管理系统(软件)、数据库管理员(人员)、硬件平台(硬件)和软件平台(软件)五部分构成...
  • 数据库原理概论理论知识点总结

    万次阅读 多人点赞 2020-03-22 10:27:59
    数据库原理概论复习指南!
  • 数据库原理的基本概念

    千次阅读 多人点赞 2020-02-28 18:16:02
    数据库原理这门课已经学了一周多了,基础概念知识比较多,也比较杂,下面整理一下,也算是增加一点记忆。 ** 数据库的四个基本概念 ** 数据(Data):数据是描述事物的符号记录,数字,文字,图像,音频,视频,学生...
  • Oracle数据库学习(一)--数据库原理及SQL

    万次阅读 多人点赞 2016-03-22 22:59:54
    数据库原理 SQL(DDL、DML) 1. 数据库原理 1.1. 数据库简介 1.1.1. 文件存储 对数据的存储需求一直存在。保存数据的方式,经历了手工管理、文件管理等阶段,直至数据库管理阶段。 文件存储方式保存数据的弊端: ...
  • 数据库原理期末考试题(经典题型)

    万次阅读 多人点赞 2017-06-28 10:46:24
    数据库原理期末考试题(经典题型)
  • 考试科目:操作系统+数据库原理 题型:60个单选+20个多选,其中操作系统(30个单选+10个多选),数据库原理(30个单选+10个多选) 单选题一题一分,多选题一题两分(多选题每题5个选项,选择其中的正确选项) 今天...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,457
精华内容 52,182
关键字:

列存储数据库原理