mysql 数据库面试题

本文详细探讨了MySQL数据库中的各种面试题目,涵盖索引原理、数据结构、存储引擎、事务隔离级别、优化技巧等内容。从索引的二叉树查询、红黑树到B-Tree和B+Tree的差异,再到MyISAM与InnoDB的区别,以及事务处理和存储引擎的工作机制,深入浅出地解析了MySQL的关键知识点。此外,还提到了内存表Heap、浮点数精度问题以及MySQL的查询优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

1 索引是什么?

1,是帮助mysql高效获取数据的排好序的数据结构。使用二分法等数据结构找到对应查询条件的数据地址,所以索引的形式也就是key-value。key是带索引的查询条件,值是查到数据的磁盘文件地址。最后根据文件地址,拿到真实的值。
2,索引存放的数据是怎么样的?我的理解是对我们加索引的字段的所有值,做树状排序,放到内存中。所以,一旦数据量很大后索引也会很占内存。

2 索引的数据结构有哪些

二叉树 红黑树 hash表 B-tree

3 数据结构–二叉树的查询原理

数据按二叉树建立一个很大的树状结构图,对录入的数据依次做数据对比,数是自上而下的,大于等于前者放右边,小于放左边

4 红黑树

是对二叉树的优化,又称作平衡二叉树,它才是我们中学学到的传统意义上的二分法。jdk1.8优化hashmap就是用到了红黑树。因为,它会自动调节数的结构,让处于大小处于中间的数放在最上面的节点。不像二叉树,是把插入的第一个数据放在最顶的节点。这样红黑树就不会出现数据倾斜(就是一个树状数据量很大,另一个却很少)的情况。

5 B-Tree

出现B-Tree的原因是因为二叉树和红黑树会由于数据量过大,让树的高度过高,导致效率低下。
B-Tree是在红黑树的基础上,把索引的叶节点放在同一层,这样同一层节点就会出现多个索引数据,(这一块其实不太好说明,要深究的可以再自行百度)

6 B+Tree

在B-Tree的基础上改动了很多,首先它才是现在流行的数据库使用的数据结构,也称为多叉平衡树。优化点如下:
1,数据的最上面两层不存放数据,只存放索引,没有存放数据真实的值,节省了内存
2,在数据库启动是只加载第一次索引数据,后者在使用时,经过数据对比,在哪个节点再加载第二层的某个节点索引。做到用哪些加载哪些,不做多余的事、
3,要说明的一点,因为在某一层有多个节点,而每个节点又有多个索引数据,所以,在这多个索引数据中,用的还是二分法比较。
4,mysql 中每一层索引节点默认大小是16k。但三层就足以方二十多万条数据。

7,mysql 存储引擎之myIsam实现原理。

1,myIsam的索引文件和数据文件时分离的(非聚集)
2,数据文件放在磁盘上,有三种格式的数据文件:
.frm:这种可以历届生frame框架的缩写,不用太深究。
.myd:存放的是每条数据的地址和对应完整的数据内容。
.myI:存放的是B+tree的索引结构。
总结,可见,myIsam存储引擎是把索引和数据分两个文件存放的,索引的值指向数据文件中的数据地址。

8,mysql 存储引擎之myIsam查询流程

假设第一层的索引数据是15…56…77…。数据库会先把第一层的索引数据加载到内存中,如果我的查询数据是30,那么首先会定位到第一层的15-56之间,然后拿到二者之间的磁盘文件地址,在把这个磁盘文件地址对应的第二层索引数据加载到内存中,做用于的数据对比查找,假设加载的索引数据内容是15…20…49.那么会再次定位到20-49之间,然后拿这二者间 的磁盘文件地址到.myd数据文件中找到对应的完整数据,这就相当于b+tree数存储结构的第三层了。
总结,可见b+tree的存储数据原理是1,索引和数据分开,2是把数据分成一小块一小块的,减少了树的层数。

9,mysql之Innodb存储引擎实现

1,innodb储存引擎对应的磁盘文件有两种格式的
.frm:还frame框架的意思,跟myisam一样,不用深究
.ibd:相当于把myISAM的.myd和.myi合并了,就是索引和数据合并到一个文件中了。
2,至于查询过程,跟myisam还是一样的。只不过在最后一步不到.myd中找数据了,而是在最后一步磁盘文件地址变成了真实的数据

10,何为聚集索引?

就是把索引和数据放到了一个文件中。即innodb.
myisam就是非聚集索引了。
对比之下,聚集索引快,但是耗内存。我接触过的都是innodb这种的。

11,为什么innodb表必须有主键,并且推荐使用整型自增?

1,因为为了维护b+tree这个数据存储结构,即使我们不设置主键,mysql也会建一个默认的。而且这个默认的我们还看不见。与其如此,还不如自觉的建一个我们能看的见的。
2,使用整型是因为,节省空间,键对比大小也快。试想如果是字符串,还有转成ASCII码对比,整型就不用了
3,自增长是因为。b+Tree内部索引也是自增长排序的,主键使用自增长可以避免叶子节点的分裂和由于做数据平衡带来的内存开销。

12,索引之hash表。都知道hash很快,那么为什么mysql不用hash这个数据结构呢?

首先要承认的是hash运算查找数据确实要快于b+tree,但是短板在于不能使用范围查询。如:select * from t where col>6;
同时,联想hbase是不是只能用key查询。还是内存heap表也是用的hash索引

13 一张表,里面有ID主键自增长,当插入17条记录后,删除了第15,16,17条记录,再把mysql重启,再插入一条记录,这条记录的id是18还是15?

1,如果表的类型是MyISAM,那么就是18,因为它会把自增主键的最大ID记录到数据文件中,重启后mysql的自增主键最大还是18.
2,如果表的类型是Innodb,那么是15,Innodb表只是把自增主键的最大ID记录到内存中,重启后,之前删掉的部分会丢失,还是从目前表里面最大的id还是增长。

14 Heap表是什么?

也称为内存表,它的数据是临时存放在内存中的,所以存储速度很快,但是服务器重启后数据就会消失,但表结构还在。再者他的索引数据结构是hash散列索引,所以表结构比较简单,非常适合做缓存。
建表案例如下:
create table ‘tablename’ (‘columnName’ varchar(256) not null) engine=memory default charset=latin1 max_rows=100000000;

重点是标注ENGINE= MEMORY,就表明它是个内存表了。
还有内存表的最大容量可以在.cnf文件中设置,如:max_heap_table_size = 2048M,当超过最大容量,数据还是要放在磁盘中的。
其他要注意的就是,它不允许blob和test字段,只能使用比较运算符=,>,<;不支持自增长,索引不能为空

15 关于float精度是8位问题的讨论

1,无论是在java还是数据库,float都是4字节,一个字节二进制8位,所以float的二进制总共是32位;
2,看下图:
在这里插入图片描述
明确了float的二进制是32位后,看上图知道,要把32位的数字进行切分:
符号位:表示正负,1负,0正
指数为:如二进制是1001.101,那么它的科学计数法的表达式是: 1.00101 ∗ 2 3 1.00101*2^3 1.0010123。这个底数是2哦,因为是2进制。如果是我们熟悉的十进制那就是10喽,要转过这个弯哦。
尾数部分就是1.00101的小数点右边的部分了,即00101
3,说明,符号位只分配了一个位置,所以二进制中这个位置只能选0,1.
而对于指数位,分配了8位,也就是8个0或者1的组合,而且第一个还要是0或1表示正负。因此指数为的十进制取值范围为-128-127,二进制是10000000-01111111.(注意127的二进制是7个1,这里八个数的第一个0表示正)
这点理解起来很困难,再重申遍,32位的指数位加底数的十进制取值范围为: 2 − 128 − 2 127 2^{-128} - 2^{127} 21282127

4,继续第三点说,指数位也是有正负的,并且是8位二进制,第一位表示正负。按道理我们应该舍弃调第一个数据,把剩下的七个转成10进制。然而实际计算时,为了消除正负号的影响,我们使用偏移量127的方式计算,为什么是127呢?
首先是因为8位的原因,如果是双精度的指数位有11位,那偏移量就是1023了,所以这是根据指数位数定的。
然后我们举个例子,先思考,本来八位的第一位是当做正负号的,可现在却哪来当做数计算,证明我也不会,我们就验证下吧,比如说-3的符号在当做负号看待是和不当做负号看待时分别的二进制是多少:当做时:1111100(计算过程是:先算3的二进制是11,然后在7位下转负数是,首位转1,其它位取反,即0000011-》1111100),不当做负号时:有8位,即11111100。这两个对于的应进制分别是:

>>> int('11111100',2)
252
>>> int('1111100',2)
124

252-124=128。
呃!有问题怎么不是127呢?想了一上午每想明白,网上的解释也没看懂,就这样吧!记住。
5,最后举个例子,那百度百科上的案例吧!

将实数-9.625变换为相应的浮点数格式。
1) 求出该实数对应的二进制:1001.101,用科学技术法表达为:-1.001101 ×2^32) 因为负数,符号为13) 指数为3,故指数域的值为3 + 127 = 130,即二进制的100000104) 尾数为1.001101,省略小数点左边的1后为001101,右侧0补齐,补够23位,
最终尾数域为:001101000000000000000005) 最终结果:1 10000010 00110100000000000000000,用16进制表示:0xC11A0000

6,double,精度是16位,有八字节,关于各位置说明如下:
在这里插入图片描述
7,最后对于所谓的单精度是8位,双精度是16位,指的是十进制下可以精确到小数点后8位和16位。所以可见,double的精度是高于float的。

16 区分char_length和length?

前者是字符数,length是字节数,

17 简述吗,mysql中innodb支持的四种事务隔离级别

1,read uncommited 读到未提交数据,属于脏读,其他事务可读到别的事务的中间数据。举例:如果一个事务要一次性插入很多条数据,那么其他事务很有可能在这个事务插入期间读取到它已插入的数据。但如果这个插入的数据后面又插入失败了,全都回滚了。不就脏读了。
2,read commited 读到提交数据 ,不可重读,事务只能看到当前事务的提交的内容。是比较安全的一种,使用最多的。这个没啥可说的,自己用自己的数据。
3,repeatable read 可重读,mysql的默认事务隔离级别。允许重读。就是在并发情况下。一个事务在读取某一范围的数据,另一个事务又在该范围内插入了新行,当该事务再次读取该范围时,会发现数据有变化了。通常这种情况是发生在复制的sql语句中,如一个sql有多个查询语句,先查询的跟后查询的数据不一样。
4,serializable:可串行化
最高的隔离级别。通过强制事务排序,是在每个读的数据行上加共享锁,保证只有一个事务操作该行。但这样超时现象会增多。

18 char和varchar的区别

1,char类型的长度是固定的,varchar的长度是可变的
这就表示,存储字符串’abc’,使用char(10),表示存储的字符将占10个字节(包括7个空字符);使用varchar2(10),,则表示只占3个字节,10是最大值,当存储的字符小于10时,按照实际的长度存储。
2.char类型的效率比varchar的效率稍高

19 列的字符串类型可以使什么?

set blob char verchar text enum

20 mysql驱动程序时什么

常见的有jdbc odbc php

21 timestamp 类型在被update current_timestamp修饰时会发生什么?

数据发生修改时该时间戳字段会自动更新为当前时间

22 linux登录mysql命令

mysql -h hostname -u username -p password

23 mysiamchk是用来做什么的?

用来压缩myisam表,减少了磁盘和内存使用。

24 mysql性能分析的命令有哪些?

show status
show profiles

25 mysql static 和mysql Dynamic有什么区别?

前者上所以字段有固定宽带,后者是动态的意思,将像text,blob等字段可以适用不同长度的数据类型。
但前者更容易恢复

26 如果设置的auto_increment表数据达到了最大值,会发生什么?

停止增长,任何插入操作都会报错

27 查看索引命令

show index from tablename;

28 like声明中%和_是什么意思?

%用于匹配更多字符,_只匹配一个

29 mysql语句不区分大小写

30 like和regexp的区别?

select * from employee where emp_name regexp "^b";
select * from employee where emp_name like "%b";

31 text 和blob的区别

首先二者都是用户存放可变的数据。
再者二者区别是blob值进行排序和比较时区分大小写,text不区分

32 显示前50行

select * from table limit0,50;

33 索引字段最多有几个

16

34 now() 和current_date的区别

前者显示年月日时分秒
后者显示年月日

35 什么样的对象可以使用create语句

database,table , index,function,user,

36 什么是同一sql函数

像count(),sum() ,concat(a,b)合并字符串,now(),等都是sql函数

37 mysql 支持事务吗?

1,默认是自动提交的,不支持事务的。
2,如果是innodb表那么就可以使用事务处理。

38 mysql记录金额用什么字段好?

常用精度较高的类型,如numeric 和decimal.
如salary decimal(9,2),9表示总的有效位数,2表示小数点后的精确位数。并四舍五入。

39 mysql 中有哪几种锁?

myisam支持表锁,innodb支持表锁和行锁,默认行锁
1,表级锁:开销小,加锁快,不会出现死锁。锁的粒度大,发生冲突的概率高。支持的并发度低。
2,行级锁:开销大,加锁慢,会出现死锁,发生锁冲突的概率小。支持更高的并发度。

40 mysql 索引失效

1,条件中有 or,有多个查询条件,并不是所有的条件都加了索引,这样即使有部分加了也不会起作用。
2,like查询是以%开头。这种相当于模糊所有的数据了,试想如果%在后面,如A%,那么就会只查以A开头的那部分数据。还有就是mysql排序准守最左前缀原则
3,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。这个不太清楚是啥原因!!!
4,如果mysql估计使用全表扫描要比使用索引快,则不使用索引。这种比较的出现在重复数据多的情况。例子暂时没找到合适的。
5,查询条件中有计算,如:select * from table where id=id+1;order by排序也算哦
等,还有其他很多,能打上这些应该可以了。
此外,查看有没有使用索引的语句是:在查询条件前加explain
在这里插入图片描述

41 数据库优化的方式

1、选取最适用的字段属性
如省市这种用枚举,因为枚举在mysql中将被用作数值型处理,处理数值明显比文本要快。
还有表字段长度尽可能设小
2、使用连接(JOIN)来代替子查询(Sub-Queries)
子查询就是select里面包含select,这种不如使用join
3,使用联合(UNION)来代替手动创建的临时表
4,使用事务,对于复制的sql,如有多条插入,保证数据的一致性,也用到了隔离性
事物以BEGIN关键字开始,COMMIT关键字结束。在这之间的一条SQL操作失败,那么,ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态。
BEGIN; INSERTINTOsalesinfoSETCustomerID=14;UPDATEinventorySETQuantity=11WHEREitem=‘book’;COMMIT;
5,使用索引,这个是重点了。
6,数据库设计是一方面,更重要的是使用,合适查询条件,会查询很快,给数据库的压力也会减小。充分利用索引。
7,建表时使用合适的存储引擎
8,只查询使用到的字段,没有使用到的就不取出来了。

42 Mysql中myisam和innodb的区别,至少5点

1,存储结构,myisam是三个文件,索引和数据分开放,innodb
索引和数据放一起。
2,存储空间,MyISAM:可被压缩,存储空间较小。 InnoDB:需要更多的内存和存储
3,事物支持 MyISAM:强调的是性能,每次查询具有原子性,其执行速度比Innodb类型更快,但是不提供事物支持。InnoDB:提供事务支持,支持回滚。
4,MyISAM: 如果执行大量的select, MyISAM是更好的选择。(因为没有支持行级锁),在增删的时候需要锁定整个表格,效率会低一些。相关的是innoDB支持行级锁,删除插入的时候只需要锁定该行就行,效率较高。
总之,myisam查询快,innodb安全,用于更新插入。
5,外键,
MyISAM: 不支持。
InoDB:支持。

43 什么情况下加索引也没有全局搜索快,举例

1,全表扫描(Full Table Scans FTS)
为实现全表扫描,Oracle 读取表中所有行,并检查每一行是否满足语句的WHERE 限制条件,全表扫描时一次I/O 能读取多个数据库块(db_file_multiblock_read_count参数设定),而不是只读取一个数据块,即多块读,这极大的减少了I/O 总次数。把读取到的数据块放到内存中匹配我们的查询条件,匹配到就拿出去了。
2,索引查询过程:根据查询条件提供的key,到加载到内存中的索引(树状)数据一一对比,找到对应的数据存储地址,到磁盘中做一次io,把数据取出来。也就是每取一次就是一次IO。
3,举例,假如有个数据量是千万级的表,分了一个10000个数据库,我们设置每次读5个数据块。那么我要查询where name=“小明”的数据,如果说这个小明有3000条数据,就要做10000/5=2000次I/O操作,把磁盘数据放到内存中查找。当然了对于每个块的查询属于逻辑操作,这个很快,我们就忽略吧!
下面我们看索引的取数。我们看的是数据库运行平稳后,索引都加载到内存中了,不考虑b+tree懒加载索引数据的方式。那么在索引中找到每个等于小明的数据地址后到数据库中取,要做3000次io,而全表搜索只用锁2000次就够了。明白了吧!
总结,就是对于查询出来的数据很多,占到表的20%左右就可能造成索引失效了。这样的情形如,大于多少年龄。还有像性别这种重复情况很多的,如果给性别加了索引。你想要查出女性的所有人信息,就要做很多次io了。

43 limit原理和分页查询为什么会在大数据量的时候很慢,怎么解决?(覆盖索引)

以这个sql为例:

SELECT * FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 30

limit是怎么取数的呢?首先说明这里的pid是用了索引的,但是limit的原理是会到索引中找到前1000030条数据,然后与磁盘做1000030次io操作后,再丢弃到前1000000条数据。不用说这样既浪费时间又占内存。既然limit是这么设计的,我们不能改变,那么怎么解决呢?
1,使用覆盖索引,就是给我们要查的数据都加上索引,这样直接取出索引数据就行了,不用与磁盘交互,所以这种要避免把表的索引列都查出来,即select *。当然了,这种思想适用的情形很多。如select name,age from table where name=“xiaoming” and age>20;如果把name和age都设为索引,那么就只用查索引就行了,因为这些数据都在索引中了.
2,使用子查询,这个方式是最流行了的。即:

SELECT * FROM `cdb_posts` WHERE pid >= (SELECT pid FROM  
`cdb_posts` ORDER BY pid LIMIT 1000000 , 1) LIMIT 30

这样就很快了,定位到起点位置,然后做30次io就行了。

44 怎么指定使用行锁还是表锁。

太难了,没接触过过,算了

45 mysql主备复制过程(没研究太深,拷贝的)

第一步是在主库上记录二进制日志。在每次准备提交事务完成数据更新前,主库将数据更新的事件记录到二进制日志中。MySQL会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。在记录二进制日志后,主库会告诉存储引擎可以提交事务了。
下一步,备库将主库的二进制日志复制到其本地的中继日志中。首先,备库会启动一个工作线程。称为I/O线程,I/O线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储(binlog dump)线程,这个二进制转储线程会读取主库上二进制日志中的事件。它不会对事件进行轮询。如果该线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生时才会被唤醒,备库I/O线程会将接收到的事件记录到中继日志中。
备库的SQL线程执行最后一步,该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。当SQL线程赶上I/O线程时,中继日志通常已经在系统缓存中,所以中继日志的开销很低。SQL线程执行的事件也可以通过配置选项来决定是否写入其自己的二进制日志中。
1、客户端SQL更新命令
2、主库执行
3、主库写binlog
4、主库client线程读binlog发送给从库的io线程
5、从库io线程写盘(relay-log)
6、从库sql线程读relay-log
7、执行更新。
这里有涉及到两个写盘,主库binlog和从库的relaylog(3、5),这是两个二进制文件。不过不用担心不停扫描文件造成的延迟,因为读文件的线程是在同一个进程内,每次写完都会广播,所以虽然看上去是异步,实际上延迟并不大。

46 mysql显示和设置隔离级别

1,显示:

mysql> show global variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
row in set (0.00 sec)

可见默认的REPEATABLE-READ 是可重复读取
2,设置:
mysql> set global transaction_isolation =‘read-committed’;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like ‘%isolation%’;
±----------------------±---------------+
| Variable_name | Value |
±----------------------±---------------+
| transaction_isolation | READ-COMMITTED |
±----------------------±---------------+
row in set (0.00 sec)
通常我们设置成提交已读取。

47 用户关系系统表设计讲解

借用网上一个非常好的讲解图:

https://blog.youkuaiyun.com/u010757785/article/details/50779455

在这里插入图片描述
这种图应该是用powerdesigner做的,
1,图中深蓝色的表可以理解成一个个实体元素,可以在系统界面上看到的数据,他们之间互不影响对方,也就是如果删除其中的任何表的数据不会影响到其他的表数据。
2,图中浅蓝色的表示是关联表,把一个个实体元素关联了起来,我们不能在web界面上直接对其操作,如我删除了角色表中的一个普通用色,那么与之关联的外表,即用户角色关联表,用户组和角色关联表也会删除对于的数据。而用户表和用户组表不会受影响。当然了,实际中角色下有用户的话,通常是不让删除的。
3,上图表设计的很细致。用户组表对用户多的系统很适用,方便管理。权限管理的菜单表,页面表,文件表把整个web界面的各个组件权限管理的很细致。
4,重点说下功能操作表,这个有点AOP的理念了,这个表用来记录每次对页面操作的痕迹的。也可以看出权限表时联系所有用户和所有界面操作内容的枢纽,所以可以通过权限表追根溯源,进而记录每次操作历史。
5,举例,比如说,有个普通用户要点击页面表中的一个删除按钮。流程是,界面点击删除按钮–>获取到当前用户和按钮id传到后台–>到用户角色关联表中查找,得到角色–>到角色权限表中查找,得到权限–>到权限表中查找得到权限等级是1。另一方面按钮id–>到权限页面元素关联表中查找,得到权限id–》到权限表中查找得到权限等级是2。所以该用户的权限小于可以操作该按钮的权限等级。
6,各个实体元素都是多对多的关系。

48 数据库连接池

数据库连接池功能和使用都可以安装多线程的线程池来理解。省去连接数据库和验证等时间,复用连接。
实现的几种方式有:
网上有个demo写的很好:

https://download.youkuaiyun.com/download/u011133213/6714537

1,自己创建一个连接池,把connection交给list管理,当一个连接操作完了后,不销毁而是重新把这个connection置空,然后放回list中。至于list的长度就是你设置的最大连接数了。
2,把配置放在tomcat的context.xml文件中,或sever.xml中。
3,使用c3p0包,是目前最流行方便的方式了。
有专门的默认配置文件:c3p0-config.xml

<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/mysql</property>
		<property name="user">root</property>
		<property name="password">root</property>
		
		<property name="initialPoolSize">10</property>
		<property name="maxIdleTime">30</property>
		<property name="maxPoolSize">20</property>
		<property name="minPoolSize">5</property>
		<property name="maxStatements">200</property>
	</default-config>
	
	<named-config name="mysql">
		<property name="acquireIncrement">50</property>
		<property name="initialPoolSize">100</property>
		<property name="minPoolSize">50</property>
		<property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
		<property name="maxStatements">0</property>
		<property name="maxStatementsPerConnection">5</property>
	</named-config>
	
	<named-config name="oracle">
		<property name="acquireIncrement">50</property>
		<property name="initialPoolSize">100</property>
		<property name="minPoolSize">50</property>
		<property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
		<property name="maxStatements">0</property>
		<property name="maxStatementsPerConnection">5</property>
	</named-config>
</c3p0-config>

上面给了三种配置,可根据:

ComboPooledDataSource ds = new ComboPooledDataSource("mysql");

指定需要的配置。
也可以看到每种配置都有连接池初始化大小,最小连接数,最大连接数据。
4,还有一种是dbcp,个人感觉跟c3p0差不多,就是在获取配置c3p0有专门的配置文件,所以会默认读取,还可以配置多个版本。而dbcp要自己读取property文件,也只能维持一个版本。
这几种方式我的理解都是把连接使用完了置空释放出来,放回到连接池中。
如:

private void release(Connection conn, Statement st,
			ResultSet rs) {
		if (rs != null){
			try{
				rs.close();
			}catch (Exception e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if (st != null){
			try{
				st.close();
			}catch (Exception e) {
				e.printStackTrace();
			}
			st = null;
		}
		if (conn != null){
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

49 mysql 联合索引 abc_ABC联合索引生效问题

对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c)。 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。

以下是一些例子:

(1) select * from myTest where a=3 and b=5 and c=4; ---- abc顺序

abc三个索引都在where条件里面用到了,而且都发挥了作用

(2) select * from myTest where c=4 and b=6 and a=3;

where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样

(3) select * from myTest where a=3 and c=7;

a用到索引,b没有用,所以c是没有用到索引效果的(b没有使用到,所以索引达不到 c ,所以c未使用索引)

(4) select * from myTest where a=3 and b>7 and c=3; ---- b范围值,断点,阻塞了c的索引

a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
50 mysql主键索引和普通索引之间的区别是什么
主键索引是一种唯一性索引,但它必须指定为“PRIMARY KEY”。
区别
1、普通索引是最基本的索引类型,没有任何限制,值可以为空,仅加速查询。普通索引是可以重复的,一个表中可以有多个普通索引。
2、主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值;索引列的所有值都只能出现一次,即必须唯一。简单来说:主键索引是加速查询 + 列值唯一(不可以有null)+ 表中只有一个。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老马识途2.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值