1、简答题
1.1、绪论
-
数据库的基本特征
数据按一定的数据模型组织、描述和储存,结构化
数据的共享性高,冗余度低,易扩充
数据独立性较高
数据由DBMS统一管理和控制
-
信息与据的关系
信息是有用的、经过加工的数据,是数据的内涵,数据是信息的载体和符号表示
信息必然是数据,但数据未必是信息,信息仅是数据的一个子集,只有有用的数据才成为信息
-
DB\DBMS\DBS 三者的关系
DB强调的是应用数据本身
DBMS是管理DB的软件
使用DB并获取信息是目的,管理DB是手段,DBMS是管理DB的工具
DBS是包含以上两者,用来维护和获取信息的整个系统
-
推动计算机技术发展的最重要的因素是什么?
硬件与软件的发展。
在计算机发展过程中,硬件和软件总是相辅相成 的: 硬件是软件运行的容器,容器的形状和大小决定了软件的设计;然而软件反映的是人类的思维,思维不受限制, 因此软件就 能反过来促使硬件按照它的定义去发展。
-
数据管理技术的产生和发展
人工管理阶段——文件系统阶段——数据库系统阶段
-
人工管理阶段特征
不能长期保存数据
数据并不是由专门的应用软件来管理,而是由使用数据的应用程序自己来管理
数据不能共享
数据不具有独立性
-
文件系统阶段特征
(1)数据可以长期保存
(2)有简单的数据管理功能
(3)数据共享能力差
(4)数据不具有独立性
-
数据模型应满足哪三方面要求
能比较真实地模拟现实世界
容易为人所理解
便于在计算机上实现
-
两类数据模型分别是什么?
概念模型:也称信息模型,它是按用户的观点来对数据和信息建模,主要用于数据库设计。
逻辑模型和物理模型:逻辑模型主要包括网状模型、层次模型、关系模型等。它是按计算机系统的观点对数据建模,主要用于DBMS的实现。物理模型是对数据最底层的抽象,描述数据在系统内部的表示方式和存取方法,在磁盘或磁带上的存储方式和存取方法。
-
概念模型的主要特点
(1) 能真实、充分地反映现实世界
(2) 具有较强的语义表达能力
(3) 易于理解、易于更改
(4) 易于向关系、网状、层次等各种数据模型转换
-
ER图包括
实体型:用矩形表示,矩形框内写明实体名。
属性:用椭圆形表示,并用无向边将其与相应的实体型连接起来。
联系:用菱形表示,菱形框内写明联系名,并用无向边分别与有关实体型连接起来,同时在无向边旁标上联系的类型(1:1,1:n或m:n)。联系也可以有属性。
-
设计E-R模型的的步骤(过程)
确定实体集及属性:针对特定的用户应用系统,确定系统哪些是实体集,有多少个实体集,每个实体集有什么属性。
确定实体集间的联系:确定实体集之间存在什么联系及联系的属性。
-
ER图示例
-
逻辑模型的主要特点
(1) 计算机能够理解并处理的数据模型
(2) 从抽象的层面描述和模拟了系统的静态特征、动态行为和约束条件
(3) 不同的逻辑模型以不同的数据抽象和表示能力来反映客观事物及其联系
-
逻辑数据模型的组成要素
数据结构:数据结构描述数据库的组成对象以及对象之间的联系
数据操作:是指对数据库中各种对象(型)的实例(值)允许执行的操作及有关的操作规则
完整性约束:数据的完整性约束条件是一组完整性规则
-
常用的逻辑数据模型有哪些
层次模型(树)、网状模型(图)、关系模型(表)、新一代模型(半结构、非结构)
-
层次模型的优缺点
优点:
层次模型的数据结构比较简单清晰。
层次数据库的查询效率高,性能优于关系数据库,不低于网状数据库。
层次数据模型提供了良好的完整性支持。
缺点:
多对多联系表示不自然。
对插入和删除操作的限制多,应用程序的编写比较复杂。
查询子女结点必须通过双亲结点。
由于结构严密,层次命令趋于程序化。
-
网状模型的优缺点
优点:
能够更为直接地描述现实世界,如一个结点可以有多个双亲。
具有良好的性能,存取效率较高。
缺点:
结构比较复杂,而且随着应用环境的扩大,数据库的结构就变得越来越复杂,不利于最终用户掌握。
DDL、DML语言复杂,用户不容易使用。
-
关系模型的优缺点
优点:
建立在严格的数学概念的基础上。
概念单一。数据结构简单、清晰,用户易懂易用。
关系模型的存取路径对用户透明。
缺点:
存取路径对用户透明导致查询效率往往不如非关系数据模型。
为提高性能而对用户的查询请求进行优化增加了开发DBMS的难度。
-
两级映像作用:数据独立性
外模式/模式映像:当模式改变时,数据库管理员修改有关的外模式/模式映像,使外模式保持不变。应用程序是依据数据的外模式编写的,从而应用程序不必修改。保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
模式/内模式映像:当数据库的存储结构改变了,数据库管理员修改模式/内模式映像,使模式保持不变。应用程序不受影响。保证了数据与程序的物理独立性,简称数据的物理独立性。
-
使用数据库系统的好处?
使用数据库系统的好处是由数据库管理系统的特点或优点决定的。使用数据库系统的好处很多。
例如:
可以大大提高应用开发的效率,方便用户的使用,减轻数据库系统管理人员维护的负担,等等。使用数据库系统可以大大提高应用开发的效率。因为在数据库系统中应用程序不必考虑数据的定义、存储和数据存取的具体路径,这些工作都由 DBMS 来完成。用一个通俗的比喻,使用了 DBMS 就如有了一个好参谋、好助手,许多具体的技术工作都由这个助手来完成。开发人员就可以专注于应用逻辑的设计,而不必为数据管理的许许多多复杂的细节操心。
还有,当应用逻辑改变,数据的逻辑结构也需要改变时,由于数据库系统提供了数据与程序之间的独立性,数据逻辑结构的改变是 DBA 的责任,开发人员不必修改应用程序,或者只需要修改很少的应用程序,从而既简化了应用程序的编制,又大大减少了应用程序的维护和修改。使用数据库系统可以减轻数据库系统管理人员维护系统的负担。因为 DBMS 在数据库建立、运用和维护时对数据库进行统一的管理和控制,包括数据的完整性、安全性、多用户并发控制、故障恢复等,都由 DBMS 执行。总之,使用数据库系统的优点是很多的,既便于数据的集中管理,控制数据冗余,提高数据的利用率和一致性,又有利于应用程序的开发和维护。
22.试述文件系统与数据库系统的区别和联系。
(1)文件系统与数据库系统的区别:
文件系统面向某一应用程序,共享性差,冗余度大,数据独立性差,记录内有结构,整体无结构,由应用程序自己控制。
数据库系统面向现实世界,共享性高,冗余度小,具有较高的物理独立性和一定的逻辑独立性,整体结构化,用数据模型描述,由数据库管理系统提供数据的安全性、完整性、并发控制和恢复能力。
(2)文件系统与数据库系统的联系:
文件系统与数据库系统都是计算机系统中管理数据的软件。
文件系统是操作系统的重要组成部分;而 DBMS 是独立于操作系统的软件。但是 DBMS 是在操作系统的基础上实现的;数据库中数据的组织和存储是通过操作系统中的文件系统来实现的。
-
数据库管理系统的功能有哪些?
(1)数据库定义功能;
(2)数据组织、存储和管理功能;
(3)数据操纵功能;
(4)数据库的事务管理和运行管理;
(5)数据库的建立和维护功能。 -
试述数据库系统三级模式结构,这种结构的优点是什么?
数据库系统的三级模式结构由外模式、模式和内模式组成。
外模式,亦称子模式或用户模式,是数据库用户(包括应用程序员和最终用户)能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。
模式,亦称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。模式描述的是数据的全局逻辑结构。外模式涉及的是数据的局部逻辑结构,通常是模式的子集。
内模式,亦称存储模式,是数据在数据库系统内部的表示,即对数据的物理结构和存储方式的描述。
数据库系统的三级模式是对数据的三个抽象级别,它把数据的具体组织留给 DBMS管理,使用户能逻辑抽象地处理数据,而不必关心数据在计算机中的表示和存储。
为了能够在内部实现这三个抽象层次的联系和转换,数据库系统在这三级模式之间提供了两层映像:外模式/模式映像和模式/内模式映像。正是这两层映像保证了数据库系统中的数据能够具有较高的逻辑独立性和物理独立性。
-
三级模式结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NvrssUBW-1662533314494)(C:\Users\Fuwenshuai\AppData\Roaming\Typora\typora-user-images\1657077589196.png)]
-
试述视图的优点。
(1)视图能够简化用户的操作;
(2)视图使用户能以多种角度看待同一数据;
(3)视图对重构数据库提供了一定程度的逻辑独立性;
(4)视图能够对机密数据提供安全保护。 -
所有的视图是否都可以更新?为什么?
不是。视图是不实际存储数据的虚表,因此对视图的更新,最终要转换为对基本表的更新。因为有些视图的更新不能惟一有意义地转换成对相应基本表的更新,所以,并不是所有的视图都是可更新的。
-
关系模式,关系,关系数据库,理解术语说出它们之间的区别联系
关系模式:关系的描述称为关系模式( relation schema)。它可以形式化地表示为R(U,D,DOM,F)
其中R为关系名,U为组成该关系的属性名集合,D为属性组U中属性所来自的域,DOM为属性向域的映像集合,F为属性间数据的依赖关系集合。
关系: 在域D1,D2,…,Dn上笛卡儿积D1xD2x…xDn的子集称为关系,表示为R(D1,D2,…,Dn)。 关系是关系模式在某一时刻的状态或内容。关系模式是静态的、稳定的,而关系是动态的、随时间不断变化的,因为关系操作在不断地更新着数据库中的数据。
关系数据库:关系数据库也有型和值之分。关系数据库的型称为关系数据库模式,是对关系数据库的描述,它包括若干域的定义以及在这些域上定义的若干关系模式。关系数据库的值是这些关系模式在某一时刻对应的关系的集合,通常就称为关系数据库。
-
候选码,主码,外码
候选码:若关系中的某一属性组的值能唯地标识一个元组,而其子集不能,则称该属性组为候选码( candidate key)。
主码:若一个关系有多个候选码,则选定其中一个为主码(primary key)。
外码:设F是基本关系R的一个或一组属性, 但不是关系R的码,如果F与基本关系R的主码K相对应,则称F是基本关系R的外部码( foreign key),简称外码。
1.2、关系数据库
-
关系数据语言的特点
高度非过程化;
能够嵌入高级语言中使用;
关系代数、元组关系演算和域关系演算三种语言在表达能力上完全等价。
-
关系的三类完整性约束是哪些?
(1)实体完整性:若属性A是基本关系R的主属性,则属性A不能取空值。
(2)参照完整性:若属性(或属性组)F是基本关系R的外码,它与基本关系S的主码Ks相对应(基本关系R和S不一定是不同的关系),则对于R中每个元组在F上的值必须为:
或者取空值(F的每个属性值均为空值);
或者等于S中某个元组的主码值。
(3)用户定义的完整性:就是针对某一具体关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求。
-
专门的关系运算有哪些?
选择、投影、连接、除
-
SQL的特点
综合统一
高度非过程化
面向集合的操作方式
以同一种语法结构提供多种使用方式
语言简洁,易学易用
-
HAVING短语与WHERE子句的区别:
WHERE子句作用于基本表或视图,从中选择满足条件的元组。
HAVING短语作用于组,从中选择满足条件的组。
-
外连接与普通连接的区别:
普通连接操作只输出满足连接条件的元组。
外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出。
-
视图的作用
能够简化用户的操作
使用户能以多种角度看待同一数据
对重构数据库提供了一定程度的逻辑独立性
能够对机密数据提供安全保护
适当的利用视图可以更清晰的表达查询
-
视图的特点
虚表,是从一个或几个基本表(或视图)导出的表
只存放视图的定义,不存放视图对应的数据
基本表中的数据发生变化,从视图中查询出的数据也随之改变
-
试述关系数据库的特点。
关系数据模型具有下列优点:
(1)关系模型与非关系模型不同,它是建立在严格的数学概念的基础上的。
(2)关系模型的概念单一,无论实体还是实体之间的联系都用关系表示,操作的对象和操作的结果都是关系,所以其数据结构简单、清晰,用户易懂易用。
(3)关系模型的存取路径对用户透明,从而具有更高的数据独立性、更好的安全保密性,也简化了程序员的工作和数据库开发建立的工作。
当然,关系数据模型也有缺点,其中最主要的缺点是,由于存取路径对用户透明,查询效率往往不如非关系数据模型。因此为了提高性能,必须对用户的查询请求进行优化,增加了开发数据库管理系统的难度。 -
什么叫数据与程序的物理独立性?什么叫数据与程序的逻辑独立性?为什么数据库系统具有数据与程序的独立性?
数据与程序的逻辑独立性:当模式改变时(例如增加新的关系、新的属性、改变属性的数据类型等),由数据库管理员对各个外模式/模式的映像做相应改变,可以使外模式保持不变。应用程序是依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
数据与程序的物理独立性:当数据库的存储结构改变了,由数据库管理员对模式/内模式映像做相应改变,可以使模式保持不变,从而应用程序也不必改变,保证了数据与程序的物理独立性,简称数据的物理独立性。
数据库管理系统在三级模式之间提供的两层映像保证了数据库系统中的数据能够具有较高的逻辑独立性和物理独立性。 -
试述关系模型的三个组成部分。
关系模型由关系数据结构、关系操作集合和关系完整性约束三部分组成。 -
试述关系模型的完整性规则。在参照完整性中,什么情况下外码属性的值可以为空值?
关系模型中可以有三类完整性约束:实体完整性、参照完整性和用户定义的完整性。关系模型的完整性规则是对关系的某种约束条件。
实体完整性规则:若属性A是基本关系R的主属性,则属性A不能取空值。
参照完整性规则:若属性(或属性组)F是基本关系R的外码,它与基本关系S的主码Ks相对应(基本关系R和S不一定是不同的关系),则对于R中每个元组在F上的值必须为:
或者取空值(F的每个属性值均为空值);
或者等于S中某个元组的主码值。
用户定义的完整性是针对某一具体关系数据库的约束条件。它反映某一具体应用所设计的数据必须满足的语义要求。
在参照完整性中,如果外码属性不是其所在关系的主属性,则可以取空值,否则不能取空值。
1.3、规范化
-
函数依赖:
设R(U)是属性集U上的关系模式。X,Y是U的子集。若对于R(U)的任意一个可能的关系r,r中不可能存在两个元组在X上的属性值相等, 而在Y上的属性值不等,则称X函数决定Y或Y函数依赖于X,记作X → Y
-
范式
-
1NF : 如果一个关系模式R的所有属性都是不可分的基本数据项,则R∈1NF。
面临的四个问题:数据冗余、插入异常、删除异常、修改困难
-
2NF: 若R∈1NF,且每一个非主属性完全函数依赖于码,则R∈2NF**。**
2NF的性质:如果R∈2NF,则R∈1NF;如果R的候选关键字是单属性或全键(All-key), 则R∈2NF
面临的问题:数据冗余、插入异常、删除异常、修改困难
-
3NF: R∈3NF,则每一个非主属性既不部分依赖于码也不传递依赖于码。
问题:没有涉及主属性下的数据冗余问题
-
BCNF:若R∈BCNF:
所有非主属性对每一个码都是完全函数依赖;
所有的主属性对每一个不包含它的码,也是完全函数依赖;
没有任何属性完全函数依赖于非码的任何一组属性。
- 3NF与BCNF的关系:
3NF和BCNF是在函数依赖的条件下对模式分解所能达到的分离程度的测度。一个模式中的关系模式如果都属于BCNF,那么在函数依赖范畴内,它已实现了彻底的分离,已消除了插入和删除的异常。
-
规范化的目的:
尽量消除插入、删除异常,修改复杂,数据冗余。
-
规范化的思想:
逐步消除数据依赖中不合适的部分,使模式中的各个关系达到某种程度的“分离” — 概念的单 一化。
-
规范化小结:
-
规范化程度越高的关系模式越好吗?
不能说规范化程度越高的关系模式就越好,在设计数据库模式结构时,必须对现实世界的实际情况和用户应用需求作进一步分析,确定一个合适的、能够反映现实世界的模式,上面的规范化步骤可以在其中任何一步终止。
-
什么是基本表?什么是视图?两者的区别和联系是什么?
基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。
视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表。即数据库中只存放视图的定义而不存放视图对应的数据,这些数据仍存放在导出视图的基本表中。视图在概念上与基本表等同,用户可以如同基本表那样使用视图,可以在视图上再定义视图。
习题:关系模式规范化习题
1.4、数据库设计
-
数据库设计的目标:
为用户和各种应用系统提供一个信息基础设施和高效率的运行环境。
-
数据库设计的基本步骤:
需求分析、概念结构设计、逻辑结构设计、数据库物理设计、数据库实施、数据库运行和维护
-
概念结构的主要特点:
(1)能真实、充分地反映现实世界
(2)易于理解
(3)易于更改
(4)易于向关系、网状、层次等各种数据模型转换
概念结构的工具:E-R模型
-
设计概念结构的方法:
1 )自顶向下,即首先定义全局概念结构的框架,然后逐步细化;
2 )自底向上,即首先定义各局部应用的概念结构,然后将它们集成起来,得到全局概念结构;
3 )逐步扩张,首先定义最重要的核心概念结构,然后向外扩充,以滚雪球的方式逐步生成其他概念结构,直至总体概念结构;
4 )混合策略,即将自顶向下和自底向上相结合,用自顶向下策略设计一个全局概念结构的框架,以它为骨架集成由自底向上策略中设计的各局部概念结构。
-
E-R图向关系模型的转换:
转换内容是将实体型、实体的属性和实体型之间的联系转换为关系模式。
实体型之间的联系包含以下五种情况 :
(1) 一个1:1联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。
-
如果转换为独立的关系模式:与该联系相连的各实体的码以及联系本身的属性均 转换为关系的属性,每个实体的码均是该关系的候选码。 如果与某一端的实体对应的关系模式合并:在该关系模式的属性中加入另一个关 系模式的码和联系本身的属性。
(2) 一个 1:n 联系可以转换为一个独立的关系模式,也可以与 n 端对应的关系模式合并。
-
如果转换为独立的关系模式:与该联系相连的各实体的码以及联系本身的属性均 转换为关系的属性,关系的码为 n 端实体的码
(3) 一个 m:n 联系转换为一个关系模式
- 该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,各实体的码 组成关系的码或关系码的一部分
(4) 三个或三个以上实体间的一个多元联系可以转换为一个关系模式
- 与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,各实 体的码组成关系的码或关系码的一部分。
(5) 具有相同码的关系模式可合并
-
将其中一个关系模式的全部属性加入到另一个关系模式中,然后去掉其中的同义 属性(可能同名也可能不同名),并适当调整属性的次序
-
目的:减少系统中的关系个数。
-
什么是数据库的逻辑结果设计,简述其设计步骤:
数据库的逻辑结构设计就是把概念结构设计阶段设计好的基本E-R图转换为与选用的DBMS产品所支持的数据模型相符合的逻辑结构。
设计步骤为:将概念结构转换为关系模型、对数据模型进行优化
课后习题 7、8、10
1.5、并行控制
-
数据保护也叫数据控制,主要包括哪些内容:
数据的安全性、数据的完整性、并发控制、数据库恢复
-
并发操作会造成哪些数据的不一致的情况?
丢失修改、读脏数据、不可重复读(重点看看ppt的动画)——破坏了事务的隔离性
-
解决死锁的办法:
产生死锁的原因: 两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死等待。
预防死锁,即破坏产生死锁的条件,包括:
- 一次封锁法:要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。但却降低了系统的并发度
- 顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。但维护成本高、难于实现。
死锁的诊断与解除:
(1)诊断死锁
- 超时法:如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。实现起来简单,但是很可能误判死锁;若限时设置的太长,死锁发生后不可以及时发现。
- 等待图法: 事务等待图动态地反映了所有事务的等待情况。并发控制子系统周期性地(比如每隔数秒)生成事务等待图,并进行检测。如果发现图中存在回路,则表示系统中出现了死锁。
(2)解除死锁: 选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有的锁,使其他事务能继续运行下去。对撤销的事务所执行的数据修改操作必须加以恢复。
-
什么样的调度是正确的?
可串行性是是并发事务正确调度的准则 。一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度。同时两段锁协议是可串行化调度的充分条件,但不是必要条件。
-
两段锁协议与预防死锁的一次封锁法有什么异同?
(1)一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议。
(2)两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。
-
什么是封锁?基本的封锁类型有哪几种?
封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不可以更新或者读取此数据对象。
基本的封锁类型包括两种:排他锁(X锁)和共享锁(S锁)
排他锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事物不可以再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A的锁之前不再读取和修改A。
共享锁又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但是不可以修改A,其他事务只能对A加上S锁,而不可以加上X锁,直到T释放其在A上的S锁。这就保证了其他事务可以读取A,但在T释放在A上的S锁之前不能对A进行任何修改。
-
活锁产生的原因和解决办法?
原因:当一系列封锁不可以按照先后顺序执行时,就可能导致一些事务无限期等待某个封锁,从未导致活锁。
避免活锁的简单方法是先来先服务策略。当多个事务请求封锁同一个数据对象时,封锁子系统按照请求封锁的先后顺序对事务进行排队,数据对象上的锁一旦释放就批准申请队列中的第一个事务获得锁。
1.6、数据库恢复
-
事务是什么,事务的性质(最重要的是一致性,)
事务是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作,是并发控制的基本单位。
性质:
原子性(atomicity,或称不可分割性): 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性(consistency): 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性(isolation,又称独立性): 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性(durability): 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
-
怎么理解在大数据下的事物一致性?对事务ACID特性的深度思考?
由单机到分布式系统
单机数据库比较容易实现数据库的一致性
数据库横向扩展、高可用、模式自由等需求时,需要对ACID理论进行取舍
保证可用性:每一个请求都能得到响应。
分布式架构和数据多副本情况下实现事务、封锁机制,考虑到分布式系统可能面临网络拥塞、数据丢包、个别节点系统故等情况下实现事务机制,分布式事务可能带来系统的可用性降低或系统复杂度提高等难题。
BASE原则:基本可用、柔软状态、最终一致性
BASE原则面向的是大型、高可用、可扩展的分布式系统,和传统的事务相反,通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,最终达到一致性状态。在实际的分布式场景中,不同业务单元和组件对数据的一致性要求是不同的,不要求要个的数据库事务,对一致性要求井不高,允许实现最终一致性,因此在具体的分布式系统架构设计过程中,ACID原则和BASE原则往往结合在一起。
大数据下的事务一致性要满足最终一致性,属于弱一致性的一种特例,系统要确保最终最终所有访问都将得到更新后的数据。其中客户端关注多并发访问时如何获取更新后的数据;服务端关注如何在小的时间窗口内将更新传播到整个系统内。
3. 故障的种类:
事务内部的故障、系统故障、介质故障、计算机病毒
1.7、数据库技术发展
-
数据库技术与其他计算机技术相结合,涌现出各种数据库系统:
数据库技术 分布处理技术 分布式数据库系统 数据库技术 并行处理技术 并行数据库系统 数据库技术 人工智能技术 演绎数据库、知识库、主动数据库系统 数据库技术 多媒体技术 多媒体数据库系统 数据库技术 模糊技术 模糊数据库系统 数据库技术 移动通信技术 移动数据库数据库系统 数据库技术 Web技术 Web数据库 -
NoSQL技术特点是什么?
对数据进行划分
放松对数据ACID一致性约束
对各个数据分区进行备份(一般是三份)
-
大数据管理的发展趋势是什么?
各类技术的相互借鉴、融合和发展是数据管理领域的发展趋势
-
推动数据库发展的三个主要动力或三个重要因素是什么?
数据、应用需求和计算机硬件技术
-
第三代数据库系统的基本特征:
第三代数据库系统应支持数据管理、对象管理和知识管理
第三代数据库系统应必须保持或继承第二代数据库系统的技术
第三代数据库系统必须对其他系统开放
1.8、大数据管理
-
什么是数据库,数据库和大数据管理有什么关系?
数据库是长期储存在计算机内、有组织的、可共享的大量数据的集合。数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种用户共享。
大数据管理依靠数据库系统,而数据库是数据库系统的核心部件之一,它是存放数据的仓库,是对数据进行管理的基础。
-
谈谈你对大数据管理的理解
随着时代的发展,数据呈现爆炸式增长,大数据的概念出现,其具有数据体量大、种类来源多样化、价值密度低、速度快【4V】等特点。大数据的规模效应给数据整理、存储、组织、检索、维护以及数据分析应用带来巨大挑战。这就对数据库提出了以下要求:
1、对数据高并发读写的需求(high performance)
2、对海量数据的高效率存储和访问的需求(huge storage)
3、对数据库的高可扩展性和高可用性的需求(high scalability & availability)
同时,我们必须为不同的业务场景选择更适合的管理工具-关系型数据库SQL和非关系型数据库NOSQL;此时不再强调全面,而强调取舍。
-
大数据的特征:
巨量、多样、快变、价值
-
大数据的应用
感知现在 预测未来——互联网文本大数据管理与挖掘
数据服务 实时推荐——基于大数据分析的用户建模
-
互联网文本大数据管理的挑战
首先,文本数据的主题是开放的,每天的新闻文档分别描述成成千上万没有直接关联的新闻事件,无法实现预定义关系模式和值域。
其次,文本大数据一般由自然语言生成,没有确定的结构,无法直接用关系型数据进行存储和查询。
最后,互联网上的数据量巨大,变化速度快,对数据库管理系统的可拓展性和实时性提出来很高的要求。
-
用户建模大数据应用的特点:
模型的建立来源于对大数据的分析结果,通俗讲是用”数据说话“。建模的过程是动态的,随着实际对象的变化,面模型也在变化。
数据处理既有对历史数据的离线分析和挖掘,又有对实时流数据的在线采集和分析。
用户模型本身也是大数据,纬度高,信息稀疏,用户模型的存储、管理是数据服务的重要任务,要满足大规模应用需要的高并发数据更新与读取。
-
NoSQL数据库系统相对于关系型数据库系统的两个明显优势:
数据模型灵活,支持多样的数据类型
高度的拓展性,很少有关系型数据库系统可以部署在超过1000个节点的集群上,但是NoSQL在大规模集群上获得了极高的性能。
-
大数据管理面临的关键问题:
大数据集成技术,大数据分析与查询技术,大数据可视化技术,大数据隐私管理,大数据融合、大数据管理、大数据分析、大数据隐私
-
大数据管理平台有哪些?
数据库、
数据湖:是一个以原始格式存储数据的存储库或系统。它按原样存储数据,而无需事先对数据进行结构化处理。一个数据湖可以存储结构化数据(如关系型数据库中的表),半结构化数据(如CSV、日志、XML、JSON),非结构化数据(如电子邮件、文档、PDF)和二进制数据(如图形、音频、视频)。
数据仓库
数据中台:数据中台是一套可持续“让企业的数据用起来”的机制,一种战略选择和组织形式,是依据企业特有的业务模式和组织架构,通过有形的产品和实施方法论支撑,构建一套持续不断把数据变成资产并服务于业务的机制。
1.9、从SQL到NoSQL
-
关系模型
优点:
有用,可以用来存储数据
缺点:
不灵活,路径依赖、顺序依赖、索引依赖
局限性:
太死板,先设计后使用,无法应对无模态、多模态问题;难以管理高维数据
扯不开,难以分散存储;无法并行处理
太复杂,费用高昂问题;管理复杂问题
-
大数据管理下关系模型的局限性/关系数据库面临的问题:
先设计后使用,无法应对无模态、多模态问题
表间关系紧密,一致性问题复杂,难以分散存储处理
难以管理海量高维数据
难以高效支持大数据分析处理
费用高昂问题、管理复杂问题
-
NoSQL产生时的几个明显特征:
不使用SQL、开源、可在集群上运行、无模式相对自由
-
NoSQL的优缺点:
优点:易扩展、高性能、数据类型灵活、高可用
缺点:没有标准、没有存储过程、不支持SQL、功能不够完善
-
NoSQL数据模型:
-
聚合模型:把业务中的一个对象作为一个整体单元来存储和操作(如读取、更新、一致性管理)
特点:“打包”
(1)关系数据库是聚合无知的(Aggregate-ignorant)。访问是无边界的,字段可以任意组合。可以用不同方式、不同视图来查看操作数据。
(2)NoSQL数据库的访问是有边界的,受聚合的限制
(3)将数据的操作限定在聚合内,因而可以将不同聚合分散存储到不同节点,形成大规模分布式存储集 群。
具体分类:键值数据库、文档数据库、列族数据库
-
图模型——使用关系存储属性
图数据库可存放实体及实体间关系。实体也叫“节点”(node),它们具有属性(property)。可将节点视为应用程序中某对象的实例。
关系又叫“边” (edge),它们也有属性。边具备方向性(directional significance),而节点则按关系组织起来,以便在其中查找所需模式。
图数据库有很多种,如 Neo4J、Infinite Graph、OrientDB 和FlockDB、Titan
特点:“分散”、点和边
-
-
NoSQL数据库的类型:
-
键值数据库:
数据库中包含大量聚合,每个聚合中都有一个获取数据所用的键或ID。
键值数据库的聚合对于数据库而言是“透明的”。透明的优势在于,可以存储任意数据,没有数据结构和类型限制。缺点在于访问聚合内容只能通过键来访问。
使用键值数据库存储数据:
MemcachedClient mcc = new MemcachedClient( new InetSocketAddress ("192.168.10.101", 11211)); mcc.add("1001", 0, "zhangsan,M,19,henan zhengzhou,math=90&chinese=92");
FileInputStream file = new FileInputStream("D:\\Pictures\\logo.png"); byte[] bytes = file.readAllBytes(); mcc.add("1002", 0, bytes); byte[] object = (byte[]) mcc.get("1002"); FileOutputStream out = new FileOutputStream("D:\\Pictures\\logo-o.png"); out.write(object);
-
文档数据库:
使用特定“文档”结构来表示、管理数据。数据库“可以看到”某个聚合的结构,从而可以用聚合中的字段进行索引和查询。缺点在于有结构和数据类型的限制。
使用文档数据库存储数据:
db.student.insert( { name: "zhangsan", sex: "M", age: 19, addr: "henan zhengzhou“ scores: { math: 90 , chinese: 92 } } ) db.student.find({ scores.math: { $lt: 80 } })
-
列族数据库 :
可以看成两级聚合,即聚合的值中包含”若干小的聚合”
使用列族数据库存储数据:
create 'student',’info',’scores’,’others’ put 'student’, '1001’, 'info:name’, ’zhangsan' put 'student’, '1001’, 'info:sex’, 'M' put 'student’, '1001’, 'info:age’, '19' put 'studen ', '1001’, 'info:addr’, 'henan zhengzhou' put 'student', '1001’, 'scores:chinese', '92' put 'student', '1001’, 'scores:math’, '90' put 'student’, '1001’, 'scores:english’, '88.4'
-
图数据库:
混合模式:文档+图
-
4类非关系数据库的特点、典型实例、适用场景
1.10、分布式存储
-
为什么要采用分布式存储/集中式存储的性能瓶颈?
随着科技的发展,集中式存储逐渐暴露了一系列的问题:比如存储传输效率低、安全问题严重易被攻击、系统易崩溃、存储成本高昂、无法永久存储等等。
实际上采用分布式存储可以说是“被迫”的,因为面对越发飞速发展的互联网、整个生态应用不断创新、用户数量不断庞大、数据阶梯式增长这些无疑不给现有的本地存储带来巨大的压力。因此,必须通过采用其他分布式存储系统去缓解相应的压力,所以分布式存储和分布式文件系统应运而生。
-
主从模式
-
优点:
(1)数据更安全:做了数据冗余,不会因为单台服务器的宕机而丢失数据
(2)性能大大提升:一主多从,不同用户从不同数据库读取,性能提升
(3)扩展性更优:流量增大时,可以方便的增加从服务器,不影响系统使用
(4)负载均衡:一主多从相当于分担了主机任务,做了负载均衡。
-
缺点:
主从之间的数据不一致,不同的客户端,如果从不同的“从”读取数据,看到不同的值,因为值的改变可能还没有从“主”传播到“从”,最坏情况下,客户端无法读取到刚写入的值。如果主服务器失败,没有传递到从服务器的数据更新都将丢失。
-
典型案例:GFS
GFS系统由三部分组成:GFS master、GFS Client、GFS chunkserver。其中,GFS master任意时刻只有一个,而chunkserver和gfs client可能有多个。
一份文件被分为多个固定大小的chunk(默认64M),每个chunk有全局唯一的文件句柄——一个64位的chunk ID,每一份chunk会被复制到多个chunkserver(默认值是3),以此保证可用性与可靠性。chunkserver将chunk当做普通的Linux文件存储在本地磁盘上。
GFS master是系统的元数据服务器,维护的元数据包括:命令空间(GFS按层级目录管理文件)、文件到chunk的映射,chunk的位置。其中,前两者是会持久化的,而chunk的位置信息来自于Chunkserver的汇报。
GFS master还负责分布式系统的集中调度:chunk lease管理,垃圾回收,chunk迁移等重要的系统控制。master与chunkserver保持常规的心跳,以确定chunkserver的状态。
GFS client是给应用使用的API,这些API接口与POSIX API类似。GFS Client会缓存从GFS master读取的chunk信息(即元数据),尽量减少与GFS master的交互。
-
GFS如何解决单点失效和性能瓶颈问题?
①解决单点失效:
GFS在不同的机架上进行数据备份。这样即使整个机架被毁或是掉线,也能确保数据的正常使用,在数据块服务器掉线或是数据被破坏时,MASTER会按照需要来复制数据块。如果是Master宕机,则有Master复制的机制:Master 服务器的状态会被复制,它所有的操作日志、checkpoint 文件都会被复制到多台机器,对 master 服务器的状态的任何操作都要等操作日志被复制到备份节点后本机磁盘后才会被提交生效。所以 Master 宕机后,重启后不会有任何数据丢失,如果无法重启或磁盘故障,则可以选择拥有全部操作日志的备份节点启动一个新的 master 进程。由此可以保证 master 的可靠性。同时,还存在一些 shadow master,在 master 宕机时能可以提供 read-only 服务
②解决性能瓶颈:
Lease机制,如果每次记录追加都需要请求Master,那么Master就会成为系统的性能瓶颈,因此,GFS通过Lease机制将chunk写操作授权给Chunk Server,Lease授权针对单个chunk,在Lease有效期内,对该chunk的写操作都由Primary Chunk Server负责,从而减少了Master的负担提高了性能
-
对等模式
-
优点:组建简单,方便,易用。
-
缺点:维护困难,只适用于小型网络。
-
分散式散列表(distributed hash table,DHT)
用来将一个关键值(key)的集合分散到所有在分散式系统中的节点,并且可以有效地将消息转送到唯一一个拥有查询者提供的关键值的节点(Peers)。这里的节点类似散列表中的存储位置。
-
简单哈希算法
-
一致性哈希算法→P2P
-
-
一致性哈希算法的优点:
节点搅动产生的开销小。增加或删除(宕机)某台服务器时,受影响的数据仅仅是此服务器到其环空间中前一台服务器之间数据,其它不会受到影响。由此带来较好的容错性和可扩展性。
-
分片与副本集
-
分片:把数据的各个部分存放于不同的服务器中,以此实现横向扩展
-
副本与副本集:同一个数据同时存放在多个位。每个数据成为一个副本。一个数据的多个副本形成一个副本集。副本集技术能提升读取性能,提升数据可靠性。副本数一般为3。
-
主从复制:
-
对等复制:
-
分布式与一致性
关系型数据库试图通过“强一致性”来避免各种不一致问题(ACID);而在NoSQL领域中,则会出现诸如“CAP定理”(CAP theorem)与“最终一致性”(eventual consistency)这种术语,一旦开始构建,就必须思考当前系统需要何种一致性。
-
更新一致性: 在并发环境中维护数据一致性所用的方式,通常分为“悲观方式”与“乐观方式”。
单服务器能做,多服务器很难。
- “悲观”方式:避免发生冲突;最常见的“悲观方式”就是采用“写入锁”:在修改某个值之前,必须先获取“写入锁”,系统确保某一时刻只有一个客户能够获得这把锁。
- “乐观” 方式:先让冲突发生,然后检测冲突并对发生的冲突进行处理。通常采用“条件更新”(conditional up}ate)也就是任意客户在执行更新操作之前,都要先测试数据的当前值和其上一次读入的值是否相同。
-
读取一致性:
- 副本一致性(replication Consistency,复制一致性):从不同副本中读取同一个数据项时,所得到的值相同。
- 最终一致性(Eventually Consistency):只要不再继续执行其他更新操作或出现错误,那么上一次更新操作的结果最终将会反映到全部节点中去。
-
CAP理论:
- 一致性(Consistency):任何一个读操作总是能读取到之前完成的写操作结果,也就是在分布式环境中,多点的数据是一致的;
- 可用性(Availability):每一个操作总是能够在确定的时间内返回,也就是系统随时都是可用的。
- 分区容忍性(Partition Tolerance):在出现网络分区(比如断网)的情况下,分离的系统也能正常运行。
在分布式系统中,这三个要素最多只能同时实现两点,不可能三者兼顾。
对于分布式数据系统,分区容忍性是基本要求。
对于大多数web应用,牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。
1.11 、键值数据库
-
键值数据库是最简单的NoSQL数据库,每个记录包含key、value两部分。
Value是要存储的数据,数据库不知道也不关心value的格式,应用程序负责理解value。
key是存取数据的唯一标识,相同标识的数据将被覆盖
-
Redis
Redis数据分片:Redis 集群没有直接使用一致性hash, 而是引入了 哈希槽的概念。Redis 集群有16384个哈希槽,每个key通过CRC16运算后对16384取模来决定放置哪个槽( CRC16(key) mod 16384)。集群的每个节点负责一部分hash槽。
-
Redis分片的作用
Redis的分片技术是指将数据分散到多个Redis实例中的方法,分片之后,每个redis拥有一部分原数据集的子集。在数据量非常大时,这种技术能够将数据量分散到若干主机的redis实例上,进而减轻单台redis实例的压力。分片技术能够以更易扩展的方式使用多台计算机的存储能力和计算能力:
(1)从存储能力的角度,分片技术通过使用多台计算机的内存来承担更大量的数据,如果没有分片技术,那么redis的存储能力将受限于单台主机的内存大小。
(2) 从计算能力的角度,分片技术通过将计算任务分散到多核或者多台主机中,能够充分利用多核、多台主机的计算能力。
- Redis 集群通过多副本来提升可用性
- Redis主从复制模型:Redis集群使用了主从复制模型,每个节点都会有N-1个复制品。
1.12、文档数据库
-
文档数据库可存放并管理“文档”(document)。
文档是文档数据库中的主要概念,相当于键值数据库所存放的“值”。其格式可以是XML、JSON、BSON等。
这些文档具备自述性(self-describing), 呈现分层的树状数据结构 (hierarchical tree data structure), 可以包含映射表、集合和纯量值。
-
文档与文档数据库
数据库中的文档彼此相似,但不必完全相同。
文档数据库可视为其值可查的键值数据库。
-
MongoDB
MongoDB是一个基于分布式文件存储的数据库,高性能、易部署、易使用,存储数据方便。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
操作实例:
db.user.insert({ _id: 1001, name: ‘张三', description: ‘是一个学生', sex: ‘M', address: ‘北京通州', tags: [‘学霸’, ‘帅哥’, ‘有钱’, ‘渣’], school: { name: ‘北京邮电大学’, starttime: ‘2013’ } })
db.user.find({id:1001}) { id: 1001, name: ‘张三', description: ‘是一个学生', sex: ‘M', address: ‘北京通州', tags: [‘学霸’, ‘帅哥’, ‘有钱’, ‘渣’], school: { name: ‘北京邮电大学’, starttime: ‘2013’}} db.user.find({name:/^张.*/}) { id: 1001, name: ‘张三', …… }} { id: 1007, name: ‘张五', …… }} db.user.find({id:1001},{name:1}) { id: 1001, name: ‘张三' }}
-
MongoDB节点的作用:
mongos:路由服务器,数据库集群请求的入口,所有的请求都通过mongos进行协调,它负责把对应的数据请求转发到对应的shard服务器上。
config server:配置服务器,存储所有数据库元信息的配置。
shard:用来保存数据,保证数据的高可用性和一致性
replica set:备份,防止出现单节点故障导致数据库失效
-
mongodb分片的原理:
mongodb分片有三种角色:
①mongos:是整个分片架构的核心。数据库集群的入口,所有的请求都通过mongos进行协调,通常有多个mongos作为请求的入口,保证高可用。对客户端而言 不知道是否有分片,只需要把数据交给mongos。mongos本身没有任何数据,他也不知道该怎么处理这数据,去找config server。
②config server:配置服务器,存储集群所有节点、分片数据路的信息。默认需要配置3个Config Server节点,保证高可用。mongos本身并没有物理存储分片服务器和数据路由信息,只是缓存再内存里。第一次启动或者重启就会从config server加载配置信息。
③shard:真正的数据存储位置,可以看成是一个个副本集。
大致的工作流程:客户端提交数据,传给mongos进程,mongos查看配置服务器config server,知道了它包含的shard有哪些,由此把数据均衡分配给各个shard。
-
MongoDB分片的作用(不是重点,可以去理解):
mongodb分片就是将大型集合分割到不同的服务器上,它可以自动且均衡的分配数据。它一般是针对特别大的需求,比如一个集合存储非常的大,几百个G。分片到10个服务器之后,每个服务器维护几十个G的数据。如果不是集合非常的大,而是库非常的多,可以不使用分片,可以向mysql一样,把不同的库指定给不同的服务器就可以。
1.13、列族数据库
-
列族数据库的特点
采用聚合模型存储数据
数据类型单一
分散存储在GFS上
不通过Master甚至Bigtable即可访问数据
适用性:特别适合存储原始数据,对数据进行批量分析
1.14、图数据库
-
图数据库可存放实体及实体间关系。实体也叫“节点”(node),它们具 有属性(property)。可将节点视为应用程序中某对象的实例。
关系又叫“边” (edge),它们也有属性。边具备方向性(directional significance),而节点则按关系组织起来,以便在其中查找所需模式。
图数据库有很多种,如 Neo4J、Infinite Graph、OrientDB 和FlockDB、Titan
-
典型图数据库实例——OrientDB
-
记录(record)
读取和存储的最小单元。记录有四种类型:文档、字节流、顶点、边。
一个记录可以是一个文档,一个顶点或者一条边。
-
文档(Document)
文档是OrientDB中最灵活的记录类型。文档默认有类型,通过约束的模式来定义,但是也可以使用无模式的
-
顶点(Vertex)
图数据库中,最基本的数据单元就是节点,OrientDB中叫做顶点。顶点为数据库存储信息。还有一个单独的记录类型叫做边,来连接顶点。
顶点也是文档。因此可以包含嵌入式的记录和任意类型。
-
边(Edge)
在图模型中,连接两个节点的弧,OrientDB叫做边。 边是双向的,仅仅连接两个顶点。
边可以是常规的或者轻量级的。常规的边作为文档存储,而轻量级的边则不是。
-
记录ID(Record ID)
当OrientDB产生一条记录时,会自动分配一个唯一的单元标示,叫做Record ID,簇标示和位置组成的。格式如下:
#:.
• 簇标示: 这个数字表示记录所属的簇。正数表示记录是被持久化的,负数表示临时存储,出现在使用投影(projections)的查询的结果中。
• 位置: 这个数字表示了在簇中的记录的绝对位置。
-
类(Classes)
类的概念来自于面向对象编程体系。在OrientDB中,类定义记录,接近于关系数据库中的表。
类可以是无模式,全模式或者混合的。它们可以继承自其它类,构成一个类的树型体系。 子类继承父类,继承了所有的属性。
-
类的属性(Property)
OrientDB允许无模式的类,即类可以有也可以没有属性。但如果需要定义索引或者约束,属性是必须的。和关系数据库相比,如果类和表对应,那么属性就和列对应
-
属性约束
约束就是限制属性的取值。例如,类型,最大最小值,是否必须或者是否可为NULL。
-
簇(Cluster)
簇是存储记录的地方。每个类有自己的簇。一个类至少有一个簇,作为它的默认簇。一个类可以支持多个簇。当创建一个新类时,OrientDB会默认创建一个新的持久化簇,和类的名称一样,小写的。
-
分布式情况下不同的簇分布在不同的服务器,将数据库中的记录物理隔离,好处:
• 优化:针对一个类,只搜索部分簇,会大大提高查询速度
• 索引:好的分割,可以减少索引的使用
• 并行查询: 查询可以在多个磁盘上并行查询
• 分片: 可以在多个实例上存储大数据集。
2、Sql语句
2.1、定义基本表
-
建立一个“学生”表Student。
CREATE TABLE Student (Sno CHAR(5) , Sname CHAR(20) , Ssex CHAR(2) , Sage SMALLINT, Sdept CHAR(20) );
-
建立一个“课程”表Course。
CREATE TABLE Course (Cno CHAR(1) PRIMARY KEY, Cname CHAR(40) NOT NULL, Cpno CHAR(1), Ccredit SMALLINT, FOREIGN KEY Cpno REFERENCES Course(Cno) );
-
建立学生选课表SC。
CREATE TABLE SC (Sno CHAR(5), Cno CHAR(1) , Grade SMALLINT, PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno) );
2.2 、修改基本表
-
向Student表增加“入学时间”列,其数据类型为日期型。
ALTER TABLE Student ADD S_entrance DATE;
-
将年龄的数据类型由字符型**(假设原来的数据类型是字符型)**改为整数。
ALTER TABLE Student ALTER COLUMN Sage INT;
-
增加课程名称必须取唯一值的约束条件。
ALTER TABLE Course ADD UNIQUE(Cname);
2.3、删除基本表
-
删除Student表。
DROP TABLE Student CASCADE;
2.4、建立索引
-
在Student表的Sname(姓名)列上建立一个聚簇索引,而且Student表中的记录将按照Sname值的升序存放。
CREATE CLUSTER INDEX Stusname ON Student(Sname);
-
为学生-课程数据库中的Student,Course,SC三个表建立索引。其中Student表按学号升序建唯一索引,Course表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引。**
CREATE UNIQUE INDEX Stusno ON Student(Sno); CREATE UNIQUE INDEX Coucno ON Course(Cno); CREATE UNIQUE INDEX SCno ON SC(Sno ASC, Cno DESC);
-
删除Student表的Stusname索引。
DROP INDEX Stusname;
2.5、单表查询
(1)选择表中的若干列
-
查询全体学生的学号与姓名。
SELECT Sno, Sname FROM Student;
-
查询全体学生的姓名、学号、所在系。
SELECT Sname,Sno,Sdept FROM Student;
-
查询全体学生的详细记录。
SELECT * FROM Student;
SELECT Sno, Sname, Ssex, Sage, Sdept FROM Student;
方法二的前提是:列的显示顺序与其在基表中的顺序相同。
-
查询全体学生的姓名及其出生年份。
SELECT Sname, 2021-Sage FROM Student;
-
查询全体学生的姓名、出生年份和所在的院系,要求用小写字母表示所有系名。
SELECT Sname, ‘Year of Birth:’ , 2021-Sage,LOWER(Sdept) FROM Student;
-
使用列别名改变查询结果的列标题。
SELECT Sname NAME, ‘Year of Birth:’ BIRTH, 2021-Sage BIRTHDAY, LOWER(Sdept) DEPARTMENT FROM Student;
(2)选择表中的若干元组
-
查询选修了课程的学生学号。
消除取值重复的行——DISTINCT,如果没有指定DISTINCT关键词,则缺省为ALL。
SELECT Sno FROM SC;
SELECT DISTINCT Sno FROM SC;
-
查询计算机科学系全体学生的名单。
SELECT Sname FROM Student WHERE Sdept = ‘CS’;
-
查询所有年龄在20岁以下的学生姓名及其年龄。
SELECT Sname, Sage FROM Student WHERE Sage < 20;
-
查询考试成绩有不及格的学生的学号。
SELECT DISTINCT Sno FROM SC WHERE Grade < 60;
-
查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。
SELECT Sname, Sdept, Sage FROM Student WHERE Sage BETWEEN 20 AND 23;
-
查询年龄不在20~23岁之间的学生姓名、系别和年龄。
SELECT Sname, Sdept, Sage FROM Student WHERE Sage NOT BETWEEN 20 AND 23;
-
查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname, Ssex FROM Student WHERE Sdept IN (‘IS’, ‘MA’, ‘CS’);
-
查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别。
SELECT Sname, Ssex FROM Student WHERE Sdept NOT IN (‘IS’, ‘MA’, ‘CS’);
-
查询学号为95001的学生的详细情况。
匹配串为固定字符串
SELECT * FROM Student WHERE Sno LIKE ‘95001’;
这里可用“=” 取代LIKE;同样可用“!=”或“<>”取代NOT LIKE。
-
查询所有姓刘的学生的姓名、学号和性别。
匹配串为含通配符的字符串
SELECT Sname, Sno, Ssex FROM Student WHERE Sname LIKE ‘刘%’;
%代表任意长度(长度可以为0)的字符串
-
查询姓“欧阳”且全名为3个汉字的学生的姓名
SELECT Sname FROM Student WHERE Sname LIKE ‘欧阳_’;
-
查询名字中第2个字为“阳”字的学生的姓名和学号
SELECT Sname, Sno FROM Student WHERE Sname LIKE ‘ _阳%’;
-
查询所有不姓刘的学生姓名。
SELECT Sname FROM Student WHERE Sname NOT LIKE ‘刘%’;
_代表任意单个字符。在字符集为ASCII时一个汉字要占两个字符的位置。
-
**查询****DB_Design课程的课程号和学分。
使用换码字符将通配符转义为普通字符
SELECT Cno, Ccredit FROM Course WHERE Cname LIKE ‘DB\_Design’ ESCAPE ‘\’;
-
查询以“DB_”开头,且倒数第3个字符为i的课程的详细情况。
SELECT * FROM Course WHERE Cname LIKE ‘DB\_%i_ _’ ESCAPE ‘\’;
-
某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT Sno, Cno FROM SC WHERE Grade IS NULL;
-
查所有有成绩的学生学号和课程号。
SELECT Sno, Cno FROM SC WHERE Grade IS NOT NULL;
-
查询计算机科学系年龄在20岁以下的学生姓名。
SELECT Sname FROM Student WHERE Sdept=‘CS’ AND Sage<20;
(3)ORDER BY子句
-
查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT * FROM Student ORDER BY Sdept, Ssage DESC;
(4)聚集函数
-
查询学生总人数。
SELECT COUNT(*) FROM Student;
-
查询选修了课程的学生人数。
SELECT COUNT(DISTINCT Sno) FROM SC;
-
计算1号课程的学生平均成绩。
SELECT AVG(Grade) FROM SC; WHERE Cno=‘1’;
-
查询选修1号课程的学生最高分数。
SELECT MAX(Grade) FROM SC; WHERE Cno=‘1’;
-
查询学生95001选修课程的总学分数。
SELECT SUM(Ccredit) FROM SC Course WHERE Sno=‘95001’ AND SC.Cno=Course.Cno;
(5)GROUP BY子句
-
求各个课程号及相应的选课人数。
SELECT Cno, COUNT(Sno) FROM SC GROUP BY Cno;
该子句的作用对象是查询的中间结果表,如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件!
-
查询选修了3门以上课程的学生学号。
SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*)>3;
2.6、连接查询
(1)等值与非等值连接查询
比较运算符包括包括=、>、<、>=、<=、!=(或<>)等。连接运算符为=时,称为等值连接 ;使用其他运算符称为非等值连接。
-
查询每个学生及其选修课程的情况。
SELECT Student.* , SC.* FROM Student , SC WHERE Student.Sno = SC.Sno;
如果属性名在参加连接的各表中是唯一的,则可以省略表名前缀!
-
上题采用自然连接方式查询
SELECT Student.Sno, Sname, Ssex, Sage,Sdept, Cno, Grade FROM Student , SC WHERE Student.Sno = SC.Sno;
(2)自身连接
-
查询每一门课的间接先修课(即先修课的先修课)。
SELECT FIRST.Cno, SECOND.Cpno FROM Course FIRST, Course SECOND WHERE FIRST.Cpno = SECOND.Cno;
(3)外连接
普通连接操作只输出满足连接条件的元组。 外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出。
左外连接列出左边关系中所有的元组,右外连接列出右边关系中所有的元组
-
采用左外连接查询每个学生及其选修课程的情况。
SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade FROM Student LEFT OUT JOIN SC ON (Student.Sno=SC.Sno);
(4)复合条件连接
WHERE子句中含有多个连接条件称为复合条件连接。
-
查询选修2号课程且成绩在90分以上的所有学生。
SELECT Student.Sno, Sname FROM Student, SC WHERE Student.Sno = SC.Sno AND SC.Cno= ‘2’ AND SC.Grade > 90;
2.7、嵌套查询
将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中。
注意:子查询的SELECT语句中不能使用ORDER BY子句,ORDER BY子句只能对最终查询结果排序。
(1)带有IN谓词的子查询
-
查询与“刘晨”在同一个系学习的学生
-- 确定“刘晨”所在系名 SELECT Sdept FROM Student WHERE Sname = ‘刘晨’; -- 查找所有在IS系学习的学生 SELECT Sno, Sname, Sdept FROM Student WHERE Sdept = ‘IS’;
方法1:
SELECT Sno, Sname, Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname = ‘刘晨’);
方法2:
SELECT S1.Sno, S1.Sname, S1.Sdept FROM Student S1, Student S2 WHERE S1.Sdept = S2.Sdept AND S2.Sname = ‘刘晨’;
-
查询选修了课程名为“信息系统”的学生学号和姓名。
方法1:
SELECT Sno, Sname -- 最后在Student关系中取出Sno和Sname FROM Student WHERE Sno IN (SELECT Sno -- 然后在SC关系中找出选修了3号课程的学生学号 FROM SC WHERE Cno IN (SELECT Cno -- 首先在Course关系中找出“信息系统”的课程号,结果为3号 FROM Course WHERE Cname = ‘信息系统’ ) );
方法2:
SELECT Student.Sno, Sname FROM Student, SC, Course WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno AND Course.Cname=‘信息系统’;
(2)带有比较运算符的子查询
-
查询与“刘晨”在同一个系学习的学生
SELECT Sno, Sname, Sdept FROM Student WHERE Sdept = (SELECT Sdept FROM Student WHERE Sname = ‘刘晨’);
-
找出每个学生超过他选修课程平均成绩的课程号。
SELECT Sno, Cno FROM SC x WHERE Grade >= (SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno);
(3)带有ANY(SOME)或ALL谓词的子查询
子查询返回多值时要使用ANY(任意一个值)或ALL(所有值)谓词修饰符。
使用ANY或ALL谓词时必须同时使用比较运算符。
-
查询其他系中比计算机科学系某一学生年龄小的学生姓名和年龄。
SELECT Sname, Sage FROM Student WHERE Sage < ANY(SELECT Sage FROM Student WHERE Sdept=‘CS’) AND Sdept < > ‘CS’ ;
也可以用聚集函数实现:
SELECT Sname, Sage FROM Student WHERE Sage < (SELECT MAX(Sage) FROM Student WHERE Sdept=‘CS’) AND Sdept < > ‘CS’ ;
-
查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
SELECT Sname, Sage FROM Student WHERE Sage < ALL(SELECT Sage FROM Student WHERE Sdept=‘CS’) AND Sdept < > ‘CS’ ;
也可以用聚集函数实现:
SELECT Sname, Sage FROM Student WHERE Sage < (SELECT MIN(Sage) FROM Student WHERE Sdept=‘CS’) AND Sdept < > ‘CS’ ;
tips: 用聚集函数实现子查询通常比直接用ANY或ALL查询效率要高!
(4)带有EXISTS谓词的子查询
带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
若内层查询结果非空,则外层的WHERE子句返回真值。
若内层查询结果为空,则外层的WHERE子句返回假值。
由EXISTS引出的子查询,其目标列表达式通常都用*
-
查询所有选修了1号课程的学生姓名。
SELECT Sname FROM Student WHERE EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=‘1’);
也可以用连接运算符实现:
SELECT Sname FROM Student, SC WHERE Student.Sno=SC.Sno AND SC.Cno= '1';
-
查询没有选修1号课程的学生姓名。
SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=‘1’);
-
查询与“刘晨”在同一个系学习的学生
SELECT Sno, Sname, Sdept FROM Student S1 WHERE EXISTS (SELECT * FROM Student S2 WHERE S2.Sdept = S1.Sdept AND S2.Sname = ‘刘晨’);
tips:所有带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS谓词的子查询等价替换。
一些带EXISTS或NOT EXISTS谓词的子查询不能被其他形式的子查询等价替换。
2.7、集合查询
参加集合操作的各查询结果的列数必须相同。
对应项的数据类型也必须相同。
-
查询计算机科学系的学生及年龄不大于19岁的学生。
SELECT * FROM Student WHERE Sdept=‘CS’ UNION SELECT * FROM Student WHERE Sage <= 19;
UNION:将多个查询结果合并起来时,系统会自动去掉重复元组。
UNION ALL:将多个查询结果合并起来时,会保留重复元组 。
其他方法:
SELECT DISTINCT * FROM Student WHERE Sdept= 'CS' OR Sage<=19;
-
查询选修了课程1或者选修了课程2的学生。
方法1:
SELECT Sno FROM SC WHERE Cno=‘1’ UNION SELECT Sno FROM SC WHERE Cno=‘2’;
方法2:
SELECT DISTINCT Sno FROM SC WHERE Cno=‘1’ OR Cno=‘ 2 ‘;
-
查询计算机科学系的学生与年龄不大于19岁的学生的交集。
方法1:
SELECT * FROM Student WHERE Sdept=‘CS’ INTERSECT SELECT * FROM Student WHERE Sage<=19;
方法2:
SELECT * FROM Student WHERE Sdept= ‘CS’ AND Sage<=19;
-
查询选修课程1的学生集合与选修课程2的学生集合的交集。
方法1:
SELECT Sno FROM SC WHERE Cno=‘1’ INTERSECT SELECT Sno FROM SC WHERE Cno=‘2’;
方法2:
SELECT Sno FROM SC WHERE Cno=' 1 ' AND Sno IN (SELECT Sno FROM SC WHERE Cno=‘2’);
-
查询计算机科学系的学生与年龄不大于19岁的学生的差集。
方法1:
SELECT * FROM Student WHERE Sdept=‘CS’ EXCEPT SELECT * FROM Student WHERE Sage<=19;
方法2:
SELECT * FROM Student WHERE Sdept= 'CS' AND Sage>19;
2.8、 插入数据
(1)插入元组
-
将一个新学生元组(学号:95020;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。
INSERT INTO Student (Sno, Sname, Ssex, Sdept, Sage) VALUES (‘95020’, ‘陈冬’, ‘男’, ‘IS’, 18);
-
插入一条选课记录**( ‘95020’, ‘1’ )****。**
INSERT INTO SC (Sno, Cno) VALUES (‘95020’, ‘1’);
RDBMS将在新插入记录的Grade列上自动地赋空值。因此也可以这么写:
INSERT INTO SC VALUES (‘95020’, ‘1’, NULL);
(2)插入子查询结果
SELECT子句目标列必须与INTO子句匹配:
-
对每一个系,求学生的平均年龄,并把结果存入数据库。
-- 在数据库中建立一个新表(系名,学生平均年龄): CREATE TABLE Dept_age (Sdept CHAR(15) AVG_age SMALLINT); -- 对Student表按系分组求平均年龄,再把系名和平均年龄存入新表中。 INSERT INTO Dept_age (Sdept, AVG_age) SELECT Sdept, AVG(Sage) FROM Student GOURP BY Sdept;
2.9、修改数据
(1) 修改某一个元组的值
-
将学生95001的年龄改为22岁。
UPDATE Student SET Sage =22 WHERE Sno=‘95001’ ;
(2)修改多个元组的值
-
将所有学生的年龄增加1岁。
UPDATE Student SET Sage =Sage+1;
(3)带子查询的修改语句
-
将计算机科学系全体学生的成绩置零。
UPDATE SC SET Grade=0 WHERE ‘CS’= (SELECT Sdept FROM Student WHERE Student.Sno=SC.Sno);
2.10、删除数据
-
删除学号为95001的学生信息。
FROM DELETE Student WHERE Sno=‘95001’ ;
-
删除学号为95020的学生记录。
DELETE FROM Student WHERE Sno=‘95020’ ;
-
删除所有的学生选课记录。
DELETE FROM SC;
-
删除计算机科学系所有学生的选课记录。
DELETE FROM SC WHERE ‘CS’= (SELECT Sdept FROM Student WHERE Student.Sno=SC.Sno);
2.11、建立视图
-
建立信息系学生的视图。
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept=‘IS’;
RDBMS执行CREATE VIEW语句的结果只是把视图定义存入数据字典,并不执行其中的SELECT语句。只是在对视图查询时,才按视图的定义从基本表中将数据查出。
-
建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生。
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept=‘IS’ WITH CHECK OPTION;
-
建立信息系选修了1号课程的学生视图。
CREATE VIEW IS_S1 (Sno, Sname, Grade) AS SELECT Student.Sno, Sname, Grade FROM Student, SC WHERE Sdept=‘IS’ AND Student.Sno = SC.Sno AND SC.Cno=‘1’ ;
-
建立信息系选修了1号课程且成绩在90分以上的学生的视图。
CREATE VIEW IS_S2 AS SELECT Sno, Sname, Grade FROM IS_S1 WHERE Grade>=90;
-
定义一个反映学生出生年份的视图。
CREATE VIEW BT_S (Sno, Sname, Sbirth) AS SELECT Sno, Sname, 2010-Sage FROM Student;
-
将学生的学号及他的平均成绩定义为一个视图。
CREATE VIEW S_G (Sno, Gavg) AS SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;
-
将Student表中所有女生记录定义为一个视图。
CREATE VIEW F_Student (F_Sno, name, sex, age, dept) AS SELECT * FROM Student WHERE Ssex=‘女’;
2.12、删除视图
-
删除视图IS_S1
DROP VIEW IS_S1;
2.13、查询视图
用户角度:查询视图与查询基本表相同!
-
在信息系学生的视图中找出年龄小于20岁的学生。
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept=‘IS’;
SELECT Sno, Sage FROM IS_Student WHERE Sage < 20 ;
视图消解转换后:
SELECT Sno, Sage FROM Student WHERE Sdept=‘IS’ AND Sage<20 ;
-
查询选修了1号课程的信息系学生。
SELECT IS_Student.Sno, Snames FROM IS_Student, SC WHERE IS_Student.Sno=SC.Sno AND SC.Cno=‘1’;
-
在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩。
SELECT * FROM S_G WHERE Gavg >= 90 ;
2.14、更新视图
用户角度:更新视图与更新基本表相同!
-
将信息系学生视图IS_Student中学号95002的学生姓名改为“刘辰”。
UPDATE IS_Student SET Sname =‘刘辰’ WHERE Sno=‘95002’ ;
视图消解转换后:
UPDATE Student SET Sname =‘刘辰’ WHERE Sno=‘95002’ AND Sdept=‘IS’;
-
向信息系学生视图**IS_Student中插入一个新的学生记录:95029,赵新,20岁。
INSERT INTO IS_Student VALUES (‘95029’, ‘赵新’, 20) ;
转换为对基本表的更新:
INSERT INTO Student (Sno, Sname, Sage, Sdept) VALUES (‘95029’, ‘赵新’, 20, ‘IS’) ;
-
删除信息系学生视图IS_Student中学号为95029的记录。
DELETE FROM IS_Student WHERE Sno=‘95029’ ;
转换为对基本表的更新:
DELETE FROM Student WHERE Sno=‘95029’ AND Sdept=‘IS’;
3、NoSQL实验
3.1、Redis
3.1.1、单机版
-
解压
tar -zxvf redis-6.0.4.tar.gz
-
移动redis目录到 /usr/local/redis目录下
mv redis-6.2.6 /usr/local/redis
-
编译并执行redis
cd /usr/local/redis #进入指定目录 make #编译,如果报错则make MALLOC=libc make install #安装
-
配置环境变量
在命令行输入下列命令
vim /etc/profile #命令,进入配置文件
并在文件后添加redis的安装路径到环境变量中。
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:REDIS_HOME/src
激活
source /etc/profile
-
启动redis服务,执行命令,单机版即完成
redis-serve
3.1.2、集群(伪分布式)
- 在opt目录下新建目录并创建6个redis节点, 一个redis节点在主机上就是一个redis进程 ,通过cp命令复制redis配置文件
cd /opt
mkdir redis
cd redis
cp /usr/local/redis/redis.conf redis1.conf //复制6份,每份命名要区分
-
修改配置文件
vim redis1.conf //以节点去为例
修改项依次为:
bind 0.0.0.0 //为了别人能访问,这里暴力的监听了所有的地址 protect-mode no //关闭保护模式 port 7001 //这个自行设置,确保每个节点不一样 daemonize yes //redis后台运行 pidfile /var/run/redis_7001.pid //修改pidfile文件名,不必须 logfile "/opt/redis/log7001.log" //修改日志标识和路径 dbfilename dump7001.rdb //修改数据库名 cluster-enabled yes //开启集群 把注释#去掉 cluster-config-file nodes_7001.conf //集群的配置 配置文件首次启动自动生成 cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置,不必须 appendonly yes //这里跟redis持久化的机制有关系
其余节点配置同理,注意对应端口号即可
-
测试节点是否正常启动
redis-server redis1.conf //启动节点服务 ps aux|grep redis //查看进程
-
集群配置
执行命令:
redis-cli -p 7001 //进入节点1
进入节点之后开始采用meet命令连接节点
cluster meet 127.0.0.1 7002 cluster meet 127.0.0.1 7003 cluster meet 127.0.0.1 7004 cluster meet 127.0.0.1 7005 cluster meet 127.0.0.1 7006
之后exit退出节点,输入以下命令即可完成集群设置
redis-cli –cluster fix 127.0.0.1:7001
-
连接集群
redis-cli -c -p 7001
3.1.3、数据库操作
- string类型数据
-
设置数据 set key value
set name 'fws'
-
查看数据情况 get key
get name
-
删除数据 del key
del name
-
添加多个数据 mset key1 value1 key2 value2…
mset name "mlx" age 18
- list类型
- 添加数据 rpush key value
rpush list 2022
- 头部添加数据 lpush key value
- 查看数据 lrange key start stop ,start 开始下标 , stop 结束下标 ,也可以 通过lindex key index 查看某个数据,index为数据对应索引,索引从0开始。
- 修改数据 lset key index value
- 删除数据 , rpop key 尾部删除 , lpop key 头部删除
- 查看长度 llen key
- Hash类型
- 添加数据 hset key field value
hset myhash field1 "hello" field2 "redis"
- 查看域值 hget key filed ,hgetall key 查看所有的域值
hget myhash field1
hgetall myhash //即得到所有的key-value
- 查看所有的value : hvals key
hvals hash //只得到value
- 删除: hdel key field — 删除域和值
hdel myhash test1
-
删除表:del key
del myhash
-
Set类型
set类型 为无序字符集合,元素具有唯一性,不重复
- 添加数据 sadd key member …
sadd num 1 2 3
- 查看数据: smembers key
smembers num
-
随机删除: spop key
-
指定删除 : srem key member
srem num 3 //删除3
3.2、MongoDB单机安装、集群搭建及使用
3.2.1、下载
- 配置MongoDB的yum源
cd /etc/yum.repos.d
vim mongodb-org-4.0.repo
[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/5.0/x86_64/
gpgcheck=0 #gpgcheck=0, 是为了省去gpg验证
enabled=1 #采用阿里巴巴的镜像安装,采用的是5.0的版本
-
安装
yum -y install mongodb-org
可通过以下命令获取安装位置:
whereis mongod
3.2.2、单机版
- 进入到/opt目录下,在该目录下创建mongo文件夹
cd /opt
mkdir mongo
-
拷贝配置文件并配置端口号
cp /etc/mongod.conf 11.conf
net: port: 9011 bindIp: 0.0.0.0
-
激活并启动mongo服务
mongod -f 11.conf mongo --port 9011
3.2.3、集群
-
这里采用一台虚拟机做一个伪分布式的集群,其原理与完全分布式的原理一致。 首先集群内要有6台机器,一共分了6个副本集,S1,S2,S3,S4,S5,S6,这里一个副本集分了三个 节点,同一个副本集中的节点有一个主节点和两个从节点,从节点的数据与主节点的一致。OS为 mongos进程(路由服务器);C为config server(配置服务器),一共设置了三个配置服务器。整体 设计如下图所示:
-
在单机版创建的mongo文件夹下进行操作,为了模拟6台机器,在该目录下创建6个文件夹,用以存储 各个模拟机器的日志文件等信息。其中1号文件夹代表1号机器,2号文件夹代表2号机器,以此类推,同 时在每个模拟机器文件夹下创建进程文件夹,用以存储机器下副本集、配置服务器、路由服务器等相关 信息。如1号机器下创建1、2、3、4四个子文件夹,分别对应S1、S2、S3、OS。以1号机器为例,这里 主要涉及的命令就是:
mkdir 1
cd 1
mkdir 1
mkdir 2
mkdir 3
mkdir 4
-
复制配置文件,采用cp命令复制,例子如下:
cp 11.conf 12.conf cp 11.conf 13.conf cp 11.conf OS.conf cp 11.conf 21.conf cp 11.conf 22.conf
3.2.4、副本集配置文件设置
-
副本集配置文件的设置,以1号机器下的1号节点为例,通过vim命令进入修改。 需要更改的配置如下:
path:/opt/mongo/1/1/mongod.log dbpath:/opt/mongo/1/1/mongod.pid pidFilePath:/opt/mong/1/1/mongod.pid port:9011 replSetName: S1 clusterRole: shardsvr
3.2.5、配置服务器的配置文件设置
-
对应24.conf、34.conf和44.conf文件,与副本集的配置设置不同的是:
replSetName: C clusterRole: configsvr
3.2.6、路由服务器的配置文件设置
-
只有一个对应的os.conf文件,与其他配置文件不同的是:
注释掉storage和时replSetName模块 sharding: configDB:C/192.168.253.137:9024 #对应本机ip和配置服务器的端口号
3.2.7、启动mongod
-
可以逐个启动,也可以写一个脚本:
mongod -f 11.conf
-
可以通过进程命令查看是否启动:
ps aux|grep mongod
3.2.8、分组
- 按照之前设计图上分组 ,以S1副本集对应分组为例,首先进入mongo服务,输入以下命令:
mongo --port 9011
进入mongo服务后,首先进入该组中任意节点,声明其组内成员,并运行。
cfg={_id:"S1", members:[{_id:0,host:'192.158.292.137:9011'},
{_id:1,host:'192.158.292.137:9021'}, {_id:2,host:'192.158.292.137:9031'}]};
rs.initiate(cfg)
其他副本集和配置服务器分组同理
3.2.9 启动并连接mongos
- 输入以下命令启动并连接mongos:
mongos -f os.conf
mongo --port 9014
3.2.10、增加分片
- 均在mongos的命令行中进行操作 :
sh.addShard("S1/192.168.253.137:9011")
sh.addShard("S2/192.168.253.137:9022")
sh.addShard("S3/192.168.253.137:9033")
sh.addShard("S4/192.168.253.137:9043")
sh.addShard("S5/192.168.253.137:9053")
sh.addShard("S6/192.168.253.137:9063")
- 使用命令查看分片情况 :
sh.status()
3.2.11、使用数据库
- 创建新的数据库并进行操作
use admin #转换到admin数据库下面
-
新建数据库:
db.runCommand({enableSharding:"stumis"}) #stumis数据库 db.runCommand({shardCollection:"stumis.students",key{"_id":"hashed"}}) #studemts集合,针对id用hash的方式做分片。
-
查看数据库
show dbs
-
批量插入数据
use stumis for(var i=1; i<=100; i++) { db.students.insert( {name:"S"+i,age:i});}
-
新建数据库 use DATABASE_NAME
use student
-
删除数据库 db.dropDatabase()
use runoob db.dropDatabase()
-
创建集合 db.createCollection(name, options)
db.createCollection("course")
-
删除集合 db.collection.drop()
db.course.drop() #删除course集合
-
插入文档 db.COLLECTION_NAME.insert(document)或
db.COLLECTION_NAME.save(document)#插入文档到MongoDB的student数据库的course集合中 db.course.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
-
查看已插入文档
#查看course集合下的文档 db.course.find() #pretty() 方法以格式化的方式来显示所有文档。 db.course.find().pretty()
-
更新文档 update
#将course集合中的标题改为MongoDB db.course.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
-
删除文档 remove
#移除 title 为 'MongoDB 教程' 的文档: db.course.remove({'title':'MongoDB 教程'})
3.3、Hbase
3,3,1、基本命令
- 创建一个表
# 表名 列族1 列族2
create 'Rumenz','user','userInfo'
- 查看数据库的表
list
- 添加数据
#表名 rowkey 列族:字段名 值
put 'Rumenz','001','user:name','入门小站'
put 'Rumenz','001','user:type','1'
- 查询记录行数
count 'Rumenz'
- 通过Row key查询记录
#表名 Row key 列族
get 'Rumenz','001','user'
- 通过Row key和列族查询数据
#表名 Row key 列族
get 'Rumenz','001','user'
- 查询表中所有的记录
# 表名
scan 'Rumenz'
- 只查看某一列的数据
scan 'Rumenz',{COLUMN=>'user:name'}
- 只查看某一列族的数据
scan 'Rumenz',{COLUMN=>'user'}
- 分页查询
```powershell
#STARTROW开始行,LIMIT=>1 取一条数据,VERSIONS=1 查询最新版本
scan 'Rumenz',{STARTROW=>'001',LIMIT=>1,VERSIONS=1}
```
- 删除某一列中的某一列值
```powershell
#user:name 为字段名
delete 'Rumenz','001','user:name'
```
- 删除某一行的值(通过Row key)
```powershell
#001是Row key
deleteall 'Rumenz','001'
```
-
更新数据
put 'Rumenz','002','user:name','新值'
-
增加列族
```powershell
alter 'Rumenz','depart'
```
- 删除列族
```powershell
alter 'Rumenz','delete'=>'depart'
```
- 删除表
```powershell
drop 'RumenzNew'
```
- 查看某个表是否存在
```powershell
exists 'RumenzNew'
```
- 查看表结构
```powershell
desc 'RumenzNew'
```
TABASE_NAME
use student
-
删除数据库 db.dropDatabase()
use runoob db.dropDatabase()
-
创建集合 db.createCollection(name, options)
db.createCollection("course")
-
删除集合 db.collection.drop()
db.course.drop() #删除course集合
-
插入文档 db.COLLECTION_NAME.insert(document)或
db.COLLECTION_NAME.save(document)#插入文档到MongoDB的student数据库的course集合中 db.course.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
-
查看已插入文档
#查看course集合下的文档 db.course.find() #pretty() 方法以格式化的方式来显示所有文档。 db.course.find().pretty()
-
更新文档 update
#将course集合中的标题改为MongoDB db.course.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
-
删除文档 remove
#移除 title 为 'MongoDB 教程' 的文档: db.course.remove({'title':'MongoDB 教程'})
3.3、Hbase
3,3,1、基本命令
- 创建一个表
# 表名 列族1 列族2
create 'Rumenz','user','userInfo'
- 查看数据库的表
list
- 添加数据
#表名 rowkey 列族:字段名 值
put 'Rumenz','001','user:name','入门小站'
put 'Rumenz','001','user:type','1'
- 查询记录行数
count 'Rumenz'
- 通过Row key查询记录
#表名 Row key 列族
get 'Rumenz','001','user'
- 通过Row key和列族查询数据
#表名 Row key 列族
get 'Rumenz','001','user'
- 查询表中所有的记录
# 表名
scan 'Rumenz'
- 只查看某一列的数据
scan 'Rumenz',{COLUMN=>'user:name'}
- 只查看某一列族的数据
scan 'Rumenz',{COLUMN=>'user'}
- 分页查询
```powershell
#STARTROW开始行,LIMIT=>1 取一条数据,VERSIONS=1 查询最新版本
scan 'Rumenz',{STARTROW=>'001',LIMIT=>1,VERSIONS=1}
```
- 删除某一列中的某一列值
```powershell
#user:name 为字段名
delete 'Rumenz','001','user:name'
```
- 删除某一行的值(通过Row key)
```powershell
#001是Row key
deleteall 'Rumenz','001'
```
-
更新数据
put 'Rumenz','002','user:name','新值'
-
增加列族
```powershell
alter 'Rumenz','depart'
```
- 删除列族
```powershell
alter 'Rumenz','delete'=>'depart'
```
- 删除表
```powershell
drop 'RumenzNew'
```
- 查看某个表是否存在
```powershell
exists 'RumenzNew'
```
- 查看表结构
```powershell
desc 'RumenzNew'
```