MySQL
索引
索引的创建:
建表时创建:
CREATE TABLE 表名(
字段名 数据类型 [完整性约束条件],
……,
[UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY
[索引名](字段名1 [(长度)] [ASC | DESC]) [USING 索引方法]
);
说明:
- UNIQUE:可选。表示索引为唯一性索引。
- FULLTEXT:可选。表示索引为全文索引。
- SPATIAL:可选。表示索引为空间索引。
- INDEX和KEY:用于指定字段为索引,两者选择其中之一就可以了,作用是 一样的。
- 索引名:可选。给创建的索引取一个新名称。
- 字段名1:指定索引对应的字段的名称,该字段必须是前面定义好的字段。
- 长度:可选。指索引的长度,必须是字符串类型才可以使用。
- ASC:可选。表示升序排列。
- DESC:可选。表示降序排列。
注:索引方法默认使用B+TREE。
建表后创建:
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY [索引名] (字段名1 [(长度)] [ASC | DESC]) [USING 索引方法];
或
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX 索引名 ON 表名(字段名) [USING 索引方法];
查看已创建的索引:
show index from 表名;
索引的删除:
DROP INDEX 索引名 ON 表名
或
ALTER TABLE 表名 DROP INDEX 索引名
提示:我们也可以直接使用工具查看
查看SQL语句对索引的使用情况(即:查询SQL的查询执行计划QEP):
在select语句前加上EXPLAIN即可。
分析该SQL的性能为:
提示:我们也可以使用SQL工具查看,如:navicat中的“解释”选项即可查看。
id:SELECT识别符。这是SELECT的查询序列号。
select_type:SELECT类型。
- SIMPLE: 简单SELECT(不使用UNION或子查询)
- PRIMARY: 最外面的SELECT
- UNION:UNION中的第二个或后面的SELECT语句
- DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
- UNION RESULT:UNION的结果
- SUBQUERY:子查询中的第一个SELECT
- DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
- DERIVED:导出表的SELECT(FROM子句的子查询)
table:表名
type:联接类型。是SQL性能的非常重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref
> fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。
一般来说,得保证查询至少达到range级别。
- system:表仅有一行(=系统表)。这是const联接类型的一个特例。
- const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。
- eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。
- ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。ref可以用于使用=或<=>操作符的带索引的列。
- ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
- index_merge:该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
- unique_subquery:该类型替换了下面形式的IN子查询的ref:value IN (SELECT primary_key FROMsingle_table WHERE some_expr);unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
- index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:value IN (SELECT key_column FROM single_table WHERE some_expr)
- range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range
- index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
- all:对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。
possible_keys:possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
key:key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
key_len:key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL将实际使用一个多部关键字的几个部分。
ref:ref列显示使用哪个列或常数与key一起从表中选择行。
rows:rows列显示MySQL认为它执行查询时必须检查的行数。
Extra:该列包含MySQL解决查询的详细信息。
- Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
- Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
- range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。对前面的表的每个行组合,MySQL检查是否可以使用range或index_merge访问方法来索取行。
- Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行。
- Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。当查询只使用作为单一索引一部分的列时,可以使用该策略。
- Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BY和ORDER BY子句时。
- Using where:WHERE子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行,如果Extra值不为Using where并且表联接类型为ALL或index,查询可能会有一些错误。
- Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。
- Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便对于每个组,只读取少量索引条目。
索引使用策略
什么时候要使用索引?
- 主键自动建立唯一索引;
- 经常作为查询条件在WHERE或者ORDER BY 语句中出现的列要建立索引;
- 作为排序的列要建立索引;
- 查询中与其他表关联的字段,外键关系建立索引
- 高并发条件下倾向组合索引;
- 用于聚合函数的列可以建立索引,例如使用了max(column_1)或者count(column_1)时的column_1就需要建立索引
什么时候不要使用索引?
- 经常增删改的列不要建立索引;
- 有大量重复的列不建立索引;
- 表记录太少不要建立索引。只有当数据库里已经有了足够多的测试数据时,它的性能测试结果才有实际参考价值。如果在测试数据库里只有几百条数据记录,它们往往在执行完第一条查询命令之后就被全部加载到内存里,这将使后续的查询命令都执行得非常快–不管有没有使用索引。只有当数据库里的记录超过了1000条、数据总量也超过了MySQL服务器上的内存总量时,数据库的性能测试结果才有意义。
索引失效的情况:
- 在组合索引中不能有列的值为NULL,如果有,那么这一列对组合索引就是无效的。
- 在一个SELECT语句中,索引只能使用一次,如果在WHERE中使用了,那么在ORDER BY中就不要用了。
- LIKE操作中,’%aaa%'不会使用索引,也就是索引会失效,但是‘aaa%’可以使用索引。
- 在索引的列上使用表达式或者函数会使索引失效,例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′。其它通配符同样,也就是说,在查询条件中使用正则表达式时,只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。
- 在查询条件中使用不等于,包括<符号、>符号和!=会导致索引失效。特别的是如果对主键索引使用!=则不会使索引失效,如果对主键索引或者整数类型的索引使用<符号或者>符号不会使索引失效。(经erwkjrfhjwkdb同学提醒,不等于,包括<符号、>符号和!,如果占总记录的比例很小的话,也不会失效)
- 在查询条件中使用IS NULL或者IS NOT NULL会导致索引失效。
- 字符串不加单引号会导致索引失效。更准确的说是类型不一致会导致失效,比如字段email是字符串类型的,使用WHERE email=99999 则会导致失败,应该改为WHERE email=‘99999’。
- 在查询条件中使用OR连接多个条件会导致索引失效,除非OR链接的每个条件都加上索引,这时应该改为两次查询,然后用UNION ALL连接起来。
- 如果排序的字段使用了索引,那么select的字段也要是索引字段,否则索引失效。特别的是如果排序的是主键索引则select * 也不会导致索引失效。
- 尽量不要包括多列排序,如果一定要,最好为这队列构建组合索引;
索引的优化
1、最左前缀
索引的最左前缀和和B+Tree中的“最左前缀原理”有关,举例来说就是如果设置了组合索引<col1,col2,col3>那么以下3中情况可以使用索引:col1,<col1,col2>,<col1,col2,col3>,其它的列,比如<col2,col3>,<col1,col3>,col2,col3等等都是不能使用索引的。
根据最左前缀原则,我们一般把排序分组频率最高的列放在最左边,以此类推。
2、带索引的模糊查询优化
在上面已经提到,使用LIKE进行模糊查询的时候,’%aaa%'不会使用索引,也就是索引会失效。如果是这种情况,只能使用全文索引来进行优化(上文有讲到)。
3、为检索的条件构建全文索引,然后使用
SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);
4、使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
聚集索引与非聚集索引:
聚集索引:
一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。
聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。
聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此 类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节 省成本。
当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。
非聚集索引:
非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
备注:聚集索引一张表只能创建一个,非聚集索引一张表可以创建多个,在mysql中InnoDB引擎是唯一支持聚集索引的存储引擎。InnoDB按照主键(Primary Key)进行聚集,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有这种索引,InnoDB就会定义隐藏的主键然后在上面进行聚集。
何时使用聚集索引或非聚集索引
锁机制
锁是计算机协调中多个进程或线程并发访问某一资源的机制。
在数据库中,除传统的计算资源(如CPU,RAM,I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要原因。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
锁的分类:
从对数据操作的类型: 读锁/写锁
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁
从对操作的粒度分: 表锁/行锁
表锁
表锁偏向MyISAM存储引擎,开销小,加锁快,无思索,锁定粒度大,发生锁冲突的概率最高,并发度最低。
手动增加表锁
lock table 表名称 read(write),表名称2 read(write),其他;
查看表上加过的锁
show open tables;
删除表锁
unlock tables;
查看哪些表被加锁了
show open tables;
如何分析表锁定
可以通过检查table_lock_waited和table_locks_immediate状态变量来分析系统上的表锁定
show status like 'table%';
这里有两个状态变量记录MySQL内部表级锁定的情况,两个变量说明如下:
Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1
Table_locks_waited 出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次锁值加1),此值高则说明存在着较严重的表级锁争用情况。
- MYISAM的读写锁调度是写优先,这也是MYISAM不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永久阻塞。
行锁
行锁偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度也最高。InnoDB与MYISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!
页锁
开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发处理能力一般。只需了解一下
总结
1 InnoDB 支持表锁和行锁,使用索引作为检索条件修改数据时采用行锁,否则采用表锁。
2 InnoDB 自动给修改操作加锁,给查询操作不自动加锁
3 行锁可能因为未使用索引而升级为表锁,所以除了检查索引是否创建的同时,也需要通过explain执行计划查询索引是否被实际使用。
4 行锁相对于表锁来说,优势在于高并发场景下表现更突出,毕竟锁的粒度小。
5 当表的大部分数据需要被修改,或者是多表复杂关联查询时,建议使用表锁优于行锁。
6 为了保证数据的一致完整性,任何一个数据库都存在锁定机制。锁定机制的优劣直接影响到一个数据库的并发处理能力和性能。
连接池
一. 为何要使用数据库连接池
假设网站一天有很大的访问量,数据库服务器就需要为每次连接创建一次数据库连接,极大的浪费数据库资源,并且极易造成数据库服务器内存溢出,拓机。
数据库连接池是一种关键的有限的昂贵的资源,这一点在多用户的网页程序中体现的尤为突出,对数据库连接的管理显著影响到整个应用程序的伸缩性和健壮性,影响程序的性能指标,数据库连接池正式针对这个问题提出的。数据库连接池负责分配,管理和释放数据库的连接,它允许应用程序重复使用一个现有的数据库连接,而不是重建一个。
数据库连接池在初始化时创建一定数量的数据库连接放到连接池中,这些数据在连接的数量上是由最小数据库连接数来设定的,无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量,连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数。当应用程序向连接池请求连接数量超过最大连接数量时,这些请求将被加入到等待队列中。
数据库连接池的最小连接数和最大连接数的设置要考虑以下几个因素:
1) 最小连接数:是连接池一直保持数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
2) 最大连接数:是连接池能申请的最大连接数,如果数据库的连接请求超过次数,后面的数据库连接将被加入到等待队列中,这会影响以后的数据库操作。
3) 如果最小连接数与最大连接数相差很大,那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接,不过这些大于最小连接数的数据库连接在使用完不会马上被释放,它将放到连接池中等待重复使用或是时间超时后被释放。
二. 传统的连接池机制与数据库连接池的运行机制区别
传统链接:一般来说,JAVA应用程序访问数据库的过程:
1) 装载数据库驱动程序;
2) 通过JDBC建立数据库连接;
3) 访问数据库,执行SQL语句;
4) 断开数据库连接;
使用了数据库连接池的机制:
1) 程序初始化时创建连接池;
2) 使用时向数据库申请可用连接;
3) 使用完毕,将连接返回给连接池;
4) 程序退出时,断开所有连接,并释放资源;
Druid连接池
1.使用步骤
(1)在mvnreposratory社区中下载jar包
(2)通过private static DruidDataSource pool = new DruidDataSource();
得到连接池的对象
(3)将链接数据库所需的url(JDBC协议),user(数据库的名字),driverClass(数据库的完全限定名),password(数据库的密码)
(4)通过
pool.setDriverClassName(driverClass);
pool.setUrl(jdbcUrl);
pool.setUsername(username);
pool.setPassword(password);
将url,user,driverClass,password传入创建好的连接池中,用于创建connection对象。
(5)通过
public static Connection getConnection() throws SQLException {
return pool.getConnection();
}
获取链接对象
2.Druid的优点
(1)Druid中已经封装好了创建好了创建Connection对象的方法,秩序要我们将url,user,driverClass,password传入就可以自动在连接池中生成Connection对象,不需要我们再去单独建立Connection对象。
(2)Druid生成的连接池中产生的Connection对象的closs()方法是重写过的,再使用closs()方法时是将这个连接归还到连接池中而不是关闭这个链接。
函数
字符函数
数学函数
日期函数
控制函数
事务
事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态。在数据库提交时,可以确保要么所有修改都已保存,要么所有修改都不保存。
事务的ACID特性
事务必须同时满足ACID的特性:
- 原子性(Atomicity)。事务中的所有操作要么全部执行成功,要么全部取消。
- 一致性(Consistency)。事务开始之前和结束之后,数据库完整性约束没有破坏。
- 隔离性(Isolation)。事务提交之前对其它事务不可见。
- 持久性(Durability)。事务一旦提交,其结果是永久的。
隔离性有隔离级别(4个)
读未提交:read uncommitted
读已提交:read committed
可重复读:repeatable read
串行化:serializable
1、 read uncommitted
- 事物A和事物B,事物A未提交的数据,事物B可以读取到
- 这里读取到的数据叫做“脏数据”
- 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
2、read committed
- 事物A和事物B,事物A提交的数据,事物B才能读取到
- 这种隔离级别高于读未提交
- 换句话说,对方事物提交之后的数据,我当前事物才能读取到
- 这种级别可以避免“脏数据”
- 这种隔离级别会导致“不可重复读取”
- Oracle默认隔离级别
3、repeatable read
- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 事务B是可重复读取数据
- 这种隔离级别高于读已提交
- 换句话说,对方提交之后的数据,我还是读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- 比如1点和2点读到数据是同一个
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”
4、serializable
- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
- 这种隔离级别很少使用,吞吐量太低,用户体验差
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发
设置事务隔离级别
方式一
可以在my.ini文件中使用transaction-isolation选项来设置服务器的缺省事务隔离级别。
该选项值可以是:
– READ-UNCOMMITTED
– READ-COMMITTED
– REPEATABLE-READ
– SERIALIZABLE
• 例如:
[mysqld]
transaction-isolation = READ-COMMITTED
方式二
通过命令动态设置隔离级别
• 隔离级别也可以在运行的服务器中动态设置,应使用SET TRANSACTION ISOLATION LEVEL语句。
• 其语法模式为:
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>
其中的<isolation-level>可以是:
– READ UNCOMMITTED
– READ COMMITTED
– REPEATABLE READ
– SERIALIZABLE
• 例如: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
视图
为何要使用视图?
1、安全性:一般是这样做的:创建一个视图,定义好该视图所操作的数据。
之后将用户权限与视图绑定,这样的方式是使用到了一个特性:grant语句可以针对视图进行授予权限。
2、查询性能提高
3、有灵活性的功能需求后,需要改动表的结构而导致工作量比较大,那么可以使用虚拟表的形式达到少修改的效果。
这是在实际开发中比较有用的
4、复杂的查询需求,可以进行问题分解,然后将创建多个视图获取数据。将视图联合起来就能得到需要的结果了。
创建视图的语法
CREATE [ORREPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
其中,CREATE:表示新建视图;
REPLACE:表示替换已有视图
ALGORITHM :表示视图选择算法
view_name :视图名
column_list:属性列
select_statement:表示select语句
[WITH [CASCADED | LOCAL] CHECK OPTION]参数表示视图在更新时保证在视图的权限范围之内
可选的ALGORITHM子句是对标准SQL的MySQL扩展。
ALGORITHM可取三个值:MERGE、TEMPTABLE或UNDEFINED。
如果没有ALGORITHM子句,默认算法是UNDEFINED(未定义的)。算法会影响MySQL处理视图的方式。
对于MERGE,会将引用视图的语句的文本与视图定义合并起来,使得视图定义的某一部分取代语句的对应部分。
对于TEMPTABLE,视图的结果将被置于临时表中,然后使用它执行语句。
对于UNDEFINED,MySQL自己选择所要使用的算法。如果可能,它倾向于MERGE而不是TEMPTABLE,
这是因为MERGE通常更有效,而且如果使用了临时表,视图是不可更新的。
LOCAL和CASCADED为可选参数,决定了检查测试的范围,默认值为CASCADED。
修改视图
修改视图是指修改数据库中存在的视图,当基本表的某些字段发生变化时,可以通过修改视图来保持与基本表的一致性。
MYSQL中通过CREATE OR REPLACE VIEW 语句和ALTER语句来修改视图
语法如下:
ALTER OR REPLACE [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
日志
Mysql日志是记录Mysql数据库的日常操作和错误信息的文件。当数据库遭到意外的损害时,可以通过日志文件来查询出错原因,并且可以通过日志文件进行数据恢复。用来记录Mysql数据库的客户端连接情况、SQL语句的执行情况和错误信息等。
Mysql日志分为4种:
-
二进制日志:以二进制文件的形式记录了数据库中的操作,但不记录查询语句。(可以还原数据库)
-
错误日志:记录Mysql服务器的启动、关闭和运行错误等信息。
-
通用日志:记录用户登录和记录查询的信息。
-
慢查询日志:记录执行时间超过指定时间的操作。(用于索引优化)
- 除二进制日志外,其他日志都是文本文件。日志文件通常存储在Mysql数据库的数据目录下。默认情况下,只启动了错误日志的功能。其他3类日志都需要数据库管理员进行设置。
二进制日志
二进制日志也叫作变更日志(update log),主要用于记录数据库的变化情况。通过二进制日志可以查询Mysql数据库中进行了那些改变。
1.1启动和设置二进制日志
在my.ini文件中添加
[mysqld]
log-bin[=DIR\[filename]]
其中DIR参数指定二进制文件的存储路径,filename参数指定二进制文件的文件名,其形式为filename.number,number的形式为000001等。每次启动Mysql服务后,都会生成一个新的二进制日志文件,这些日志文件的’number’会不断递增。除了生成二进制文件之外,还会生成一个名为filename.index的文件。这个文件中存储所有二进制日志文件的清单。
注意:二进制日志与数据库的数据文件最好不要放在同一个硬盘,即使数据文件所在的硬盘被破坏,也可以使用另一块硬盘的二进制日志来恢复数据库文件。
1.2查看二进制日志: mysqlbinlog filename.number
1.3删除二进制日志:
二进制日志会记录大量的信息。如果很长时间不清理二进制日志,将会浪费很多的磁盘空间。
删除所有二进制日志: reset master
根据编号来删除二进制日志: purge master logs to ‘filename.number’;
根据创建时间来删除二进制日志:purge master logs to ‘yyyy-mm-dd hh:MM:ss’;
1.4使用二进制文件还原数据库
二进制日志记录了用户对数据库中数据的改变。如 insert、update、create语句等都会记录在二进制文件中。一旦数据库遭到破坏,可以通过二进制日志来还原数据库。
还原数据库的命令:
mysqlbinlog filename.number | mysql -u root -p
暂停和重启二进制日志功能:
set sql_log_bin=0 暂停二进制文件
set sql_log_bin=1 重启二进制文件
错误日志
错误日志是Mysql数据库中最常用的一种日志。错误日志主要用来记录Mysql服务的开启、关闭和错误信息。
2.1启动和设置错误日志
错误日志功能是默认开启的,而且无法被禁止。存储在数据文件夹下,错误日志文件通常的名称为hostname.err,其中hostname表示Mysql服务器的主机名。错误日志的存储位置可以通过Log-error选型来设置。
[mysqld]
log-error=DIR/[filename] 同二进制日志设置参数含义相同。
2.2查看错误日志
错误日志文件记录着开启关闭和出现异常的信息。错误文件以文本形式存储,可以直接打开。
2.3删除错误日志
数据库管理员可以删除很久以前的错误日志,以保证Mysql服务器上的硬盘空间。
mysqladmin -u -root -p flush-logs
通用查询日志
通用查询日志是用来记录用户的所有操作,包括启动和关闭,更新语句和查询语句。
3.1启动和设置通用查询日志
[mysqld]
log[=DIR[filename]]
3.2查看通用查询日志
由于通用查询日志的存储形式为文本形式,因此可以直接打开查询。
3.3删除通用查询日志
mysqladmin -u root -p flush-logs
慢查询日志
慢查询日志是用来记录执行时间超过指定时间的查询语句。通过慢查询日志,可以查找出那些查询语句的执行效率很低,以便进行优化。
4.1启动和设置慢查询日志
[mysqld]
log-slow-queries[=DIR[filename]] #设定存储的位置和名字,默认为hostname-slow.log
long_query_time=n #设定时间值,该值的单位是秒,如果不设置,默认时间为10秒。
查看慢查询日志也是直接打开文件即可,删除与通用查询日志相同。