B+树和 B 树的区别 插入节点怎么分裂
B+Tree 相对于 B-Tree 有几点不同:
- 非叶子节点只存储键值信息。
- 所有叶子节点之间都有一个链指针。
- 数据记录都存放在叶子节点中。
B+ Tree 更适合用来做存储索引:
- B+ 数的磁盘读写代价更低
- B+ 数的查询效率更加稳定
- B+ 数更有利于对数据库的扫描(范围查询)
插入节点怎么分裂
有人建议给每张表都建一个自增主键,这样做有什么优点跟缺点
自增主键
在MySQL数据库中,可通过sql语句AUTO_INCREMENT来对特定的字段启用自增赋值 使用自增ID作为主键,能够保证字段的原子性.
优点:
数据库自动编号,速度快,而且是增量增长,按顺序存放,对于检索非常有利;
数字型,占用空间小,易排序,在程序中传递也方便;
如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题。
缺点:
因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其它系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的)。特别是在新系统上线时,新旧系统并行存在,并且是异库异构的数据库的情况下,需要双向同步时,自增主键将是你的噩梦;
在系统集成或割接时,如果新旧系统主键不同是数字型就会导致修改主键数据类型,这也会导致其它有外键关联的表的修改,后果同样很严重;
若系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个字符标识(例如“o”,old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。
UUID
UUID含义是通用唯一识别码 (Universally Unique Identifier),指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。换句话说能够在一定的范围内保证主键id的唯一性。
优点
出现数据拆分、合并存储的时候,能达到全局的唯一性
缺点
影响插入速度, 并且造成硬盘使用率低
uuid之间比较大小相对数字慢不少, 影响查询速度。
uuid占空间大, 如果你建的索引越多, 影响越严重
sql,group by 的理解
group by的作用是对by后面的类别进行分组,这个类别可以是一个也可以是多个,此外group by是先排序后分组。然后select中的东西必须是group by后面的内容,或者是聚合函数,否则就会报错,理解如下:
类别列被压缩成一个了,而其他列还是正常。这样一来,如果再select中还有其他列,比如姓名字段,那么就会报错,因为类别只有一个,而姓名有好多个,无法成表,于是报错。
SQL中Group By的使用
mybatis 中 #与$的区别
1 #是将传入的值当做字符串的形式,eg:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id ='1'.
2 $是将传入的数据直接显示生成sql语句,eg:select id,name,age from student where id =${id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id = 1.
3 使用#可以很大程度上防止sql注入。(语句的拼接 #{xxx},使用的是PreparedStatement,会有类型转换,比较安全 简单的说就是#{}是经过预编译的,是安全的,${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。)
4 但是如果使用在order by 中就需要使用 $.
5 在大多数情况下还是经常使用#,但在不同情况下必须使用$.
我觉得#与$的区别最大在于:#{} 传入值时,sql解析时,参数是带引号的,而${}传入值,sql解析时,参数是不带引号的。
一个成绩表求出有不及格科目的同学
SELECT 学生.班级,COUNT(score<60)
FROM 学生选课
LEFT JOIN 学生
ON 学生选课.学生ID=学生.学生ID
GROUP BY 学生.班级
500 万数字排序,内存只能容纳 5 万个,如何排序,如何优化?
方案一:位图法
对这些数进行位图排序,只需要约5000000/8 = 625000byte,就是0.625M,排序后输出。但是该方法具有局限性,需要知道这些数据中的最大值。而且要考虑数据疏密程度,如果最大值1000000,而只有100个元素,那么效率会变得非常低
方案二:归并排序法
多路归并就是从多个有序数列中归并。
将500万的数据,分成40个有序文件,分别在内存中排序,然后对这40个有序文件进行归并排序。
读取每个文件中第一个数(每个文件的最小数),存放在一个大小为40的data数组中
选择data数组中最小的数min_data,及其相应的文件索引(来自哪个文件)index
将min_data写入到文件result,然后更新数组data(根据index,读取该文件的下一个数代替min_data)
判读是否所有数据都读取完毕,否则返回到2步。
问了一个这样的表(三个字段:姓名,id,分数)要求查出平均分大于 80 的 id 然后分数降序排序。 然后经过提示用聚合函数 avg。
select id from table group by id having avg(score) > 80 order by avg(score) desc。
建表的原则
数据库三大范式
select 语句实现顺序
查询中用到的关键词主要包含六个,并且他们的写sql语句时的顺序依次为
select–from–where–group by–having–order by
其中select和from是必须的,其他关键词是可选的,这六个关键词的执行顺序 与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行
from:需要从哪个数据表检索数据
where:过滤表中数据的条件
group by:如何将上面过滤出的数据分组
having:对上面已经分组的数据进行过滤的条件
select:查看结果集中的哪个列,或列的计算结果
order by :按照什么样的顺序来查看返回的数据
A和B两个表做等值连接(Innerjoin)怎么优化 哈希
如果有hash join,就不用做这种限制了,用第一个表(小表)建hash table,第二个表在hash table中查找匹配的项,复杂度是n。缺点是hash table占的内存可能会比较大,不过也有基于磁盘的hash join,实现起来比较复杂
参考文献:
zhihu:《阿里巴巴JAVA开发手册》里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写?
数据库连接池的理解和优化
count 是否计算 null 值 的行等
做统计的时候,null是不计算在count以内的。所以字段的值最好不要设置为null。
SQL 语句的 5 个连接概念
1.内连接
1.1.等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
1.2.不等值连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。
1.3.自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。
2.外连接
2.1.左联接:是以左表为基准,将a.stuid = b.stuid的数据进行连接,然后将左表没有的对应项显示,右表的列为NULL
2.2.右连接:是以右表为基准,将a.stuid = b.stuid的数据进行连接,然以将右表没有的对应项显示,左表的列为NULL
2.3.全连接:完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
3.交叉连接
交叉连接:交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。
内连接:内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。
SQL的几种连接:内连接、左联接、右连接、全连接、交叉连接
表锁和行锁应用场景:
表级锁使用与并发性不高,以查询为主,少量更新的应用,比如小型的web应用; 而行级锁适用于高并发环境下,对事务完整性要求较高的系统,如在线事务处理系统。 以上就是行锁、表锁等的特点和应用场景。
表锁: 开销小,加锁快,不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
行锁: 开销大,加锁慢,会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
juejin: 阿里P8架构师谈:MySQL行锁、表锁、悲观锁、乐观锁的特点与应用
哈希索引优缺点
哈希索引就是采用一定的哈希算法,将键值换算成新的哈希值,检索时不需要想B+Tree那样从根结点开始查找,而是经过计算直接定位,所以速度很快。
但是也有限制:
- 只支持精确查找,不能用于部分查找和范围查找。无法排序和分组。因为原来有序的键值经过哈希算法很可能打乱。
- 如果哈希冲突很多,查找速度很慢。比如在有大量重复键值的情况下。
- 不能利用部分索引查询
- 不能避免表扫描