(计算机基础 核心知识)数据库

1.数据库中什么时候应该用索引

索引是存储引擎中用于快速找到记录的一种数据结构。在关系型数据库中,索引具体是一种对数据库中一列或多列的值进行排序的存储结构。

为什么引入索引,为了提高数据查询的效率。索引对数据库查询良好的性能非常关键,当表中数据量越来越大,索引对性能的影响越重要。

使用索引

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该创建索引
  3. 查询中排序的字段创建索引将大大提高排序的速度(索引就是排序加快速查找
  4. 查询中统计或者分组的字段;

不需要建立索引

  1. 频繁更新的字段不适合创建索引因为每次更新不单单是更新记录,还会更新索引,保存索引文件
  2. where条件里用不到的字段,不创建索引;
  3. 表记录太少,不需要创建索引;
  4. 经常增删改的表;
  5. 数据重复且分布平均的字段,因此为经常查询的和经常排序的字段建立索引。注意某些数据包含大量重复数据,因此他建立索引就没有太大的效果,例如性别字段,只有男女,不适合建立索引

索引分类

在MySQL中, 索引有两种分类方式:逻辑分类和物理分类。

按照逻辑分类,索引可分为:

主键索引:一张表只能有一个主键索引不允许重复、不允许为 NULL

唯一索引:数据列不允许重复,允许为 NULL 值,一张表可有多个唯一索引,唯一索引可以创建在单个列上,也可以创建在多个列的组合上

普通索引:一张表可以创建多个普通索引,一个普通索引可以包含多个字段,允许数据重复,允许 NULL 值插入;

全文索引:让搜索关键词更高效的一种索引。

按照物理分类,索引可分为:

聚集索引:一般是表中的主键索引,如果表中没有显示指定主键,则会选择表中的第一个不允许为 NULL 的唯一索引,如果还是没有的话,就采用 Innodb 存储引擎为每行数据内置的 6 字节 ROWID 作为聚集索引。每张表只有一个聚集索引,因为聚集索引的键值的逻辑顺序决定了表中相应行的物理顺序。聚集索引在精确查找和范围查找方面有良好的性能表现(相比于普通索引和全表扫描),聚集索引就显得弥足珍贵,聚集索引选择还是要慎重的(一般不会让没有语义的自增 id 充当聚集索引);

非聚集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同(非主键的那一列),一个表中可以拥有多个非聚集索引。

在目前用的最多的mysql的InnoDB存储引擎中,是使用B+Tree索引方法来进行索引建立的。

B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。

B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。先了解二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree),B+树即由这些树逐步优化而来。

答:当在主键上进行选择时,系统会自动给你建索引,当然这个索引你也可以自己去建立。显然回答的又不对

老师继续提问,是不是只要在这个列上有索引,就应该去用索引。我说不是这样,这是数据库系统内部的事情,它可以选择用索引,也可以选择不用。

老师继续追问,如果让你去设计一个数据库系统,你会选择什么时候用索引,什么时候不用。我答数据量很大的时候我们用索引是比较划算的,比如说从一万个数据里面选一个数据,而它恰好又有索引,这时你就可以用索引

但是如果从一万个数据里面选9999个,像这种极端情况,就没必要用索引了,直接遍历就可以了

一般来说,选取的数据的个数是总个数的10%以下,用索引是比较划算的,因为索引也是有代价的

那你知道数据库在数据比较多的时候应该做怎么样的优化,可以为数据建立索引,加快查询数据的速度

2.数据库的外键

外键也叫FOREIGN KEY,是用于将两个表链接在一起的键。

FOREIGN KEY是一个表中的一个字段(或字段集合),它引用另一个表中的PRIMARY KEY。

外键带来的好处主要是,保证数据的完整性和一致性,主要目的是控制存储在外键表中的数据。同时支持关联查询。FOREIGN KEY约束用于防止会破坏表之间链接的操作

关于外键的使用存在一些争议,因为它在确保两个表之间的关系的时候又带来很多限制,很多工程师认为应该在代码逻辑里控制两个表的关系,而不在数据库表之间定义这样的关系。同时,外键对数据的插入删除等都会带来影响,因为表与表之间存在关联,因此各种操作都会变慢,因此在定义外键之前应该尽量考虑好数据的量,以及数据的读写频率等等。

个人从目前的实际经验出发也不是特别喜欢太多的外键关系存在。尽量子代码曾通过逻辑控制数据之间的关系可能确实是更好的做法。在使用的时候应该结合实际情况进行抉择。

3.哈希能够支持区间查询吗

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希码索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储

因为索引自身只需存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引查找的速度非常快。然而,哈希索引也有他的限制:

  • 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行,不过,访问内存中的行的速度很快,所以大部分情况下这一点对性能的影响并不明显。
  • 哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序
  • 哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。
  • 哈希索引只支持等值比较查询,包括=、IN()、<=>、也不支持任何范围查询
  • 访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。
  • 如果哈希冲突很多的话,一些索引维护操作的代价也会很高。例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应的引用,冲突越多,代价越大。

因为这些限制,哈希索引只适用于某些特定的场合。而一旦适合哈希索引,则它带来的性能提升将非常显著。举个例子,在数据仓库应用中有一种经典的“星型” schema,需要关联很多查找表,哈希索引就非常适合查找表的需求。 除了Memory引擎外,NDB集群引擎也支持唯一哈希索引,且在NDB集群引擎中作用非常特殊。 InnoDB 引擎有一个特殊额功能叫做“自适应哈希索引”,当 InnoDB注意到某些索引值被使用得非常频繁时,它会在内存中基于B-Tree索引之上再创建一个哈希索引,这样就让B-Tree索引页具有哈希索引的一些优点,比如快速的哈希查找。这是一个完全自动的、内部的行为,用户无法控制或者配置,不过若果有必要,完全可以关闭该功能。

4.除了关系型数据库还有什么数据库

关系型数据库采用了关系模型(可以简单理解为二维表格类型)组织数据,一般可以遵守事务的ACID特性 不是由关系模型进行存储的均可视作非关系型数据库,比如以键值对的redis,图数据库等。

关系型数据库

关系型数据库是指采用了关系模型来组织数据的数据库。简单来说,关系模式就是二维表格模型。

优点

(1)容易理解,二维表的结构非常贴近现实世界,二维表格,容易理解。

(2)使用方便,通用的sql语句使得操作关系型数据库非常方便

(3)易于维护,数据库的ACID属性,大大降低了数据冗余和数据不一致的概率

瓶颈

(1 )海量数据的读写效率

对于网站的并发量高,往往达到每秒上万次的请求,对于传统关系型数据库来说,硬盘I/o是一个很大的挑战。

(2) 高扩展性和可用性。

在基于web的结构中,数据库是最难以横向拓展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库没有办法简单的通过添加更多的硬件和服务节点来拓展性能和负载能力。

非关系型数据库

网状数据库、层次数据库(比较老的

关系型数据库的最大优点就是事务的一致性,这个特性,使得关系型数据库中可以适用于一切要求一致性比较高的系统中。比如:银行系统。

但是在网页应用中,对这种一致性的要求不是那么的严格,允许有一定的时间间隔,所以关系型数据库这个特点不是那么的重要了。相反,关系型数据库为了维护一致性所付出的巨大代价就是读写性能比较差。而像微博、facebook这类应用,对于并发读写能力要求极高,关系型数据库已经无法应付。所以必须用一种新的数据结构存储来替代关系型数据库。所以非关系型数据库应用而生。

1.概念

NoSQL非关系型数据库,主要指那些非关系型的、分布式的,且一般不保证ACID的数据存储系统,主要代表MongoDBRedis、CouchDB。

NoSQL提出了另一种理念,以键值来存储,且结构不稳定,每一个元组都可以有不一样的字段,这种就不会局限于固定的结构,可以减少一些时间和空间的开销。使用这种方式,为了获取用户的不同信息,不需要像关系型数据库中,需要进行多表查询。仅仅需要根据key来取出对应的value值即可。

2.分类

非关系数据库大部分是开源的,实现比较简单,大都是针对一些特性的应用需求出现的。根据结构化方法和应用场景的不同,分为以下几类。

(1)面向高性能并发读写的key-value数据库

主要特点是具有极高的并发读写性能,例如Redis、Tokyo Cabint等。

(2)面向海量数据访问的面向文档数据库

特点是,可以在海量的数据库快速的查询数据。例如MongoDB以及CouchDB.

(3)面向可拓展的分布式数据库

解决的主要问题是传统数据库的扩展性上的缺陷。

3.缺点

但是由于Nosql约束少,所以也不能够像sql那样提供where字段属性的查询。因此适合存储较为简单的数据。有一些不能够持久化数据,所以需要和关系型数据库结合。

对比

1.存储上?

Sql通常以数据库表的形式存储,例如存储用户信息,SQL中增加外部关系的话,需要在原表中增加一个外键,来关联外部数据表。如下:

NoSql采用key-value的形式存储

2.事务

SQL中如果多张表需要同批次被更新,即如果其中一张表跟新失败的话,其他表也不会更新成功。这种场景可以通过事务来控制,可以在所有命令完成之后,再统一提交事务。在Nosql中没有事务这个概念,每一个数据集都是原子级别的。

3.数据表 VS 数据集

关系型是表格型的,存储在数据表的行和列中。彼此关联,容易提取。而非关系型是大块存储在一起。

4.预定义结构 VS 动态结构

在sql中,必须定义好表结构之后,才能够添加数据,例如定义表的主键、索引、外键等。表结构可以在定义之后更新,但是如果有比较大的结构变更,就会变的比较复杂。

在Nosql数据库中,数据可以在任何时候任何地方添加。不需要预先定义。

5.存储规范 VS 存储代码

关系型数据库为了规范性,把数据分配成为最小的逻辑表来存储避免重复,获得精简的空间利用。但是多个表之间的关系限制,多表管理就有点复杂。

当然精简的存储可以节约宝贵的数据存储,但是现在随着社会的发展,磁盘上付出的代价是微不足知道的。

非关系型是平面数据集合中,数据经常可以重复,单个数据库很少被分开,而是存储成为一个整体,这种整块读取数据效率更高。

6.纵向拓展 VS 横向拓展

为了支持更多的并发量,SQL数据采用纵向扩展,提高处理能力,通过提高计算机性能来提高处理能力。

NoSql通过横向拓展,非关系型数据库天然是分布式的,所以可以通过集群来实现负载均衡。

7.其他方面

比如:关系型是结构化查询语言,NoSql是采用更简单而且精确的数据访问方式;SQl数据库大多比较昂贵,而NoSql大多是开源的

五、选择?

目前许多大型互联网都会选用MySql+NoSql的组合方案,因为SQL和NoSql都有各自的优缺点。

关系型数据库适合存储结构化数据,比如:用户的账号、地址:

(1)这些数据通常需要做结构化查询,比如说Join,这个时候,关系型数据库就要胜出一筹。

(2)这些数据的规模、增长的速度通常是可以预期的。

(3)事务性、一致性,适合存储比较复杂的数据。

NoSql适合存储非结构化数据,比如:文章、评论

(1)这些数据通常用于模糊处理,例如全文搜索、机器学习,适合存储较为简单的数据。

(2)这些数据是海量的,并且增长的速度是难以预期的。

(3)按照key获取数据效率很高,但是对于join或其他结构化查询的支持就比较差。

总结:

SQL数据库依然强大,可以可靠的处理事务并且保持事务的完整性,只有你的数据非常大,操作扩展需要更加分布式的系统时,才考虑NoSql数据库。

5.范式

  • 1NF 第一范式: 要求数据库表中每一列都是不可分割的基本数据项,避免重复属性。
  • 2NF 第二范式: 在1NF基础上,要求非主键列完全依赖于主键,消除部分子函数依赖。
  • 3NF 第三范式: 在2NF基础上,要求非主键列不依赖于其他非主属性,消除传递依赖。
  • BCNF 巴克斯范式: 修正的第三范式,防止主键某列依赖于主键其他列。
  • 4NF 第四范式: 限制属性间不允许有非平凡且非函数依赖的多值依赖。

所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。

说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。

如果关系模式R为第一范式,并且R中每一个非主属性完全函数依赖于R的某个候选键, 则称为第二范式模式。

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。

例如员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。

简而言之,第二范式(2NF)就是非主属性完全依赖于主关键字。

所谓完全依赖是指不能存在仅依赖主关键字一部分的属性(设有函数依赖W→A,若存在XW,有X→A成立,那么称W→A是局部依赖,否则就称W→A是完全函数依赖)。如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。

如果关系模式R是第二范式,且每个非主属性都不传递依赖于R的候选键,则称R为第三范式模式。

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

曾获多国内大厂的 ssp 秋招 offer,且是Java5年的沉淀老兵(不是)。专注后端高频面试与八股知识点,内容系统详实,覆盖约 30 万字面试真题解析、近 400 个热点问题(包含大量场景题),60 万字后端核心知识(含计网、操作系统、数据库、性能调优等)。同时提供简历优化、HR 问题应对、自我介绍等通用能力。考虑到历史格式混乱、质量较低、也在本地积累了大量资料,故准备从头重构专栏全部内容

全部评论

相关推荐

06-07 16:43
已编辑
门头沟学院 C++
Huner_:怎么可能推到master,scm里面是合并分支,然后生成一个工单,需要montor审批才能提交
投递字节跳动等公司7个岗位 我和mentor的爱恨情仇 我的实习日记
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务