面试题__001

 1. mysql中myisam与innodb的区别,至少5点

1. InnoDB支持事物,而MyISAM不支持事物
2. InnoDB支持行级锁和表级锁,而MyISAM只支持表级锁
3. InnoDB支持外键,而MyISAM不支持
4. InnoDB不支持全文索引,而MyISAM支持
5. InnoDB支持MVCC, 而MyISAM不支持
6. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可
7. AUTO_INCREMENT存储的不同

 

2.  innodb的日志有多少种及其配置方式

1. 错误日志:记录出错信息,也记录一些警告信息或者正确的信息
2. 慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中。
3. 二进制日志:记录对数据库执行更改的所有操作
4. 查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行。

 

3. explain出来的各种item的意义

 
 

 

4. 请简洁地描述下MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别

Read Uncommitted(读取未提交内容)
      在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

Read Committed(读取提交内容)
      这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

Repeatable Read(可重读)
      这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control 间隙锁)机制解决了该问题。注:其实多版本只是解决不可重复读问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题。

Serializable(可串行化)
    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

对于不同的事务,采用不同的隔离级别分别有不同的结果。不同的隔离级别有不同的现象。主要有下面3种现在:
1、脏读(dirty read):一个事务可以读取另一个尚未提交事务的修改数据。
2、非重复读(nonrepeatable read):在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。
3、幻像读(phantom read):在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。
不同的隔离级别有不同的现象,并有不同的锁定/并发机制,隔离级别越高,数据库的并发性就越差

 

5. [SELECT *] 和[SELECT 全部字段]的2种写法有何优缺点,至少写出四点

1. 前者要解析数据字典,后者不需要
2. 结果输出顺序,前者与建表列顺序相同,后者按指定字段顺序
3. 表字段改名,前者不需要修改,后者需要改
4. 后者可以建立索引进行优化,前者无法优化
5. 后者的可读性比前者要高

 

 6. HAVNG 子句 和 WHERE的异同点,至少写出3点

1. 语法上:where 用表中列名,having用select结果别名
2. 影响结果范围:where从表读出数据的行数,having返回客户端的行数
3. 索引:where 可以使用索引,having不能使用索引,只能在临时结果集操作
4. where后面不能使用聚集函数,having是专门使用聚集函数的

 

7. 分布式数据库产品的特点

1. 数据分布在多个异地点,抗灾性强
2. 并发性高
3. 受网络影响很大
4. 单机的性能不是特别重要,但是总体成本很高
5. 扩展性强

 

8. 索引

1. 复合索引
    比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;
    如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,
    但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。
    因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
    只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
2. 索引命中
    a. 一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
    b. NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。
    c. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
    d. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
        select id from t where num=10 or num=20
        可以这样查询:
        select id from t where num=10
        union all
        select id from t where num=20
    e. in 和 not in 也要慎用,否则会导致全表扫描, 对于连续的数值,能用 between 就不要用 in 了
    f. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。
        然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
        select id from t where num=@num
        可以改为强制查询使用索引:
        select id from t with(index(索引名)) where num=@num
    g. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
        select id from t where num/2=100
        应改为:
        select id from t where num=100*2
    h. 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。
    i. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
    j. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,
        否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致

 

9. 一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15 ? 

1. 如果表的类型是MyISAM,那么是18。 因为MyISAM表会把自增主键的最大ID记录到数据文件里,重启MySQL自增主键的最大ID也不会丢失
2. 如果表的类型是InnoDB,那么是15。 InnoDB表只是把自增主键的最大ID记录到内存中,所以重启数据库或者是对表进行OPTIMIZE操作,都会导致最大ID丢失。

 

10. 拆分大的 DELETE 或 INSERT 语句

如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。
所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法。下面是一个示例: while (1) {
  //每次只做1000条
  mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");

  if (mysql_affected_rows() == 0) {
    // 没得可删了,退出!
    break;
  }

  // 每次都要休息一会儿
  usleep(50000);
}

 

11. 垂直分割 

“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)
  示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字段。
  那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。
  小一点的表总是会有好的性能。   示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。
  所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。 另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。

 

12. 常用优化方案

1. 选取最适用的字段属性 
    例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。
    同样的,如果可以的话,我们应该使用MEDIUMINT而不是 BIGIN来定义整型字段。
2. 应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。
3. 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。
4. 使用连接(JOIN)来代替子查询(Sub-Queries) 
5. 使用联合(UNION)来代替手动创建的临时表 
6. 使用索引
7. 正确的sql语句

 

13. sql语言分4大类

   DDL--CREATE,DROP,ALTER
   DML--INSERT,UPDATE,DELETE
   DQL-SELECT
   DCL--GRANT,REVOKE,COMMIT,ROLLBACK

 

 14. memcached、redis、mongodb的区别联系

1. https://www.zhihu.com/question/19645807
2
. http://blog.csdn.net/s1070/article/details/51255094

 

 15. 链接

1. http://www.cnblogs.com/suoning/default.html?page=1

 

转载于:https://www.cnblogs.com/hangtt/p/6423425.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值