面试七:数据库mysql

1.高并发查询 数据库优化

1、优化sql
2、分库分表
3、读写分离
4、nosql数据库
5、缓存
6、索引

2.怎么优化sql?

1.建立索引(explain字段查询索引有没有用到,索引不是越多越好)
2.查询数量多的时候使用LIMIT
3.避免 SELECT *
4.用IN来替换OR
5.LIKE双百分号无法使用到索引

id:选择标识符
select_type:表示查询的类型。
table:输出结果集的表
partitions:匹配的分区
type:表示表的连接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引

key_len:索引字段的长度
ref:列与索引的比较
rows:扫描出的行数(估算的行数)
filtered:按表条件过滤的行百分比
Extra:执行情况的描述和说明

3.mysql怎么分库分表?怎么设计?怎么读写分离?

取模 1、中间变量 = user_id%(库数量*每个库的表数量);
2、库序号 = 取整(中间变量/每个库的表数量);
3、表序号 = 中间变量%每个库的表数量;
例如:数据库有256 个,每一个库中有1024个数据表,用户的user_id=262145,按照上述的路由策略,可得:

1、中间变量 = 262145%(256*1024)= 1;
2、库序号 = 取整(1/1024)= 0;
3、表序号 = 1%1024 = 1;
这样的话,对于user_id=262145,将被路由到第0个数据库的第1个表中。

读写分离:主从结构
1.当master正常时,读操作发生在两个slave上,写操作发生在master上。
master通过主从配置实时同步数据到两个slave上。

2.当master挂了,为了数据的一致性,和master为主从关系的slave2被停止访问。
这时slave1负责读和写,当master重新恢复后,slave1同步数据给master,然后再次恢复最初读写状态。

4.varchar和text区别,text的长度

varchar,text为可变长

text存储可变长度的非Unicode数据,最大长度为2^31-1个字符。

5.数据库四大特性

ACID

原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)

6.数据库索引

普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它 是一种特殊的唯一索引,不允许有空值。
全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
索引并不是越多越好,是要占磁盘空间的。

Mysql索引主要有两种结构:B+树和hash.

hash:

优点:当查找某一条记录的时候,速度非常快.当时因为是hash结构,每个键只对应一个值

缺点:是散列的方式分布.所以他并不支持范围查找和排序等功能.

B+树:

优点:数据结构以平衡树的形式来组织,因为是树型结构,所以更适合用来处理排序,范围查找等功能.

相对hash索引,B+树在查找单条记录的速度虽然比不上hash索引,但是因为更适合排序等操作

索引失效的几种情况

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)

要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

2.对于多列索引,不是使用的第一部分,则不会使用索引

3.like查询以%开头

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

7.外键怎么设计

主键是能确定一条记录的唯一标识。
外键用于与另一张表的关联,是能够确定令一张表记录的字段,用于保持数据的一致性。

有外键的时候,数据库会自动帮你检查A的b是否在B的b中存在。 --尽量不用

删除有外键关联表的时候,先禁用外键约束,set foreign_key_checks=0;
再删除数据,再启动外键约束,set foreign_key_checks=1

8.为何说外键有性能问题:

1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增删,
更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;

9.数据库的事务隔离级别

ISOLATION_READ_NOT_COMMITTED(读未提交):会出现幻读、脏读、不可重复读
ISOLATION_READ_COMMITTED(读已提交):造成幻读、不可重复读(oracle默认)
ISOLATION_REPEATABLE_READ(可重复读):但会出现幻读 (mysql默认)
ISOLATION_SERIALIZABLE(序列化):防止脏读、不可重复读、幻读

10.什么是脏读、不可重复读、幻读

脏读:两个并发事务,事务b读取了事务a尚未提交的数据。
幻读:一个事务修改所有,另一个事务新增,发现有一个没有改掉。
不可重复读:事务a读取了数据,事务b修改,事务a再读,就发现不一样。

11.选用的mysql数据库存储引擎?

1)InnoDB:支持事务安全表(ACID),支持行锁定和外键是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键

2)MyISAM:拥有较高的插入、查询速度,但不支持事务,不支持外键。

3)MEMORY:将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问

InnoDB: 支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高
(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除
操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。

MyISAM: 插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择
MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用。

MEMORY: 所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,
对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,
这类数据库只使用在相对较小的数据库表。

同一个数据库也可以使用多种存储引擎的表。如果一个表要求比较高的事务处理,可以选择InnoDB。
这个数据库中可以将查询要求比较高的表选择MyISAM存储。如果该数据库需要一个用于查询的临时表,
可以选择MEMORY存储引擎。

12.存放表情字段的表怎么设计?

utf8mb4

13.mysql去重

用where,紧接着group by 分组,再次筛选则用having

eg:查询选课在三门以上且各门课程均及格的学生的学号及其总成绩,查询结果按总成绩降序列出。
程序清单如下:
SELECT SNO,SUM(SCORE) AS TotalScore
FROM SC
WHERE SCORE>=60
GROUP BY SNO
HAVING COUNT(*)>=3
ORDER BY SUM(SCORE) DESC

14.什么是锁、行锁、表锁?

锁:是协调多个进程或线程并发访问某一资源的一种机制。

表锁:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般

Myisam:共享锁(读)、排他锁(写)。

Innodb:行锁是基于索引实现的,如果不通过索引访问数据,InnoDB会使用表锁。

15.binlog日志

Mysql的binlog日志作用是用来记录mysql内部增删改查等对mysql数据库有更新的内容的记录(对数据库的改动),对数据库的查询select或show等不会被binlog日志记录;主要用于数据库的主从复制以及增量恢复

MySQL binlog的三种工作模式

(1)Row level

日志中会记录每一行数据被修改的情况,然后在slave端对相同的数据进行修改。

优点:能清楚的记录每一行数据修改的细节

缺点:数据量太大

(2)Statement level(默认)

每一条被修改数据的sql都会记录到master的bin-log中,slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql再次执行

优点:解决了 Row level下的缺点,不需要记录每一行的数据变化,减少bin-log日志量,节约磁盘IO,提高新能

缺点:容易出现主从复制不一致

(3)Mixed(混合模式)

结合了Row level和Statement level的优点
  
16.MySQL 主从同步延时问题

半同步复制,用来解决主库数据丢失问题,指的就是主库写入 binlog 日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了。
并行复制,用来解决主从同步延时问题,指的是从库开启多个线程,并行读取 relay log 中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。

你可能感兴趣的:(JAVA)