- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
如果想找id为8的学生的信息,没有索引,此时的查找过程就相当于一个“顺序表查找”。
如果是针对顺序表查找,顺序表也是在内存当中,内存访问的速度快,并且数据也没那么多的时候,还可以勉强接受。
如果是针对数据库顺序查找,数据库的数据是在磁盘上,磁盘访问的速度更慢,并且数据量也可能非常多。这样速度就可能会变慢。
索引就是为了避免数据库进行顺序查找,提高查找效率。
索引可以考虑的数据结构有两种:1.哈希表 2.二叉搜索树 ,因为它们查找的速度都比较快。哈希表查找的时间复杂度O(1),二叉搜索树查找的时间复杂度O(logN)。
但是索引用这两种作为数据结构会有些缺点:
例如查找id<6并且>3的学生的信息。select * from student where id<6 and id>3;
哈希表用来作为索引数据结构的缺点:
我们都知道哈希表下的每个结点都是由链表连接起来的,哈希表的查找过程是把key代入哈希函数,计算得到下标,再根据下标取到对应的链表,再去遍历比较key是否相等。因此哈希表只能处理相等的情况,不能处理其它的逻辑(> >= < <= , between…and)等
二叉搜索树用来作为索引数据结构的缺点:
相比于哈希表,二叉搜索树虽然能处理范围查找,但是处理效率不高。
1.二叉搜索数每个结点最多两个叉,当数据量比较大的时候,树的高度就会较高,最终的操作效率也就会越低。
2.二叉搜索树直接获取到中序遍历也不是很高效O(N)
二叉搜索树的其它缺点:
因此:索引的数据结构是B+树,但要了解B+树之前要先了解B树。
B树也称为B-树(不是B减数),它是基于二叉搜索树来进行优化的。
叶子和非叶子都是由存储数据的,,都要放到磁盘上。
它是一棵N叉树,因此它的高度肯定会比二叉树的高度低,因此查找的效率更快。
它跟二叉树相比最大的差异:
1.每个结点不是2叉,而是n叉。
2.每个结点不是存一个数据了,而是可能存多个。
仔细观察能够发现,每个结点的存的数据的个数和该结点的度是相关的。
度=存的个数+1.
将B树中的一小部分截取下来:
B+树的存储结构:
非叶子结点上的数据相当于id,它能够快速找到叶子结点中对应的id,并获取id对应的数据。
和B树相比,主要是两个地方发生了变化:
1.每一层的元素之间都链接到了一起。
2.数据只在叶子结点上保存,非叶子结点上只保存一些辅助查找的边界信息。
B+树更多的优点:
索引起到的作用:加快查找效率,减慢插入和删除,修改效率(需要同步调整索引结果)
索引也会占到额外的内存空间(本质上用时间换取空间)
给具体的表中某列加索引的时候,加在主键上的索引(主键索引)和加在其它列上的索引是截然不同的。
主键索引的叶子结点存的是数据的完整记录,其它索引的叶子结点存的是主键的id。
例如:我们在创建表的时候给id加上主键,那主键索引就为id。此时要查找名字为李四的id,因为其它索引是存的id值。因此会先找到李四对应的主键id值,**再根据主键id去主键索引中查找id为1的全部数据,根据主键id在表中查找主键索引id的操作称为回表。**每条数据可能是一条长记录。
索引的应用场景主要是应用在查找很频繁,但是插入,删除,修改都不频繁的场景,这种场景非常常见。
需要考虑以下几点:
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。
创建主键约束(primary key)、唯一约束(unique)、外键约束时(foreign key),会自动创建对应的列的索引。
如:当我们的一个student表的id要关联于class表中的学生的id,创建的主键id是在class表当中的。因此这样才能确定该班中的学生有谁。
show index from 表名;
案例:查看学生表已有的索引
show index from student;
对于非主键、非唯一约束、非外键的字段,可以创建普通索引。
create index 索引名 on 表名(字段名);
案例:创建学生中name字段的索引
create index index_name_student on student(name);
drop index 索引名 on 表名;
案例:删除班级表中name字段的索引
drop index index_name_student on student;
索引的创建和删除都是耗时操作,因此不必要的时候已经创建好索引的情况下尽量少去自己创建索引,并且不要在生产环境中创建索引。
面试问题总结:
1.索引是啥?
2.索引要解决的问题
3.索引的应用场景
4.索引的数据结构
a) 为什么不用哈希表
b) 为什么不用二叉搜索树
c) 啥是B树,相较上面两个有什么优势
d) 啥是B+树,为什么用它来作索引的数据结构
5.更详细的说下索引的细节方面
事务解决的问题:
例如有个数据表,保存了一些人的银行账户余额,接下来需要进行A->B转账3000块钱。
可以分为两个步骤:
1.A的账户余额减3000
2.B的账户余额加3000
但是,如果1执行成功了,执行2的时候出了问题,此时A 的钱减少了而B的没有增加,3000块钱是不是就凭空消失了呢?
因此事务的概念:
把一组操作封装到一起,称为一个共同的执行单元,此时执行整个事务就能避免上面的问题。
事务的特性总称为ACID。
a) 原子性:事务中的若干个操作,要么全部执行成功,要么全部都不执行。但此处的不执行并不是真正的不执行,而是一旦中间某个步骤执行出错,就把前面已经执行完毕的步骤回滚(rollback)回去。步骤回滚要借助逆向操作,目的是把原来操作造成的影响进行还原。例如:减3000的逆操作就是加3000.
b) 一致性:执行事务的前后,数据始终处于一种合法的状态,例如转账操作,减账户余额的时候,不能账户余额减成负数。
c) 持久性:事务一旦执行完毕,此时对于数据的修改就是持久生效的(写入磁盘了)。注:数据存到磁盘中就是持久的,数据存到内存中就是不持久的(重启就没了)
d) 隔离性:比较复杂,设计到“并发执行事务”,它能够引发一系列的问题:脏读、不可重复读、幻读 => 解决方案 => 数据库隔离级别 。
(1)开启事务:start transaction;
(2)执行多条SQL语句
(3)回滚或提交:rollback/commit;
说明:rollback即是全部失败,commit即是全部成功。
start transaction;
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';
commit;
这几天我一直在努力。我一直在自学 CSS,所以对菜鸟好一点。我正在创建一个推荐 slider 。推荐以 3 个 block 显示。我希望前 2 个下降,第 3 个上升。但是当 slider 激活时,无
我最近开始学习 Nodejs,现在我很困惑我的网络应用程序使用什么,html 还是 ejs (Express)。 Ejs 使用 Express 模块,而 .html 使用 HTML 模块。我的第一个问
假设我们有一个 PostgreSQL 表contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。 存储方式如下: id 主键 电子邮件 文本 email_la
我成功为一种新的tesseract语言编写了traineddata文件,但是当我完成时,我继续收到以下错误: index >= 0 && index = 0 && 索引 < size_used_ :E
这个问题已经有答案了: How to deal with SettingWithCopyWarning in Pandas (21 个回答) 已关闭 4 年前。 假设我有一个像这样的数据框,第一列“密
如果我有一个位置或行/列同时用于 A 和 B 位置,请检查 B 是否与 A 成对角线? 1 2 3 4 5 6 7 8 9 例如,我如何检查 5 是否与 7 成对角线? 此外,如果我检查 4 是
MongoDB:索引 一、 创建索引 默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引 > db.user.getIndexes() [ { "v
一、索引介绍 索引是一种用来快速查询数据的数据结构。 B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。 MongoDB不使用索引
我无法决定索引。 就像我有下面的查询需要太多时间来执行: select count(rn.NODE_ID) as Count, rnl.[ISO_COUNTRY_CODE] as Cou
我有这些表: CREATE TABLE `cstat` ( `id_cstat` bigint(20) NOT NULL, `lang_code` varchar(3) NOT NULL,
我正在尝试找到一种方法来提高包含 IP 范围的 mysql 表的性能(在高峰时段每秒最多有 500 个 SELECT 查询(!),所以我有点担心)。 我有一个这种结构的表: id smallint(
jquery index() 似乎无法识别元素之一,总是说“无法读取未定义的属性‘长度’”这是我的代码。mnumber 是导致问题的原因。我需要 number 和 mnumber 才能跟踪使用鼠标,并
我们有一个包含近 4000 万条记录的 MongoDB 集合。该集合的当前大小为 5GB。此集合中存储的数据包含以下字段: _id: "MongoDB id" userid: "user id" (i
文档说:如果你有多个字段的复合索引,你可以用它来查询字段的开始子集。所以如果你有一个索引一个,乙,丙你可以用它查询一种一个,乙a,b,c 我的问题是,如果我有一个像这样的复合索引一个,乙,丙我可以查询
我正在使用 $('#list option').each(function(){ //do stuff }); 循环列表中的选项。我想知道如何获取当前循环的索引? 因为我不想让 var i = 0;循
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL
SQLite 索引(Index) 索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
我是 RavenDB 的新手。我正在尝试使用多 map 索引功能,但我不确定这是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。 汽车文件看起来像这样: { Id: "
我有以下数据,我想根据范围在另一个表中建立索引 我想要实现的是,例如,如果三星的销售额为 2500,则折扣为 2%,低于 3000 且高于 1000 我知道它可以通过索引来完成,与多个数组匹配,然后指
我正在检查并删除 SQL 数据库中的重复和冗余索引。 所以如果我有两个相同的索引,我会删除。 例如,如果我删除了重叠的索引... 索引1:品牌、型号 指标二:品牌、型号、价格 我删除索引 1。 相同顺
我是一名优秀的程序员,十分优秀!