zoukankan      html  css  js  c++  java
  • 备战秋招——数据库

    事务

    事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。事务是DBMS中最基础的单位,事务不可分割。

    事务具有4个基本特征,分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Duration),简称ACID。

    ACID

    1. 原子性(Atomicity)

    原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

    2. 一致性(Consistency)

    一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

    拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

    3. 隔离性(Isolation)

    隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

    即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

    多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。

    这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。

    不同的隔离级别:

    Read Uncommitted(读取未提交[添加中文释义]内容):最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。

    Read Committed(读取提交内容):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。

    Repeated Read(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。

    Serialization(可串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。

    4. 持久性(Durability)

    持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

    例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

    数据库的三大范式

    第一范式:当关系模式R的所有属性都不能再分解为更基本的数据单位时,称R是满足第一范式,即属性不可分

    第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式

    第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,即非主属性不传递依赖于键码

     

    B+树

    B+树的特征:

    1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。

    2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

    3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

    B+树的优势:

    1.中间节点不存指针,所以单一节点存储更多的元素,所以整个树的高度比较小,使得查询的IO次数更少。

    2.所有查询都要查找到叶子节点,查询性能稳定。

    3.所有叶子节点形成有序链表,便于范围查询。

    唯一索引和主键索引的比较

    唯一索引
    唯一索引不允许两行具有相同的索引值。
    如果现有数据中存在重复的键值,则大多数数据库都不允许将新创建的唯一索引与表一起保存。当新数据将使表中的键值重复时,数据库也拒绝接受此数据。例如,如果在 employee 表中的职员姓氏(lname) 列上创建了唯一索引,则所有职员不能同姓。

    主键索引
    主键索引是唯一索引的特殊类型。
    数据库表通常有一列或列组合,其值用来唯一标识表中的每一行。该列称为表的主键。
    在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

    它们的一些比较:
    (1)对于主键/unique constraint , oracle/sql server/mysql等都会自动建立唯一索引;
    (2)主键不一定只包含一个字段,所以如果你在主键的其中一个字段建唯一索引还是必要的;
    (3)主键可作外键,唯一索引不可;
    (4)主键不可为空,唯一索引可;
    (5)主键也可是多个字段的组合;
    (6)主键与唯一索引不同的是:
    a.有not null属性;
    b.每个表只能有一个。

     

    主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。

    MySQL 数据加密方式

    1、第一种加密方式,password()函数,使用MySQLSHA1(安全Hash算法)进行加密
    mysql一般的加密方式是password('root')将root在数据库客户端以40位字符串显示出来。这个40位字符串是来自于mysql的密码库。如果要改用户名密码的话update t_user set password=password('root') where username='Jim',将用户名为Jim的密码修改为root。
    两次用password()函数给root字符串加密,得出来的结果一样,说明密码产生自mysql的密码库

    脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。脏读就是读到了一个未提交的中间数据。

    不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(主要修改) 两次读取中间被修改了

    幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。(针对insert)

    Mysql主要包含四种隔离状态:

    事务隔离级别

    脏读

    不可重复读

    幻读

    读未提交(read-uncommitted)

    不可重复读(read-committed)

    可重复读(repeatable-read)

    串行化(serializable)

    首先,需要明白一点,隔离程度越强,事务的执行效率越低。

    ANSI/ISO SQL 定义了 4 种标准隔离级别:

    ① Serializable(串行化):花费最高代价但最可靠的事务隔离级别。

    “写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

    事务 100% 隔离,可避免脏读、不可重复读、幻读的发生。

    ② Repeatable read(可重复读,默认级别):多次读取同一范围的数据会返回第一次查询的快照,即使其他事务对该数据做了更新修改。事务在执行期间看到的数据前后必须是一致的。

    但如果这个事务在读取某个范围内的记录时,其他事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行,这就是幻读。

    可避免脏读、不可重复读的发生。但是可能会出现幻读。

    ③ Read committed (读已提交):保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。

    可避免脏读的发生,但是可能会造成不可重复读。

    大多数数据库的默认级别就是 Read committed,比如 Sql Server , Oracle。

    ④ Read uncommitted (读未提交):最低的事务隔离级别,一个事务还没提交时,它做的变更就能被别的事务看到。

    任何情况都无法保证。

     请你回答一下mongodb和redis的区别

    内存管理机制上:Redis 数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。MongoDB 数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

    支持的数据结构上:Redis 支持的数据结构丰富,包括hash、set、list等。

    MongoDB 数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富

    Redis是单线程的,但是为什么这么高效呢?

    虽然Redis文件事件处理器以单线程方式运行,但是通过使用I/O多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与Redis服务器中其他同样以单线程运行的模块进行对接,这保持了Redis内部单线程设计的简单性。

    Redis的数据类型有哪些,底层怎么实现?

    1)字符串:整数值、embstr编码的简单动态字符串、简单动态字符串(SDS)

    2)列表:压缩列表、双端链表

    3)哈希:压缩列表、字典

    4)集合:整数集合、字典

    5)有序集合:压缩列表、跳跃表和字典

    MySQL Redis MongoDB的使用场景和优缺点

    所以总结一下,MongoDB 的适用场景为:数据不是特别重要(例如通知,推送这些),数据表结构变化较为频繁,数据量特别大,数据的并发性特别高,数据结构比较特别(例如地图的位置坐标),这些情况下用 MongoDB , 其他情况就还是用 MySQL ,这样组合使用就可以达到最大的效率。

     

    MongoDB更类似Mysql,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询JSON数据,能存储海量数据,但是不支持事务。

    Mysql在大数据量时效率显著下降,MongoDB更多时候作为关系数据库的一种替代。

    一般MySQL在单表数据量超过500万后,性能就会下降的比较快

    内存管理机制

    Redis数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的LRU算法删除数据。

    MongoDB数据存在内存,由linux系统mmap实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

    支持的数据结构

    Redis支持的数据结构丰富,包括hash、set、list等。

    MongoDB数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

    性能

    二者性能都比较高,应该说都不会是瓶颈。

    可靠性

    二者均支持持久化。

    集群

     MongoDB集群技术比较成熟,Redis从3.0开始支持集群。

    不适用场景

    Ø  需要使用复杂sql的操作

    Ø  事务性系统

    MySQL

    MySQL 是一个关系型数据库。
    MySQL在 WEB 应用方面 MySQL 是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
    MySQL 是一种关联数据库管理系统, 关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
    MySQL 所使用的 SQL 语言是用于访问数据库的最常用标准化语言。其社区版的性能卓越,搭配 PHP 和 Apache 可组成良好的开发环境。

    优点

    1、体积小、速度快、总体拥有成本低,开源,提供的接口支持多种语言连接操作。
    2、支持多种操作系统。
    3、MySQL 的核心程序采用完全的多线程编程。线程是轻量级的进程,它可以灵活地为用户提供服务,而不过多的系统资源。用多线程和C语言实现的MySQL 能很容易充分利用CPU。 
    4、 MySQL 有一个非常灵活而且安全的权限和口令系统。当客户与MySQL 服务器连接时,他们之间所有的口令传送被加密,而且MySQL 支持主机认证。
    5.、MySQL 能够提供很多不同的使用者界面,包括命令行客户端操作,网页浏览器,以及各式各样的程序语言界面,例如 C++,Perl,Java,PHP,以及Python。你可以使用事先包装好的客户端,或者干脆自己写一个合适的应用程序。MySQL可用于 Unix,Windows,以及OS/2等平台,因此它可以用在个人电脑或者是服务器上。

    缺点 

    1、不支持热备份。

    2、MySQL不支持自定义数据类型。

    3、MySQL最大的缺点是其安全系统,主要是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变。

    4、MySQL对存储过程和触发器支持不够良好。

    5、尽管 MySQL 理论上仍是开源产品,也有人抱怨它诞生之后更新缓慢。然而,应该注意到有一些基于 MySQL 并完整集成的数据库(如 MariaDB),在标准的 MySQL 基础上带来了额外价值。

    6、MySQL对XML支持不够良好。

    MongoDB 和 Redis 都是 NoSQL(非关系型的数据库),采用结构型数据存储。
    二者在使用场景中,存在一定的区别, 这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。
    MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主从模式。

    Redis

    Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
    它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
     

    优点:

    1、读写性能优异。
    2、支持数据持久化,支持 AOF 和 RDB 两种持久化方式。
    3、支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
    4、数据结构丰富:数据结构丰富:支持 string、hash、set、sortedset、list 等数据结构。
     

    缺点:

    1、Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的 IP 才能恢复。
    2、 主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后还会引入数据不一致的问题,降低了系统的可用性。
    3、Redis 的主从复制采用全量复制,复制过程中主机会 fork 出一个子进程对内存做一份快照, 并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入 集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一 次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
    4、 Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

    MongoDB

    MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
    在高负载的情况下,添加更多的节点,可以保证服务器性能。
    MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
    MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
    MongoDB的数据索引是B-树。

    优点:

    1、弱一致性(最终一致),更能保证用户的访问速度。

    2、文档结构的存储方式,能够更便捷的获取数。
    3、内置 GridFS,高效存储二进制大对象 (比如照片和视频)。

    4、内置Sharding。提供基于Range的Auto Sharding机制:一个collection可按照记录的范围,分成若干个段,切分到不同的Shard上。

    5、第三方支持丰富。(这是与其他的NoSQL相比,MongoDB也具有的优势)。

    6、性能优越:在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 

     

    缺点: 

    1、mongodb不支持事务操作。所以事务要求严格的系统(如果银行系统)肯定不能用它。
    2、mongodb占用空间过大。
    3、MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方。
     
     
     
     
     
     
     
     
     
     

    mysql 存储引擎

    数据库对同样的数据,有着不同的存储方式和管理方式,在mysql中,称为存储引擎。
     
    memory建立起来的表,数据,全部存在内存里,不存放在磁盘上,它的速度是非常快的
    但是也有一个问题,如果服务器一旦关机,内容就都没有了
    所以一般 ,不需要持久保存的,可以用memory引擎
     
     
    myisam引擎有个优点,我们给别人建完数据库
    想把数据给他,可以直接拷贝
    data下的文件即可 test目录就是test库的所有数据
    inmysqlmysql5.6.12data est
    而innodb是不可以的,它是多张表,多个库混在一起写的,直接拷贝那个文件不好使的
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    Java基础中的一些注意点(续)
    Java基础中的一些注意点
    Java基础知识学习
    JavaScript DOM2
    JavaScript window
    函数
    JavaScript数组
    JavaScript循环练习2
    JavaScript循环练习
    JavaScript循环
  • 原文地址:https://www.cnblogs.com/DSKer/p/10935143.html
Copyright © 2011-2022 走看看