数据库重要知识

Table of Contents

1.常见的数据库优化手段

2.索引的优缺点,什么字段上应该建立索引

3.数据库连接池

javax.sql.DataSource

4. 怎么用原生的JDBC访问数据库?

5. MVCC原理及应用?

6. Mysql并发控制

6.1 读写锁

6.2 锁粒度

7. noSql

基本情况

优点

不足

适合noSql的场景

数据库表schema经常变化

数据库表字段是复杂数据类型

高并发数据库请求

海量数据的分布式存储

典型使用方式:

Nosql与sql的区别

8. MongoDB:


1.常见的数据库优化手段

策略名称 描述
表结构优化   表结构优化是数据库优化中最重要的,需要结合实际情况来看怎么设计更加的优化合理
sql语句优化

sql语法优化,写出更加便捷的sql语句

处理逻辑优化,如配合索引和缓存的使用:一个常见的做法是,将涉及到大数据量的sql语句记录下来,观察日志,有侧重点的优化

分区分表

分区是指将一张表的数据按照一定的规则分到不同的区来保存。若一张表中有几种类型,可以考虑分表

    举一个例子,分区按照月份来分,将不同类型的字段分表,这么做的好处就是增删改查数据的时候范围已经大大缩小了

索引优化

索引的原理是在进行增删改的时候就预先按照指定的字段顺序排列后保存了,在查找的时候就可以从索引找到对应的指针找到数据

  优点:查询效率很高 缺点:每次增删改要更新索引,降低增删改的速度

分离活跃数据

 将活跃数据单独存放起来

   比如登录网站,可以将活跃度高的用户单独存放(依据最近登录时间或者单位时间内登录次数等),查询时先从活跃数据查找,没有再去不活跃处查找

读写分离

读写分离的本质是对数据库进行集群,在高并发的情况下降低单台服务器的压力。

  一般将写的服务器叫主服务器,写入后同步到读服务器(即从服务器),并将读请求分配到多个服务器上

   

2.索引的优缺点,什么字段上应该建立索引

优点:查询效率很高 缺点:每次增删改要更新索引,降低增删改的速度。

紧接着的问题:数据库索引的原理是什么?为什么加索引访问比不加索引快呢?

1、表的主键、外键必须有索引; 
2、经常与其他表进行连接的表,在连接字段上应该建立索引; 
3、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引; 
4、索引应该建在选择性高的字段上; 存储空间固定的字段更适合选作索引的关键字。与 text 类型的字段相比, char 类型的字段较为适合选作索引关键字
5、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引。例如,与字符串相比,整数字段占用的存储空间较少,因此,较为适合选作索引关键字。
6、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:

A、正确选择复合索引中的主列字段,一般是选择性较好的字段;

B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;

C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;

E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;

7、频繁进行数据操作的表,不要建立太多的索引; 
8、删除无用的索引,避免对执行计划造成负面影响;

3.数据库连接池

若通过我们自己编写jdbc连接数据库,则服务器每次处理用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。

而数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.

数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:

  1. 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
  2. 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
  3. 如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.

数据库连接池的逻辑图如下:

javax.sql.DataSource

在jdk当中有一个类DataSource,专门用来做数据库连接管理和配置的。

这个类代表的是一个连接物理数据源(即我们的数据库)的工厂。它是DriverManager的一种替代方案,一个 DataSource对象是获得一个数据库连接的更好的方式。一个实现了DataSource借口的对象通常会被注册在一个naming service里面based on JNDI api.

DataSource接口是被一个驱动程序供应商实现(如mysql数据库的实现就是mysql connector,postgres的实现就是postgresql connector). 有三种实现的方式

  1. 基本的实现-提供一个标准的连接对象
  2. 连建池的实现-提供一个可以自动加入连建池的练剑对象。这种实现要和一个中间层连接池管理器一起工作。
  3. 分布式事务实现-产生一个可以被用于分布式事务并且总是放在连接池的连接对象。这种实现要和一个中间层连接池管理器一起工作。

Spring Boot实现了自动加载DataSource及相关配置,定义在ServiceConnectionFactory类当中。我们可以自己配置数据库连接池的各种参数,如:

  1. private int minPoolSize;
  2. private int maxPoolSize;
  3. private int maxWaitTime;

Druid

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

Druid是一个开源项目,源码托管在github上,源代码仓库地址是 https://github.com/alibaba/druid。同时每次Druid发布正式版本和快照的时候,都会把源码打包,你可以从上面的下载地址中找到相关版本的源码

Druid 0.1.18 之后版本都发布到maven中央仓库中,所以你只需要在项目的pom.xml中加上dependency就可以了。例如:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid-version}</version>
    </dependency>

也可以选择 Maven仓库查找公共的仓库地址:http://www.mvnrepository.com/artifact/com.alibaba/druid

Druid的监控统计功能是通过filter-chain扩展实现,如果你要打开监控统计功能,配置StatFilter,具体看这里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter

更多

4. 怎么用原生的JDBC访问数据库?

原生的JDBC编程主要分一下几个步骤:(原生的JDBC编程指,仅应用java.sql包下的接口和数据库驱动类编程,而不借助任何框架)

  1. 加载JDBC驱动程序;
  2. 负责管理JDBC驱动程序的类 DriverManager 会识别加载的驱动程序,用 DriverManager 类的方法 getConnection()来创建一个数据库连接类的实例对象;
  3. 获取Connection对象的实例,用Connection对象的方法创建一个 Statement 对象实例,执行标准的SQL语句,对数据库、表进行相关操作。
  4. 返回的结果用 ResultSet 类来处理。
  5. 出现异常时,对事物进行回滚。

JDBC对事务的支持:

在JDBC的数据库操作中,一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元。我们通过提交commit()或是回退rollback()来结束事务的操作。关于事务操作的方法都位于接口java.sql.Connection中。

首先我们要注意,在JDBC中,事务操作默认是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作。操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回退。

其次,在JDBC中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交。倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生相应的异常。此时就可以在异常捕获时调用rollback()进行回退。这样做可以保持多次更新操作后,相关数据的一致性。

5. MVCC原理及应用?

全称是Multi-Version Concurrent Control,即多版本并发控制,实现MVCC是为了提升并发性能。不仅是Mysql,包括oracle,Postgresql等数据库也实现了MVCC,但是各自的实现机制不尽相同。

可以认为MVCC是行级锁的一个变种,但是他在很多情况下多避免了加锁操作,因此开销更低。MVCC是通过保存数据在某个时间点的快照来实现的,也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。前面说的不同存储引擎的MVCC实现是不同的,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。

在MVCC协议下,并且可以实现非阻塞的读. InnoDB,是MySQL的数据库引擎之一,InnoDB是通过在每一行的记录后面保存两个隐藏的列来实现的,这两个类一个保存行的创建时间,一个保存删除时间,但这个并不是实际的时间值,而是一个自动增长的系统版本号(version number)

6. Mysql并发控制

6.1 读写锁

为解决并发的读写数据的问题,可以通过一个由两种类型的锁组成的锁系统来解决问题。这两种类型的锁通常被称为共享锁(shared lock)和排他锁(exclusive lock),也叫做读锁 read lock和写锁 write lock。

6.2 锁粒度

两种最重要的锁策略是:

表锁 table lock:锁定整张表。开销最小。

行级锁row lock:行级锁可以最大程度的支持并发处理,同时也带来最大的锁开销。

7. noSql

基本情况

NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。

SQL (Structured Query Language) 数据库,指关系型数据库。主要代表:SQL Server,Oracle,MySQL,PostgreSQL。很有意思的一件事情是:sql的中文就是结构化查询语言,这就是一个针对关系型数据库的概念。

NoSQL(Not Only SQL)泛指非关系型数据库。主要代表:MongoDB,Redis,CouchDB。

世界上主流的存储系统大部分还是采用了关系型数据库,其主要有一下优点:

1.事务处理—保持数据的一致性;

2.由于以标准化为前提,数据更新的开销很小(相同的字段基本上只有一处);

3.可以进行Join等复杂查询。

虽然关系型数据库已经在业界的数据存储方面占据不可动摇的地位,但是由于其天生的几个限制,使其很难满足上面这几个需求

1. 扩展困难:由于存在类似Join这样多表查询机制,使得数据库在扩展方面很艰难;

2. 读写慢:这种情况主要发生在数据量达到一定规模时由于关系型数据库的系统逻辑非常复杂,使得其非常容易发生死锁等的并发问题,所以导致其读写速度下滑非常严重;

3. 成本高:企业级数据库的License价格很惊人,并且随着系统的规模,而不断上升;

4. 有限的支撑容量:现有关系型解决方案还无法支撑Google这样海量的数据存储;

优点

  1. 简单的扩展:典型例子是Cassandra,由于其架构是类似于经典的P2P,所以能通过轻松地添加新的节点来扩展这个集群;
  2. 快速的读写:主要例子有Redis,由于其逻辑简单,而且纯内存操作,使得其性能非常出色,单节点每秒可以处理超过10万次读写操作;
  3. 低廉的成本:这是大多数分布式数据库共有的特点,因为主要都是开源软件,没有昂贵的License成本;

不足

  1. 不提供对SQL的支持:如果不支持SQL这样的工业标准,将会对用户产生一定的学习和应用迁移成本;
  2. 支持的特性不够丰富:现有产品所提供的功能都比较有限,大多数NoSQL数据库都不支持事务,也不像MS SQL Server和Oracle那样能提供各种附加功能,比如BI和报表等;
  3. 现有产品的不够成熟:大多数产品都还处于初创期,和关系型数据库几十年的完善不可同日而语;

适合noSql的场景

NoSQL并不是任何场景,NoSQL都要优于关系型数据库,有以下几个场景比较适合:

  • 数据库表schema经常变化

如在线商城,维护产品的属性经常要增加字段,这就意味着ORMapping层的代码和配置要改,如果该表的数据量过百万,新增字段会带来额外开销(重建索引等)。NoSQL应用在这种场景,可以极大提升DB的可伸缩性,开发人员可以将更多的精力放在业务层

  • 数据库表字段是复杂数据类型

对于复杂数据类型,比如SQL Sever提供了可扩展性的支持,像xml类型的字段。很多用过的同学应该知道,该字段不管是查询还是更改,效率非常一般。主要原因是是DB层对xml字段很难建高效索引,应用层又要做从字符流到dom的解析转换。NoSQL以json方式存储,提供了原生态的支持,在效率方便远远高于传统关系型数据库

  • 高并发数据库请求

此类应用常见于web2.0的网站,很多应用对于数据一致性要求很低,而关系型数据库的事务以及大表join反而成了”性能杀手”。在高并发情况下,sql与no-sql的性能对比由于环境和角度不同一直是存在争议的,并不是说在任何场景,no-sql总是会比sql快

  • 海量数据的分布式存储

海量数据的存储如果选用大型商用数据,如Oracle,那么整个解决方案的成本是非常高的,要花很多钱在软硬件上。NoSQL分布式存储,可以部署在廉价的硬件上,是一个性价比非常高的解决方案。

典型使用方式:

  1. NoSQL和关系数据库结合
  2. NoSQL作为缓存服务器

Nosql与sql的区别

SQL 数据库

在使用之前需要定义表的一个模式

在表中存储相关联的数据

支持 join 多表查询

提供事务

使用一个强声明性语言查询

提供足够的支持,专业技能和工具

NoSQL 数据库

将相关联的数据存储在类似 JSON 格式,名称-值

可以保存没有指定格式的数据

保证更新一个文档 – 但不是多个文档

提供出色的性能和可伸缩性

使用 JSON 数据对象查询

其他区别

条目 sql数据库 nosql数据库
存储方式 存在特定结构的表中 存储方式可以是JSON文档、哈希表或者其他方式
表/集合数据的关系 必须定义好表和字段结构后才能添加数据,例如定义表的主键(primary key),索引(index),触发器(trigger),存储过程(stored procedure)等。表结构可以在被定义之后更新,但是如果有比较大的结构变更的话就会变得比较复杂 数据可以在任何时候任何地方添加,不需要先定义表
外部数据存储 如果需要增加外部关联数据的话,规范化做法是在原表中增加一个外键,关联外部数据表 NoSQL中除了这种规范化的外部数据表做法以外,我们还能用如下的非规范化方式把外部数据直接放到原数据集中,以提高查询效率。缺点也比较明显,更新审核人数据的时候将会比较麻烦
 SQL中的JOIN查询 SQL中可以使用JOIN表链接方式将多个关系数据表中的数据用一条简单的查询语句查询出来。 NoSQL未提供对多个数据集中的数据做查询

此处参考:链接

8. MongoDB:

  • 面向无需定义表结构的文档数据
  • 具有非常快的处理速度
  • 通过BSON的形式可以保存和查询任何类型的数据
  • 无法进行JOIN处理,但是可以通过嵌入(embed)来实现同样的功能
  • 使用sharding(范围分割)算法来分散数据

猜你喜欢

转载自blog.csdn.net/topdeveloperr/article/details/81396498
今日推荐