大部分知识点来源于该博主——骆昊
知识点来源于网络,知道的可以在评论区贴上来源喔
《零散知识点总结1》
该文章涉及:Dubbo、HTTP和HTTPS、Mybatis、Hibernate、 Zookeeper、Kafka、Elasticsearch、Redis
《零散知识点总结2》
该文章涉及:MySQL、Java并发编程、Java IO 和 NIO、JUnit单元测试
《零散知识点总结3》
该文章涉及 :Java Web、spring、SpringMVC、springboot、springcloud、微服务
《零散知识点总结4》
该文章涉及:JVM和GC、Linux、Git、RabbitMQ
《零散知识点总结5》
该文章涉及:多线程、反射、对象拷贝、异常、容器
什么是MySQL?
MySQL是一个开源的关系型数据管理系统,用于存取数据、查询、更新和管理数据。
对MySQL数据库去重的关键字是什么?
select distinct 字段名 from 表名
数据库自带的distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重复记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段。
新增表:
Create table 表名{
字段 类型 限制(主键/是否自增/是否允许为空) //主键:PRIMARY KEY ; 自增:AUTO_INCREMENT ;不允许为空:NOT NULL
}
MySQL的约束有哪些?
NOT NULL: 约束字段的内容一定不能为NULL。
UNIQUE: 约束字段唯一性,一个表允许有多个Unique约束。
PRIMARY KEY(主键): 约束字段唯一,不可重复,一个表只允许存在一个。
FOREIGN KEY(外键): 用于预防破坏表之间连接的动作,也能防止非法数据插入外键。
CHECK: 用于控制字段的值范围。
删除表:
delete from 表名 where 字段名=字段值
每次删除一行,可回滚数据 rollbacktruncate table 表名
清空表中数据,保留表的数据结构(删表数据不可以回滚)drop table 表名
删除表数据跟表结构,不可回滚新增数据:insert into 表名 列名1,2,... values(1,2,...)
删除数据:delete from 表名 where 过滤条件
查询数据:select 字段名 from 表名 where 字段名=字段值 order by 字段值 asc(升序)/desc(降序)
select 字段名 from 表名 where 字段名=字段值 order by 字段值 asc(升序)/desc(降序)
select * from 表/表达式 where 过滤条件/group by 分组内容/having 组内条件/order by 字段 排序方式(asc/desc)
1. Having 和where 的区别:having是在分组后对数据进行过滤
where是在分组前对数据进行过滤
having后面可以使用聚合函数
where后面不可以使用聚合
在查询过程中执行顺序:from>where>group(含聚合)>having>order>select。
2. 聚合语句:sum、min、max、avg、count
having的作用和where的作用类似,但是where不能和聚合函数(max,min,sum,avg等)一起使用,因此需要having。
Eg:select * from table having max(column_name);
注意:where …… group by …… having ……
模糊查询:select 字段 from 表名 where条件 like ‘模糊查询内容’
查询内容例如:姓苏的 like ‘苏%’;姓苏且长度为3 的 like ‘苏__’ 这_代表占用一个字位置
字段名 like '%字段值%'
字段名 like '%李_%' 表示查询以李字开头的
字段名 like '%_李%' 表示查询以李字结尾的
字段名 like '[张李王]三' 表示将会查询出张三、李三、王三
修改数据:update 表名 set 字段名=新值 where id=5
MySQL多表连接有哪些方式?怎么用的?这些连接都有什么区别?
连接方式:左连接、右连接、内连接
使用方法:
左连接:select * from A left join B on A.id=B.id;
右连接:select * from A right join B on A.id=B.id;
内连接:select * from A inner join B on a.xx=b.xx;
(其中inner可以省略)
写作 :select * from A join B on a.xx=b.xx;
区别:
Inner join 内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集
left join 在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。
right join 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。
如何显示前 50 行?
在 MySQL 中,使用以下代码查询显示前 50 行:select * from 表名 where limit 0,50
SQL 语言包括哪几部分?每部分都有哪些操作关键字?
SQL 语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。
Create Table,Alter Table,Drop Table, Craete/Drop Index
等Select ,insert,update,delete,
grant(授予),revoke(撤销)
select
列对比运算符是什么?
在 SELECT 语句的列比较中使用=,<>,<=,<,> =,>,<<,>>,<=>,AND,OR 或 LIKE
运算符。
可以从这几个维度回答这个问题:加索引、避免返回不必要的数据、适当分批量进行、优化sql结构、分库分表、读写分离
is null
和is not null
如何通俗地理解三个范式?
范式化设计优缺点:
优点:可以尽量得减少数据冗余,使得更新快,体积小
缺点: 对于查询需要多个表进行关联,减少写的效率增加读的效率,更难进行索引优化
反范式化:
优点:可以减少表得关联,可以更好得进行索引优化
缺点:数据冗余以及数据异常,数据的修改需要更多的成本
MySQL数据库和Redis的区别?
MySQL和Redis都可以存放数据,但MySQL里的数据是永久的,而Redis里的数据是缓存并有缓存机制,新的数据过来,老的数据会根据缓存机制失效。但是从Redis中读取数据比较快方便,而MySQL里的逻辑复杂,数据量大,读取数据耗时长。
UNION和UNION ALL的区别?
锁
什么是锁?
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
MySQL 中的锁
基本锁类型:锁包括行级锁和表级锁
锁的优化策略
不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。
说一下 MySQL 的行锁和表锁?
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
说一下乐观锁和悲观锁?
乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。
什么是死锁?怎么解决?
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。
有四个必要条件:互斥条件,请求和保持条件,环路等待条件,不剥夺条件。
MySQL 中有哪些不同的表格?
共有 5 种类型的表格: MyISAM、Heap、Merge、INNODB、ISAM
说一下 MySQL 常用的引擎?(InnoDB 、MyIASM )
引擎 | 特点 |
---|---|
MyIASM 引擎 | 不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选 |
InnoDB 引擎 | mysql 5.1 后默认的数据库引擎,提供了对数据库 ACID事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。 |
MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?
SQL 标准中定义了 4 种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些是在事务内和事务间可见的,哪些是不可见的。
较低级别的隔离通常可以执行更高的并发,系统的开销也更低。
SQL 标准定义的四个隔离级别为:
Read Uncommitted ( 未提交读 ) 、
Read Committed (提交读)、
Repeatable Read (可重复读)、
Serializable (可串行化) ,
不同的隔离级别有不同的现象,并有不同的锁 和 并发机制,隔离级别越高,数据库的并发性 能 就越差, 4 种事 隔离级别与并发性能的关系:
一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 id 是几?
InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。
如何获取当前数据库版本?
使用 select version()
获取当前 MySQL 数据库版本。
char 和 varchar 的区别?
主键和候选键有什么区别?
表格的每一行都由主键唯一标识,一个表只有一个主键。
主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键引用
如果一个表有一列定义为 TIMESTAMP,将发生什么?
每当行被更改时,时间戳字段将获取当前时间戳。
列设置为 AUTO INCREMENT 时,如果在表中达到最大值,会发生什么情况?
它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。
怎样才能找出最后一次插入时分配了哪个自动增量?
LAST_INSERT_ID 将返回由 Auto_increment 分配的最后一个值,并且不需要指定表名称
怎么看到为表格定义的所有索引?
索引是通过以下方式为表格定义的:SHOW INDEX FROM
LIKE 声明中的
%
和_
是什么意思?
%
对应于 0 个或更多字符,_
只是 LIKE 语句中的一个字符。
如何在 Unix 和 MySQL 时间戳之间进行转换?
UNIX_TIMESTAMP 是从 MySQL 时间戳转换为 Unix 时间戳的命令
FROM_UNIXTIME 是从 Unix 时间戳转换为 MySQL 时间戳的命令
BLOB 和 TEXT 有什么区别?
BLOB 是一个二进制对象,可以容纳可变数量的数据。TEXT 是一个不区分大小写的 BLOB。
BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小写,对 TEXT 值不区分大小写。
MySQL 如何优化 DISTINCT?
distinct 在所有列上转换为group by,并与 order by子句结合使用。
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
NOW()和 CURRENT_DATE()有什么区别?
什么是非标准字符串类型?
什么是通用 SQL 函数?
MySQL 事务
数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。
事务特性(ACID):
Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
或者这样理解:
事务就是被绑定在一起作为一个逻辑工作单元的 SQL 语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过 ACID 测试,即原子性,一致性,隔离性和持久性。
MySQL 支持事务吗?
在缺省模式下,MySQL 是 autocommit
模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,MySQL 是不支持事务的。
但是如果你的 MySQL 表类型是使用 InnoDB Tables
或 BDB tables
的话,你的MySQL 就可以使用事务处理,使用 SETAUTOCOMMIT=0
就可以使 MySQL 允许在非 autocommit
模式
在非autocommit
模式下,你必须使用 COMMIT
来提交你的更改,或者用 ROLLBACK
来回滚你的更改。
Myql 中的事务回滚机制概述
事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元)
事务回滚:在同一个事务中,但凡有一个异常了,就所有的操作都回滚到未修改的状态(包括该事务中已经完成的部分都回到未修改状态)
MySQL 里记录货币用什么字段类型好?
NUMERIC (数值型)和 DECIMAL(小数,十进制数) 类型被 MySQL 实现为同样的类型,这在 SQL92 标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定。
例如:salary DECIMAL(9,2)
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代表将被用于存储小数点后的位数。
因此,在这种情况下,能被存储在 salary 列中的值的范围是从-9999999.99 到9999999.99。
【MYSQL】金额(金钱)相关的数据存储类型
int
对于游戏币等代币,一般存储为int类型是可行的。
问题在于越界,int类型长度为11位。
在存储人民币相关的金额的时候,则只能存储到9长度的人民币,也就是说,最大只能存储999999999,不到10亿的数值,如果业务增长很快的话,就会给自己留下隐患。
Decimal(十进制数)
Decimal为专门为财务相关问题设计的数据类型。
DECIMAL从MySQL 5.1引入,列的声明语法是DECIMAL(M,D)。在MySQL 5.1中,参量的取值范围如下:
说明:float占4个字节,double占8个字节,decimail(M,D)占M+2个字节。
如DECIMAL(5,2) 的最大值为9 9 9 9 . 9 9,因为有7 个字节可用。
能够解决数据的范围和精度的问题。
总结:这两种方式都是可行的解决方案,我们可以根据具体情况使用合适的方案。
sqlyog是工具还是数据库?
MySQL,oracle是数据库,SQLyog是连接MySQL的可视化客户端软件(数据库管理工具,数据库软件)。SQLyog 可以快速直观地让用户完成对数据库的操作
MySQL和Oracle 区别?
区别:
Oracle数据库收费的 MySQL开源的免费
Oracle是大型数据库 Mysql是中小型数据库,
类型的区别
mysql:
oracle:
sql查询语句的区别
oracle sql语句和mysql sql语句有一定的区别:
一、Oracle语法:
oracle 左连接、右连接可以使用(+)
来实现【这个(+)
可以这样理解:(+)
表示补充,哪个表有(+)
那它就是匹配表】
关于使用(+)的一些注意事项:
1.1.(+)
操作符只能出现在WHERE
子句中,并且不能与OUTER JOIN
语法同时使用。
1.2. 当使用(+)
操作符执行外连接时,如果在WHERE子句中包含有多个条件,则必须在所有条件中都包含(+)
操作符。
1.3.(+)
操作符只适用于列,而不能用在表达式上。
1.4.(+)
操作符不能与OR和IN操作符一起使用。
1.5.(+)
操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。
左连接(left outer join
/ left join
)
left join(左连接):左表为主表,右表为匹配表
查询语句:select * from A表 a left join B表 b on a.id=b.id;
或:select * from A表 a left outer join B表 b on a.id=b.id;
用(+)来实现:select * from A表 a ,B表 b where a.id=b.id(+);
右外连接(right outer join
/ right join
)
right join(右连接):右表为主表,左表为匹配表
查询语句:select * from A表 a right join B表 b on a.id=b.id;
或:select * from A表 a right outer join B表 b on a.id=b.id;
用(+)来实现:select * from A表 a ,B表 b where a.id(+)=b.id;
全外连接(full outer join
/ full join
)
全外连接又可以称全连接,左表和右表都不做限制,所有的记录都显示,两表不足的地方均为NULL
,全外连接不支持(+)
写法
查询语句:select * from A表 a full join B表 b on a.id=b.id;
或:select * from A表 a full outer join B表 b on a.id=b.id;
补充: select * from A表 a, B表 b where a.id=b.id;
或 select * from A表 a join B表 b on a.id=b.id;
二、Mysql只能使用left join 、right join
等关键字.
空字符串问题
Oracle中空字符串''
就是null
(也就是说,只有null,没有空字符),而MySQL是区分null
和''
的。
NULL 是什么意思
NULL 这个值表示 UNKNOWN
(未知):它不表示""
(空字符串)。对 NULL 这个值的任何比较都会生产一个 NULL 值。您不能把任何值与一个 NULL 值进行比较,并在逻辑上希望获得一个答案。使用 IS NULL 来进行 NULL 判断
左连接:left join 左表主表,右表是匹配表,左表存在数据右表不存在时显示的是左表字段有数据右表null
右连接:right join
内连接:inner join 显示左右表共有的数据
全连接:union
注意:使用union进行拼接查询的时候,表中字段要一致的数才可以进行查询,要不容易出错
union会自动将完全重复的数据去除掉;union all会保留那些重复的数据
MySQL 服务器通过权限表来控制用户对数据库的访问,权限表存放在 MySQL 数据库里,由 MySQL_install_db
脚本初始化。这些权限表分别 user,db,table_priv,columns_priv 和 host。
列的字符串类型可以是什么?
字符串类型是:SET、BLOB、ENUM、CHAR、TEXT
MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
SELECT * FROM TABEL 改为 SELECT field_1,field_2, field_3 FROM TABLE
什么是数据库索引?
数据库索引是数据库系统中一个重要的概念,索引也叫做 key ,是一种用于提升数据库查询效率的数据结构。索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。我们可以把索引理解成一本书的目录,通过目录我们可以快速找到对应章节的内容,同样的,通过数据库索引,我们可以快速找到数据表中对应的记录。
具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。
总而言之,索引就像给数据表建了一个目录一样。
索引的设计原则
为什么在使用索引?
ORDER BY
和 GROUP BY
等操作时,可以很快得到结果。数据库索引的优点和缺点
优点:
建立索引能够加快表与表之间的连接
创建唯一性索引,保证数据库表中每一行数据的唯一性
为用来排序或者分组的字段添加索引能够加快分组和排序顺序
能够有效的加快数据的检索速度,缩短数据的检索时间
查询的过程中使用优化隐藏器,提高系统的性能
缺点:
会导致表的增删改的效率降低(因为索引也要动态的维护)
创建索引和维护索引需要时间成本
创建索引和维护索引需要空间成本越大 (索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间)
MySQL索引在哪个模块中实现的?
MySQL 的索引是在存储引擎这一层实现的,因此每一种存储引擎都有不同的实现方式,对同一种索引的处理方式也完成不同。
为什么设置了索引却不起作用?(索引失效的情况)
%
开头的 LIKE
语句,模糊匹配SELECT * FROM users WHERE name LIKE '%小张%';
SELECT * FROM users WHERE name LIKE '%小张';
不过以 % 为结尾则可以使用索引,如:
SELECT * FROM users WHERE name LIKE '张%';
OR
语句前后没有同时使用索引SELECT * FROM users id = 10 or name='test'
varchar
不加单引号的话可能会自动转换为 int 型)MySQL索引底层使用什么数据结构?
在 MySQL 中,大部分情况下,索引都是使用 B-Tree 作为底层数据结构, B-Tree 只是一种泛称,实际上不同的存储引擎使用 B-Tree 时,有不同的变种,比如 InnoDB 使用的是 B+Tree 。
另外也有一些特殊的索引结构,比如哈希索引,哈希索引底层则使用的是哈希表,在 MySQL中,只有 Memory 存储引擎支持哈希索引。
什么情况下不要使用索引
既然索引是有代价的,那么就不要在不应该使用索引的情况下去使用它。
数据唯一性差的字段不要使用索引
比如性别,只有两种可能数据。意味着索引的二叉树级别少,多是平级。这样的二叉树查找无异于全表扫描。
频繁更新的字段不要使用索引
比如logincount登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率。
字段不在where语句出现时不要添加索引
只有在where语句出现,mysql才会去使用索引
数据量少的表不要使用索引
使用了改善也不大
另外,如果mysql估计使用全表扫描要比使用索引快,则不会使用索引。
什么是回表?
回表是对Innodb存储引擎而言的,在 InnoDB 存储引擎中,主键索引的叶子节点存储的记录的数据,而普通索引的叶子节点存储的主键索引的地点。
当我们通过主键查询时,只需要搜索主键索引的搜索树,直接可以得到记录的数据。
当我们通过普通索引进行查询时,通过搜索普通索引的搜索树得到主键的地址之后,还要再使用该主键对主键搜索树进行搜索,这个过程称为回表。
聚簇索引与非聚簇索引的区别?
聚簇索引:聚簇索引的顺序就是数据的物理存储顺序,并且索引与数据放在一块,通过索引可以直接获取数据,一个数据表中仅有一个聚簇索引。
非聚簇索引:索引顺序与数据物理排列顺序无关,索引文件与数据是分开存放。
MySQL主键索引、唯一索引与普通索引的区别?
设置为主键索引的字段不允许为 NULL ,而且一张数据表只能有一个主键索引。
设置为唯一索引的字段,其字段值不允许重要。
普通索引可以包含重复的值,也可以为 NULL
索引可以提高查询性能,那是不是索引创建越多越好?
索引作为一个数据表的目录,本身的存储就需要消耗很多的磁盘和内存存储空间。
并助在写入数据表数据时,每次都需要更新索引,所以索引越多,写入就越慢。
尤其是糟糕的索引,建得越多对数据库的性能影响越大。
MyISAM与InnoDB在处理索引上有什么不同?
MyISAM 存储引擎是非聚族索引,索引与数据是分开存储的,索引文件中记录了数据的指针
而 InnoDB 存储引擎是聚族索引,即索引跟数据是放在一块的, InnoDB 一般将主键与数据放在一块,如果没有主键,则将 unique key 作为主键,如果没有 unique key ,则自动创建一个 rowid 作为主键,其他二级索引叶子指针存储的是主键的位置。
什么是索引的最左前缀原则?
MySQL 数据库不单可以为单个数据列创建索引,也可以为多个数据列创建一个联合索引,比如:
CREATE TABLE test(
a INT NOT NOT,
b INT NOT NOT,
KEY(a,b)
);
当我们使用下面的查询语句时,由于 WHERE 语句中查询的条件就是联合索引,所以可以很快查询到数据。
SELECT * FROM test WHERE a=1 AND b=1;
同样,下面的语句也会利用上面创建的联合索引,这是因为 MySQL 会按照索引创建的顺序进行排序,然后根据查询条件从索引最左边开始检测查询条件是否满足该索引,由于字段 a 在最左边,所以满足索引。
SELECT * FROM test WHERE a=1;
而使用 字段b 进行查询时,则为满足,因为从最左边匹配到的是 字段a ,所以 MySQL 判断为不满足索引条件。
SELECT * FROM test WHERE b=1;
什么是覆盖索引?
如果一个索引中包含查询所要的字段时,此时不需要再回表查询,我们就称该索引为覆盖索引。
比如下面的查询中,字段id是主键索引,所以可以直接返回索引的值,显著提升了查询的性能。
SELECT id FROM users WHERE id BETWEEN 10 AND 20;
可以使用多少列创建索引?
任何标准表最多可以创建 16 个索引列。
索引的底层实现原理和优化
B+树,经过优化的 B+树
主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此 InnoDB 建议为大部分表使用默认自增的主键作为主索引。
怎么验证 MySQL 的索引是否满足需求?
使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。
explain 语法:explain select * from table where type=1
。
栈中如何优化 MySQL?
最好是按照以下顺序优化:
MySQL 慢查询优化、索引优化、以及表等优化总结
优化数据库的方法
NOTNULL
,例如’省份’、’性别’最好适用 ENUM
主键、外键和索引的区别?
主键 | 外键 | 索引 | |
---|---|---|---|
定义 | 唯一标识一条记录,不能有重复的,不允许为空 | 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 | 该字段没有重复值,但可以有一个空值 |
作用 | 用来保证数据完整性 | 用来和其他表建立联系用的 | 是提高查询排序的速度 |
个数 | 主键只能有一个 | 一个表可以有多个外键 | 一个表可以有多个唯一索引 |
简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)
索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。
普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE
把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY
来创建。
索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)
索引,这就是联合索引。
索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。
SQL 注入漏洞产生的原因?如何防止?
SQL 注入产生的原因:程序开发过程中不注意规范书写 sql 语句和对特殊字符进行过滤,导致客户端可以通过全局变量 POST 和 GET 提交一些 sql 语句正常执行。
防止 SQL 注入的方式:
magic_quotes_gpc 和 magic_quotes_runtime
addslashes
进行 sql 语句转换Sql 语句书写update、insert、delete、select、 *
。为表中得字段选择合适得数据类型
字段类型优先级:
整形int>date,
time>enum,
char>varchar>blob,
text 优先考虑数字类型,其次是日期或者二进制类型,最后是字符串类型,同级别的数据类型,应该优先选择占用空间小的数据类型
存储时期
datatime
:以 yyyy-MM-dd HH:mm:ss
格式存储时期时间,精确到秒,占用 8 个字节得存储空间,datatime 类型与时区无关
关于yyyy-MM-dd HH:mm:ss (年-月-日 时:分:秒) 的大小写说明:
MM与mm 大写是为了区分“ 月 ”与“ 分 ”
HH 是为了区分 12小时制 与 24小时制 。小写的h是12小时制,大写的H是24小时制。
Timestamp:以时间戳格式存储,占用 4 个字节,范围小 1970-1-1 到 2038-1-19,显示依赖于所指定得时区,默认在第一个列行的数据修改时可以自动得修改timestamp
列得值
Date:(生日)占用得字节数比使用字符串.datatime.int 储存要少,使用 date 只需要 3 个字节,存储日期月份,还可以利用日期时间函数进行日期间得计算
Time:存储时间部分得数据
注意:不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,在进行查找过滤可以利用日期得函数)使用 int 存储日期时间不如使用 timestamp 类型
对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:
1、索引的目的是什么?
2、索引对数据库系统的负面影响是什么?
负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
3、为数据表建立索引的原则有哪些?
在最频繁使用的、用以缩小查询范围的字段上建立索引。
在频繁使用的、需要排序的字段上建立索引
4、什么情况下不宜建立索引?
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等
说一下数据库的事务隔离?
MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:
transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE
。
READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)。
READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。
REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。
SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据。
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
MySQL 问题排查都有哪些手段?
使用 show processlist
命令查看当前所有连接信息。
使用 explain
命令查询 SQL 语句执行计划。
开启慢查询日志,查看慢查询的 SQL。
如何做 MySQL 的性能优化?
为搜索字段创建索引。
避免使用 select *
,列出需要查询的字段。
垂直分割分表。
选择正确的存储引擎。
MySQL和Redis都可以存放数据,但MySQL里的数据是永久的,而Redis里的数据是缓存并有缓存机制,新的数据过来,老的数据会根据缓存机制失效。
但是从Redis中读取数据比较快方便,而MySQL里的逻辑复杂,数据量大,读取数据耗时长。
什么是视图?为什么要使用视图?
视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成。为了提高复杂SQL语句的复用性和表操作的安全性,MySQL数据库管理系统提供了视图特性。
视图有哪些特点?使用场景有哪些?
视图特点:
1、视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。
2、视图是由基本表(实表)产生的表(虚表)。
3、视图的建立和删除不影响基本表。
4、对视图内容的更新(添加,删除和修改)直接影响基本表。
5、当视图来自多个基本表时,不允许添加和删除数据。
视图用途:简化sql查询,提高开发效率,兼容老的表结构。
视图的常见使用场景:
1、重用SQL语句;
2、简化复杂的SQL操作。
3、使用表的组成部分而不是整个表;
4、保护数据
5、更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
讲一下视图的优缺点?
创建视图
创建视图是指在已经存在的 MySQL 数据库表上建立视图。视图可以建立在一张表中,也可以建立在多张表中。
基本语法:可以使用 CREATE VIEW 语句来创建视图。CREATE VIEW <视图名> AS
语法说明如下:
对于创建视图中的 SELECT 语句的指定存在以下限制:
视图定义中引用的表或视图必须存在。但是,创建完视图后,可以删除定义引用的表或视图。可使用check table 语句检查视图定义是否存在这类问题。
视图定义中允许使用 order by语句,但是若从特定视图进行选择,而该视图使用了自己的order by 语句,则视图定义中的 order by将被忽略。
视图定义中不能引用 temporary表(临时表),不能创建 temporary 视图。
with check option的意思是,修改视图时,检查插入的数据是否符合 where 设置的条件。
原文链接《创建视图(CREATE VIEW)》
,show processlist
,查看session情况,确定是不是有消耗资源的sql在运行。了解什么是表分区吗?表分区的好处有哪些?
表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
存储更多数据。分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。和单个磁盘或者文件系统相比,可以存储更多数据。
优化查询。在where语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及sum和count语句时,也可以在多个分区上并行处理,最后汇总结果。
分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。
避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问。
完整性约束包括哪些?
数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。
分为以下四类:
与表有关的约束:包括列约束(NOT NULL
(非空约束))和表约束(PRIMARY KEY、foreign key、check、UNIQUE
) 。
什么叫视图?游标是什么?
视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。
游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
什么是存储过程?用什么来调用?
存储过程是一个预编译的 SQL 语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次 SQL,使用存储过程比单纯 SQL 语句执行要快。可以用一个命令对象来调用存储过程。
什么是基本表?什么是视图?
基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从
一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表
试述视图的优点?
(1) 视图能够简化用户的操作
(2) 视图使用户能以多种角度看待同一数据;
(3) 视图为数据库提供了一定程度的逻辑独立性;
(4) 视图能够对机密数据提供安全保护
你可以用什么来确保表格里的字段只接受特定范围里的值?
Check 限制,它在数据库表格里被定义,用来限制输入该列的值。
触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。
在 java 中守护线程和本地线程区别?
java 中的线程分为两种:守护线程(Daemon)和用户线程(User)。
任何线程都可以设置为守护线程和用户线程,通过方法 Thread.setDaemon(boolon);true 则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon() 必须在 Thread.start()之前调用,否则运行时会抛出异常。
两者的区别:
唯一的区别是判断虚拟机(JVM)何时离开,Daemon 是为其他线程提供服务,如果全部的 User Thread 已经撤离,Daemon 没有可服务的线程,JVM 撤离。也可以理解为守护线程是 JVM 自动创建的线程(但不一定),用户线程是程序创建的线程;比如 JVM 的垃圾回收线程是一个守护线程,当所有线程已经撤离,不再产生垃圾,守护线程自然就没事可干了,当垃圾回收线程是 Java 虚拟机上仅剩的线程时,Java 虚拟机会自动离开。
(守护线程为本地线程服务,当所有的本地线程撤离后,JVM离开,此时剩下的线程就是守护线程)
扩展:Thread Dump 打印出来的线程信息,含有 daemon 字样的线程即为守护进程,可能会有:服务守护进程、编译守护进程、windows 下的监听 Ctrl+break的守护进程、Finalizer 守