跳转至

数据库面试题(爪哇程序员)

456.存储引擎概念

原文:https://zwmst.com/3987.html

数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以 获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。存储引擎主要有:

  1. MyIsam
  2. InnoDB
  3. Memory
  4. Archive
  5. Federated

457.InnoDB(B+树)

原文:https://zwmst.com/3989.html

InnoDB 底层存储结构为B+树, B树的每个节点对应innodb的一个page,page大小是固定的,一般设为 16k。其中非叶子节点只有键值,叶子节点包含完成数据。

适用场景:

  1. 经常更新的表,适合处理多重并发的更新请求。
  2. 支持事务。
  3. 可以从灾难中恢复(通过 bin-log 日志等)。
  4. 外键约束。只有他支持外键。
  5. 支持自动增加列属性 auto_increment。

458.TokuDB(Fractal Tree-节点带数据)

原文:https://zwmst.com/3991.html

TokuDB 底层存储结构为 Fractal Tree,Fractal Tree 的结构与 B+树有些类似, 在 Fractal Tree中,**每一个 child 指针除了需要指向一个 child 节点外,还会带有一个 Message Buffer ,这个Message Buffer 是一个 FIFO 的队列,用来缓存更新操作。

例如,一次插入操作只需要落在某节点的 Message Buffer 就可以马上返回了,并不需要搜索到叶子节点。这些缓存的更新会在查询时或后台异步合并应用到对应的节点中。

TokuDB 在线添加索引,不影响读写操作, 非常快的写入性能, Fractal-tree 在事务实现上有优势。 他主要适用于访问频率不高的数据或历史数据归档。

459.MyIASM

原文:https://zwmst.com/3993.html

MyIASM是 MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当 INSERT(插入)或 UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。

ISAM 执行读取操作的速度很快,而且不占用大量的内存和存储资源。在设计之初就预想数据组织成有固定长度的记录,按顺序存储的。—ISAM 是一种静态索引结构。

缺点是它不 支持事务处理。

460.Memory

原文:https://zwmst.com/3995.html

Memory(也叫 HEAP)堆内存:使用存在内存中的内容来创建表。每个 MEMORY 表只实际对应一个磁盘文件。MEMORY 类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH 索引。但是一旦服务关闭,表中的数据就会丢失掉。 Memory 同时支持散列索引和 B 树索引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索引相等的比较快但是对于范围的比较慢很多。

461.索引

原文:https://zwmst.com/3997.html

索引(Index)是帮助 MySQL 高效获取数据的数据结构。常见的查询算法,顺序查找,二分查找,二叉排序树查找,哈希散列法,分块查找,平衡多路搜索树 B 树(B-tree)

462.常见索引原则

原文:https://zwmst.com/3999.html

  1. 选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。

  2. 为经常需要排序、分组和联合操作的字段建立索引:

  3. 为常作为查询条件的字段建立索引。

  4. 限制索引的数目: 越多的索引,会使更新表变得很浪费时间。

  5. 尽量使用数据量少的索引

  6. 如果索引的值很长,那么查询的速度会受到影响。

  7. 尽量使用前缀来索引 如果索引字段的值很长,最好使用值的前缀来索引。

  8. 删除不再使用或者很少使用的索引

  9. 最左前缀匹配原则,非常重要的原则。

  10. 尽量选择区分度高的列作为索引 区分度的公式是表示字段不重复的比例

  11. 索引列不能参与计算,保持列“干净”:带函数的查询不参与索引。

  12. 尽量的扩展索引,不要新建索引。

463.数据库三范式

原文:https://zwmst.com/4001.html

范式是具有最小冗余的表结构。

464.第一范式(1st NF -列都是不可再分)

原文:https://zwmst.com/4005.html

第一范式的目标是确保每列的原子性:如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)

465.第二范式(2nd NF-每个表只描述一件事情)

原文:https://zwmst.com/4007.html

首先满足第一范式,并且表中非主键列不存在对主键的部分依赖。 第二范式要求每个表只描述一件事情。

466.第三范式(3rd NF- 不存在对非主键列的传递依赖)

原文:https://zwmst.com/4009.html

第三范式定义是,满足第二范式,并且表中的列不存在对非主键列的传递依赖。除了主键订单编号外,顾客姓名依赖于非主键顾客编号。

467.数据库事务

原文:https://zwmst.com/4011.html

事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行 。事务是一个不可分割的工作逻辑单元。

468.原子性(Atomicity)

原文:https://zwmst.com/4013.html

事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。

469.一致性(Consistency)

原文:https://zwmst.com/4015.html

当事务完成时,数据必须处于一致状态。

470.隔离性(Isolation)

原文:https://zwmst.com/4017.html

对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。

471.永久性(Durability)

原文:https://zwmst.com/4019.html

事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。

472.存储过程(特定功能的 SQL 语句集)

原文:https://zwmst.com/4021.html

一组为了完成特定功能的 SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

473.存储过程优化思路

原文:https://zwmst.com/4023.html

  1. 尽量利用一些 sql 语句来替代一些小循环,例如聚合函数,求平均函数等。
  2. 中间结果存放于临时表,加索引。
  3. 少使用游标。sql 是个集合语言,对于集合运算具有较高性能。而 cursors 是过程运算。比如对一个 100 万行的数据进行查询。游标需要读表 100 万次,而不使用游标则只需要少量几次读取。
  4. 事务越短越好。sqlserver 支持并发操作。如果事务过多过长,或者隔离级别过高,都会造成并发操作的阻塞,死锁。导致查询极慢,cpu 占用率极地。
  5. 使用 try-catch 处理错误异常。
  6. 查找语句尽量不要放在循环内。

474.触发器(一段能自动执行的程序)

原文:https://zwmst.com/4025.html

触发器是一段能自动执行的程序,是一种特殊的存储过程,触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作时触发。诸如:update、insert、delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。触发器是当对某一个表进行操作时触发。诸如:update、insert、delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。

475.数据库并发策略

原文:https://zwmst.com/4027.html

并发控制一般采用三种方法,分别是乐观锁和悲观锁以及时间戳。

476.乐观锁

原文:https://zwmst.com/4030.html

乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据;悲观锁就刚好相反,觉得自己读数据库的时候,别人可能刚好在写自己刚读的数据,其实就是持一种比较保守的态度;时间戳就是不加锁,通过时间戳来控制并发出现的问题。

477.悲观锁

原文:https://zwmst.com/4032.html

悲观锁就是在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加锁,只有自己把数据读完了,才允许别人修改那部分数据,或者反过来说,就是自己修改某条数据的时候,不允许别人读取该数据,只有等自己的整个事务提交了,才释放自己加上的锁,才允许其他用户访问那部分数据。

478.时间戳

原文:https://zwmst.com/4034.html

时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”,每次读出来的时候,把该字段也读出来,当写回去的时候,把该字段加1,提交之前 ,跟数据库的该字段比较一次,如果比数据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁机制,但是这种方法可以大大提高数据库处理的并发量,

479.行级锁

原文:https://zwmst.com/4036.html

行级锁是一种排他锁,防止其他事务修改此行;在使用以下语句时,Oracle 会自动应用行级锁:

  1. INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];
  2. SELECT … FOR UPDATE 语句允许用户一次锁定多条记录进行更新
  3. 使用 COMMIT 或 ROLLBACK 语句释放锁。

480.表级锁

原文:https://zwmst.com/4038.html

表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使用的MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

481. 页级锁

原文:https://zwmst.com/4040.html

页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB 支持页级锁

482.基于 Redis 分布式锁

原文:https://zwmst.com/4042.html

  1. 获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key为 val 的字符串,返回 1;若 key 存在,则什么都不做,返回 0)加锁,锁的 value值为一个随机生成的 UUID,在释放锁的时候进行判断。并使用 expire 命令为锁添加一个超时时间,超过该时间则自动释放锁。
  2. 获取锁的时候调用 setnx,如果返回 0,则该锁正在被别人使用,返回 1 则成功获取锁。 还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
  3. 释放锁的时候,通过 UUID 判断是不是该锁,若是该锁,则执行 delete 进行锁释放。

483.分区分表

原文:https://zwmst.com/4044.html

分库分表有垂直切分和水平切分两种。

484.垂直切分(按照功能模块)

原文:https://zwmst.com/4046.html

将表按照功能模块、关系密切程度划分出来,部署到不同的库上。例如,我们会建立定义数据库 workDB、商品数据库 payDB、用户数据库 userDB、日志数据库 logDB 等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。

485.水平切分(按照规则划分存储)

原文:https://zwmst.com/4048.html

当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如 userID 散列,进行划分,然后存储到多个结构相同的表,和不同的库上。

486.两阶段提交协议

原文:https://zwmst.com/4050.html

分布式事务是指会涉及到操作多个数据库的事务,在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。

XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。 XA 接口函数由数据库厂商提供。

二阶段提交(Two-phaseCommit)是指,在计算机网络以及数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。通常,二阶段提交也被称为是一种协议(Protocol))。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的 ACID 特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

487.准备阶段

原文:https://zwmst.com/4053.html

事务协调者(事务管理器)给每个参与者(资源管理器)发送 Prepare 消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的 redo 和 undo 日志,但不提交,到达一种“万事俱备,只欠东风”的状态。

488.提交阶段

原文:https://zwmst.com/4055.html

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

489.缺点

原文:https://zwmst.com/4059.html

同步阻塞问题

  1. 执行过程中,所有参与节点都是事务阻塞型的。

单点故障

  1. 由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。

数据不一致(脑裂问题)

  1. 在二阶段提交的阶段二中,当协调者向参与者发送 commit 请求之后,发生了局部网络异常或者在发送 commit 请求过程中协调者发生了故障,导致只有一部分参与者接受到了commit 请求。于是整个分布式系统便出现了数据部一致性的现象(脑裂现象)。

二阶段无法解决的问题(数据状态不确定)

  1. 协调者再发出 commit 消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

490.三阶段提交协议

原文:https://zwmst.com/4061.html

三阶段提交( Three-phase commit ) , 也 叫 三 阶 段 提 交 协 议 ( Three-phase commit protocol),是二阶段提交(2PC)的改进版本。

与两阶段提交不同的是,三阶段提交有两个改动点。

  1. 引入超时机制。同时在协调者和参与者中都引入超时机制。
  2. 在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。也就是说,除了引入超时机制之外,3PC 把 2PC 的准备阶段再次一分为二,这样三阶段提交就有 CanCommit、PreCommit、DoCommit 三个阶段。

491.CanCommit 阶段

原文:https://zwmst.com/4063.html

协调者向参与者发送 commit 请求,参与者如果可以提交就返回 Yes 响应,否则返回 No 响应。

492.PreCommit 阶段

原文:https://zwmst.com/4065.html

协调者根据参与者的反应情况来决定是否可以继续进行,有以下两种可能。假如协调者从所有的参与者获得的反馈都是 Yes 响应,那么就会执行事务的预执行假如有任何一个参与者向协调者发送了 No 响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。

493.doCommit 阶段

原文:https://zwmst.com/4067.html

该阶段进行真正的事务提交,主要包含

  1. 协调这发送提交请求
  2. 参与者提交事务
  3. 参与者响应反馈( 事务提交完之后,向协调者发送 Ack 响应。)
  4. 协调者确定完成事务。

494.柔性事务

原文:https://zwmst.com/4069.html

在电商领域等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于 CAP 理论以及 BASE 理论,有人就提出了 柔性事务 的概念。CAP(一致性、可用性、分区容忍性)理论大家都理解很多次了,这里不再叙述。说一下 BASE 理论,它是在 CAP 理论的基础之上的延伸。包括 基本可用(Basically Available)、柔性状态(Soft State)、最终一致性(Eventual Consistency)。

495. 柔性事务-两阶段型

原文:https://zwmst.com/4071.html

就是分布式事务两阶段提交,对应技术上的 XA、JTA/JTS。这是分布式环境下事务处理的典型模式。

496.补偿型

原文:https://zwmst.com/4073.html

TCC 型事务(Try/Confirm/Cancel)可以归为补偿型。

WS-BusinessActivity 提供了一种基于补偿的 long-running 的事务处理模型。服务器 A 发起事务,服务器 B 参与事务,服务器 A 的事务如果执行顺利,那么事务 A 就先行提交,如果事务 B 也执行顺利,则事务 B 也提交,整个事务就算完成。但是如果事务 B 执行失败,事务 B 本身回滚,这时事务 A 已经被提交,所以需要执行一个补偿操作,将已经提交的事务 A 执行的操作作反操作,恢复到未执行前事务 A 的状态。这样的 SAGA 事务模型,是牺牲了一定的隔离性和一致性的,但是提高了 long-running 事务的可用性。

497.异步确保型

原文:https://zwmst.com/4075.html

通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响。

498.最大努力通知型(多次尝试)

原文:https://zwmst.com/4077.html

这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不同的一点是, 在消息由 MQ Server 投递到消费者之后, 允许在达到最大重试次数之后正常结束事务。

499.CAP

原文:https://zwmst.com/4079.html

CAP 原则又称 CAP 定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

500.一致性(C)

原文:https://zwmst.com/4081.html

在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

501.可用性(A)

原文:https://zwmst.com/4083.html

在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)

502.分区容忍性(P)

原文:https://zwmst.com/4085.html

以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择。

887.请简洁描述 MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?

原文:https://zwmst.com/5038.html

SQL 标准定义的四个隔离级别为:

  1. read uncommited :读到未提交数据
  2. read committed:脏读,不可重复读
  3. repeatable read:可重读
  4. serializable :串行事物

888.在 MySQL 中 ENUM 的用法是什么?

原文:https://zwmst.com/5040.html

ENUM 是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用。 SQL 语法如下:

Create table size(name ENUM('Smail,'Medium','Large');

889.CHAR 和 VARCHAR 的区别?

原文:https://zwmst.com/5042.html

CHAR 和 VARCHAR 类型在存储和检索方面有所不同。 CHAR 列长度固定为创建表时声明的长度,长度值范围是 1 到 255。 当 CHAR 值被存储时,它们被用空格填充到特定长度,检索 CHAR 值时需删除尾随空格。

890.列的字符串类型可以是什么?

原文:https://zwmst.com/5044.html

字符串类型是: SET BLOB ENUM CHAR TEXT VARCHAR

891.MySQL 中使用什么存储引擎?

原文:https://zwmst.com/5046.html

存储引擎称为表类型,数据使用各种技术存储在文件中。 技术涉及: Storage mechanism Locking levels Indexing Capabilities and functions.

892.TIMESTAMP 在 UPDATE CURRENT_TIMESTAMP 数据类型上做什么?

原文:https://zwmst.com/5048.html

创建表时 TIMESTAMP 列用 Zero 更新。只要表中的其他字段发生更改,UPDATE CURRENT_TIMESTAMP 修饰符就将时间戳字段更新为当前时间。

893.主键和候选键有什么区别?

原文:https://zwmst.com/5050.html

表格的每一行都由主键唯一标识, 一个表只有一个主键。 主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键引用。

894.MySQL 数据库服务器性能分析的方法命令有哪些?

原文:https://zwmst.com/5052.html

Show status 一些值得监控的变量值: Bytesreceived 和 Bytessent 和服务器之间来往的流量。 Com 服务器正在执行的命令。 Created 在查询执行期限间创建的临时表和文件。 Handler 存储引擎操作。 Select 不同类型的联接执行计划。 Sort_* 几种排序信息。

Show session status like ‘Select’; Show profiles SET profiling=1; Show profiles\G Show profile;

895.LIKE 和 REGEXP 操作有什么区别?

原文:https://zwmst.com/5054.html

LIKE 和 REGEXP 运算符用于表示 ^ 和%。

SELECT * FROM <tablename> WHERE * REGEXP "^b";
SELECT * FROM <tablename> WHERE * LIKE "%b";

896.BLOB 和 TEXT 有什么区别?

原文:https://zwmst.com/5056.html

BLOB

BLOB 是一个二进制对象,可以容纳可变数量的数据。有四种类型的 BLOB

  1. TINYBLOB
  2. BLOB
  3. MEDIUMBLOB 和
  4. LONGBLOB

它们只能在所能容纳价值的最大长度上有所不同。

TEXT

TEXT 是一个不区分大小写的 BLOB。四种 TEXT 类型

  1. TINYTEXT
  2. TEXT
  3. MEDIUMTEXT 和
  4. LONGTEXT

它们对应于四种 BLOB 类型,并具有相同的最大长度和存储要求。 BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小写,对 TEXT 值不区分大小写。

897.数据库的三范式?

原文:https://zwmst.com/5060.html

第一范式:数据库表的每一个字段都是不可分割的。 第二范式:数据库表中的非主属性只依赖于主键。 第三范式:不存在非主属性对关键字的传递函数依赖关系。

898.MySQL 表中允许有多少个 TRIGGERS?

原文:https://zwmst.com/5063.html

在 MySQL 表中允许有六个触发器,如下: BEFORE INSERT AFTER INSERT BEFORE UPDATE AFTER UPDATE BEFORE DELETE and AFTER DELETE

899.什么是通用 SQL 函数?

原文:https://zwmst.com/5065.html

数学函数

  1. Abs(num)求绝对值
  2. floor(num)向下取整
  3. ceil(num)向上取整

字符串函数

  1. insert (s1,index,length,s2) 替换函数
    1. S1 表示被替换的字符串
    2. s2 表示将要替换的字符串
    3. Index 表示被替换的位置, 从 1 开始
    4. Lebgth 表示被替换的长度
  2. upper(str),ucase(str)将字母改为大写
  3. lower(str),lcase(str)将字母改为小写
  4. left(str,length)返回 str 字符串的前 length 个字符
  5. right(str,length)返回 str 字符串的后 length 个字符
  6. substring(str,index,length)返回 str 字符串从 index 位开始长度为length 个字符(index 从 1 开始)
  7. reverse(str)将 str 字符串倒序输出

日期函数

  1. curdate()、current_date( ) 获取当前日期
  2. curtime()、current_time( ) 获取当前日期
  3. now()获取当前日期和时间
  4. datediff(d1、d2)d1 和 d2 之间的天数差
  5. adddate(date,num)返回 date 日期开始,之后 num 天的日期
  6. subdate(date,num)返回 date 日期开始,之前 num 天的日期

聚合函数

  1. Count(字段)根据某个字段统计总记录数(当前数据库保存到多少条数据)
  2. sum(字段)计算某个字段的数值总和
  3. avg(字段)计算某个字段的数值的平均值
  4. Max(字段)、min(字段)求某个字段最大或最小值

900.MySQL 中有哪几种锁?

原文:https://zwmst.com/5067.html

MyISAM 支持表锁,InnoDB 支持表锁和行锁,默认为行锁。 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。

901.MySQL 数据优化。

原文:https://zwmst.com/5069.html

优化数据类型

  1. 避免使用 NULL,NULL 需要特殊处理, 大多数时候应该使用 NOT NULL,或者使用一个特殊的值,如 0,-1 作为默认值。
  2. 仅可能使用更小的字段,MySQL 从磁盘读取数据后是存储到内存中的,然后使用 cpu 周期和磁盘 I/O 读取它,这意味着越小的数据类型占用的空间越小.

小心字符集转换

  1. 客户端或应用程序使用的字符集可能和表本身的字符集不一样,这需要MySQL 在运行过程中隐含地进行转换,此外,要确定字符集如 UTF-8 是否支持多字节字符,因此它们需要更多的存储空间。

_优化 count(mycol) 和 count()

优化子查询

  1. 遇到子查询时,MySQL 查询优化引擎并不是总是最有效的,这就是为什么经常将子查询转换为连接查询的原因了,优化器已经能够正确处理连接查询了,当然要注意的一点是,确保连接表 (第二个表) 的连接列是有索引的,在第一个表上 MySQL 通常会相对于第二个表的查询子集进行一次全表扫描,这是嵌套循环算法的一部分。

优化 UNION

  1. 在跨多个不同的数据库时使用 UNION 是一个有趣的优化方法,UNION 从两个互不关联的表中返回数据,这就意味着不会出现重复的行,同时也必须对数据进行排序,我们知道排序是非常耗费资源的,特别是对大表的排序。
  2. ION ALL 可以大大加快速度,如果你已经知道你的数据不会包括重复行,或者你不在乎是否会出现重复的行,在这两种情况下使用UNION ALL 更适合。此外,还可以在应用程序逻辑中采用某些方法避免出现重复的行,这样 UNION ALL 和 UNION 返回的结果都是一样的,但 UNION ALL 不会进行排序。

902.MySQL 的关键字。

原文:https://zwmst.com/5071.html

添加索引: alter table tableName add 索引(索引字段) 主键:primary key 唯一:unique 全局:fulltext 普通:index 多列: index index_name 页级: 引擎 BDB。次锁定相邻的一组记录。 表级: 引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行。 行级: 引擎 INNODB , 单独的一行记录加锁,对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。 表级锁速度快,但冲突多,行级冲突少,但速度慢。

903.存储引擎。

原文:https://zwmst.com/5073.html

存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。

  1. MyISAM:这种引擎是 mysql 最早提供的。这种引擎又可以分为静态 MyISAM、动态 MyISAM 和压缩 MyISAM 三种:
    1. 静态 MyISAM:如果数据表中的各数据列的长度都是预先固定好的,服务器将自动选择这种表类型。因为数据表中每一条记录所占用的空间都是一样的,所以这种表存取和更新的效率非常高。当数据受损时,恢复工作也比较容易做。
    2. 动态 MyISAM:如果数据表中出现 varchar、text 或 BLOB 字段时,服务器将自动选择这种表类型。相对于静态 MyISAM,这种表存储空间比较小,但由于每条记录的长度不一,所以多次修改数据后,数据表中的数据就可能离散的存储在内存中,进而导致执行效率下降。同时,内存中也可能会出现很多碎片。因此,这种类型的表要经常用optimize table 命令或优化工具来进行碎片整理。
    3. 压缩 MyISAM:以上说到的两种类型的表都可以用 myisamchk 工具压缩。这种类型的表进一步减小了占用的存储,但是这种表压缩之后不能再被修改。另外,因为是压缩数据,所以这种表在读取的时候要先时行解压缩。

但是,不管是何种 MyISAM 表,目前它都不支持事务,行级锁和外键约束的功能。

  1. MyISAM Merge 引擎:这种类型是 MyISAM 类型的一种变种。合并表是将几个相同的 MyISAM 表合并为一个虚表。常应用于日志和数据仓库。
  2. InnoDB:InnoDB 表类型可以看作是对 MyISAM 的进一步更新产品,它提供了事务、行级锁机制和外键约束的功能。
  3. memory(heap):这种类型的数据表只存在于内存中。它使用散列索引,所以数据的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中。
  4. archive:这种类型只支持 select 和 insert 语句,而且不支持索引。
  5. Desc[ribe] tablename:查看数据表的结构。
  6. show engines:命令可以显示当前数据库支持的存储引擎情况。

904.数据库备份。

原文:https://zwmst.com/5076.html

必须要在未登录状态下

  1. 导出整个数据库

    mysqldump -u 用户名 -p 数据库名 > 导出的文件名

  2. 导出一个表

    mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名

  3. 导出一个数据库结构

    mysqldump -u dbuser -p -d --add-drop-table dbname >d:/dbname_db.sql

    -d 没有数据 –add-drop-table 在每个 create 语句之前增加一个 drop table

905.truncate delete drop 的区别。

原文:https://zwmst.com/5078.html

drop(DDL 语句):是不可逆操作,会将表所占用空间全部释放掉; truncate(DDL 语句):只针对于删除表的操作,在删除过程中不会激活与表有关的删除触发器并且不会把删除记录放在日志中;当表被 truncate 后,这个表和索引会恢复到初始大小; delete(DML 语句):可以删除表也可以删除行,但是删除记录会被计入日志保存,而且表空间大小不会恢复到原来; 执行速度:drop>truncate>delete。

906.Redis 是什么?两句话做一下概括。

原文:https://zwmst.com/5080.html

是一个完全开源免费的 key-value 内存数据库 2. 通常被认为是一个数据结构服务器,主要是因为其有着丰富的数据结构 strings、map、 list、sets、 sorted sets。

  1. Redis 使用最佳方式是全部数据 in-memory。
  2. Redis 更多场景是作为 Memcached 的替代者来使用。
  3. 当需要除 key/value 之外的更多数据类型支持时,使用 Redis 更合适。
  4. 当存储的数据不能被剔除时,使用 Redis 更合适。

907.Redis(管道,哈希)。

原文:https://zwmst.com/5082.html

  1. Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
  2. Redis 支持数据的备份,即 master-slave 模式的数据备份。
  3. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

908.Redis 实现原理或机制。

原文:https://zwmst.com/5084.html

Redis 是一个 key-value 存储系统。和 Memcached 类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的 value 类型,除了和 string 外,还支持lists(链表)、sets(集合)和 zsets(有序集合)几种数据类型。这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。 Redis 是一种基于客户端 – 服务端模型以及请求 / 响应协议的 TCP 服务。这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听 Socket 返回,通常是以阻塞模式,等待服务端响应。服务端处理命令,并将结果返回给客户端。 在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。 Redis 管道技术最显著的优势是提高了 Redis 服务的性能。 分区是分割数据到多个 Redis 实例的处理过程,因此每个实例只保存 key 的一个子集。 通过利用多台计算机内存的和值,允许我们构造更大的数据库。 通过多核和多台计算机,允许我们扩展计算能力;通过多台计算机和网络适配器,允许我们扩展网络带宽。 Redis 的一些特性在分区方面表现的不是很好: 涉及多个 key 的操作通常是不被支持的。举例来说,当两个 set 映射到不同的Redis 实例上时,你就不能对这两个 set 执行交集操作。 涉及多个 key 的 Redis 事务不能使用。 当使用分区时,数据处理较为复杂,比如你需要处理多个 rdb/aof 文件,并且从多个实例和主机备份持久化文件。 增加或删除容量也比较复杂。Redis 集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做 presharding 的技术对此是有帮助的。

909.Redis 有两种类型分区。

原文:https://zwmst.com/5086.html

最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的 Redis 实例。 比如,ID 从 0 到 10000 的用户会保存到实例 R0,ID 从 10001 到 20000 的用户会保存到 R1,以此类推。 这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对 Redis 来说并非是好的方法。 哈希分区:另外一种分区方法是 hash 分区。这对任何 key 都适用,也无需是object_name: 这种形式,像下面描述的一样简单: 用一个 hash 函数将 key 转换为一个数字,比如使用 crc32 hash 函数。对 keyfoobar 执行 crc32(foobar) 会输出类似 93024922 的整数。 对这个整数取模,将其转化为 0-3 之间的数字,就可以将这个整数映射到 4 个Redis 实例中的一个了。93024922 % 4 = 2,就是说 key foobar 应该被存到 R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用 % 操作符实现。 实际上,上面的集群模式还存在两个问题:

  1. 扩容问题: 因为使用了一致性哈稀进行分片,那么不同的 key 分布到不同的 Redis-Server 上,当我们需要扩容时需要增加机器到分片列表中,这时候会使得同样的 key 算出来落到跟原来不同的机器上,这样如果要取某一个值,会出现取不到的情况,对于这种情况,Redis 的作者提出了一种名为 Pre-Sharding 的方式:Pre-Sharding 方法是将每一个台物理机上,运行多个不同断口的 Redis 实例,假如有三个物理机,每个物理机运行三个 Redis 实际,那么我们的分片列表中实际有 9 个 Redis 实例,当我们需要扩容时,增加一台物理机,步骤如下:
    1. 在新的物理机上运行 Redis-Server;
    2. 该 Redis-Server 从属于 (slaveof) 分片列表中的某一 Redis-Server(假设叫 RedisA);
    3. 等主从复制 (Replication) 完成后,将客户端分片列表中 RedisA 的IP 和端口改为新物理机上 Redis-Server 的 IP 和端口;
    4. 停止 RedisA。 这样相当于将某一 Redis-Server 转移到了一台新机器上。Prd-Sharding 实际上是一种在线扩容的办法,但还是很依赖 Redis 本身的复制功能的,如果主库快照数据文件过大,这个复制的过程也会很久,同时会给主库带来压力。所以做这个拆分的过程最好选择为业务访问低峰时段进行。
  2. 单点故障问题: 还是用到 Redis 主从复制的功能,两台物理主机上分别都运行有 Redis-Server,其中一个 Redis-Server 是另一个的从库,采用双机热备技术,客户端通过虚拟 IP 访问主库的物理 IP,当主库宕机时,切换到从库的物理 IP。只是事后修复主库时,应该将之前的从库改为主库(使用命令 slaveof no one),主库变为其从库(使命令 slaveof IP PORT),这样才能保证修复期间新增数据的一致性。


回到顶部