数据库的基本概念

数据库和数据库实例

数据库(Database)指的是物理操作系统文件或者磁盘数据块的集合,比如数据文件、索引文件、结构文件等。并非所有的数据库系统都是基于文件的,也有直接把数据写入数据存储的形式。

数据库实例(Database Instance)
实例指的是操作系统中一系列的进程以及为这些进程所分配和使用的内存块。数据库实例是访问数据库的通道,通常来说一个数据库实例对应了一个数据库。
在这里插入图片描述
多实例
除了单实例外,还有多实例,多实例指的是多个数据库实例对应一个数据库,多实例操作可以充分的利用硬件资源,让服务器性能最大化。
在这里插入图片描述
分布式集群
集群就是一组相互独立的服务器,通过高速的网络组成一个计算机系统。
分布式每个服务器中都可能有数据库的一份完整副本,或者部分副本,所有服务器通过网络互相连接,共同组成一个完整的、全局的逻辑上集中、物理上分布的大型数据库。
在这里插入图片描述

数据库连接和会话

数据库连接(connection)
物理层面的通信连接,指的是一个通过网络建立的客户端和专有服务器(Dedicated Server)或调度器(Shared Server)的一个网络连接。
建立连接时候指定连接参数,如服务器主机名或ip,端口号,连接用户名和口令等。
在这里插入图片描述

数据库会话(session)
客户端和数据库之间通信的逻辑概念。
通信双方从开始通信到通信结束期间的一个上下文(Context)。这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器、对应的应用程序进程号、对应的用户登录等信息。
会话(Session) 是和连接(Connection)是同时建立的,两者是对同一件事情不同层次的描述。

数据库连接池
频繁的建立和关闭数据库连接,会使得对连接资源的分配和释放成为数据库的瓶颈,从而降低数据库系统的性能。
连接池:数据库连接的附庸,连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。
加粗样式

Schema

Schema是数据库形式语言描述的一种结构,是对象的集合
在这里插入图片描述
table_a是名称相同的表,因为属于不同的schema,所以可以名称相同,而实际上可能存储不同的数据,具有不同的结构,在访问同名表的时候,要指定shcema名称来明确指向目标表:
select * from schema2.table_a;
明确要访问的是schema2下面的table_a的表

表空间 (Tablespace)

表空间是数据库的逻辑划分,一个表空间只能属于一个数据库。所有的数据库对象都存放在指定的表空间中。但主要存放的是表, 所以称作表空间。
表空间是由一个或者多个数据文件组成,通过表空间定义数据库对象文件的存放位置。数据库中所有对象在逻辑上都存放在表空间中。在物理上储存在表空间所属的数据文件中。
在这里插入图片描述
系统内置表空间
GaussDB 100创建时,系统预定义6个表空间

表空间说明
SYSTEM存放GaussDB 100的元数据
TEMP当用户的SQL语句需要磁盘空间来完成某个操作时,GaussDB 100数据库会从TEMP表空间分配临时段。
UNDO存放UNDO数据
USERS默认的用户表空间,创建新用户且没有指定表空间时,该用户的所有信息会放入USE表空间中
TEMP2存放NOLOGGING表数据
TEMP2_UNDO存放NOLOGGING表的Undo数据

SYTEM表空间:为保证数据库运行稳定,建议不要在SYSTEM表空间存放用户数据。SYSTEM表空间默认不自动扩展,如果SYSTEM表空间用满,应及时增加数据文件或扩展表空间。
TEMP表空间:SQL语句中间结果集,以及用户常见的临时表都会使用到TEMP表空间。
UNDO表空间:当执行DML(INSERT,UPDATE和DELETE等)操作时,将执行操作之前的旧数据写入UNDO表空间。其主要作用包括事务回滚、数据库实例恢复、读一致性、闪回查询。

表(table)

指的是一系列二维数据的集合,用来代表和储存数据对象之间的关系。表中的每一行称为一个记录,由若干个字段组成,字段也称为域,表中的每一列为一个字段,每个字段包含2个属性:列名和数据类型。
在这里插入图片描述
表中能存放的记录理论上是没有限制的,但是物理上可能会收到存储或者系统等方面的限制。

临时表
临时表用来保存一个会话或者一个事务中需要的数据。当会话退出或者用户提交和回滚事务的时候,临时表的数据自动清空,但表结构仍然存在。临时表中的数据是临时的,过程性的,不需要和普通数据表那样永久保留的。
临时表又分

会话级临时表临时表中的数据只在会话生命周期之中存在,当用户退出会话结束的时候,自动清除临时表中数据。
事务级临时表临时表中的数据只会在一个事务中,当事务一旦提交或者回滚后,临时表中的数据就会被自动清空,默认创建事务级别临时表。

表的储存方式
按照数据的储存方式分为了:行储存、列储存。
行存储表不同列同一行的数据物理存储也在一起,INERT和UPDAT的时候能够一次性写入记录,但是选择查询的时候,即便只查询其中的几列,所有数据也都会被读取;
列存储在写入数据的时候要把记录先拆开,一行记录被拆开多列,然后相同列的数据保存在物理临近的区域,所以在列存储模式下,一行记录写入次数明显比行存储多,这种写入次数的增加导致insert和update操作的时候,列存表相对开销比较大,性能相对差一些。
但是在查询的时候,如果只是查询整个表中很少的字段,对于行存也要把整个记录完全读出,不需要的列也会被读取出来,然后再内存中消除这些不需要的冗余列。
而对于列存储表,查询的时候,只要扫描涉及到的列,然后进行读取就可以,所以IO扫描和读取范围都要小很多。
列存储查询可以剔除无关的列,当查询只有少量列时,可以极大的减少查询的数据量,提高查询速度

储存方式的选择
列储存适合统计分析类查询,适合OLAP场景,数据挖掘等大量查询的应用。
行储存适合点查询(返回记录少,基于索引的简单查询),适合OLTP场景,大量的写操作,数据增删改操作较多的场景。

NOLOGGING表
指的是不记录Redo日志的日志表,并且日志量减少能够提高数据写性能,但是没有Redo日志,一旦出现故障,数据库重启后就无法进行恢复(Recover)操作。
Redo日志记录的是数据被修改后的值,可以用来恢复未写入data file的已成功事务更新的数据,例如:某一事务的事务序号为T1,其对数据X进行修改,设X的原值是5,修改后的值为15,那么Redo日志为<T1, X, 15>,如果系统发生故障时候,X修改的操作丢失,X仍然为5,那么重启后,可以根据Redo日志,再做一次修改操作,把X的值修改成15。

分区(Partition)

分区表是将大表的数据分成许多小的数据子集,称为分区。

范围分区表将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。这种分区方式是最为常用的,并且分区键经常采用日期,例如将销售数据按照月份进行分区。
列表分区表将庞大的表分割成小的、易于管理的小块。
哈希分区表在很多情况下,用户无法预测某个列上的数据变化范围,因而无法实现创建固定数量的范围分区或列表分区。在这种情况下,哈希分区提供了一种在指定数量的分区中均等地划分数据的方法,写入表中的数据均匀地分布在各个分区中,用户无法预测数据将被写入哪个分区中。
间隔分区表间隔分区表是一种特殊的范围分区表。对于普通的范围分区,用户预先创建了多少个分区,如果插入不在该分区的数据时,数据库会报错。这种情况下,用户可以手动添加分区,也可以使用间隔分区。

分区的好处:改善查询性能、增强可用性、方便维护、均衡I/O。

分区剪枝的原理
分区剪枝指的是对分区对象的查询可以仅仅搜索自己关系的分区,来提高查询效率,例如整个表包含了10年数据,没有分区表就要扫描所有10年的数据计算结果、而分区表只要扫描1年的分区表数据就可以。
在这里插入图片描述
例如上图SQL语句,通过select查询2019年6月到7月间的销售总额。

数据分布

GaussDB 100分布式数据库的数据表是分散在所有数据节点(DataNode,DN)上的,所以创建表的时候需要指定分布列。

分布方式说明
Hash表数据通过Hash方式散列到集群中的所有DN。
Replication集群中每一个DN都有一份全量表数据。
List表数据通过List方式分布到指定DN节点上。
Range表数据通过Range方式分布到指定DN节点上。

复制(Replication)适合于记录集较小的表,表中数据在各节点上完全复制,各DN都拥有全量数据,Hash/List/Range这三种方式适合数据量较大的表。

数据类型

在这里插入图片描述
浮点型:数据类型real和double是不准确的、牺牲精度的数字类型。不准确意味着一些数值不能准确地转换成内部格式并且是以近似的形式存储的,因此存储后再把数据打印出来可能显示一些缺失。
所以在金融计算对精度有严格要求的应用中,数据类型应当首选decimal,numeric这种精度数据类型。char类型是定长字符串,当插入的字符少于设定的长度是,会自动在后面补足空白

数据类型设计建议
尽量使用高效数据类型、尽量使用执行效率比较高的数据类型、尽量使用短字段的数据类型、使用一致的数据类型。
当多个表存在逻辑关系时,表示同一含义的字段应该使用相同的数据类型。
对于字符串数据,建议使用变长字符串数据类型,并指定最大长度。

视图 (View)

视图与基本表不同,并不是物理上实际存在的,是一个虚表。视图就像一个窗口,透过它可以看到数据库中用户感兴趣的数据及变化。视图每次被引用的时候都会运行一次。

索引 (Index)

索引提供指向存储在表的指定列中的数据值的指针,如同图书的目录,能够加快表的查询速度,但同时也增加了插入、更新和删除操作的处理时间。
在创建索引时,以下建议作为参考:
1、在经常需要搜索查询的列上创建索引,可以加快搜索的速度。
2、在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构。
3、在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的。
4、在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。
6、在经常使用WHERE子句的列上创建索引,加快条件的判断速度。
为经常出现在关键字ORDER BY、GROUP BY、DISTINCT后面的字段建立索引。

有效索引
创建索引 ≠ 索引一定被使用,索引创建成功后,系统会自动判断何时引用索引。当系统认为使用索引比顺序扫描更快时,就会使用索引。索引创建成功后,必须和表保持同步以保证能够准确地找到新数据,这样就增加了数据操作的负荷。需要定期删除无用的索引。
可以通过使用explain语句来查看执行计划来判断是否使用索引。

索引方式描述
唯一索引可用于约束索引属性值的唯一性,或者属性组合值的唯一性。
多字段索引一个索引可以定义在表中的多个属性上。
部分索引建立在一个表的子集上的索引,这种索引方式只包含满足条件表达式的元组。
表达式索引索引建立在一个函数或者从表中一个或多个属性计算出来的表达式上。表达式索引只有在查询时使用与创建时相同的表达式才会起作用。

约束

数据的完整性是指数据的正确性和一致性,可以通过定义表时定义完整性约束,完整性约束是一种规则,本身不占用数据库空间,完整性约束和表结构定义一起保存在数据字典中。
在这里插入图片描述
常见的约束类型
唯一性和主键约束(UNIQUE/PRIMARY KEY)
外键约束(FOREIGN KEY)
检查约束(CHECK)
非空约束(NOT NULL)
默认约束(DEFAULT)

唯一性:当字段中所有取值不会出现重复记录的时候,可以给对应字段增加唯一性约束,例如身份证字段,员工工号字段,如果一个表中没有任何唯一性约束,那么表中的记录是可以出现重复记录的。
非空(NOT NULL):如果当前字段从业务含义上说不应当出现空值或者未知数据的话,就可以增加NOTNULL 约束,保证插入的数据都是非空的数据。
默认约束:当insert数据的时候,如果没有给定取值,那么使用默认约束,就会给一个默认的初始值,比如会员等级分,初始会员可以给等级分的默认值为0

如果使用default约束,实际上是针对一些意外的情况默认赋值了,这种默认值可能会隐藏一些潜在的问题。所以对于OLAP系统来说,default约束要慎用或者少用,oltp系统来说使用率较高

事务(Transaction)

数据库中的数据是共享资源,允许多用户同时访问相同的数据。当多个用户同时对一段数据进行增删改的操作的时候,如果不采取任何措施,就会造成数据异常,事务就是防止这种情况的发生而产生的概念。
事务是用户定义的数据操作系列,这些操作作为一个完整的工作单元执行。一个事务内的所有语句作为一个整体,要么全部执行,要么全部不执行。
比如A账户给B账户转账1000元,第一个操作:A账户-1000,第二个操作:B账户+1000,转账的两个操作必须通过事务来保证全部操作成功,或者全部失败。
事务结束的标记有两个,正常结束,COMMIT(提交事务)。异常结束,ROLLBACK(回滚事务)。

事务的处理模型分为两类:

显式事务事务有显式的开始和结束标记
隐式事务每一条数据操作语句都自动地成为一个事务

GaussDB 100是OLTP数据库,采用的是显式事务处理模型,但没有提供显式定义事务开始的语句,它把第一个可执行的SQL作为事务的开始。所以它只提供了结束语句,commit和rollback。GaussDB 100默认不自动提交,需要显式COMMIT才会提交事务,否则会话时会丢失记录。

事务特征-ACID

原子性(Atomicity)事务是数据库的逻辑工作单位,事务中的操作,要么都做,要么都不做。
一致性(Consistency)事务的执行结果必须是使数据库从一个一致性状态转到另一个一致性状态。
隔离性(Isolation)数据库中一个事务的执行不能被其他事务干扰。即一个事务的内部操作及使用的数据对其他事务是隔离的,并发执行的各个事务不能相互干扰。
持久性(Durability)事务一旦提交,对数据库中数据的改变是永久的。提交后的操作或者故障不会对事务的操作结果产生任何影响。

数据不一致情况

“Dirty”Reads(脏读)
一个事务读取到了其他事务中还没有提交(Committed)的数据。因为未提交数据存在回滚的可能,所以被称为“脏”数据。
在这里插入图片描述
事务T1进行转账A给B账户转账200元,A初始余额为1000,B初始余额为500元。
(1)事务T1把A的值从1000修改为800,B的值修改为700,但还没有提交事务;
(2)此时T2事务开始读取数据,它读取到T1修改后的A的值为800;
(3)T1事务进行回滚,以为没有提交,所以A恢复到事务开始时候的值1000,B的值为500. 但此时对于T2,A的值还是800,这种情况就是脏读。T2读取到了T1还没有提交的数据

Non-repeatable Reads(不可重复读)
一个事务所获取到的数据是可以被其它事务修改的。一个事务在处理过程中多次读取同一个数据(重复读),这个数据是可能发生变化的,因此被称为不可重复读。
在这里插入图片描述
Phantom Read(幻影读)是不可重复读的更为特殊的一个场景。事务T1按照一定条件读取数据(使用了where条件过滤)后,事务T2删除了部分记录或者插入了一些新的记录,这些变更的数据是满足where条件过滤的。那么当T1再次按照相同条件读取数据时,就会发现莫名其妙地少了(也可能多了)一些数据。这些变化的数据就被称为“幻影”数据。
幻影数据也有叫幽灵数据的,所以幻影读也有叫幽灵读的。
(1)事务T1计算A和B的求和,此时求和值为A+B = 300;
(2)事务T2读取到了B数值,计算后得到结果为400,并写回计算结果
(3)事务T1再次读取A,B数值,并求和结果这次计算结果变成了500,对于T1事务来说,仍然在一个事务中,多次读取统一个数据源,但是发生了变化,这种情况就是不可重复读。

事务隔离级别
ANSI SQL标准定义了4种事务隔离级别来避免3种数据不一致的问题。事务等级从高到低,分别为:

Serializable(序列化)系统事务排队进行处理,这样能解决所有数据不一致的问题,但是会大幅降低系统并行处理的速度。
Repeatable read(可重复读)一个事务一旦开始,事务过程中所读取的所有数据不允许被其他事务修改。依然无法解决幻影读的问题。
Read Committed(已提交读)一个事务能读取到其他事务提交过(Committed)的数据。会发生不可重复度的现象。
Read Uncommitted(未提交读)一个事务能读取到其他事务修改过,但是还没有提交的(Uncommitted)的数据。会发生脏读现象。

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值