1.事务的特征有哪些?分别是什么意思?

A 原子性 在一个事务的所有操作,要么全部成功,要么全部失败
C 一致性 事务执行的前后,数据保持一致性,例如转账
D 持久性 事务一旦提交,则永久保存,即使故障也不丢失
I 隔离性 多个并发的事务应该要互相隔离,如果隔离不好,则产生:

  1. **脏读:** 一个事务读取到另一个事务未提交的数据<br /> **不可重复读** :一个事务读到另一个事务的已提交的更新数据<br /> **幻读:** 一个事务读到另一个事务的已提交的插入数据<br />为了防止这些现象,修改数据库的隔离级别
级别 脏读 不可重复读 幻读 说明
read uncommited
read commited oracle默认隔离级别
repeatable read mysql默认隔离级别
Serializable

* 数据库的隔离级别:

Read Uncommitted :读取未提交内容:

  • 在这个隔离级别,所有事务都可以看到未提交事务的执行结果;在这种级别上,可能会产生许多问题,除非用户真的知道自己在做什么,并且有很好的理由去这样做。本隔离级别很少用于实际应用,因为它的性能也不比其他级别的性能好多少,而别的级别还有其他更多的优点。读取为提交数据,也被称为“脏读”; 会出现的情况:脏读,幻读

    Read Committed:读取提交内容:

  • 大多数数据库系统的默认隔离级别(但是,MySQL的默认隔离级别并不是这个),满足了隔离早先最简单的定义:一个事务开始的时候,只能看见已经提交的事务所做出的改变,一个事务从开始到提交前,所做的任何数据都是不可见的,除非已经提交。这种隔离级别也支持所谓的不可重复读。这意味着用户运行同一条语句两次,看到的结果都是不同的; 幻读

    Repeatable Read :可重复读:

  • 这是MySQL的默认隔离级别,该级别解决的读未提交内容隔离级别所导致的问题;它保证了同一事务的多个实例在并发读取事务时,会看到同样的数据行。不过,这会导致另外一个头疼的问题就是“幻读”。在InnoDB和Falcon存储引擎在通过多版本的并发控制机制解决了幻读的问题; 幻读

    Serialzable : 可串行化:

  • 这个隔离级别是最高的隔离级别;通过强制事务的排序,让他不能相互冲突,从而解决了幻读的问题。简单来说就是可串行化在每个读的操作上加锁,每个读操作只有获取到锁才能进行读操作;因此在实际使用的时候,会导致极大的性能下降,但是如果要确保数据的稳定和安全性,且不要求高并发的时候,用户可以去选择该隔离级别;


* ,事务的传播行为:7

  • PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。(required需要,没有新建,有加入)
  • PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。(supports支持,有则加入,没有就不管了,非事务运行)
  • PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。(mandatory强制性,有则加入,没有异常)
  • PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。(requires_new需要新的,不管有没有,直接创建新事务)
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。(not supported不支持事务,存在就挂起)
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。(never不支持事务,存在就异常)
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。(nested存在就在嵌套的执行,没有就找是否存在外面的事务,有则加入,没有则新建)

表级锁:
对整个表记录锁定,一个事务修改数据的时候,另一个事务无法修改数据.
语法:
lock table tb_user read loacl;
update tb_user xxxxxx
insert into tb_user
unlock;
特点:锁定范围比较大,比较影响性能
应用场景:在数据迁移场景下使用
行级锁:
对表的某条(某行)记录锁定
行级锁分别为 共享锁 和 拍他锁
共享锁:一个事务在修改记录的时候,另一个事务无法修改记录,但是可以读取.
update tb_user set sex = ‘女’where id =1 lock in share mode;
排他锁:一个事务在修改记录的时候,另一个事务无法修改和读取数据.
select from tb_user where id = 1 for update;
3.MySQL一张表中有1千万条数据,现在查询比较慢,有什么优化思路?(必问)或问:请问MySQL优化思路?
1)SQL语句优化,如:需要查询什么避免用
,尽量比较时用>= <= 尽可能用exits not exits,少用in not in
2)需要考虑对查询频繁的字段建立索引或联合(复合)索引.
但是要避免写SQL语句时索引失效的情况,如何得知SQL是否执行索引?使用explain查询执行计划
常见的可能导致索引失效的情况:
使用or, in like查询&放在右边
如在使用联合索引,遵守最左前缀原则
3)如果说表单数据太多(上千万),可以采用水平分库分表(采用ShardingJdbc技术)
4)如果业务数据用于复杂的查询场景,把MySQL数据库导入Elasticsearch中,进行全文检索,从而效率更高

4.如何防止SQL注入?

1)JDBC使用PreparedStatement(不要使用Statement),在用mybatis/mybatis-plus时,则尽量使用#{param},不要使用${param},因为PrepareStatement可以先预编译sql语句(SQL语义确定),在进行复制,这样不会改变sql语义.
2)使用过滤器过滤用户输入的特殊符号(# < > where)
3)对请求参数字符串长队,格式进行限制

5.MySQL索引有哪些类型?

1)普通索引(INDEX):最基本的索引,没有任何限制
create index indexName on tableName(fieldName)
2)唯一索引(UNIQUE):与”普通索引”类似,不同的就是:索引列的值必须唯一,但允许有空值,一张表可用多个唯一索引
3)主键索引(PRIMARY KEY):是一种特殊的唯一索引,不允许有空值,一张表只能有一个主键索引
4)组合索引(INDEX)/复合索引/联合索引:为了更多的提高mysql效率可简历组合索引,遵循”最左前缀”原则.
create index indexName on tableName(fieldName1,fieldName2…)
5)全文索引(FULLTEXT):仅可用于MyISAM表,用于在一篇文章中,检索文本信息的,针对较大的数据,生成全文索引,很耗时间与空间.

* 索引是什么?索引的基本原理:

  • 索引在MySQL中也叫一种键,是存储引擎用于快速找到数据记录的一种数据结构,索引是数据库保证高性能非常关键的点;尤其在数据量越来越大的时候,索引对性能的优化来讲显得非常重要;
  • 因此,索引的优化应该是对查询性能优化最有效 的手段了;
  • 索引(原理):索引其实就是相当于书本的目录,先定位到章节,然后定位到这个章节的一个小节,再去定位到页;这样子比你全书查询页要快得多;
    • 优点)本质就是在大量的数据中尽可能地去减少搜索的范围,减少查询的次数,来筛选出需要的结果,同时把随机的事件变成有顺序的事件;
  • 索引的基本结构
    • 在InnoDB引擎中,数据结构都是采用了B+树索引;
    • 而在Memory引擎采用的是Hash索引;(memory引擎在断电的时候会导致数据丢失)
  • 虽然B+树索引的单条记录的查询速度比不上Hash索引,但是更适合排序的操作,但是呢,B+树的高度更低,因此在多条查询的速度要更快,因此,常用的也是B+树索引;毕竟,在日常开发也不可能只对单条数据进行查询;
  • 索引的缺点:
  • 索引会占用内存空间,因此,在非必要的字段就不要去建立索引;避免在后续数据量大的时候导致内存的占用;而且在需要频繁更新语句的情况下,也不要使用索引,因为在更新数据的时候如果有索引的存在,那数据库还有对索引进行维护,导致性能的降低;
  • 建立索引的时机:
  • 一般在开发初期是不会大量建立索引的,费时费力;一般是在后续上线后的迭代开发对原来的架构进行优化才去进行建立索引;

    6.为什么MySQL的索引采用B+树,而不是B树,Hash,二叉树,红黑树?

    1)Hash,只适合等值查询,不适合范围查询 id = 5
    2)一般二叉树,可能会退化成链表,相当于全表扫描
    3)红黑树,是一种特殊化的平衡二叉树,MySQL数据量很大时,索引的体积也会很大,内存放不下的会从磁盘存取,树的层次太高的华,读取磁盘的次数就多了.
    4)B树在范围查询时,存在回旋查找的问题,导致性能不高.B+树叶子节点是有序链表,便于范围查询(MySQL的索引对B+树的叶子节点进行了改造,改造成了双向链表)

    7.MySQL的MyISAM和InnoDB的索引使用B+Three实现有什么不同?

    InnoDB采用聚簇索引存储,索引和数据存储在一个文件中,默认使用表的主键列值来构建B+树(表没有定义主键也会包含隐式主键) .ibd文件
    MyISAM采用非聚簇索引存储,索引和数据文件是分两个文件存储的,可以没有主键索引.

    8.请问你们用ShardingJDBC分裤分表后是如何扩容的?(问法:你们使用ShardingJDBC后,原有数据库的数据是怎样迁移到新的数据库的?)

    1) 站点挂一个公告”为了为广大用户提供更好的服务,本站/游戏将在今晚00:00-2:00之间升级,届时不能登录,用户周知”
    2) 微服务停止服务,数据库不再有流量写入;
    3) 新建2n个新库,并做好高可用; 2主2从 4主4从
    4) 写一个小脚本进行数据迁移,把数据从n个库里select出来, insert到2
    n个库里;(最耗时)
    5) 修改微服务的数据库路由配置,模n变成模2*n
    6) 微服务重启,新连接库重新对外提供服务

    9.请问关于设计数据库你有什么心得?(必问)

    1)关于数据库的三大范式
    第一范式(1NF):字段不可分,否则就不是关系数据库
    第二范式(2NF):有主键,非主键字段依赖主键;突出唯一性
    第三范式(3NF):非主键字段不能相互依赖.每列都与主键有直接关系
    2)冗余字段设计(解决一对多关系)
    比如文章故意设计冗余作者名字字段,这样查询文章时可以显示作者名称,减少关联表查找作者表,提高查询效率.
    3)一个字段存储多个ID值(用逗号隔开)(解决多对多的关系)
    减少表连接,提高查询效率
    比如自媒体或App文章的多个封面图片地址,设计一个封面images存储了所有封面地址,每个地址用逗号隔开

    10,MySQL的主从复制原理:

    image.png
  1. master主节点服务器有个数据的变更记录二进制日志文件Binlog日志,当数据发送变化的时候,会将其改变写入到该日志中;
  2. 而Slave从节点服务器会探测binlog日志文件,当检测到了日志的变化,会开启一个I/OThread线程请求对二进制事件进行操作;
  3. 同时主节点会为每个I/O Thread线程启动一个dump线程,用来为从节点发送二进制事件,并将BinLog日志文件的二进制数据写入到从节点的中继日志RelayLog中;然后从节点Slave会启动SQL Thread线程从中继日志文件中读取二进制数据;在本地进行随机重放 ,让主从节点的数据保持一致,完成数据同步后,I/O和SQL线程会进行休眠,直到下次被唤醒;

    1. 注意

      1. 主从数据库的复制至少要两个MySQL服务;
      2. 两个不同的MySQL服务使用的版本尽量相同,如果不能保证版本的一致,那么要保证主库的版本要低于从库的版本;
      3. 两个MySQL服务的系统时间要同步;

        11,MySQL中的聚簇索引和非聚簇索引的区别:

        这两个索引的类型是和储存引擎相关的;

        聚簇索引:

      • 一般是InnoDB储存引擎默认的索引类型,聚簇索引:其实就是指数据必须和索引放在一起;在InnoDB的文件夹中数据文件和索引文件全部都放到ibd文件中;如果索引是主键那么就使用主键,没有主键就用唯一键,没有唯一键的话就使用6字节的row id;总之,聚簇索引的特征就是索引必须和数据放在一起;

        非聚簇索引:

      • 非聚簇索引是MyISAM的特有索引类型;非聚簇索引:就是指数据不需要和索引放在一起,在MyISAM引擎中的数据文件是放在myd文件中,而索引文件是放在myi文件中;

  • 因为非聚簇索引的数据和索引是分开存放的,所以使用非聚簇索引的引擎要比聚簇索引的引擎插入数据要快,因为每次插入的数据量都被分开了,就不需要像聚簇索引那样还要对索引数据进行处理;
  • 所以,在大批量插入数据的时候,非聚簇索引引擎MyISAM会更高效;

    12,B树与B+树的区别:

    特点:
    B树叶子节点非叶子节点都存数据(索引和数据都存储),且叶子节点数据无链指针
    B+树只有叶子节点存数据(叶子存储数据,非叶子存储索引),且叶子节点数据有链指针

B树的优势:
在B树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;
B树的缺点:
当进行范围查找时,存在“回旋查找”的问题,效率低

B+树的优势:
所有叶子节点形成有序链表,便于范围查询(不存在回旋查询的问题)

正是因为B+有这样的特点,所以MySQL的索引采用B+树存储!!!
MySQL底层还对B+树进行优化,叶子节点采用双向链表,这样不管大于还是小于范围查询,都很快了!

复写: B树:叶子节点和非叶子节点都会存储数据,且叶子节点是无链指针; B+树:只有叶子节点才会存储数据,且叶子节点是有链指针;

13,链表查询中的左连接和右连接,内连接:

  • 外连接:
    • 左连接:表示将满足的数据显示,在左表中不满足要求的数据也显示;
    • 右连接:表示将满足要求的数据显示,并且右表中不满足要求的数据也显示;
  • 内连接

    • 只显示满足要求的数据;

      14,B+树为什么这么快:

      在B+树中,因为所有的记录数据节点都是按照大小循序储存在叶子节点中的,而非叶子节点只存储key值信息,这种数据结构能极大地增加key值的存储数量,从而减低B+数的高度;因此,B+树的查询要比B树快得多;

      15,* 将1kw条数据插入mysql数据库中,怎么样效率高:

    1. 首先,数据库单个表的容量默认是4m,如果超过限额就会报错,因此我们先要设置表的容量大小:

      1. set global max_allowed_packet = 100*1024*1024;
    2. 然后,通过代码,分批将数据进行插入;例如,每次将10w条数据插入数据库;而且在使用 insert into 语句的时候,要一次用一条,不要分开来用;

    3. 如果还需要提升效率,我了解到 load 语句,这条语句是读取文件的数据将数据组插入到表中,效率比 insert into 更快;