数据库面试题

 

1 sql优化: 即减少sql语句的执行时间,有哪些方法

1 避免在索引列上使用计算,因为这样会导致索引失效;避免在索引列上使用 IS NULL 和 IS NOT NULL

2 对查询进行优化,应尽量避免全表扫描,首先可以考虑在where和order by涉及的列上建立索引

3 尽量避免在where的子句中对字段进行null值判断,否则引擎就会放弃使用索引,从而进行全表扫描;
   尽量避免在where子句中对字段进行表达式操作,否则引擎就会放弃使用索引,从而进行全表扫描;
   尽量避免在where子句中使用!=或<>操作符,否则引擎就会放弃使用索引,从而进行全表扫描;
   尽量避免在where子句中使用or来连接条件,否则引擎就会放弃使用索引,从而进行全表扫描。

4 如果数值是连续的,能用between就不要用in

5 任何地方都不要使用 select * from table ,要用具体的字段代替“*”,只取出需要的字段

6 模糊搜索尽量避免使用前置百分号,否则引擎就会放弃使用索引,从而进行全表扫描

7 一个表的索引数最好不要超过6个,因为太多的索引会影响到表的更新速度

8 如果字段只包含数值信息,尽量不要设计为字符类型,否则会降低查询和连接的性能,同时还会增加存储开销

9 避免频繁创建和删除临时表,减少系统表资源的消耗

10 尽量使用 varchar/nvarchar 代替 char/nchar ,因为变长字段的存储空间小,这样可以节省存储空间,同时对于查询来说,在一个相对较小的字段内搜索,效率自然会更高

11 尽量使用表变量来代替临时表
12 减少表连接,可适当增加冗余字段。
13 表连接情况下,把表数据量大的放于最前面,减少查询行数

14 用EXISTS替代IN、用NOT EXISTS替代NOT IN

  select * from table where exists (子查询)
子查询有返回结果, 则exists()返回true, 主查询返回结果
子查询每有返回结果, 则exists()返回false, 主查询不返回结果

2 如何创建索引?

查看表中已有索引: show index from 表名;

主键列会自动创建索引

创建索引的语法格式: alter table 表名 add index [索引名](列名, ..)

索引名不指定,默认使用字段名

删除索引的语法格式: alter table 表名 drop index 索引名

如果不知道索引名,可以查看创表sql语句: show create table classes;

联合索引的好处:减少磁盘空间开销,因为每创建一个索引,其实就是创建了一个索引文件,那么会增加磁盘空间

3 创建索引的原则?

  索引查询是数据库中重要的记录查询方法,要不要进入索引以及在那些字段上建立索引都要和实际数据库系统的查询要求结合来考虑,下面给出实际中的一些通用的原则: 

1. 在经常用作过滤器的字段上建立索引;
2. 在SQL语句中经常进行GROUP BY、ORDER BY的字段上建立索引;
3. 在不同值较少的字段上不必要建立索引,如性别字段;
4. 对于经常存取的列避免建立索引;
5. 用于联接的列(主健/外健)上建立索引;
6. 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定;
7. 缺省情况下建立的是非簇集索引,但在以下情况下最好考虑簇集索引,如:含有有限数目(不是很少)唯一的列;进行大范围的查询;充分的利用索引可以减少表扫描I/0的次数,有效的避免对整表的搜索。当然合理的索引要建立在对各种查询的分析和预测中,也取决于DBA的所设计的数据库结构。

4 oracle 索引建立的若干原则

  我们首先要考虑的是数据量,数据量级别的不同,要考虑的问题有很大区别。几千条记录建不建索引其实都无所谓了,差个几豪秒也感觉不出来,但数据量一旦要增长到百万, 千万级别,索引的重要性就体现出来了。

  没有索引一个查询可能要几个小时甚至几天才能出来,对数据库的影响不仅仅是查询速度的降低, 在io 上的花费和对数据库连接资源的占用甚至会拖跨数据库。那么怎样建立索引,建立什么类型的索引呢,应该按照几个方面来考虑。

  1. 先要了解业务需求,总结出应用会按照哪几个字段来进行查询。例如一个人员查询系统可能会按照(姓名,身份证件号码,性别,住址,民族等),当然可能是几个字段的组合查询。
  2. 确定了第一步后要估计数据的分布。相同值有多少,是不是均匀。如姓名字段就会有大量的重复情况;性别可能只有两个值(1,2 分别代表男,女),民族会有56 个。
  3. 确定索引的类型。选择性高的字段建立B- 树索引最好,如果数据量太大,可考虑把索引分区,在并发情况下通常会表现很好。相当于把一棵很大的B树拆开成了多棵小树。只有几个值的字段如性别并且数据分布比较均匀,查询的平均命中率要是非常高就不需要建立索引,否则可以建立位图索引(但会影响并发)。

oracle建立索引原则 :

索引需要平衡query和DML的需要,常用于(子)查询的表应建立索引;
把索引建到不同的表空间中;
使用统一的extent大小:
五个block的倍数或者tablespace指定的MINIMUM EXTENT的倍数;
创建索引考虑用NOLOGGING参数,重建索引的时候也一样;
创建索引时INITRANS值应该比相应的table的值高一些;

对常用SQL语句的where条件中的列建立唯一索引或组合索引,组合条件查询中相应的组合索引更有效;
对于组合索引,根据列的唯一值概率,安排索引顺序;

如果一个列具有很低的数据基数,并且或者可具有空值,不应作为索引列;
如果where语句中不得不对查询列采用函数查询,如upper函数,最好建立相应函数索引;

对于低基数集的列,并包含OR等逻辑运算,考虑用Bitmap索引,对于从大量行的表中返回大量的行时也可以考虑Bitmap索引;
避免在有大量并发DML运算的表中使用Bitmap索引

5 索引的优缺点

1 优点

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

2 缺点

第一,创建索引和维护索引要耗费时间,这种时间随着数据 量的增加而增加。
第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

6 在哪些列上能创建索引

一般来说,应该在这些列 上创建索引:

在经常需要搜索的列上,可以加快搜索的速度;
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
在经常用在连接的列上,这 些列主要是一些外键,可以加快连接的速度;
在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
在经常需要排序的列上创 建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

7 sql去重

SQL中的三种去重方法

1 distinct
2 group by
3 row_number 窗口函数进行去重, 在支持窗口函数的 sql(如Hive SQL、Oracle等等) 中可以使用

8 内连接和外连接的区别

  内连接(自然连接):inner join

    只有两张表相匹配的行才能出现在结果集, 消除笛卡尔积查询

  外连接: outer join

  左外连接:左边为主表,左边的表显示全部;右边为副表,右边无符号数据时显示null,不符合的不显示;

  右外连接:右边为主表,右边的表显示全部;左边为副表,左边无符号数据时显示null,不符合的不显示;

  全外连接:左边为主表,右边为副表,主表和副表全部显示,右边无符号数据时显示null,左边无符号数据时显示null,符合条件的数据会显示在一行;

  交叉连接:cross join

    左边为主表,右边为副表,显示的数据为笛卡尔乘积的形式

9 java中如何使用redis

  java中利用jedis连接redis
  获取连接: Jedis jedis = new Jedis("localhost", "6376");

10 redis支持的数据类型及各数据类型的使用场景?

string, 简单的key-value类型,普通的key/ value 存储都可以归为此类

1 存放session key
2 短信的验证码

hash: 即map键值对格式的

存放结构化数据,比如用户信息

1 用户信息比如用户的昵称、年龄、性别、积分等,我们需要先序列化后存储为一个字符串的值,在修改时, 就需要反序列化修改某一项的值,再序列化存储回去。这样不仅增大了开销, 也不适用于一些可能并发操作的场合

2 而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值

list: List是一个双向链表

1 各种列表,比如twitter的关注列表、粉丝列表等,最新消息排行、每篇文章的评论等也可以用Redis的list结构来实现
2 消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出执行

set: 是一种无序的集合, 不重复。将重复的元素放入Set会自动去重。

1 某些需要去重的列表
2 可以存储一些集合性的数据

sortedset: 有序集合

1 存放一个有序的并且不重复的集合列表
2 可以做带权重的队列
3 排行榜相关
4 新闻按照用户投票和时间排序

11 redis如何解决数据过期?

  通过更改key过期,可以将某些集群中的Redis内存使用量减少25%,因此Redis 提供了两种的方式,用于删除过期的数据

定期删除
  Redis 默认 100ms 随即抽取部分设置过期时间的 key,过期了就删除。优点是避免长时间的在扫描过期 key,缺点是有些过期 key 无法被删除
不扫描全部 key 的原因是,当设置了过期时间的 key 太多的情况下,会很耗时间,O(n) 的时间复杂度。

惰性删除

  如果查询了某个过期 key,但定期删除没有删除掉,那就将其删除了。key 没过期就正常返回。

12 数据库表的设计注意事项有哪些?

1 数据库表命名,将业务和基础表区分,采用驼峰表示法等
2 数据不要物理删除,应该加一个标志位,以防用户后悔时,能够恢复
3 排序字段,按照某种类型来排序(sortcode)最好不依赖id排序,这样方便我们查询记录时按照某种方式排序,而不依赖id。
4 数据是否允许删除和允许编辑,例如管理员不能删除,这样我们在查询数据时就可以根据该字段标示来决定某条记录是否可以编辑。而不用固化到代码中。
5 增加备注字段,虽然我们考虑了很多用户需要输入信息的需求,但是无论何时我们都不可能考虑全,因此可以定义一个备注字段,允许用户将其它的信息填写在这里。无论表设计的再神奇,那么还是加一个备注字段。
6 添加时间,有添加时间可以明确知道记录什么时候添加的。
7 修改时间,可以知道记录什么时候被修改了,一旦数据出现问题,可以根据修改时间来定位问题。比如某人在这个时间做了哪些事。

13 三大范式的了解?

第一范式(原子性)
  是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值
第二范式(完全依赖主键)
  需要确保数据库表中每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。一张表中出现数据重复就可以将其拆分成两个表
第三范式(直接依赖主键)
  需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
  有时为了满足查询速度,可以有意识的让某些表有些冗余,这是为了提高整个数据库的性能,所以有些时候,不一定要拘泥于达到第三范式或bcn 范式,只要数据库的设计可以提高整个数据库的性能,这就是一个合理的数据库

14 存储过程的了解和使用?

什么是存储过程

  SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

  存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和控制结构组成。

  当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。

  数据库中的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。

存储过程的优点:

  (1).增强SQL语言的功能和灵活性:存储过程可以用控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
  (2).标准组件式编程:存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
  (3).较快的执行速度:如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
  (4).减少网络流量:针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织进存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少网络流量并降低了网络负载。
  (5).作为一种安全机制来充分利用:通过对执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

15 数据库如何实现分页?

1 MySQL实现分页: 使用limit
2 Oralce实现分页:

1 Oracle中有个rownum,其含义更加明显,就是第几行的意思,这样我们就可以通过where条件来进行分段查询了。
  select * from t_user where rownum>=2 and rownum<=4
  注意:oracle上面的语句查不到数据,应该套一层,如下
  select * from (select a.*, rownum rn from t_user a where rownum <= 4) where rn >= 2
2 minus 运算符来实现分页, 查询语句为:
  select rownum,t.* from T_ACCOUNT t where rownum<=20
  minus
  select rownum,t.* from T_ACCOUNT t where rownum<=10

3 sqlserver: 在分页查询上,SQL Server比较费劲,没有一个专门的分页的语句,靠的是一种巧妙的方法实现分页查

select * from t_user select * from (select top 2 * from (select top 6 * from t_user order by id asc ) as aaa order by id desc) as bbb order by id asc

16 百万级量的数据分页查询如何优化?

  mysql: select * from news where id>=(select id from news limit 490000,1) limit 10;

  limit只有一个参数, 默认查询第1页, limit后跟的是每页记录数

17 数据库的乐观锁和悲观锁的理解和使用?

1 理解

1、悲观锁,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。【数据锁定:数据将暂时不会得到修改】
  悲观锁是读取的时候为后面的更新加锁,之后再来的读操作都会等待。这种是数据库锁
  悲观锁是数据库实现,他阻止一切数据库操作
2、乐观锁,认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息。让用户决定如何去做
  乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,
需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝
  之所以叫乐观,因为这个模式没有从数据库加锁
  乐观锁优点程序实现,不会存在死锁等问题。他的适用场景也相对乐观。阻止不了除了程序之外的数据库操作。

2 使用

1 ORM框架中悲观锁乐观锁的应用
2 悲观锁
  select... for update
3 乐观锁

  • 1 乐观锁使用的是版本号
    • 1 修改数据之前先查询数据对应的版本号
    • 2 一个线程修改时先检查数据库中的版本号和自己拿到的版本号是否一致
    • 3 修改完毕后把版本号加1
  • 2 乐观锁不能防止其他线程修改数据

18 数据库中日期和字符串的相互转换?

1 Oracle

  时间转字符串 to_char(date,format): select to_char(sysdata,'YYYY"年"MM"月"DD"日"') 时间转字符串 from dual

  字符串转时间 to_date(str,format): select to_date('2019-10-25 17:15:20','yyyy-MM-dd HH24:mi:ss') 字符串转时间 from dual

2 MySQL

  时间转字符串DATE_FORMAT(): select DATE_FORMAT(SYSDATE(),'%Y年%m月%d日') MySQL日期转字符串 from DUAL;

  字符串转时间str_to_date(): select str_to_date('2019-10-25 15:43:28','%Y-%m-%d %H:%i:%s');
   H大写是指的是:24小时制;h小写是指的是12小时制;

19 union和unionAll区别?

UNION 并集,表中的所有数据,并且去除重复数据(工作中主要用到的是这个);

1 UNION 操作符用于合并两个或多个 SELECT 语句的结果集
2 需要满足以下条件:

  • 1、相同数量的列;
  • 2、列也必须拥有相似的数据类型;
  • 3、同时,每条 SELECT 语句中的列的顺序必须相同。

3 union去重, 对结果排序

UNION ALL,表中的数据都罗列出来,不去重, 结果不排序

20 mysql的存储引擎有哪些?

MyISAM存储引擎: 非事务处理存储引擎
innoDB存储引擎: 具备外键支持功能的事务处理引擎
MEMORY存储引擎: 置于内存的表
ARCHIVE存储引擎: 用于数据存档的引擎, 数据被插入后就不能再修改了

21 事务的隔离级别有哪些?

Read uncommitted (读未提交):最低级别,任何情况都无法保证。
Read committed (读已提交):可避免脏读的发生。
Repeatable read (可重复读):可避免脏读、不可重复读的发生。
Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

22 mysql和oracle默认的隔离级别是什么?

  mysql默认的事务处理级别是'REPEATABLE-READ(repeatable read)',也就是可重复读

  oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。

  默认系统事务隔离级别是READ COMMITTED,也就是读已提交

23 sql如何行转列和列转行?

1 行转列

1 行转列一般通过CASE WHEN 语句来实现
2 也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现。
用传统的方法,比较好理解。层次清晰,而且比较习惯。
但是PIVOT 、UNPIVOT提供的语法比一系列复杂的SELECT…CASE 语句中所指定的语法更简单、更具可读性
3 主要思路是分组后使用case进行条件判断处理

2 列转行

主要思路也是分组后使用case,也可以用union运算符

select 'a' as 'q'; 这个语句执行后可以把'a'作为列'q'中的值

24 如何查看sql的执行计划?

  MySQL使用 explain 关键字来查看SQL的执行计划

25 oracle中的分析函数有哪些?

row_number()可以通过over 根据某字段排序完之后进行组内(如果有partition by)排序。

rank()是排名的函数,该函数组内排序后会进行跳号,分数相同的作为并列。

dense_rank()该函数不会跳号,分数相同为并列第一,下一个是第二

26 数据库中除了聚合函数之外还有哪些常用的函数?

常用函数

1 时间函数

获取当前系统时间select now();
获取系统的时分秒select curtime();
获取系统的年月日select curdate();

2 数学函数

向上取舍select ceil(数值);
向下取舍select floor(数值);
获取四位小数select ceil(rand()*10000);
随机数select rand();//0~1之间的随机数;

27 oracle数据库merge()函数的作用和使用?

  通常我们对数据库数据进行插入的时候,会判断数据是否已经存在,如果存在就修改,不存在就插入,一般我们会写两个sql,一个insert一个update,那么其实oracle中存在merge函数,可以一次性解决这个问题

  作用: 能够在一个SQL语句中对一个表同时执行inserts和updates操作. MERGE命令从一个或多个数据源中选择行来updating或inserting到一个或多个表
  使用: 比如向数据库插入一条数据 如果ID和name都相同 就更新AGE的数据,否则就插入

28 sql 中 drop, truncate, delete 的区别?

相同点:drop、delete、truncate 都是删除表的内容。

不同点:

drop:删除表内容和结构,释放空间,没有备份表之前要慎用;
truncate:删除表的内容,表的结构存在,可以释放空间,没有备份表之前要慎用
delete:删除表的内容,表的结构还存在,不释放空间,可以回滚恢复;

drop:drop test 删除表test,并释放空间,将test删除的一干二净
truncate:truncate test 删除表test里的内容,并释放空间,但不删除表的定义,表的结构还在,且truncate删除数据不能只删除一行, 只能删除整张表的数据
delete:

  (1)删除制定数据:删除表test中年龄等于30且国家为US的数据:delete from test where age=30 and country =‘US’;
  (2)删除整个表:仅删除表test内的所有内容,保留表的定义,不释放空间:delete from test 或delete *from test


在都删除整张表的情况下:drop > truncate > delete
  truncate table 速度更快,占用的日志更少,这是因为 TRUNCATE TABLE 直接释放数据页并且在事务日志中也只记录数据页的释放
而 DELETE 是一行一行地删除,在事务日志中要记录每一条记录的删除

sql语句的不同

drop table table_name;
truncate table_name;
delete from table_name;

29 mysql如何忽略表名的大小写?

linux下mysql默认是要区分表名大小写的

mysql是否区分大小写设置是由参数lower_case_table_names决定的

操作:找到你mysql的配置文件my.ini(linux下是my.cnf),打开后找到“[mysqld]”节点,在下面加上一句话

1)lower_case_table_names = 0 (默认)
区分大小写(即对大小写不敏感),默认是这种设置。这样设置后,在mysql里创建的表名带不带大写字母都没有影响,都可以正常读出和被引用。
2)lower_case_table_names = 1
不区分大小写(即对大小写敏感)。这样设置后,表名在硬盘上以小写保存,MySQL将所有表名转换为小写存储和查找表上。该行为也适合数据库名和表的别名。也就是说,mysql设置为不分区大小写后,创建库或表时,不管创建时使用大写字母,创建成功后,都是强制以小写保存!

MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:

1)数据库名与表名是严格区分大小写的;
2)表的别名是严格区分大小写的;
3)列名与列的别名在所有的情况下均是忽略大小写的;
4)变量名也是严格区分大小写的;
5)MySQL在Windows下都不区分大小写,但是在Linux下默认是区分大小写的。
6)如果想在查询时区分字段值的大小写,则字段值需要设置BINARY属性,设置的方法有多种:
  a)创建时设置:CREATE TABLE T(A VARCHAR(10) BINARY);
  b)使用alter修改

所以在不同操作系统中为了能使程序和数据库都能正常运行,最好的办法是在设计表的时候都转为小写!!

30 having和where的区别?

  “Where”是一个约束声明,在查询数据库的结果返回之前对数据库中的查询条件进行约束,即在结果返回之前起作用,且where后面不能使用“聚合函数”;

  where后面之所以不能使用聚合函数是因为where的执行顺序在聚合函数之前

  “Having”是一个过滤声明,所谓过滤是在查询数据库的结果返回之后进行过滤,即在结果返回之后起作用,并且having后面可以使用“聚合函数”。
having既然是对查出来的结果进行过滤,那么就不能对没有查出来的值使用having

  聚合函数是比较where和having的关键

31 游标的作用和使用

1 作用: 用来存储查询结果集的
2 使用: 遍历游标中的数据, 相当于有一个指针指向游标中的第一行数据,每获取一行记录,指针向下移一行
3 语法格式

1 声明游标

  • 1 格式:declare cursor_name cursor for select_statement
  • 2 格式介绍
    • 1 cursor_name:游标名称,存储sql语句执行的结果
    • 2 select_statement:sql语句

2 打开游标

  •  格式:open cursor_name;

3 遍历游标中的数据

  • 1 介绍:相当于有一个指针指向游标中的第一行数据,每获取一行记录,指针向下移一行
  • 2 格式
    • fetch cursor_name into var_name [, var_name] ...
  • 3 格式介绍
    • 1 一行fetch只能获取游标中的一行记录,并把记录中每一列的值赋值给var_name
    • 2 一个var_name保存一行记录中一个列的值,若有多个列,需要多个变量
    • 3 要输出游标中的所有数据,需要使用循环语句

4 关闭游标

  •  格式:close cursor_name;

32 如何使用数据库中的定时器, 触发器, 定时任务?

定时器

  自 MySQL5.1.6起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录、对数据进行汇总等等),来取代原先只能由操作系统的计划任务来执行的工作
  更值得 一提的是MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精 确到每分钟执行一次
  可将一些数据库操作定时任务,从程序中挪到数据库中进行操作,可大大提升执行效率

触发器

触发器是mysql5新增的功能,触发器和存储过程一样,都是嵌入到mysql的一段程序。(备注如果after触发器执行失败事务会回滚)

定时任务

mysql怎么让一个存储过程定时执行
查看event是否开启: show variables like '%sche%'; 或者 SHOW VARIABLES LIKE 'event_scheduler';

OFF表示关闭。那么,可以使用 sql去开启事件执行

SET GLOBAL event_scheduler = ON;

到此就可以定时执行执行的过程。

将事件计划开启: set global event_scheduler=1;
关闭事件任务: alter event e_test ON COMPLETION PRESERVE DISABLE;
开户事件任务: alter event e_test ON COMPLETION PRESERVE ENABLE;

33 oracle中如何实现递归查询?

1 oracle中的递归查询采用的语法为 start with 。。。 connect by ..... = prior ....

2 sql语句

SELECT * FROM tree START WITH id = 2 CONNECT BY PRIOR pid = id -- 递归查询父节点
union
SELECT * FROM tree START WITH id = 2 CONNECT BY pid = PRIOR id; -- 递归查询子节点

34 高并发下如何保证修改数据安全?

Mysql中的有两种方法:

  select…for update或lock in share mode

Select...for update的实现方式:
set autocommit =0;//关闭自动提交
begin;//开始事务
select * from order where id=989879 for update;//查询信息
update order set name='names';//修改信息
commit;//提交事务
执行select…for update时,一般的SELECT查询则不受影响。

 

Lock in share mode的是实现方式:
set autocommit =0;//关闭自动提交
begin;//开始事务
select * from order where id=989879 lock in share mode;//锁定查询的字段
update order set name='names';//修改信息
commit;//提交事务

  lock in share mode或select…for update是在事务内起作用的,涉及行锁的概念。能保证当前session事务锁定的行不被其他session所修改。
前者属于共享锁,允许其他事务添加共享锁,不允许其他事务修改或者加排它锁。后者属于排它锁,不允许其他事务添加共享锁和排它锁,也不允许修改。
  一般情况下推荐使用select…for update。使用lock in share mode时需要注意死锁的问题,就是如果两个session同时对一行加锁,那么将无法执行修改,必须等一个session退出以后才能执行。
  如果有两个session加锁后同时修改一行,那么将有一个session被引擎强制关闭并重启,这样另一个session的修改就可以顺利执行
  如果只有一个session修改,另一个session不做修改动作,那么这个尝试修改的session将会一直等待锁被释放才能继续执行。

  乐观锁: 版本号

  悲观锁: for update

35 oracle中如何实现主键自增?

1 oracle中没有自增字段,可通过序列+触发器间接实现
2 实现

1 建立数据表
2 创建自动增长序列

create sequence seq_tb_user
minvalue 1
nomaxvalue
start with 1
increment by 1
nocycle --一直累加,不循环
--nocache; --不缓存
cache 10; --缓存10条

3 创建触发器

CREATE OR REPLACE TRIGGER tr_tb_user
BEFORE INSERT ON tb_user FOR EACH ROW WHEN (new.id is null)
begin
select seq_tb_user.nextval into:new.id from dual;
end;

4 提交

36 delete误删数据没有备份怎么恢复?

1 mysql可以通过日志记录进行恢复

1 将日志记录中的sql语句重新执行一次
2 找到mysql的data目录下的mysql-bin.00000X文件,类似这种的,应该有很多个,因为配置时候文件名可以配,所以不保证一定是这样的,要是不一样应该也很好找,就是有一组有规律XXXX.00000X文件就是了。
3 将日志文件导出成sql文件,方法是在命令行窗口下(其实就是cmd窗口)调用mysql的bin目录mysqlbinlog程序
  mysqlbinlog --start-date="2013-10-01 00:00:00" --stop-date="2013-12-12 12:00:00" E:\mysql-5.5.21-win32\data\mysql-bin.000067 > e:\67.sql

2 可以使用数据库闪回

37 oracle死锁如何处理?

1 一般情况下,只要将产生Oracle死锁的语句提交就可以了,但是在实际的执行过程中。用户可能不知道产生死锁的语句是哪一句。可以将程序关闭并重新启动就可以了
2 查找Oracle死锁的进程:kill掉这个Oracle死锁的进程

3 查看数据库中那些用户产生了锁,杀掉ORACLE进程,查找并杀死死锁的进程

 

posted @ 2021-07-13 22:05  mini9264  阅读(75)  评论(0编辑  收藏  举报