Mysql架构与索引优化分析
1. MySQL 锁机制1.1 概述定义
123456锁是计算机协调多个进程或线程并发访问某个资源的机制。在数据库系统中, 除了传统的计算机资源(如:CPU, RAM。I/O等)的争用外, 数据也是一种供多用户共享的资源。如何保证数据并发的访问和一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤重要,也更加复杂。
生活购物案例
](https://zhangxin-blog.oss-cn-beijing.aliyuncs.com/blog/mysql/zzyy/mq69.jpg)
锁的分类
对数据操作的类型分(读/写)
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响
写锁(排他锁):当前写操作没有完成之前,它会阻隔其他写锁和读锁
对数据操作的粒度来分
表锁
行锁
1.2 三锁1.2.1 表锁(偏写)特点:偏向 MyISAM 存储引擎,开销小,加锁块;无死锁;锁定粒度大,发生锁冲突的概率高,并发度最低。
案例分析建表SQL
123456789101112131 ...
synchronized原理(C++源码)
1. javap 反汇编1.1 目标通过javap反汇编学习synchronized的原理
我们编写一个简单的synchronized代码,如下:
12345678910111213141516package com.zzxx.demo04_synchronized_monitor;public class Demo01 { private static Object obj = new Object(); public static void main(String[] args) { synchronized (obj) { System.out.println("1"); } } public synchronized void test() { System.out.println("a"); }}
我们要看synchronized的原理,但是synchron ...
Mysql架构与索引优化分析
1. Mysql逻辑架构介绍和其它数据库相比,MySQL有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。
1.1 Mysql简介MSQL概述MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司。
MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
Mysql是开源的,所以你不需要支付额外的费用。
Mysql是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统。
Mysql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
MySQL使用标准的SQL数据语言形式。
Mysql可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
MySQL支持大型数据库,支持5000万条记录的数据仓库,32 ...
Mysql架构与索引优化分析
1. 索引优化1.1 索引分析一表
12345678910111213141516171819#建SQLcreate table if not exists `article` (`id` int(11) auto_increment not null,`author_id` int(11) not null,`category_id` int(11) not null,`views` int(11) not null,`comments` int(11) not null,`title` varchar(255) not null,`content` text not null,primary key(id));insert into `article`(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) values (1, 1, 1, 1, '1', '1'),(2, 2, 2, 2, '2', '2'),(3, ...
synchronized优化
JDK6 synchronized优化1. CAS1.1 目标
学习CAS的作用
学习CAS的原理
CAS我在之前大厂面试题中详细讲解过,需要的去看看就行了,
因为这里需要对比一波所以再次复习一波。
1.2 CAS概述和作用- oiuytrCAS的全成是: Compare And Swap(比较相同再交换)。是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。
CAS的作用:CAS可以将比较和交换转换为C原子操作,这个原子操作直接由CPU保证。CAS可以保证共享变量赋值时的原子操作。CAS操作依赖3个值:内存中的值V,旧的预估值X,要修改的新值B,如果旧的预估值X等于内存中的值V,就将新的值B保存到内存中。
CAS和volatile实现无锁并发123456789101112131415161718192021222324252627282930/* 目标:演示原子性问题 1.定义一个共享变量number 2.对number进行1000的++操作 3.使用5个线程来进行 */public class Demo01 & ...
你问我答08
问:现在聊点基础的吧,我现在new两个value为1的Integer对象用==比较返回什么
呃,返回false 用valueOf创建的话==会返回true。Integer,long 这几个封装类型里面会维护一个缓存。用来缓存比较小的值,默认缓存是-128到127这个范围的值。
问:我看你做过订单系统。你这个系统里面的金额用的什么类型啊?
代码里面用BigDecimal,mysql 里面用Decimal
问:为什么不用double 呢?
因为double 会丢精度呃会出现1.00001这种不精确的值。
问:知道为什么会出现这种值吗?
这是因为十进制小数和二进制转化的问题啊。你比如0.8转化成二进制的话,小数部分就是11001100这种无限循环。计算机就只会取前面一部分值进行存储啊,后面循环的部分就丢了,再转化成十进制的时候就丢精度了。
问:那为什么BigDecimal 能表示精准的浮点数呢?
BigDecimal里面说白了就是浮点数转化成整数存储,然后记录小数点的位置在哪里。这个转化成的整数一般都是Long范围内的,所以直接用L ...
你问我答06
问:如何才能让mysql 出现一个死锁呢?
举个例子吧,我们用两个mysql 的客户端,分别起两个事务啊,然后在第一个事务里面去修改id=1的行。呃,然后第二个事务的话就去修改id=2的这一行。呃,这个时候呢呃第一个事务已经拿到了id=1这一行的锁啊,第二个事务呢就已经拿到了id=2这个行的锁。然后呢在第一个事务里面呃再去修改id=2这一行啊,然后再去第二个事务里面去修改id=1这一行啊。这个时候呢第一个事务会尝试拿id=2这一行的锁啊,但是拿不到啊,因为已经被第二个事务锁住了啊。然后第二个事务呢也尝试去拿id=1这一行的锁也拿不到啊。因为被第一个事务锁住了啊,这样的话就形成了死锁。
问:发生了死锁怎么办呢?
呃,我知道的就那么几种,一个是设置锁等待的超时时间。还有一个就是开启mysql 检查死锁的功能。但是这两种方式都不是特别好。要是依靠锁等待超时来解这个死锁的话,这个超时时间不是特别好把握。比如超时时间设置短了,就有可能导致一些正常的事务回滚了。那如果设置长了,就会导致阻塞时间比较长,然后影响系统的性能。那mysql 死锁检查功能的话,性能也不是特别好。它是一个O(n)的算 ...
你问我答07
问:嗯,先来写个题,求一个二叉树里面两个节点之间的路径的最大值,不能走回头路啊。比如这个数里面四到三的路径是最大的,那就是四二一三啊,五到三可以啊,然后返回这个路径上的节点个数啊,比如说四二一三啊就是四。嗯,解释一下你这段代码吧。
我用的是深度优先遍历,要算整个树里面两个节点的最大路径啊,那可以先算左子树的深度啊,然后再算右子树的深度啊,然后再加上根结点啊,就是整个数里面两个节点的最大路径了。然后递归一直往下拆啊,拆到叶子节点啊,然后递归返回的时候,就计算各个子数的最大路径啊,用max 记录一下就可以了。
问:先聊聊你之前做过的项目吧。我看你之前做过订单的模块,你这一天的订单量大概有多少呢?
大概一天十万左右的单吧,具体多少我忘记了。
问:嗯,当时用的什么存储呢?
主要用的是mysql。
问:你们数据库有没有进行分库分表呢?
订单表的话,当时是分了十个库,每个库里面存三十天的订单,然后每天分一百张表。
问:是根据哪个字段进行分库的呢?
按照订单号进行分库分表的,订单号分了三个部分,包含了用户的userId,一个小时级别的时间戳。我记得是距离二零一五年十二月一号的小时 ...
你问我答05
问:,先来写道题吧,用栈来实现一下队列的效果吧。嗯,简单说一下你实现的思路吧。
我是用了两个栈实现的,一个是来模拟队尾,一个是用来模拟队头。入队的时候呢直接进队尾的那个栈就行。然后要出队的那个时候就先查队头的这个栈啊,如果这个栈有数据的话,嗯,就需要直接弹出啊。如果说是没有的话,嗯,就把队尾的那个栈里面的全部数据都弹出来,然后压到队头的栈,等这个队尾的栈弹干净了之后,再从队头栈里面呃数据出栈就可以了。
问:平时用过零拷贝技术吗?说说他为什么比普通的拷贝要快呢?
比如说我把磁盘的数据发送出去,要是按照正常的方式,就需要创建一个byte数组。然后调read 方法读取数据,到这个byte数组里面,这就发生了一次用户态到内核态啊,还有一次内核态到用户态的切换。然后我们的线程再把这个byte数组拷贝到网卡的缓冲区里面啊,这又是两次用户态,还有内核态之间的转化。这种切换其实就是为了进行数据拷贝,其他的啥也没干,就是比较耗资源了。那这个零拷贝呢他就可以直接把磁盘的数据拷贝到网卡缓冲区里面啊。就这样的话就是减少了这些用户态和内核态的切换啊,也减少了数据在缓冲区之间的拷贝了。
问:嗯,你实际用 ...
你问我答01
问 我们先来说一下: HashMap 的工作原理是什么?
HashMap底层是通过数组和单向链表实现的,数组中的每个元素都是一个链表,而链表中的每个节点都是一个Entry对象,它里面存储的才是真正的KV数据,然后我们在存储键值对的时候,会先去调用哈希方法计算Key的哈希值,然后去模这个数组的长度,就能拿到存储Key的数组的下标,然后呢,我们遍历这个下标里面存储的这个单向链表,把里面每一个Key,还有插入的Key进行equal比较,如果在这个时候返回true的话,就直接更新Value值,如果全部比较,都返回了False,那就直接把新的键值对插入到这个链表中,在put的过程中,当哈希表中存储的键值对超过了数组长度乘以负载因子的时候,就会将这个数组扩容两倍,还有就是在插入链表的时候,如果链表长度超过了一个阈值,就会从链表转化成红黑树,然后我们那个时候阈值默认是8,在查询KV数据的时候,我们会先调用哈希方法计算Key的哈希值,然后去模数组的长度,这样就能拿到存储Key的数组下标,然后呢我们在遍历其中的链表,进行equa比较,得到Value 值,那哈希表的核心原理呢 ,其实就是hash值过滤 ...




