数据库面试篇

0、数据库三个范式。

1.第一范式:列不可再分;

2.第二范式:行可以唯一区分,主键约束

3.第三范式:表的非主属性不能依赖与其他表的非主属性;

4.外键约束 且三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上;

0、数据库性能优化有哪些方式?

SQL 优化:

1.尽量避免使用 SELECT    *

2.只查询一条记录时使用 limit 1

3.使用连接查询代替子查询;

4.尽量使用一些能通过索引查询的关键字。

表结构优化:

1.尽量使用数字类型字段,提高比对效率;

2.长度不变且对查询速度要求高的数据可以考虑使用 char,否则使用 varchar;表中字段过多时可以适当的进行垂直分割,将部分字段移动到另外一张表;表中数据量过大可以适当的进行水平分割,将部分数据移动到另外一张表。

其它优化:

        对查询频率高的字段适当的建立索引,提高效率;根据表的用途使用合适的数据库引擎;读写分离。

1SQL查询出来的结果分页展示一般怎么做?

Oracle

select * from  (select *,rownum as tempid from student )  t 
where t.tempid between
+ pageSize*(pageNumber-1) + and + pageSize*pageNumber

MySQL

select * from students limit + pageSize*(pageNumber-1) + , + pageSize;

sql server:

select top + pageSize + * from students where id not in + 
(select top
+ pageSize * (pageNumber-1) +  id from students order by id)+order by id;

1查询语句中select from where group by having order by的执行顺序

from--where--group by--having--select--order by

HQL语句如果连接超时或者出现异常怎么办?让事务回滚,在回滚时加上try catch语句

1、索引定义,优缺点?

索引:是对数据库表中一列或多列的值进行排序的一种存储结构。索引的作用相当于图书的目录,可以根据目录中页码快速找到所需的内容。索引的实现通常使用B树及其变种B+

索引优点:

1.加快查询速度。

2.唯一索引保证每一行数据的唯一性。

3.在使用order bygroup by 子句进行数据查询时,可以减少排序和分组的时间。

索引缺点:

1.索引需要占用物理空间;

2.当对表中的数据进行增加,删除和修改时,索引也要时时维护,降低了数据维护速度。

3.索引减慢了数据录入的速度,同时增加了数据库的尺寸大小。

2、索引类型?

主键索引:数据记录里面不能有 null,数据内容不能重复,在一张表里不能有多个主键索引。 
普通索引:使用字段关键字建立的索引,主要是提高查询速度。 
唯一索引:字段数据是唯一的,数据内容里面能否为 null,在一张表里面,是可以添加多个唯一索引。 
全文索引:在比较老的版本中,只有 myisam 引擎支持全文索引,在 innodb5.6后引擎也支持全文索引,在 mysql 中全文索引不支持中文。我们一般使用 sphinx 集合coreseek 来实现中文的全文索引。

聚集索引 :在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。

3、使用索引查询一定能提高查询的性能吗?为什么?

通过索引查询数据比全表扫描要快,但也不是绝对的;

原因:

1. 索引需要空间来存储,也需要定期维护;

2. 每当有记录在表中增减或索引列被修改时,索引本身也会被修改. 这意味着每条记录的insert,delete,update将为此多付出4,5 次的磁盘input/output.

3. 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.使用索引查询不一定能提高查询性能。

4、索引范围查询(index range scan)适用于两种情况:

(1)基于一个范围的检索,一般查询返回结果集小于表中记录数的30%;

(2)基于非唯一性索引的检索(索引就是为了提高查询性能而存在的,如果在查询中索引没有提高性能,只能说是用错了索引,或者讲是场合不同);

5、什么样的字段适合建索引?

1.唯一;2.不为空;3.经常被查询的字段

5、列举 创建索引但是无法命中索引的8种情况。

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)

2.对于多列索引,不是使用的第一部分,则不会使用索引

3.like查询是以%开头

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

6 对小表查询

7 提示不使用索引

8 统计数据不真实

9.单独引用复合索引里非第一位置的索引列.

4. 对于那些定义为text, image和bit数据类型的列不应该增加索引;

5、索引在什么情况下遵循最左前缀的规则?

在使用组合索引查询的时候需要遵循最左前缀规则
最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(><betweenlike)就停止匹配,比如a = 1 and b = 2 and c > 3 and d= 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。=in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。

6、视图定义,视图作用?

视图:SELECT语句组成的查询定义的一张或多张表中的数据组成的虚拟表

视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化。

视图作用:如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询; 
视图本质上就是一条SELECT语句,所以当访问视图时,只能访问到所对应的SELECT语句中涉及到的列,对基表中的其它列起到安全和保密的作用,可以限制数据访问。

7、视图的优缺点?

优点:

1)对数据库的访问,视图可以有选择性的选取数据库里的一部分。

2)用户通过简单的查询可以从复杂查询中得到结果。

3)维护数据的独立性,试图可从多个表检索数据。

4) 对于相同的数据可产生不同的视图。可以控制权限

缺点:查询视图时,必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,那么就无法更改数据;

8、视图的使用场景有哪些?

1.把多个表查询结果联合起来; 2.查询的数据来源于不同的表。

9、表和视图的关系?

1.视图就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据。

2.表就是关系数据库中实际存储数据用的。

10、存储过程定义,存储过程优缺点?

存储过程:SQL 语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。(是针对比较复杂的sql业务处理。复杂的表操作,业务复杂对表涉及的改动量多的时候一般会用,就是由sql累积组成,存储过程也有回滚和提交事务的。存储过程用在一般固定的业务处理,因为它灵活性比较差。)

游标就像是for循环,或是行标,就比如说数组的下标。

存储过程优点:

1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。

2.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。而这些操作,如果用程序来完成,就变成了一条条的 SQL 语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。

3.存储过程可以重复使用,可减少数据库开发人员的工作量。

4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权。 

存储过程的缺点 
1. 可移植性差 
2. 占用服务器端多的资源,对服务器造成很大的压力 
3. 可读性和可维护性不好 

11、存储过程用什么来调用?

1)可以用一个命令对象来调用存储过程;

2)可以供外部程序调用;

12、函数的定义

通常是数据库中已经定义的方法,他接收参数并返回某种类型,并且语句中有返回语句return 变量; 

13、游标的定义

是查询结果返回的结果集首地址指针。可以定义ref引用游标,依次取得记录并批量操作。

(是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改)。

游标的作用?如何知道游标已经到了最后?
游标用于定位结果集的行,通过判断全局变量@@FETCH_STATUS可以判断是否到了最后,通常此变量不等于0表示出错或到了最后。

14、怎样创建一个存储过程, 游标在存储过程怎么使用, 有什么好处

附:存储过程的一般格式,游标使用参考问题 

1 .使用游标可以执行多个不相关的操作.如果希望当产生了结果集后,对结果集中的数据进行多种不相关的数据操作 
2. 使用游标可以提供脚本的可读性 
3. 使用游标可以建立命令字符串,使用游标可以传送表名,或者把变量传送到参数中,以便建立可以执行的命令字符串. 
但是个人认为游标操作效率不太高,并且使用时要特别小心,使用完后要及时关闭 

15、存储过程与函数的区别?

1.存储过程声明用procedure,函数声明用function;

2.存储过程声明时不需返回类型,函数声明时要返回类型,而且至少要包括一个有效的return语句;

3.存储过程可作为一个独立的PL/SQL语句来执行,函数不能独立执行,必须作为表达式的一部分调用;

4.存储过程在SQL语句(DML 或SELECT)中不可调用,函数SQL语句(DML 或SELECT)中可以调用;

16、使用存储过程访问数据库比直接用SQL语句访问有哪些优点?

存储过程是预编译过的,执行时无须编译,执行速度更快;存储过程封装了一批SQL语句,便于维护数据的完整性与一致性;可以实现代码的复用。

17、触发器的作用?

触发器是一种特殊的存储过程,主要是通过事件来触发而被执行的

1.可以强化约束,来维护数据的完整性和一致性;

2.可以跟踪数据库内的操作从而不允许未经许可的更新和变化;

3.可以联级运;如某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。

18、触发器的作用,什么时候用触发器,创建触发器的步骤,触发器里是否可以有commit, 为什么?

 触发器是可以由事件来启动运行的,存在于数据库服务器中的一个过程。他的作用:可以实现一般的约束无法完成的复杂约束,从而实现更为复杂的完整性要求。使用触发器并不存在严格的限定,只要用户想在无人工参与的情况下完成一般的定义约束不可以完成的约束,来保证数据库完整性,那么就可以使用触发器。

由于触发器主要是用来保证数据库的完整性的,所以要创建一个触发器,首先要明确该触发器应该属于那一种(DML,INSTEAD OF,SYSTEM)因为他们各有个的用途;其次就是要确定触发器被触发以后所设计到的数据。

触发器中不可以使用COMMIT

19、约束

约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性

19、什么是事务?选择熟悉的数据库实现一个事务处理,如信用卡提款.

事务:就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,要么全部执行,要么全部不执行,要将分组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性;定义事务的SQL语句有:BEGIN TRANSACTION,COMMIT,ROLLBACK。

        原子性:就是事务所包含的数据库操作要么都做,要么都不做. 

  一致性:是事务原子性的体现,事务所对应的数据库操作要么成功要么失败没有第三种情况。事务不管是提交成功与否都不能影响数据库数据的一致性状态。

  隔离性:事务对数据的操作不能够受到其他事务的影响。

  持续性:也就是说事务对数据的影响是永久的。

  对信用卡提款这一事务而言就是要保证’提取到现金’和’卡帐号余额’的修改要同时成功或失败.

  BEGIN TRANSACTION

    读取A的帐户余额BALANCE

    BALANCE=BALANCE-AMOUNT转帐金额

    IF(BALANCE<0)

      THEN ROLLBACK

    ELSE BEGIN

      将A的新余额写回

      读取B的帐户余额BALANCEB

      BALANCEB=BALANCEB+AMOUNT转帐金额

      将B的新余额写回

      COMMIT

    END IF

END

19、数据库事务及隔离级别

隔离级别:脏读、幻读、一致读、不可重复读、更新丢失

1.脏读(Dirty Reads:一个事务开始读取了某行数据但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险很可能所有操作都被回滚

2.幻读(Phantom Reads:也称为幻像(幻影)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的

3.不可重复读(Non-repeatable Reads:一个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交

4.两次更新问题(Second lost updates problem:无法重复读取特例,有两个并发事务同时读取同一行数据然后其中一个对它进行修改提交而另一个也进行了修改提交这就会造成第一次写操作失效

5.更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔离开

20、锁是什么?

锁:在所有的DBMS(数据库管理系统)中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。

锁分为行级锁和表锁。

行级锁:主要是在执行操作过程中,锁定指定的行。

主要的锁行语句有:insert ,update,delete ,及select ....for update。

表锁:指在运行操作指令过程中,由用户指定锁定某张表。lock table  XXX in mode share;

共享锁,排他锁,共享排它,行共享,行排他。

锁模式包括

共享锁:(读取)操作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。

排他锁(X锁):对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

更新锁:更新 (U) 锁可以防止通常形式的死锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则两个事务需都要转换共享锁为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。
若要避免这种潜 在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。 

锁的粒度主要有以下几种类型:

行锁: 粒度最小,并发性最高

页锁:一次锁定一页。25个行锁可升级为一个页锁。

表锁:粒度大,并发性低

数据库锁:控制整个数据库操作

乐观锁:乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。一般的实现乐观锁的方式就是记录数据版本

悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁等,都是在做操作之前先上锁

20、数据库的乐观锁和悲观锁是什么? oracle 是行级锁

数据库管理系统(DBMS)中,并发控制的任务是:确保在多个事务同时存取同一数据时,不破坏事务的隔离性和统一性以及数据库的统一性。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

21、悲观锁和乐观锁的区别,怎么实现

悲观锁:一段执行逻辑加上悲观锁,不同线程同时执行时,只能有一个线程执行,其他的线程在入口处等待,直到被释放。

乐观锁:一段执行逻辑加上乐观锁,不同线程同时执行时,可以同时进入执行,在最后更新数据的时候要检查这些数据是否被其他线程修改了(版本和执行初是否相同),没有修改则进行更新,否则放弃本次操作。

悲观锁的实现:

//0.开始事务

begin;/begin work;/start transaction; (三者选一就可以)

//1.查询出商品信息

select status from t_goods where id=1 for update;

//2.根据商品信息生成订单

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status2

update t_goods set status=2;

//4.提交事务

commit;/commit work;

乐观锁的实现

1.查询出商品信息

select (status,status,version) from t_goods where id=#{id}

2.根据商品信息生成订单

3.修改商品status2

update t_goods 

set status=2,version=version+1

where id=#{id} and version=#{version};

21、什么是线程死锁?死锁如何产生?如何避免线程死锁?

死锁的介绍:

线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。

死锁的产生的一些特定条件:

1、互斥条件:进程对于所分配到的资源具有排它性,即一个资源只能被一个进程占用,直到被该进程释放

2、请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。 

3、不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用。

4、循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。

如何避免:

1、加锁顺序:

当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。当然这种方式需要你事先知道所有可能会用到的锁,然而总有些时候是无法预知的。

2、加锁时限:

加上一个超时时间,若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。但是如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁。

3、死锁检测:

死锁检测即每当一个线程获得了锁,会在线程和锁相关的数据结构中(mapgraph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。

22、序列的作用

1.Oracle使用序列来生成唯一编号,用来处理一个表中自增字段。

2.Oracle序列是原子对象,并且是一致的。就是说,一旦您访问一个序列号,Oracle将在处理下一个请求之前自动递增下一个编号,从而确保不会出现重复值;

23、去除重复sql  

分组后筛选条件完成删除,比如: delete from 表 where id not in(select max(id) from 表 group by 重复列 ) );将数据相同的记录划分为一个组,保留组内id最大的记录

23、内连接,左连接,右连接的区别

内连接:指主表,从表中符合连接条件的记录全部显示

左连接:外连接方式,主要是显示主表,从表中符合连接条件的记录,并且主表中所有不符合连接条件的记录也要显示。

 右连接:外连接方式,主要是显示主表,从表中所有符合连接条件的记录,并且从表中不符合的记录也要显示。

23、一条sql执行过长的时间,你如何优化,从哪些方面?

1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)

2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合

3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度

4、针对数量大的表进行历史表分离(如交易流水表)

5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步

6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等

7、查看mysql执行日志,看看是否有其他方面的问题

个人理解:从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去酌手考虑

 

24、什么是PL/SQL

PL/SQL是一种程序语言,叫做过程化SQL语言,是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算。

24、了解XSS攻击吗?如何防止?

XSS是跨站脚本攻击,首先是利用跨站脚本漏洞以一个特权模式去执行攻击者构造的脚本,然后利用不安全的Activex控件执行恶意的行为。

使用htmlspecialchars()函数对提交的内容进行过滤,使字符串里面的特殊符号实体化。

24、什么是SQL注入式攻击?

SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。常见的SQL注入式攻击过程类如:

⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码。

⑵ 登录页面中输入的内容将直接用来构造动态SQL命令,或者直接用作存储过程的参数。

下面是ASP.NET应用构造查询的一个例子:

  1. System.Text.StringBuilder query = new System.Text.StringBuilder(
  2.    "SELECT * from Users WHERE login = '")
  3.    .Append(txtLogin.Text).Append("' AND password='")
  4.    .Append(txtPassword.Text).Append("'");

⑶ 攻击者在用户名字和密码输入框中输入”’或’1’=’1”之类的内容。

⑷用户输入的内容提交给服务器之后,服务器运行上面的ASP.NET代码构造出查询用户的SQL命令,但由于攻击者输入的内容非常特殊,所以最后得到的SQL命令变成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。

⑸ 服务器执行查询或存储过程,将用户输入身份信息和服务器中保存身份信息进行对比。

⑹ 由于SQL命令实际上已被注入式攻击修改,已经不能真正验证用户身份,所以系统会错误地授权给攻击者。

如果攻击者知道应用会将表单中输入的内容直接用于验证身份的查询,他就会尝试输入某些特殊的SQL字符串篡改查询改变其原来的功能,欺骗系统授予访问权限。

系统环境不同,攻击者可能造成的损害也不同,这主要由应用访问数据库的安全权限决定。如果用户的帐户具有管理员或其他比较高级的权限,攻击者就可能对数据库的表执行各种他想要做的操作,包括添加、删除或更新数据,甚至可能直接删除表

24、如何防范SQL注入式攻击?

在利用表单输入的内容构造SQL命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。

⑴ 对于动态构造SQL查询的场合,可以使用下面的技术:

第一:替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改SQL命令的含义。再来看前面的例子,"SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'"显然会得到与"SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'"不同的结果。

第二:删除用户输入内容中的所有连字符,防止攻击者构造出类如"SELECT * from Users WHERE login = 'mas' -- AND password =''"之类的查询,因为这类查询的后半部分已经被注释掉,不再有效,攻击者只要知道一个合法的用户登录名称,根本不需要知道用户的密码就可以顺利获得访问权限。

第三:对于用来执行查询的数据库帐户,限制其权限。用不同的用户帐户执行查询、插入、更新、删除操作。由于隔离了不同帐户可执行的操作,因而也就防止了原本用于执行SELECT命令的地方却被用于执行INSERT、UPDATE或DELETE命令。

用存储过程来执行所有的查询。SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。

限制表单或查询字符串输入的长度。如果用户的登录名字最多只有10个字符,那么不要认可表单中输入的10个以上的字符,这将大大增加攻击者在SQL命令中插入有害代码的难度。

⑷检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端都执行——之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。

在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给服务器。因此,要保证验证操作确实已经执行,唯一的办法就是在服务器端也执行验证。你可以使用许多内建的验证对象,例如 RegularExpressionValidator,它们能够自动生成验证用的客户端脚本,当然你也可以插入服务器端的方法调用。如果找不到现成的验证对象,你可以通过CustomValidator自己创建一个。

将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了”消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入SQL命令。System.Web.Security.FormsAuthentication类有一个 HashPasswordForStoringInConfigFile,非常适合于对输入数据进行消毒处理。

检查提取数据的查询所返回的记录数量。如果程序只要求返回一个记录,但实际返回的记录却超过一行,那就当作出错处理

24SQL有哪三种注入方式?SQL安全

动态SQL拼装注入、SQL溢出漏洞、获取管理员权限、

24SQL注入的主要特点

变种极多,攻击简单,危害极大

24SQL注入的主要危害

1)未经授权操作数据库的数据                2)恶意纂改网页

3)私自添加系统账号或者是数据库使用者账号  4)网页挂木马

24SQL注入漏洞产生的原因?如何防止?

SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。

防止SQL注入的方式:

1.开启配置文件中的magic_quotes_gpc 和 magic_quotes_runtime设置

2.执行sql语句时使用addslashes进行sql语句转换

3.Sql语句书写尽量不要省略双引号和单引号。

4.过滤掉sql语句中的一些关键词:update、insert、delete、select、 * 。

5.提高数据库表和字段命名技巧,对一些重要字段根据程序的特点命名,取不易被猜到的。

6.Php配置文件中设置register_globals为off,关闭全局变量注册

7.控制错误信息,不要在浏览器上输出错误信息,将错误信息写到日志文件中。

25、谈谈你了解的数据库,有没有写过存储过程?简单说一些sql优化。

 mysql5,sqlserver2005,oracle9i,oracle10g,oracle11g,h2.

 创建存储过程格式:create or replace procedure proc_XX(a number,b out varchar2,c in out varchar2) is 变量声明;begin  ...sql语句块;end;

sql优化:1.查询操作尽量操作指定字段,条件设置时应从右到左,将明确的条件放置在右边,先执行。

 2.少用in ,is not null,is null等判断,尽量用exists,或=相应操作符。

 3.连接表查询时,以连接查询优先。少用子查询。

 4.适当用集合操作。

5.采用视图查询来屏蔽安全要求级别较高的字段或表结构。

26、数据库怎样实现每隔30分钟备份一次?

通过操作系统的定时任务调用脚本导出数据库

27、现在有一张正在使用的表,数据量为1000W,你如何做优化?

1、在查询概率高的字段上建立索引;

2、将表分区,如按月份分12个区;

3、优化SQL语句;

4、控制查询条件;

5、定期备份数据库,将过去一段时间内的数据清除。

27、怎么对数据库百万级数据进行优化?

使用读写分离技术(让主数据库(master)处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库(slave)处理SELECT查询操作)

27、怎样将一个旧数据库数据移到一个新的数据库 

1. Imp/exp将数据库中的数据导入到新的库中 

2. 如果是存储迁移直接将存储设备挂到新机器上

28、数据库的几种物理文件?

1)数据文件 2)控制文件 3)日志文件

29、在数据库中查询语句速度很慢,如何优化?

1.建索引;   2.减少表之间的关联 ;

3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面;

4.简化查询字段,对返回结果的进行控制,尽量返回少量数据 ;

5.尽量用PreparedStatement来查询,不要用Statement

30dropdeletetruncate删除的区别

1.delete和truncate只删除表的数据不删除表的结构;

2.速度: drop> truncate >delete ;

3.delete语句是dml,这个操作会进行事务提交之后才生效;

4.如果有相应触发器被触发时,truncate,drop删除不触发触发器因为它们的ddl;

5.truncate table :删除内容不删除定义,释放空间。

delete table:删除内容不删除定义,不释放空间。

drop table :删除内容和定义,释放空间。

6.delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项,TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放

drop   隐式提交,不能回滚,

删除表结构及所有从数据,将表所占空间全部释放。

删除表的结构所依赖的约束,触发器,索引,依赖于该表的存储过程/函数将保留,但是变为invalid状态。

delete 逐行删除,并且同时将该行的的删除操作记录在redo和undo表空间中以便进行回滚(rollback)和重做操作。

truncate  删除所有数据,TRUNCATE不记录日志,表结构及其列、约束、索引等保持不变。

版权声明:本文为博主原创文章,转载请附上博文链接!

32dropdeletetruncate分别在什么场景之下使用?

1.删除表时,用drop;

2.删除部分数据行时候,用delete from 表名where条件;

3.保留表而删除所有数据的时候用truncate;

33unionunion all有什么不同?  并集

union: 显示两个表的全部内容,删除重复行,相同的行在结果中只显示一次。

union all:显示两个表的全部内容,不删除重复,结果为多集,相同的数据会出现多次。

注:从效率上说,union all 要比union快很多;

34charVarchar2varchar有什么区别?

(1)char(长度):存储固定长度的字符串。

(2)varchar2(长度):存储可变长度的字符串,按实际长度存储;

(3)varchar是varchar2的同义词,工业标准的varchar类型可以存储空字符串,但是oracle不能使用,尽管它保留以后可以使用的权利。

35order bygroup by的区别   1.order by 排序;2.group by 分组;

35existsin

in是在内存里遍历比较,而exists需要查询数据库,所以当B表数据量较大时,exists效率优于in。

exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是其内查询语句的结果集空或者非空,空则返回false,非空则返回true。

外表大,用IN;内表大,用EXISTS

not in 和not exists

如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;

而not extsts 的子查询依然能用到表上的索引。

所以无论那个表大,用not exists都比not in要快。

35on where

on条件是在生成临时表时使用的条件

where条件是在临时表生成后,再对临时表进行过滤的条件

on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤

35WHEREHAVINGON的比较

WHERE和HAVING关键字都可以对查询结果进行筛选,两者的区别是WHERE的作用时间是在计算之前就完成的,而having是在计算后才起作用的。HAVING只会在检索出所有记录之后才对结果集进行过滤

ON关键字实际上也是对数据进行筛选,只不过是在多表关联时使用。需要注意的是,在我们常用的操作中,表关联是最耗时的操作之一。尤其是两张大表的关联

35、优化修改删除语句

如果你同时修改或删除过多数据,会造成cpu利用率过高从而影响别人对数据库的访问。

如果你删除或修改过多数据,采用单一循环操作,那么会是效率很低,也就是操作时间过程会很漫长。

36、什么是内存泄漏?

一般我们所说的内存泄漏指的是堆内存的泄漏。堆内存是程序从堆中为其分配的,大小任意的,使用完后要显示释放内存。当应用程序用关键字new等创建对象时,就从堆中为它分配一块内存,使用完后程序调用free或者delete释放该内存,否则就说该内存就不能被使用,我们就说该内存被泄漏了。

37、维护数据库完整性和一致性,你喜欢用触发器还是自写业务逻辑?为什么?

1)尽可能使用约束,如check,主键,外键,非空字段等来约束,这样做效率最高也最方便。

2)其次是使用触发器,这种方法可以保证,无论什么业务系统访问数据库都可以保证数据的完整新和一致性。最后考虑的是自写业务逻辑,但这样做麻烦,编程复杂,效率低下。

38、超键、候选键、主键、外键分别是什么?

1.超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。

2.候选键:最小超键,即没有冗余元素的超键。

3.主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。

4.外键:一个用来建立两个表之间关系的约束,在一个表中存在另一个表主键称此表的外键。

39、主键和外键的区别?

1.主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;

2.外键和另一张表的主键关联,不能创建对应表中不存在的外键。

39SQL语句中相关子查询非相关子查询有什么区别?

子查询:嵌套在其他查询中的查询称之。

子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。

所有的子查询可以分为两类,即相关子查询非相关子查询

(1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。

(2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。

故非相关子查询比相关子查询效率高

39、说一下关系型数据库和非关系型数据库的区别 

非关系型数据库的优势:

  1. 性能:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高
  2. 可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

使用场景:日志、埋点、论坛、博客等

关系型数据库的优势:

  1. 复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询
  2. 事务支持:使得对于安全性能很高的数据访问要求得以实现。

使用场景:所有有逻辑关系的数据存储

39、如何访问链表中间节点

对于这个问题,我们首先能够想到的就是先遍历一遍整个的链表,然后计算出链表的长度,进而遍历第二遍找出中间位置的数据。这种方式非常简单。

若题目要求只能遍历一次链表,那又当如何解决问题?

可以采取建立两个指针,一个指针一次遍历两个节点,另一个节点一次遍历一个节点,当快指针遍历到空节点时,慢指针指向的位置为链表的中间位置,这种解决问题的方法称为快慢指针方法。

40、关系数据库系统与文件数据库系统的区别在那里?关系数据库系统一般适用那些方面?

  关系数据库系统文件系统的区别在于:

  首先,关系性数据库的整体数据是结构化的,采用关系数据模型来描述,这是它与文件系统的根本区别。(数据模型包括:数据结构,数据操作以及完整性约束条件)

  其次,关系数据库系统的共享性高,冗余低可以面向整个系统,而文件系统则具有应用范围的局限性,不易扩展。

  第三,关系数据库系统采用两级映射机制保证了数据的高独立性,从而使得程序的编写和数据都存在很高的独立性。这方面是文件系统无法达到的,它只能针对于某一个具体的应用。(两级映射:保证逻辑独立性的外模式/模式映射和保证物理独立性的内模式/模式映射。外模式:用户模式,是数据库用户的局部数据的逻辑结构特征的描述。模式:数据库全体数据的逻辑结构特征的描述。内模式:也就是数据最终的物理存储结构的描述。)

  第四,就是关系性数据库系统由统一的DBMS进行管理,从而为数据提供了如安全性保护,并发控制,完整性检查和数据库恢复服务。

41、你在项目现场,用户要求你向正在运行的表中添加一个字段,你该怎么做?
第一种方法:关闭数据库,然后使用受限模式打开,由sys/sysdba来进行
第二种方法:不关闭数据库,将数据库置于静默状态在SYS/SYSDBA模式下用ALTER SYSTEM QUISCE RESTRICTED,这种状态下只有SYS/SYSDBA才可以对数据库进行操作,修改完毕之后再退出静默状态ALTER SYSTEM UNQUISCE
在这里复习到了数据库的两种特殊状态:静默状态(QUISCE)和挂起状态
静默状态就是只有特殊权限的SYS/SYSDBA才可以对数据库进行操作,使用ALTER SYSTEM QUISCE RESTRICTED以后系统将等候活动着的会话主动结束,同时阻止建立新的会话,系统挂起所有的SQL语句,等恢复以后再重新激活会话执行挂起的SQL。
挂起状态就是系统将数据库所有对物理文件(数据文件,控制文件,日志文件)的I/O操作都暂停,但是并不禁止非DBA用户对数据库进行操作。这种状态主要用于进行数据库备份、

42、数据库三范式是什么?

第一范式(1NF):

字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)

数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。

第二范式(2NF):

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。

要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。

第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。

第三范式(3NF):

满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

所以第三范式具有如下特征:

1,每一列只有一个值

2,每一行都能区分。

3,每一个表都不包含其他表已经包含的非主关键字信息。

例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。

43、数据库建表的注意事项?

一、字段名及字段配制合理性

1、剔除关系不密切的字段

2、字段命名要有规则及相对应的含义(不要一部分英文,一部分拼音,还有类似a.b.c这样不明含义的字段)

3、字段命名尽量不要使用缩写(大多数缩写都不能明确字段含义)

4、字段不要大小写混用(想要具有可读性,多个英文单词可使用下划线形式连接)

5、字段名不要使用保留字或者关键字

6、保持字段名和类型的一致性

7、 慎重选择数字类型

8、 给文本字段留足余量

二、系统特殊字段处理及建成后建议

1、添加删除标记(例如操作人、删除时间)

2、 建立版本机制

三、表结构合理性配置

1、多型字段的处理

就是表中是否存在字段能够分解成更小独立的几部分(例如:人可以分为男人和女人)

2、 多值字段的处理

可以将表分为三张表,这样使得检索和排序更加有调理,且保证数据的完整性!

四、其它建议

1、对于大数据字段,独立表进行存储,以便影响性能(例如:简介字段)

2、使用varchar类型代替char,因为varchar会动态分配长度,char指定长度是固定的。

3、给表创建主键,对于没有主键的表,在查询和索引定义上有一定的影响。

4、避免表字段运行为null,建议设置默认值(例如:int类型设置默认值为0)在索引查询上,效率立显!

5、建立索引,最好建立在唯一和非空的字段上,建立太多的索引对后期插入、更新都存在一定的影响(考虑实际情况来创建)。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值