mysql 知识

1.  数据库事务的四个特性及含义

数据库事务transanction正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

2.视图的作用,视图可以更改么?

视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。
视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖。
创建视图:create view XXX as XXXXXXXXXXXXXX;
对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。

3.drop,delete与truncate的区别

drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。

(1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。

(2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。

(3) 一般而言,drop > truncate > delete

(4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view

(5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。

(6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。

(7) delete语句为DML(data maintain Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。

(8) truncate、drop是DLL(data define language),操作立即生效,原数据不放到 rollback segment中,不能回滚

(9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老师想触发trigger,还是用delete。

(10) Truncate table 表名 速度快,而且效率高,因为:
truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。

(11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。

(12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。

 

4浅谈 DML、DDL、DCL的区别

   

  • DML(data manipulation language)数据操纵语言:

    就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。

     

  • DDL(data definition language)数据库定义语言:

    其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上

      

  • DCL(Data Control Language)数据库控制语言:

    是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。这个比较少用到。

5 索引

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。

第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

 

索引类型:

  普通索引 是最基本的索引,它没有任何限制。它有以下几种创建方式:

(1)直接创建索引

CREATE INDEX index_name ON table(column(length))

(2)修改表结构的方式添加索引

ALTER TABLE table_name ADD INDEX index_name ON (column(length))

  唯一索引

   

与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
(1)创建唯一索引

CREATE UNIQUE INDEX indexName ON table(column(length))

(2)修改表结构

ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))

  主键索引 : 是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引    

  组合索引  

  指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

  ALTER TABLE `table` ADD INDEX name_city_age (name,city,age); 

  全文索引

   主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。  

ALTER TABLE article ADD FULLTEXT index_content(content)


B_tree索引和hash索引的区别





6 连表查询
1.内连接 : 等值连接 左右表中匹配的数据
2.左连接 : left join 左表的全部数据加上右表中与左表匹配的数据

7 mysql 数据库引擎
引擎类型:
1.InnoDB :B+tree 存储的是数据的地址 ,
是一个事务型的存储引擎,有行级锁定和外键约束,事物是行级锁,由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。

    适用场景:
    1)经常更新的表,适合处理多重并发的更新请求。
    2)支持事务。
    3)可以从灾难中恢复(通过bin-log日志等)。
    4)外键约束。只有他支持外键。
    5)支持自动增加列属性auto_increment。


2.MyIsam
(默认引擎):
B+tree 存储的是数据的本身
MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
  

    适用场景:
    1)不支持事务的设计,但是并不代表着有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。
    2)不支持外键的表设计。
    3)查询速度很快,如果数据库insert和update的操作比较多的话比较适用。
    4)整天 对表进行加锁的场景。
    5)MyISAM极度强调快速读取操作。
    6)MyIASM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。
    缺点:
    就是不能在表损坏后恢复数据。(是不能主动恢复)

  3.Memory : Memory(也叫HEAP)堆内存嘛,使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH索引。

    适用场景:
    1)那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地堆中间结果进行分析并得到最终的统计结果。
    2)目标数据比较小,而且非常频繁的进行访问,在内存中存放数据,如果太大的数据会造成内存溢出。可以通过参数max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。
    3)数据是临时的,而且必须立即可用得到,那么就可以放在内存中。
    4)存储在Memory表中的数据如果突然间丢失的话也没有太大的关系。
    注意: Memory同时支持散列索引和B树索引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索引相等的比较快但是对于范围的比较慢很多。
    特性要求:
    1)要求存储的数据是数据长度不变的格式,比如,Blob和Text类型的数据不可用(长度不固定的)。
    2)要记住,在用完表格之后就删除表格。


 4.
Merge_Myisam :

    是一个相同的可以被当作一个来用的MyISAM表的集合。“相同”意味着所有表同样的列和索引信息。
    也就是说,他将MyIsam引擎的多个表聚合起来,但是他的内部没有数据,真正的数据依然是MyIsam引擎的表中,但是可以直接进行查询、删除更新等操作。
    比如:我们可能会遇到这样的问题,同一种类的数据会根据数据的时间分为多个表,如果这时候进行查询的话,就会比较麻烦,Merge可以直接将多个表聚合成一个表统一查询,然后再删除Merge表(删除的是定义),原来的数据不会影响。


  5.Blackhole

  任何写入到此引擎的数据均会被丢弃掉, 不做实际存储;Select语句的内容永远是空。
  他会丢弃所有的插入的数据,服务器会记录下Blackhole表的日志,所以可以用于复制数据到备份数据库。
  使用场景:
  1)验证dump file语法的正确性
  2)以使用blackhole引擎来检测binlog功能所需要的额外负载
  3)充当日志服务器


(3)使用建议:
以下两点必须使用 InnoDB:
1)可靠性高或者要求事务处理,则使用InnoDB。这个是必须的。
2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况指定InnoDB数据引擎的创建。
对比之下,MyISAM的使用场景:
1)做很多count的计算的。如一些日志,调查的业务表。
2)插入修改不频繁,查询非常频繁的。



修改引擎类型

  一 修改配置文件my.ini

  将mysql.ini另存为my.ini,在[mysqld]后面添加default-storage-engine=InnoDB,重启服务,数据库默认的引擎修改为InnoDB

   二   在建表的时候指定

create table mytbl(   
    id int primary key,   
    name varchar(50)   
)type=MyISAM;

alter table table_name type = InnoDB;
查看数据库引擎
show table status from table_name; 

小细节:
1.MySQL中varchar与char的区别:char(N)存储的字段是定长的N,varchar(N)变长,字段长度不能超过N
2.不走索引的情况
1. where 子句中使用 or 来连接条件
select id from t where num=10 or num=20
2. where 子句中使用 like %
3. in 和 not in 优化用( between and )
4.
应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where num/2=100
5.
.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

        select id from t where substring(name,1,3)='abc'--name以abc开头的id

        select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id

        应改为:

        select id from t where name like 'abc%'

        select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

          6.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
7.很多时候用 exists 代替 in 是一个好的选择
3.mysql查询字段区不区分大小写? 不区分,哪怕值也不区分

3.group by having 子句执行顺序

  我们如果就是查询每个部门成绩大于89的员工数,可以这样写:

  SELECT dept,COUNT(user_name) FROM ec_uses WHERE score>89 GROUP BY dept;

  对这个查询的过程进行分析,其实是:先查出绩效成绩大于89的员工记录,然后再用count聚合函数统计部门的人数,也就是说where是在聚合之前筛选记录的,

  SELECT dept,COUNT(user_name) count_tmp FROM ec_uses GROUP BY dept HAVING count_tmp>1;

      这个是先聚合 再执行having子句


 



posted @ 2018-11-02 15:05  英特费斯  阅读(158)  评论(0编辑  收藏  举报