Java面试题(三)- 数据库

目录

1. 通用

2. Mysql

3. Oracle

4. Redis

5. MongoDB


1. 通用

1.1. 数据库三范式
第一范式(1NF)
       在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 
       所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。
       在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式要求数据表中的每一列(每个字段)必须是不可拆分的最小单元。
第二范式(2NF)
       第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。
       第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式要求表中的所有列,都必须依赖于主键,而不能有任何一列与主键没有关系。
第三范式(3NF) 
       满足第三范式(3NF)必须先满足第二范式(2NF)。第三范式(3NF)要求一个数据库表中不包含其它表中已包含的非主关键字信息。简而言之,第三范式要求表中的每一列只与主键直接相关而不是间接相关,表中的每一列只能依赖于主键。
1.2. 数据库优化
       用PreparedStatement一般来说比Statement性能高
       有外键约束会影响插入和删除性能,如果程序能够保证数据的完整性,那在设计数据库时就去掉外键。
       sql 语句全部大写
       表中允许适当冗余
       索引对查询性能的改进
1.3. union和union all
       union在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。
       union all只是简单的将两个结果合并后就返回。从效率上说,UNION ALL 要比UNION快很多。
1.4. 注册Jdbc驱动程序的三种方式
       System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
       Class.forName("com.mysql.jdbc.Driver");
       DriverManager.registerDriver(newcom.mysql.jdbc.Driver());
1.5. JDBC中的PreparedStatement相比Statement的好处
       相对比较安全,可以防止sql注入,有预编译功能,相同操作批量数据效率较高
1.6. 用jdbc连接并访问oracle数据的程序代码

    //1.加载驱动
    Class.forName("oracle.jdbc.driver.OracleDriver");
    //2.创建连接
    Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","scott","123");
    //3.创建statement
    Statement stm = conn.createStatement();
    //4.执行SQL语句,并返回结果
    String sql = "'";
    ResultSet rs = stm.executeQuery(sql);
    //5.处理结果集
    while (rs.next()) {}
    //6.关闭连接
    conn.close();    

1.7. 大数据量下的分页解决方法
       最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容。再sql语句无法实现分页的情况下,可以考虑对大的结果集通过游标定位方式来获取某页的数据。
1.8. 数据连接池的工作机制
       调用:客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。
       释放:当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建连接和销毁连接的过程。
1.9. 主键、外键、超键、候选键
       主 键:
              数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
       外 键:
              在一个表中存在的另一个表的主键称此表的外键。
       超 键:
              在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。
       候选键:
              是最小超键,即没有冗余元素的超键。
1.10. 为什么要用 ORM? 和JDBC 有何不一样?
       用JDBC编程访问数据库,代码量较大,关系数据对象之间,存在各种复杂关系,容易出错。
       ORM则建立了Java对象与数据库对象之间的映射关系,也自动根据数据库对象之间的关系创建Java对象的关系,使程序员更加专注于业务逻辑的实现。
       采用JDBC编程,在很多时候存在效率低下的问题,如果采用ORM技术,则大大降低通讯量,提高运行效率。
1.11. *脏读、不可重复读和幻读
       脏读:一个事务读取了另一个事务改写但是未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
       不可重复读:一个事物执行相同的查询两次或者两次以上,但是每次都得到不同的数据。通常是因为另一个并发事务在两次查询期间更新了数据。
       幻读:一个事务读取了几行数据,接着另一个并发事务插入了一些数据。在随后的查询中,第一个事务发现多了一些原本不存在的事务。
1.12. 数据库备份方式
       完全备份,事务日志备份,增量备份,文件备份。
1.13. 数据库备份分类
       逻辑备份,物理备份,热备份,冷备份。
1.14. 数据库数据保护方式
       用户标识和鉴别;存取控制;视图机制;审计;数据加密。
1.15. 视图
       视图是一个虚拟表,对视图不一定可以进行增删改操作,查询可以。使用视图,可以简化数据操作,基表中的数据就有了一定的安全性。
1.16. 存储过程、触发器
       存储过程是一组为完成特定功能的SQL语句集合,可以说是一种函数。
       触发器是一种特殊的存储过程,当表被修改(增、删、改)时它隐式地被激发。
1.17. 绑定变量是什么?有什么优缺点?
       绑定变量实质就是变量,就是在sql语句中使用变量,通过改变变量的值来得到不同的结果。
       优点:sql语句是分为动态部分和静态部分的。使用动态绑定,可以减少sql的解析,从而减少了数据库引擎在sql解析上资源的消耗。提高了执行效率和可靠性。减少对数据库的访问实际上就是减少了数据库的工作量。
       缺点:经常需要使用动态SQL的写法,由于参数的不同,可能SQL的执行效率不同。
1.18. 索引,用法原理,索引的类型
       索引是若干数据行的关键字的列表(是对数据库表中一列或多列的值进行排序的一种存储结构),索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容,大大减少读取数据块的I/O次数,从而提高数据访问性能。
       索引的类型有:B树索引,位图索引,函数索引等。
1.19. 使用索引查询一定能提高查询的性能吗?为什么?
       不一定,如果表中数据少的话,没必要用索引,通过索引查询数据比全表扫描要快,索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改,不必要的索引反而会使查询反应时间变慢。
1.20. drop、truncate和delete
        truncate和 delete只删除数据不删除表的结构,truncate不能触发触发器,delete会触发触发器;drop语句将删除表的结构被依赖的约束,触发器,索引;依赖于该表的存储过程/函数将保留,但是变为无效状态,将表所占用的空间全部释放。
        delete是DML语句,事务提交之后才生效,可以回滚;truncate,drop是DDL语言,操作立即生效,不能回滚。
        速度上一般来说: drop>truncate >delete 
1.21. 控制文件都含有哪些信息?
        控制文件存放有实例信息(实例名称创建时间等),数据文件和日志文件信息,还有系统运行时记录的系统变更码(SCN),检查点信息和归档的当前状态信息等。数据库在加载数据库的时候首先要读取控制文件获得和数据库有关的物理结构信息之后才能够正确加载数据文件和日志文件并打开数据库。
1.22. 数据库的几种物理文件
        数据文件(mdf),日志文件(ldf),控制文件(cdf)
1.23. 使用存储过程访问数据库比直接用SQL语句访问有哪些优点?
        存储过程是预编译过的,执行时无须编译,执行速度更快;存储过程封装了一批SQL语句,便于维护数据的完整性与一致性;可以实现代码的复用。
1.24. 触发器的作用,什么时候用触发器,创建触发器的步骤,触发器里是否可以有commit,为什么?
        触发器可以实现一般的约束无法完成的复杂约束,从而实现更为复杂的完整性要求。
        使用触发器并不存在严格的限定,只要用户想在无人工参与的情况下完成一般的定义约束不可以完成的约束,来保证数据库完整性,那么就可以使用触发器。
        创建一个触发器,首先要明确该触发器应该属于那一种,因为它们各有个的用途;其次就是要确定触发器被触发以后所涉及到的数据。
        触发器中不能进行任何事务操作,任何对被触发表进行操作的事务都将失败,所以触发器中不能有commit。
1.25. 关系数据库系统与文件数据库系统的区别在那里?关系数据库系统一般适用那些方面?
        首先,关系性数据库的整体数据是结构化的,采用关系数据模型来描述,这是它与文件系统的根本区别。
        其次,关系数据库系统的共享性高,冗余低可以面向整个系统,而文件系统则具有应用范围的局限性,不易扩展。
        第三,关系数据库系统采用两级映射机制保证了数据的高独立性,从而使得程序的编写和数据都存在很高的独立性。这方面是文件系统无法达到的,它只能针对于某一个具体的应用。
        第四,就是关系性数据库系统由统一的DBMS进行管理,从而为数据提供了如安全性保护,并发控制,完整性检查和数据库恢复服务。
1.26. *事务,使用目的,四大特性
        事务是并发控制单位,是用户定义的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单位。
        保持数据的一致性和完整性。
        原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可以只执行其中的一部分操作。
        一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态。
        隔离性(isolation):通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。
        持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库中。
1.27. 声明式事务管理的事务属性(5种)
        隔离级别:指若干个并发的事务之间的隔离程度。
        传播行为:定义了客户端与彼调用方法之间的事务边界。
        事务超时:指定事务运行的最长时间,超时就回滚。
        只读:表明事务是否是只读的。
        回滚规则:定义了哪些异常会导致事务回滚而哪些不会。
1.28. 怎么在JDBC内调用一个存储过程?
        使用CallableStatement。
1.29. 你所了解的数据源技术有那些?使用数据源有什么好处?
        Dbcp,c3p0等。当连接的数据库信息发生改变时,不需要再更改程序代码就实现了数据库信息的更新。
1.30.  char、varchar、text的区别
        1. char长度固定,即每条数据占用等长字节空间;适合用在身份证号码、手机号码等定。
        2. varchar可变长度,可以设置最大长度;适合用在长度可变的属性。
        3. text不设置长度, 当不知道属性的最大长度时,适合用text。
        按照查询速度: char最快, varchar次之,text最慢。
1.31. sql优化
        sql语句优化,尽量避免全表扫描,如尽量避免使用or,in,not in等
        建索引
        拆分表或增加中间表

2. Mysql

2.1. MYSQL支持事务吗?
       在缺省情况下,mysql是不支持事务的。默认情况下是自动提交的,在非autocommit的模式下必须使用commit语句提交,或者使用rollback进行事务回滚。
2.2. MYSQL相比于其他数据库有哪些特点?
  1>可以处理拥有上千万条记录的大型数据 
  2>支持常见的SQL语句规范 
  3>可移植行高,安装简单小巧 
  4>良好的运行效率,有丰富信息的网络支持 
       5>调试、管理,优化简单
2.3. 如何解决MYSQL数据库中文乱码问题?
  1>在数据库安装的时候指定字符集 
  2>如果在安完数据库以后可以更改以配置文件 
  3>建立数据库时候:指定字符集类型 
       4>建表的时候也指定字符集
2.4. MySQL取得当前时间的函数是?格式化日期的函数是?
       取得当前时间用 now() 。
       在数据库中格式化时间用DATE_FORMAT(date, format)。
2.5. MySQL几种备份方式
       逻辑备份:使用mysql自带的mysqldump工具进行备份。备份成sql文件形式。
       物理备份:直接拷贝mysql的数据目录。
       双机热备份。 
2.6. mysql默认端口号
       3306
2.7. 确定有哪些存储引擎可用?
       mysql> show engines
2.8. 查看其进程是否正常命令
       mysql>show processlist
2.9. MySQL怎么修复损坏的表?
       有两种方法,一种方法使用mysql的check table和repair table 的sql语句,另一种方法是使用MySQL提供的多个myisamchk,          isamchk数据检测恢复工具。
2.10. mysql主从用什么方式传输日志
       mySQL 复制基于主服务器在二进制日志中跟踪所有对数据库的更改。每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。
2.11. MySQL主备同步的基本原理
       MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。
       MySQL复制是基于主服务器在二进制日志中跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收主服务器已经记录到日志的数据。
       当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,并在本机上执行相同的更新。然后封锁并等待主服务器通知新的更新。从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。

3. Oracle

3.1. Oracle索引种类类,唯一索引和位图索引的概念。
       Oracle索引有B树索引,位图索引,函数索引,簇索引等。
唯一索引是B树索引的一种,它要求被索引的字段值不可以重复。在创建的时候使用B树算法创建。 
位图索引为每一个唯一的字段值创建一个位图,位图中使用位元来对应一个记录的rowID,位元到rowID是通过映射的到的。
3.2. Oracle中的控制文件什么时候读取
       Oracle服务器启动时,先启动实例然后再读取数据库的各个文件,这些文件里也用控制文件。
3.3. Oracle系统进程主要有哪些,作用是什么?
       数据写进程(DBWR):负责将更改的数据从数据库缓冲区高速缓存写入数据文件 
  日志写进程(LGWR):将重做日志缓冲区中的更改写入在线重做日志文件 
  系统监控 (SMON): 检查数据库的一致性如有必要还会在数据库打开时启动数据库的恢复 
  进程监控 (PMON): 负责在一个Oracle进程失败时清理资源 
  检查点进程(CKPT):负责在每当缓冲区高速缓存中的更改永久地记录在数据库中时,更新控制文件和数据文件中的数据库状态信息。 
  归档进程 (ARCH):在每次日志切换时把已满的日志组进行备份或归档。 
       恢复进程 (RECO): 保证分布式事务的一致性,在分布式事务中,要么同时提交,要么同时回滚。
3.4. SGA主要有那些部分,主要作用是什么
       系统全局区SGA是Oracle为实例分配的一组共享缓冲存储区,用于存放数据库数据和控制信息,实现对数据库数据的管理和操作。
       SGA主要包括: 
       1)共享池:用来存储最近执行的SQL语句和最近使用的数据字典的数据。   
       2)Java池: 用于支持JAVA虚拟机,存储Java代码。 
       3)大型池:供RMAN备份和共享连接模式。
       4)数据缓冲区:用来存储最近从数据文件中读写过的数据。 
       5)重作日志缓冲区:用来记录服务或后台进程对数据库的操作。
3.5. tablespace和datafile
       一个tablespace可以有一个或多个datafile,每个datafile只能在一个tablespace内,table中的数据,通过hash算法分布在tablespace中的各个datafile中,tablespace是逻辑上的概念,datafile则在物理上储存了数据库的种种对象。
3.6. Oracle中回滚的概念,回滚段的作用是什么?
       回滚就是在事务提交之前将数据库数据恢复到事务修改之前数据库数据状态。 
       保存数据修改前的映象,数据读一致性。一个事务只能使用一个回滚段。 
3.7. table/segment/extent/block之间关系?
       这些都是Oracle存储的逻辑结构。
       一个table至少是一个segment,table可以看成是一个逻辑上的概念,segment可以看成是这个逻辑概念的物理实现。
       block是Oracle存储的最基本单位,一个extent由一系列连续的Oracle blocks组成。
3.8. MySQL、Oracle的优化策略
       优化的策略一般包括: 内存优化、操作系统优化、数据存储的优化、网络优化等方法。具体到不同的数据库涉及到要调整不同的数据库配置文件、不同的操作系统参数、网络参数等等, 不同的数据库不同。
3.9. Oracle中的异常有哪几类
       预定义的异常,非预定义的异常,用户定义的异常。
3.10. 分区表的应用
       当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个“表空间”(物理文件上),这样查询数据时,不至于每次都扫描整张表而只是从当前的分区查到所要的数据大大提高了数据查询的速度。
       表分区有以下优点: 
              1)改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
              2)增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
              3)维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
              4)均衡I/O:可以把不同的分区映射到不同磁盘以平衡I/O,改善整个系统性能。
3.11. 表空间区管理方式?哪种方式现在是推荐使用的?
       默认方式 :字典管理方式
       推荐方式 :本地管理方式
3.12. 表空间如何扩展?
       增加数据文件,扩展数据文件大小。
3.13. Oracle的基本数据类型有哪些
       字符类型char、varchar
       数字类型number
       日期类型Date
       二进制及大文本数据BLOB、CLOB
3.14. 在Oracle中,所创建的表空间信息放在哪里?
       存放在数据字典中,数据字典内容对应于系统表空间SYSTEM表空间。
3.15. Oracle数据库都有哪些类型的文件?
       数据文件,控制文件,日志文件,参数文件。
3.16. 简述Oracle的启动和关闭各有多少步骤?
       启动:启动实例、装载数据库数据、打开数据库。 
       关闭:关闭数据库、卸载数据库数据、关闭实例。
3.17. 介绍一下Oracle的体系结构
  逻辑体系结构:块,区,段,表空间 
  物理体系结构:表空间,三大文件 
       软件体系结构:SGA,后台进程
3.18. Oracle默认端口号
       1521
3.19. Oracle数据库中decode函数的作用是什么
       将查询结果翻译成其他值。

4. Redis

4.1. *什么是Redis,应用场景,优缺点
Redis是一个基于内存的高性能key-value数据库。
优点
          (1) 速度快:整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
          (2) 支持丰富数据类型,支持string,list,set,sorted set,hash ,单个value的最大限制是1GB
          (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 
          (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
缺点
       数据库容量受到物理内存的限制,不能用作海量数据的高性能读写。
应用场景
       缓存:提升访问速度、降低数据库压力
       消息队列:主要用于业务解耦、流量削峰及异步处理实时性低的业务。
       排行榜:Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。
       计数器:用来记录访问量、播放数,Redis提供的incr命令来实现计数器功能,内存操作,性能非常好。
       分布式锁:并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败。
       社交网络:点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很方便的的实现这些功能。
       Session存储:Redis具有缓存数据持久化的能力,当缓存因出现问题而重启后,之前的缓存数据不会丢失,避免了因为session突然消失带来的用户体验问题。
4.2. Redis主要消耗什么物理资源
       内存。
4.3. Redis官方为什么不提供Windows版本?
       目前Linux版本已经相当稳定,而且用户量很大,无需开发windows版本,反而会带来兼容性等问题。
4.4. 一个字符串类型的值存储最大容量
       512M
4.5. Redis数据淘汰策略
       noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外) 
       allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
       volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
       allkeys-random: 回收随机的键使得新添加的数据有空间存放。
       volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
       volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放
4.6. Jedis与Redisson
       Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
4.7. Redis哈希槽
       Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
4.8. Redis集群会有写操作丢失吗?
       Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
4.9. Redis集群之间是如何复制的?最大节点个数是多少
       异步复制
       16384个
4.10. Redis事务相关的命令,key的过期时间和永久有效设置命令
       MULTI、EXEC、DISCARD、WATCH
       EXPIRE和PERSIST
4.11. Redis内存优化
       尽可能使用散列表,散列表使用的内存非常小,所以应该尽可能的将数据模型抽象到一个散列表里面。比如web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。
4.12. 为什么要做Redis分区?分区方案
       分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。
       客户端分区、代理分区、查询路由。
4.13. 穿透及对策
       现象:在redis中查不到,压力打在了DB上
       对策:将确定不存在/不合法的数据访问结果,记录在redis中 
4.14. 雪崩及对策
       现象:大量的缓存数据 同时失效,压力打在了DB上
       对策:细分各类数据的有效期长短、就某一类中各个具体数据有效期上可以略作区别、预留DB抗压能力
4.15. 预热及对策
       现象:上线或启动时,需要加载大量数据到redis。在加载完成前,压力打到了DB
       对策:少量数据可在接收请求前 提前加载;热点数据可提前加载;先设定默认值,再对数据进行定期刷新;
4.16. 降级及对策
       现象:redis挂掉了,导致压力打到了DB
       对策:在内存中存储热点数据、默认数据
4.17. 为什么说redis能够快速执行
       (1) 绝大部分请求是纯粹的内存操作(非常快速)
       (2) 采用单线程,避免了不必要的上下文切换和竞争条件
       (3) 非阻塞IO - IO多路复用
4.18. Redis关于线程安全问题
       Redis实际上是采用了线程封闭的观念,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁。
4.19. redis常用的五种数据类型
       1.String(字符串)
              String是简单的 key-value 键值对,value 不仅可以是 String,也可以是数字。它是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。
       2.Hash(哈希)
              Redis hash 是一个键值对集合,对应Value内部实际就是一个HashMap,Hash特别适合用于存储对象。
       3.List(列表)
              Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。
底层实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
       4.Set(集合)
              Redis的Set是String类型的无序集合,它的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
       5.zset(有序集合)
              Redis zset 和 set 一样也是String类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double类型的分数,用来排序。

5. MongoDB

5.1. 为什么要使用mongo
       关系型数据库不擅长:大量数据的写入;字段不固定,表结构变更;简单查询需要快速返回结果。mongoDB作为非结构化数据库不仅可以处理结构化数据,而且更适合处理非结构化数据(文本、图像、超媒体等信息)。它突破了关系型数据库结构定义不易改变而且数据定长的限制,在处理连续信息和非结构化信息中有着关系型数据库无法比拟的优势。
       MongoDB的优势:大数据量高性能,易扩展,高可用性,轻松实现大数据量的存储;完善的Java API,存储格式是JSON,对JAVA,JS来说非常好处理,运维起来很方便,清晰的版本控制,非常活跃的社区。
5.2. MongoDB在数据库中存储二进制数据的解决方案
       将文件转化为二进制数据存入mongodb
              先读取文件内容,然后塞进bson.binary.Binary对象里,最后像平常那样写入数据库;获取文件一样的简单,像平时那样查找数据,然后将二进制内容写入文件即可;
       使用gridfs
              如果是大文件可以使用gridfs,gridfs会把文件分成若干块来存储,每一块的大小默认为256K,所以,如果是小文件,就不要用gridfs来存储了,不然会浪费空间的,gridfs是MongoDB之上的分布式文件系统,可以使用mongodb的分片和复制机制,因为Mongodb分配数据空间时以2GB为单位,所以gridfs不产生磁盘碎片。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java数据库查询结果的输出 摘自:北京海脉信息咨询有限公司   利用Java开发数据库应用时,经常需要在用户界面上显示查询结果。我们可以利用Vector、JTable、AbstractTableModel等个类较好地解决这一问题。 类Vector:   定义如下: public class Vector extends AbstractList implements List , Cloneable , Serializable{…} 类JTable:   JTable组件是Swing组件中比较复杂的小件,隶属于javax.swing包,它能以二维表的形式显示数据。类Jtable: 定义如下: public class JTable extends JComponent implements TableModelListener, Scrollable, TableColumnModelListener, ListSelectionListener, CellEditorListener, Accessible{…} 类AbstractTableModel:   定义如下: public abstract class AbstractTableModel extends Object implements TableModel, Serializable{…}   生成一个具体的TableModel作为AbstractTableMode的子类,至少必须实现下面个方法: public int getRowCount(); public int getColumnCount(); public Object getValueAt(int row, int column);   我们可以建立一个简单二维表(5×5): TableModel dataModel = new AbstractTableModel() { public int getColumnCount() { return 5; } public int getRowCount() { return 5;} public Object getValueAt(int row, int col) { return new Integer(row*col); } }; JTable table = new JTable(dataModel); JScrollPane scrollpane = new JScrollPane(table); 数据库及其连接方法:   我们采用Sybase数据库数据库存放在数据库服务器中。路径为:D:WORKER,数据库名为:worker.dbf。具有以下字段: 字段名 类型 Wno(职工号) VARCHAR Wname(职工名) VARCHAR Sex(性别) VARCHAR Birthday(出生日期) DATE Wage(工资) FLOAT   要连接此数据库,需使用java.sql包中的类DriverManager。此类是用于管理JDBC驱动程序的实用程序类。它提供了通过驱动程序取得连接、注册,撤消驱动程序,设置登记和数据库访问登录超时等方法。   具体连接方法如下:   定位、装入和链接SybDriver类。 driver="com.sybase.jdbc.SybDriver"; SybDriver sybdriver=(SybDriver) Class.forName(driver).newInstance();   注册SybDriver类。 DriverManager.registerDriver(sybdriver);   取得连接(SybConnection)对象引用。 user="sa"; password=""; url="jdbc:sybase:Tds:202.117.203.114:5000/WORKER"; SybConnection connection= (SybConnection)DriverManager.getConnection (url,user,password); 建立完连接后,即可通过Statement接口进行数据库的查询与更改。 实现方法:   对象声明。   AbstractTableModel tm;   //声明一个类AbstractTableModel对象   JTable jg_table;//声明一个类JTable对象   Vector vect;//声明一个向量对象   JScrollPane jsp;//声明一个滚动杠对象   String title[]={"职工号","职工名",   "性别","出生日期","工资"};   //二维表列名   定制表格。   实现抽象类AbstractTableModel对象tm中的方法:   vect=new Vector();//实例化向量   tm=new AbstractTableModel(){   public int getColumnCount(){   return title.length;}//取得表格列数   public int getRowCount(){   return vect.size();}//取得表格行数   public Object getValueAt(int row,int column){   if(!vect.isEmpty())   return   ((Vector)vect.elementAt(row)).elementAt(column);   else   return null;}//取得单元格中的属性值   public String getColumnName(int column){   return title[column];}//设置表格列名   public void setValueAt   (Object value,int row,int column){}   //数据模型不可编辑,该方法设置为空   public Class getColumnClass(int c){   return getValueAt(0,c).getClass();   }//取得列所属对象类   public boolean isCellEditable(int row,int column){   return false;}//设置单元格不可编辑,为缺省实现   };   定制表格:   jg_table=new JTable(tm);//生成自己的数据模型   jg_table.setToolTipText("显示全部查询结果");   //设置帮助提示   jg_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);   //设置表格调整尺寸模式   jg_table.setCellSelectionEnabled(false);   //设置单元格选择方式   jg_table.setShowVerticalLines(true);//   设置是否显示单元格间的分割线   jg_table.setShowHorizontalLines(true);   jsp=new JScrollPane(jg_table);//给表格加上滚动杠   显示查询结果。   连接数据库:已给出。   数据库查询:   Statement stmt=connection.createStatement();   ResultSet rs=stmt.executeQuery   ("select * from worker");   显示查询结果:   vect.removeAllElements();//初始化向量对象   tm.fireTableStructureChanged();//更新表格内容   while(rs.next()){   Vector rec_vector=new Vector();   //从结果中取数据放入向量rec_vector中   rec_vector.addElement(rs.getString(1));   rec_vector.addElement(rs.getString(2)); rec_vector.addElement(rs.getString(3)); rec_vector.addElement(rs.getDate(4));   rec_vector.addElement(new Float(rs.getFloat(5)));   vect.addElement(rec_vector);   //向量rec_vector加入向量vect中   }   tm.fireTableStructureChanged();   //更新表格,显示向量vect的内容   实现示图中记录前翻、后翻的效果,有两种方法:   如果软件环境支持JDBC2.0,可直接利用rs.prevoius()和rs.next()获得记录,然后通过类JTextField中的setText()方法,显示出各个字段值。   如果不支持JDBC2.0,则可利用向量Vector按行取出JTable中数据。自定义一个指针,用来记录位置。当指针加1时,取出上一行数据放入Vector中显示;指针减1时,取出下一行数据显示。显示方法同上。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值