数据库基础知识
什么是MySQL?
-
MySQL是一个数据库管理系统。
数据库是数据的结构化集合。
-
MySQL数据库是关系型的。
关系数据库将数据存储在单独的表中,而不是将所有数据放在一个大仓库中。数据库结构被组织成针对速度进行了优化的物理文件。具有对象(例如数据库,表,视图,行和列)的逻辑模型提供了灵活的编程环境。您设置规则来管理不同数据字段之间的关系,例如一对一,一对多,唯一,必需或可选,以及 不同表之间的“指针”。数据库执行这些规则,因此,使用设计良好的数据库,您的应用程序将永远不会看到不一致,重复,孤立,孤立,过时或丢失的数据。
**“ MySQL ” 的SQL部分代表 “结构化查询语言”。SQL是用于访问数据库的最常见的标准化语言。**根据您的编程环境,您可以直接输入SQL(例如,生成报告),将SQL语句嵌入用另一种语言编写的代码中,或使用隐藏SQL语法的特定于语言的API。
SQL由ANSI / ISO SQL标准定义。自1986年以来,SQL标准一直在发展,并且存在多个版本。在本手册中,“ SQL-92 ”是指1992年发布的标准,“ SQL:1999 ”是指1999年发布的标准,“ SQL:2003 ”是指标准的当前版本。我们随时使用 “ SQL标准”一词来表示SQL标准的当前版本。
-
MySQL软件是开源的。
开源意味着任何人都可以使用和修改该软件。任何人都可以从互联网上下载MySQL软件并使用它而无需支付任何费用。如果愿意,您可以学习源代码并进行更改以适合您的需求。
-
MySQL数据库服务器非常快速,可靠,可扩展且易于使用。
-
MySQL Server在客户端/服务器或嵌入式系统中运行。
MySQL数据库软件是一个客户端/服务器系统,由支持不同后端的多线程SQL Server,几个不同的客户端程序和库,管理工具以及各种应用程序编程接口(API)组成。
-
可以使用大量的MySQL软件。
MySQL的主要功能
内部和便携性
- 使用具有独立模块的多层服务器设计。
- 设计为使用内核线程完全多线程,以轻松使用多个CPU(如果有)。
- 提供事务性和非事务性存储引擎。
- 使用
MyISAM
索引压缩非常快速的B树磁盘表()。 - 旨在使其相对容易地添加其他存储引擎。如果要为内部数据库提供SQL接口,这将很有用。
- 使用非常快速的基于线程的内存分配系统。
- 使用优化的嵌套循环联接执行非常快速的联接。
- 实现内存中的哈希表,用作临时表。
- 使用高度优化的类库来实现SQL函数,该类库应尽可能快。通常,查询初始化后根本没有内存分配。
- 提供服务器作为在客户端/服务器网络环境中使用的单独程序,以及作为可嵌入(链接)到独立应用程序中的库。此类应用程序可以隔离使用,也可以在没有网络可用的环境中使用。
资料类型
- 许多数据类型:有符号/无符号整数1,2,3,4,和8个字节长,
FLOAT
,DOUBLE
,CHAR
,VARCHAR
,BINARY
,VARBINARY
,TEXT
,BLOB
,DATE
,TIME
,DATETIME
,TIMESTAMP
,YEAR
,SET
,ENUM
,和开放GIS空间类型。 - 固定长度和可变长度的字符串类型。
陈述和功能
-
查询
SELECT
列表和WHERE
子句中的 完全运算符和函数支持 。例如:mysql> SELECT CONCAT(first_name, ' ', last_name) -> FROM citizen -> WHERE income/dependents > 10000 AND age > 30;
-
完全支持SQL
GROUP BY
和ORDER BY
子句。支持基函数(COUNT()
,AVG()
,STD()
,SUM()
,MAX()
,MIN()
,和GROUP_CONCAT()
)。 -
支持标准SQL和ODBC语法,
LEFT OUTER JOIN
并RIGHT OUTER JOIN
同时支持它们。 -
支持标准SQL要求的表和列别名。
-
支持
DELETE
,INSERT
,REPLACE
,和UPDATE
以返回更改(受影响)的行数,或返回通过连接到服务器时设置标志,而不是匹配的行的数量。 -
支持特定于MySQL的
SHOW
语句,该语句检索有关数据库,存储引擎,表和索引的信息。支持INFORMATION_SCHEMA
数据库,根据标准SQL实现。 -
一条
EXPLAIN
语句,显示优化器如何解析查询。 -
函数名称与表或列名称的独立性。例如,
ABS
是一个有效的列名。唯一的限制是对于函数调用,函数名称和其后的“(
”之间不允许有空格 。请参见 第9.3节“关键字和保留字”。 -
您可以在同一条语句中引用来自不同数据库的表。
安全
- 特权和密码系统,非常灵活和安全,并且可以进行基于主机的验证。
- 连接服务器时,通过对所有密码通信进行加密来实现密码安全。
可扩展性和限制
- 支持大型数据库。我们将MySQL Server与包含5000万条记录的数据库一起使用。我们也知道使用MySQL Server的用户有200,000个表和大约5,000,000,000行。
- 每个表最多支持64个索引。每个索引可以包含1到16列或部分列。
InnoDB
表的最大索引宽度为767字节或3072字节。
连接性
本土化
客户和工具
MySQL 8.0的新增功能
https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html
- 数据字典。 MySQL现在合并了一个事务性数据字典,用于存储有关数据库对象的信息
- 原子数据定义语句(Atomic DDL)。 原子DDL语句将数据字典更新,存储引擎操作以及与DDL操作关联的二进制日志写入操作组合到单个原子事务中。
- 升级程序。 以前,在安装新版本的MySQL之后,MySQL服务器会在下次启动时自动升级数据字典表,从MySQL 8.0.16开始,服务器执行以前由mysql_upgrade处理的任务。
- 安全性和帐户管理。 添加了这些增强功能,以提高安全性并在帐户管理中实现更大的DBA灵活性:
mysql
现在 ,系统数据库中的授权表是InnoDB
(事务性)表。以前,这些是MyISAM
(非事务性)表。- 以前,帐户管理对帐单(例如
CREATE USER
或DROP USER
),命名多个用户可以对某些用户成功,而对其他用户则失败。现在,每个语句都是事务性的,并且对于所有命名的用户都成功,或者回滚,并且在发生任何错误时都不起作用。如果成功,则将语句写入二进制日志;如果失败,则不写入语句。在这种情况下,将发生回滚并且不进行任何更改。 - 一个新的
caching_sha2_password
身份验证插件可用。caching_sha2_password
实现SHA-256密码哈希,但是使用缓存来解决连接时的延迟问题。 - MySQL现在支持角色,这些角色被称为特权集合。
- MySQL现在合并了用户帐户类别的概念
- 资源管理。 MySQL现在支持创建和管理资源组,并允许将服务器中运行的线程分配给特定的组,以便线程根据该组可用的资源执行。
- 表加密管理。 现在可以通过定义和强制执行加密默认值来全局管理表加密。
- InnoDB增强功能。
- 每次值更改时,当前最大自动增量计数器值都会写入重做日志,并保存到每个检查点的引擎专用系统表中。这些更改使当前的最大自动增量计数器值在服务器重新启动期间保持不变。
- 在
ROLLBACK
操作之后立即重新启动服务器 不再导致重用分配给回滚事务的自动增量值。 - 遇到索引树损坏时,
InnoDB
将损坏标志写入重做日志,这会使损坏标志崩溃。InnoDB
还将内存损坏标志数据写入每个检查点上的引擎专用系统表。在恢复期间,InnoDB
在将内存表和索引对象标记为已损坏之前,从两个位置读取损坏标志并合并结果。 InnoDB
memcached的插件支持多个get
操作(读取在一个单一的多键-值对分布式缓存 查询)和范围查询。
ENUM类型
https://dev.mysql.com/doc/refman/8.0/en/enum.html
该ENUM
类型具有以下优点:
- 在列的一组可能值有限的情况下,压缩数据存储。您指定为输入值的字符串会自动编码为数字。见 第11.7节,“列类型存储需求”为存储需求
ENUM
类型。 - 可读的查询和输出。这些数字将转换回查询结果中的相应字符串。
枚举文字的索引值
每个枚举值都有一个索引:
-
列规范中列出的元素分配有索引号,从1开始。
-
空字符串错误值的索引值为0。这意味着您可以使用以下
SELECT
语句查找ENUM
分配了无效值的行:mysql> SELECT * FROM tbl_name WHERE enum_col=0;
-
NULL
值 的索引是NULL
。 -
术语“索引”在这里是指枚举值列表中的位置。它与表索引无关。
为什么要使用数据库
数据保存在内存
优点: 存取速度快
缺点: 数据不能永久保存
数据保存在文件
优点: 数据永久保存
缺点:1)速度比内存操作慢,频繁的IO操作。2)查询数据不方便
数据保存在数据库
1)数据永久保存
2)使用SQL语句,查询方便效率高。
3)管理数据方便
什么是SQL?
结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言。
作用:用于存取数据、查询、更新和管理关系数据库系统。
什么是MySQL?
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。
数据库三大范式是什么
https://developer.aliyun.com/article/248114
第一范式:每个列都不可以再拆分。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。
mysql有关权限的表都有哪几个
MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:
- user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
- db权限表:记录各个帐号在各个数据库上的操作权限。
- table_priv权限表:记录数据表级的操作权限。
- columns_priv权限表:记录数据列级的操作权限。
- host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。
MySQL的binlog有有几种录入格式?分别有什么区别?
有三种格式,statement,row和mixed。
- statement模式下,**每一条会修改数据的sql都会记录在binlog中。**不需要记录每一行的变化,减少了binlog日志量,**节约了IO,提高性能。**由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。
- row级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。
- mixed,一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。
此外,新版的MySQL中对row级别也做了一些优化,当表结构发生变化的时候,会记录语句而不是逐行记录。
数据类型
mysql有哪些数据类型
-
1、整数类型
,包括TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,分别表示1字节、2字节、3字节、4字节、8字节整数。任何整数类型都可以加上UNSIGNED属性,表示数据是无符号的,即非负整数。
长度
:整数类型可以被指定长度,例如:INT(11)表示长度为11的INT类型。长度在大多数场景是没有意义的,它不会限制值的合法范围,只会影响显示字符的个数,而且需要和UNSIGNED ZEROFILL属性配合使用才有意义。
例子
,假定类型设定为INT(5),属性为UNSIGNED ZEROFILL,如果用户插入的数据为12的话,那么数据库实际存储数据为00012。 -
2、实数类型
,包括FLOAT、DOUBLE、DECIMAL。
DECIMAL可以用于存储比BIGINT还大的整型,能存储精确的小数。
而FLOAT和DOUBLE是有取值范围的,并支持使用标准的浮点进行近似计算。
计算时FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你可以理解成是用字符串进行处理。 -
3、字符串类型
,包括VARCHAR、CHAR、TEXT、BLOB
VARCHAR用于存储可变长字符串,它比定长类型更节省空间。
VARCHAR使用额外1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,否则使用2字节表示。
VARCHAR存储的内容超出设置的长度时,内容会被截断。
CHAR是定长的,根据定义的字符串长度分配足够的空间。
CHAR会根据需要使用空格进行填充方便比较。
CHAR适合存储很短的字符串,或者所有值都接近同一个长度。
CHAR存储的内容超出设置的长度时,内容同样会被截断。使用策略:
对于经常变更的数据来说,CHAR比VARCHAR更好,因为CHAR不容易产生碎片。
对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。
使用时要注意只分配需要的空间,更长的列排序时会消耗更多内存。
尽量避免使用TEXT/BLOB类型,查询时会使用临时表,导致严重的性能开销。 -
4、枚举类型(ENUM)
,把不重复的数据存储为一个预定义的集合。
有时可以使用ENUM代替常用的字符串类型。
ENUM存储非常紧凑,会把列表值压缩到一个或两个字节。
ENUM在内部存储时,其实存的是整数。
尽量避免使用数字作为ENUM枚举的常量,因为容易混乱。
排序是按照内部存储的整数 -
5、日期和时间类型
,尽量使用timestamp,空间效率高于datetime,
用整数保存时间戳通常不方便处理。
如果需要存储微妙,可以使用bigint存储。
看到这里,这道真题是不是就比较容易回答了。
引擎
MySQL存储引擎MyISAM与InnoDB区别
存储引擎Storage engine:MySQL中的数据、索引以及其他对象是如何存储的,是一套文件系统的实现。
常用的存储引擎有以下:
- Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
- MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。
- MEMORY引擎:所有的数据都在内存中,数据的处理速度快,但是安全性不高。
MyISAM与InnoDB区别
Mysql 5.7 之后支持全文索引
MyISAM索引与InnoDB索引的区别?
- InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
- InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
- MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
- InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。
MYISAM 不支持主外键,不支持事务,而且是表锁,不适合高并发的操作,在缓存方面,只缓存索引,不缓存真实的数据,而InnoDB,支持事务,支持主外键,是行锁,适合高并发的操作,并且在缓存的时候不仅缓存索引还缓存真实数据,对内存要求较高
InnoDB引擎的4大特性
- 插入缓冲(insert buffer)
- 二次写(double write)
- 自适应哈希索引(ahi)
- 预读(read ahead)
存储引擎选择
如果没有特别的需求,使用默认的Innodb
即可。
MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。
Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键。比如OA自动化办公系统。
索引
什么是索引?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。
索引下推
- 索引下推(index condition pushdown )简称ICP,在Mysql5.6的版本上推出,用于优化查询。
- 在不使用ICP的情况下,在使用**非主键索引(又叫普通索引或者二级索引)**进行查询时,存储引擎通过索引检索到数据,然后返回给MySQL服务器,服务器然后判断数据是否符合条件 。
- 在使用ICP的情况下,如果存在某些被索引的列的判断条件时,MySQL服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合MySQL服务器传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器 。
- 索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少MySQL服务器从存储引擎接收数据的次数。
索引下推在非主键索引上的优化,可以有效减少回表的次数,大大提升了查询的效率。
索引有哪些优缺点?
索引的优点
- 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
- 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点
- 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
- 空间方面:索引需要占物理空间。
索引使用场景(重点)
上图中,根据id
查询记录,因为id
字段仅建立了主键索引,因此此SQL执行可选的索引只有主键索引,如果有多个,最终会选一个较优的作为检索的依据。
-- 增加一个没有建立索引的字段
alter table innodb1 add sex char(1);
-- 按sex检索时可选的索引为null
EXPLAIN SELECT * from innodb1 where sex='男';
可以尝试在一个字段未建立索引时,根据该字段查询的效率,然后对该字段建立索引(
alter table 表名 add index(字段名)
),同样的SQL执行的效率,你会发现查询效率会有明显的提升(数据量越大越明显)。
order by
当我们使用order by
将查询结果按照某个字段排序时,如果该字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序(将数据从硬盘分批读取到内存使用内部排序,最后合并排序结果),这个操作是很影响性能的,因为需要将查询涉及到的所有数据从磁盘中读到内存(如果单条数据过大或者数据量过多都会降低效率),更无论读到内存之后的排序了。
但是如果我们对该字段建立索引alter table 表名 add index(字段名)
,那么由于索引本身是有序的,因此直接按照索引的顺序和映射关系逐条取出数据即可。而且如果分页的,那么只用取出索引表某个范围内的索引对应的数据,而不用像上述那取出所有数据进行排序再返回某个范围内的数据。(从磁盘取数据是最影响性能的)
join
对
join
语句匹配关系(on
)涉及的字段建立索引能够提高效率
索引覆盖
如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询而不会访问原始数据(否则只要有一个字段没有建立索引就会做全表扫描),这叫索引覆盖。因此我们需要尽可能的在select
后只写必要的查询字段,以增加索引覆盖的几率。
只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。
这里值得注意的是不要想着为每个字段建立索引,因为优先使用索引的优势就在于其体积小。
索引有哪几种类型?
主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。
唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
- 可以通过
ALTER TABLE table_name ADD UNIQUE (column);
创建唯一索引 - 可以通过
ALTER TABLE table_name ADD UNIQUE (column1,column2);
创建唯一组合索引
普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。
- 可以通过
ALTER TABLE table_name ADD INDEX index_name (column);
创建普通索引 - 可以通过
ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);
创建组合索引
全文索引: 是目前搜索引擎使用的一种关键技术。
- 可以通过
ALTER TABLE table_name ADD FULLTEXT (column);
创建全文索引
索引的数据结构(b树,hash)
索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。
1)B树索引
mysql通过存储引擎取数据,基本上90%的人用的就是InnoDB了,按照实现方式分,InnoDB的索引类型目前只有两种:BTREE(B树)索引和HASH索引。B树索引是Mysql数据库中使用最频繁的索引类型,基本所有存储引擎都支持BTree索引。通常我们说的索引不出意外指的就是(B树)索引(实际是用B+树实现的,因为在查看表索引时,mysql一律打印BTREE,所以简称为B树索引)
查询方式:
主键索引区:PI(关联保存的时数据的地址)按主键查询,
普通索引区:si(关联的id的地址,然后再到达上面的地址)。所以按主键查询,速度最快
B+tree性质:
1.)n棵子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引。
2.)所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.)所有的非终端结点可以看成是索引部分,结点中仅含其子树中的最大(或最小)关键字。
4.)B+ 树中,数据对象的插入和删除仅在叶节点上进行。
5.)B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。
2)哈希索引
简要说下,类似于数据结构中简单实现的HASH表(散列表)一样,当我们在mysql中用哈希索引时,主要就是通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。当然这只是简略模拟图。
索引的基本原理
索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。
索引的原理很简单,就是把无序的数据变成有序的查询
- 把创建了索引的列的内容进行排序
- 对排序结果生成倒排表
- 在倒排表内容上拼上数据地址链
- 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据
索引算法有哪些?
索引算法有 BTree算法和Hash算法
BTree算法
BTree是最常用的mysql数据库索引算法,也是mysql默认的算法。因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量, 例如:
-- 只要它的查询条件是一个不以通配符开头的常量
select * from user where name like 'jack%';
-- 如果一通配符开头,或者没有使用常量,则不会使用索引,例如: </