MySQL
-
什么是事务,MySQL是如何支持事务的?
事务就是一段sql 语句的批处理,但是这个批处理是一个原子 ,不可分割,要么都执行,要么回滚(rollback)都不执行。
事务具体四大特性,也就是经常说的ACID :
1.原子性(所有操作要么全部成功,要么全部失败回滚)
2.一致性(事务执行之前和执行之后都必须处于一致性状态。)
3.隔离性(数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离)
4.持久性(一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,
即使遭遇故障依然能够通过日志恢复最后一次更新在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现 BEGIN 开始一个事务 ROLLBACK 事务回滚 COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式: SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1 开启自动提交
-
数据库索引种类?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度
MySQL索引的类型:
- 普通索引:这是最基本的索引,它没有任何限制
2.唯一索引:索引列的值必须唯一,但允许有空值,如果是组合索引,则列值的组合必须唯一
3.全文索引:全文索引仅可用于 MyISAM 表,可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加(切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法)
- 单列索引、多列索引:多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。
5.组合索引(最左前缀):简单的理解就是只从最左面的开始组合(实在单列索引的基础上进一步压榨索引效率的一种方式)
- 普通索引:这是最基本的索引,它没有任何限制
-
你用的Mysql是哪个引擎,各引擎之间有什么区别?
主要 MyISAM 与 InnoDB 两个引擎,其主要区别如下:
InnoDB 支持事务,MyISAM 不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而 MyISAM就不可以了;
MyISAM 适合查询以及插入为主的应用,InnoDB 适合频繁修改以及涉及到安全性较高的应用;
InnoDB 支持外键,MyISAM 不支持;
MyISAM 是默认引擎,InnoDB 需要指定;
InnoDB 不支持 FULLTEXT 类型的索引;
InnoDB 中不保存表的行数,如 select count() from table 时,InnoDB;需要扫描一遍整个表来计算有多少行,但是 MyISAM 只要简单的读出保存好的行数即可。注意的是,当 count()语句包含 where 条件时 MyISAM 也需要扫描整个表;
对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在 MyISAM表中可以和其他字段一起建立联合索引;清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM 则会重建表;
InnoDB 支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%‘
-
Sql注入是如何产生的,如何防止?
程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量
POST和GET提交一些sql语句正常执行。产生Sql注入。下面是防止办法:
a. 过滤掉一些常见的数据库操作关键字,或者通过系统函数来进行过滤。
b. 在PHP配置文件中将Register_globals=off;设置为关闭状态
c. SQL语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号
d. 提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的
e. 对于常用的方法加以封装,避免直接暴漏SQL语句
f. 开启PHP安全模式:Safe_mode=on;
g. 打开magic_quotes_gpc来防止SQL注入
h. 控制错误信息:关闭错误提示信息,将错误信息写到系统日志。
i. 使用mysqli或pdo预处理。
-
数据库三大范式?
什么是范式:简言之就是,数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系。所以建立科学的,规范的的数据库是需要满足一些 规范的来优化数据数据存储方式。在关系型数据库中这些规范就可以称为范式。
什么是三大范式:
第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。
第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。
第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF.
注:关系实质上是一张二维表,其中每一行是一个元组,每一列是一个属性
-
mysql 下面那些查询不会使用索引
between, like "c%" , not in, not exists, !=, <, <=, =, >, >=,in
-
mysql 中 varchar 与 char 的区别以及 varchar(50)中的 50 代表的含义
varchar与char的区别char是一种固定长度的类型,varchar则是一种可变长度的类型 尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。 varchar(50)代表的含义: varchar(50)中50的涵义最多存放50个字符,varchar(50)和(200)存储hello所占空间一样,但后者在排序时会消耗更多内存, 因为order by col采用fixed_length计算col长度(memory引擎也一样)
-
叙述mysql半同步复制原理
mysql的主备库通过binlog日志保持一致,主库本地执行完事务,binlog日志落盘后即返回给用户;备库通过拉取主库binlog日志来同步主库的操作。默认情况下,主库与备库并没有严格的同步,因此存在一定的概率备库与主库的数据是不对等的。半同步特性的出现,就是为了保证在任何时刻主备数据一致的问题。相对于异步复制,半同步复制要求执行的每一个事务,都要求至少有一个备库成功接收后,才返回给用户。实现原理也很简单,主库本地执行完毕后,等待备库的响应消息(包含最新备库接收到的binlog(file,pos)),接收到备库响应消息后,再返回给用户,这样一个事务才算真正完成。在主库实例上,有一个专门的线程(ack_receiver)接收备库的响应消息,并以通知机制告知主库备库已经接收的日志,可以继续执行。
-
请简述sql注入的攻击原理及如何在代码层面防止sql注入?
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。[1] 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击. 根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面: ①不当的类型处理; ②不安全的数据库配置; ③不合理的查询集处理; ④不当的错误处理; ⑤转义字符处理不合适; ⑥多个提交处理不当。 预防措施: 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。 2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。 3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。 4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。 5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装 6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等
-
简述leftjoin和rightjoin的区别?
left join:外链接之左连接:优先显示左表全部记录 #以左表为准,即找出所有员工信息,当然包括没有部门的员工 #本质就是:在内连接的基础上增加左边有右边没有的结果 right join:外链接之右连接:优先显示右表全部记录 #以右表为准,即找出所有部门信息,包括没有员工的部门 #本质就是:在内连接的基础上增加右边有左边没有的结果
-
什么是MySQL慢日志?
慢日志查询的主要功能就是,记录sql语句中超过设定的时间阈值的查询语句。例如,一条查询sql语句,我们设置的阈值为1s,当这条查询语句的执行时间超过了1s,则将被写入到慢查询配置的日志中. 慢查询主要是为了我们做sql语句的优化功能. 配置项说明: 登陆mysql服务: > show variables like ‘%query%‘; 关注三个配置项即可。 1.slow_query_log 该配置项是决定是否开启慢日志查询功能,配置的值有ON或者OFF. 2.slow_query_log_file 该配置项是慢日志查询的记录文件,需要手动创建. 3.long_query_time 该配置项是设置慢日志查询的时间阈值,当超过这个阈值时,慢日志才会被记录.配置的值有0(任何的sql语句都记录下来),或者>0(具体的阈值).该配置项是以秒为单位的,并且可以设置为小数. 4.log-queries-not-using-indexes 该配置项是为了记录未使用到索引的sql语句.
-
mysql 中怎么创建索引?
建表时创建 CREATE TABLE 表名( 字段名 数据类型 [完整性约束条件], ……, [UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY [索引名](字段名1 [(长度)] [ASC | DESC]) [USING 索引方法] ); 说明: UNIQUE:可选。表示索引为唯一性索引。 FULLTEXT:可选。表示索引为全文索引。 SPATIAL:可选。表示索引为空间索引。 INDEX和KEY:用于指定字段为索引,两者选择其中之一就可以了,作用是 一样的。 索引名:可选。给创建的索引取一个新名称。 字段名1:指定索引对应的字段的名称,该字段必须是前面定义好的字段。 长度:可选。指索引的长度,必须是字符串类型才可以使用。 ASC:可选。表示升序排列。 DESC:可选。表示降序排列。 注:索引方法默认使用BTREE。
-
数据库的脏读、不可重复读、幻读
- 脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"。
- 不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。
- 幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”
事务的隔离级别
数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上 “串行化”进行,这显然与“并发”是矛盾的。同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。
事务的四种隔离级别
读数据一致性及允许的并发副作用隔离级别 读数据一致性 脏读 不可重复读 幻读 未提交读(Read uncommitted) 最低级别,只能保证不读取物理上损坏的数据 是 是 是 已提交度(Read committed) 语句级 否 是 是 可重复读(Repeatable read) 事务级 否 否 是 可序列化(Serializable) 最高级别,事务级 否 否 否 -
开启慢日志
1 执行 SHOW VARIABLES LIKE “%slow%”,获知 mysql 是否开启慢查询 slow_query_log 慢查询开启状态 OFF 未开启 ON 为开启 slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
2 修改配置文件( 放在[mysqld]下),重启 long_query_time 查询超过多少秒才记录
3 测试是否成功
4 慢查询日志文件的信息格式
SQL语句优化
- 对语句的优化
①用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;
通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;
②能够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;算法的结构尽量简单;
③在查询时,不要过多地使用通配符如 SELECT * FROM T1 语句,要用到几列就选择几列如:
SELECT COL1,COL2 FROM T1;
④在可能的情况下尽量限制尽量结果集行数如:SELECT TOP 300 COL1,COL2,COL3 FROM T1,因为某些情况下用户是不需要那么多的数据的。
⑤不要在应用中使用数据库游标,游标是非常有用的工具,但比使用常规的、面向集的SQL语句需要更大的开销;按照特定顺序提取数据的查找。
- 避免使用不兼容的数据类型
例如float和int、char和varchar、binary 和varbinary是不兼容的。
数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。
例如:
SELECT name FROM employee WHERE salary > 60000
在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000 是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。 若在查询时强制转换,查询速度会明显减慢。
- 避免在WHERE子句中对字段进行函数或表达式操作。
若进行函数或表达式操作,将导致引擎放弃使用索引而进行全表扫描。
- 避免使用!=或<>、IS NULL或IS NOT NULL、IN ,NOT IN等这样的操作符
- 尽量使用数字型字段
- 合理使用EXISTS,NOT EXISTS子句。
- 尽量避免在索引过的字符数据中,使用非打头字母搜索。
- 分利用连接条件
- 消除对大型表行数据的顺序存取
- 避免困难的正规表达式
- 使用视图加速查询
- 能够用BETWEEN的就不要用IN
- DISTINCT的就不用GROUP BY
- 部分利用索引
- 能用UNION ALL就不要用UNION
- 不要写一些不做任何事的查询
- 尽量不要用SELECT INTO语句
- 必要时强制查询优化器使用某个索引
- 虽然UPDATE、DELETE语句的写法基本固定,但是还是对UPDATE语句给点建议:
a) 尽量不要修改主键字段。
b) 当修改VARCHAR型字段时,尽量使用相同长度内容的值代替。
c) 尽量最小化对于含有UPDATE触发器的表的UPDATE操作。
d) 避免UPDATE将要复制到其他数据库的列。
e) 避免UPDATE建有很多索引的列。
f) 避免UPDATE在WHERE子句条件中的列。
- 对语句的优化
原文地址:https://www.cnblogs.com/ghylpb/p/12684411.html