前言
索引是mysql重要的一环,mysql可以大大的提高检索的速度。
我们看看菜鸟教程对索引的比喻
打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。
拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。
如果索引是按照拼音,笔画,偏旁部首等排序的目录快速找到需要的字,那没有索引就相当于从前往后挨个找我们所需要的字。
我们经常使用的仓库层条件查找应该加入索引,但是索引不能无节制的加入。因为我们索引是通过牺牲空间去换取搜索时间。索引在减少搜索时间的同时,也会增加更新数据表的时间,对表进行INSERT、UPDATE和DELETE操作的时候,不仅仅是对数据操作,还要去操作索引文件。
但是,制约我们的永远是我们的查询速度,所以,索引对我们很有用处。
唯一索引
索引分四种。我们常用的有两种,普通索引与唯一索引。
唯一索引顾名思义,就是通过某一查询方法能查到唯一一条数据。
唯一索引经常被用于限制数据。举个例子。现在有课程(course)和知识点(tag)两个实体。知识点允许名称相同,但是不允许有两个相同名称知识点关联同一课程。也就是说,不存在两个知识点课程id和名称都相同。我们在数据库如何保证呢,就需要用到我们的唯一索引。使用课程id与名称name建立唯一索引。就可以避免这个问题。
JPA外键索引
当我们通过JPA使用@ManyToOne
,@OneToMany
等这些注释去关联外键时,JPA会为我们自动注入外键索引,就是通过我们绑定的字段去添加一个普通索引。比如我们的标签tag实体与course实体通过course_id关联,我们在tag实体类加入
/**
* 标签属于某门唯一的课程
*/
@ManyToOne
@JoinColumn(nullable = false)
private Course course;
在运行项目时,JPA会自动为我们加入course_id普通索引。
JPA唯一索引
我们使用注解可以自定义索引,比如我们刚才唯一索引的例子,我们通过course_id和name两个字段去定义一个唯一索引
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"course_id", "name"})})
JPA会为我们生成course_id与name唯一索引。
但是,出现了一个问题。我们发现原来的 coruse_id普通索引消失了。这是为什么呢?
猜测可能JPA索引为了避免生成大量索引,刚才我们也说了索引也有坏处,如果每个字段都有索引就相当于都没有索引。JPA在建立course_id与name唯一索引的同时,删除了course_id普通索引,避免索引滥用。如果我们把唯一索引中的course_id变为其他字段,则不会删除。
字段写法
我们观察一下,我们在写course_id的时候是用的下横线式的写法。如果我们写一个普通的变量,比如deletedAt字段,则需要驼峰式的写法,为什么会有两种写法呢。
我们猜测,下横线式写法用于表示别的表的字段,因为我们course为关联的表,而id为course表里的字段,我们在表示别的表的字段的时候,使用下横线式写法,而在写自己表中的字段的时候,用驼峰式写法。我们猜测这么做是为了防止字段冲突,在这里是为了防止与一个叫tag表中courseId字段冲突,虽然实际中我们并没有那个字段。
我们在实体中将name字段加上@Column
注解,就像这样
@Column(name = "test")
private String name;
此时我们不得不将我们写的唯一注解中的name变为test。这是我们再猜测我们写的语法其实是看的@Column
注解中name
的值,且name默认为本字段名。
总结
当我们遇到一个找不到原因的现象的时候,我们不妨站在规则制定者的角度去想问题,然后想一个可以合理解释的通的原因。可能这并不是最终正确原因,但是对于现阶段的学习是正确的,我们不可能去学习JPA源码,成本是非常大的。我们想一个合理的解释可以适用于现阶段的学习就可以了。未来我们可能会否定自己的答案去得到一个更准确的答案。学习就是一个不断自我否定的过程,回想近几百年的物理学发展,不也是这样吗。
感谢老师的指导。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。