(更新至2016.10.14r)SQL语法知识巩固
2016.10.14r
1.什么是数据持久层?
持久层,又叫数据访问层。是和数据库直接打交道的层,所有增删改查的操作全在这个层里。
数据持久层是位于业务逻辑层和数据库之间,用于存储数据的一个模块。把数据持久层单独作为J2EE体系的一个层提出来的原因就是能够在对象-关系数据库之间提供一个成功的企业级映射解决方案,尽最大可能弥补这两种范例之间的差异,其目的是通过持久层的框架将数据库存储从服务层中分离出来是,自己接触到的持久层框架主要是,直接自己编写JDBC等SQL语句;
JDBC的全称是Java DataBase Connectivity,即Java数据库连接。它是一套行业标准的API,可以在Java应用程序中与关系型数据库建立连接,并执行相关操作,例如Oracle,DB2等主流数据库产品。
2.PL/sql与普通sql的区别?
普通sql它不面向过程,即前一条语句与后一条语句无关。
PL/SQL,Oracle对SQL标准的扩充,增加了面向过程的功能,所以可以用来编写存储过程、存储函数、触发器等等。
3.数据库优化之——i/o开销和cpu开销分别是什么?过大时如何解决?
- i/o开销表示的是 在写入文件和读取文件时候的压力值。io大会对磁盘造成压力影响性能;
- cpu开销,当一条SQL发送给数据库服务器后,系统首先会将SQL字符串进行hash运算,得到hash值后再从服务器内存里的SQL缓存区中进行检索,如果有相同的SQL字符,并且确认是同一逻辑的SQL语句,则从共享池缓存中取出SQL对应的执行计划,根据执行计划读取数据并返回结果给客户端。
如果在共享池中未发现相同的SQL,**则根据SQL逻辑新生成一条执行计划并保存在SQL缓存区中,然后根据执行计划读取数据并返回结果给客户端。如果每条SQL都会产生执行计划,这样会导致共享池耗尽,缓存命中率也很低。
解决方法是:使用绑定变量
2016.10.12r
1.如何将某个字段中的值清空?如何删除某个表中的字段?
UPDATE table_name set filed_name='';
Alter TABLE table_name DROP COLUMN field_name;
Alter TABLE table_name DROP (field_name1,field_name1);同时删除两个字段。
2.oracle的执行计划中表的链接方式有几种,分别适用在什么情况下?
在日常基于数据库应用的开发过程中,我们经常需要对多个表或者数据源进行关联查询而得出我们需要的结果集。那么Oracle到底存在着哪几种连接方式?
-
(1)嵌套循环连接(nested loop)
嵌套循环连接的工作方式是这样的:
1、 Oracle首先选择一张表作为连接的驱动表,这张表也称为外部表(Outer Table)。由驱动表进行驱动连接的表或数据源称为内部表(Inner Table)。
2、 提取驱动表中符合条件的记录,与被驱动表的连接列进行关联查询符合条件的记录。在这个过程中,Oracle首先提取驱动表中符合条件的第一条记录,再与内部表的连接列进行关联查询相应的记录行。在关联查询的过程中,Oracle会持续提取驱动表中其他符合条件的记录与内部表关联查询。 -
(2)哈希连接(hash join)
哈希连接分为两个阶段,如下。
1、 构建阶段:优化器首先选择一张小表做为驱动表,运用哈希函数对连接列进行计算产生一张哈希表。通常这个步骤是在内存(hash_area_size)里面进行的,因此运算很快。
2、 探测阶段:优化器对被驱动表的连接列运用同样的哈希函数计算,得到的结果与前面形成的哈希表进行探测返回符合条件的记录。这个阶段中如果被驱动表的连接列的值没有与驱动表连接列的值相等的话,那么这些记录将会被丢弃而不进行探测。
哈希连接只适用于等值连接。 -
(3)** 排序合并连接(merge join)**
在排序合并连接中是没有驱动表的概念的,两个互相连接的表按连接列的值先各自排序,排序完后形成的结果集再互相进行合并连接提取符合条件的记录。相比嵌套循环连接,排序合并连接比较适用于返回大数据量的结果。
排序合并连接在数据表预先排序好的情况下效率是非常高的。
3.数据库的性能优化方法有哪些?
(1)传统的有:
- 建立分区表;
一般而言,数据库的读写操作的数量级是不一样的,读操作要远远多于写操作,而读操作需要查找到对应的数据行才行,因此为了加快读操作,数据库会为表数据创建索引。但是有利必有弊,创建索引会带来额外的存储成本,尤其是在海量数据的情况下,索引会很庞大,增删改操作都有可能会引发索引结构的变动,反而得不偿失。而分库分表或分区表技术的本质,就是将庞大的数据表划分多个表,规避了之前所说的弊端。
- 建立索引;
- 适当冗余
- 返回更少数据(不必要的字段)
(2)其他方法:
- 存储过程,如果采用存储过程你可以将整个业务逻辑封装在存储过程里,然后在客户端直接调用存储过程处理,这样可以减少数据库交互的成本。
- 减少应用和数据库的交互次数。如一次插入一个sql语句,若有10000条则要执行10000次,对于DML语句(insert,delete,update等)使用batch操作。
2016.10.10r
1.事务型数据库与分析型数据库的特征及二者区别?
-
事务型数据库主要是实时的,面向应用的数据库,响应及时性要求很高,只关注最近一段时间的数据。就是平时搭建的服务都叫事务型数据库。
-
分析型数据库主要是用于在大量数据中分析规律的,一般存储的数据时间跨度长,数据量大,对实时性要求不高,通过查询分析规律趋势,用于产品决策等,如数据仓库。
两者所面向的目标不一样。
2016.10.7r
国庆假就这样快结束了,真不知道后面自己能够去哪里。不过始终保持乐观吧,总在变的更好一点。
1.关于乐观锁和悲观锁的区别?
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据(包括读或者写数据)的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
2.如何命令启动数据库?
net start mysql
3.oracle中如何查看执行计划?
explain plan for select t.*, t.rowid from A5 t where t.l = '101214' and t.k like '%8号' order by i ;
2016.9.29r
中午等外卖的时候看到两个问题,一是数据库事务,二是EM算法,于是随便查了一下。
下午快四点,自己中期答辩结束,后面自己还是要细化一点,不然真的一点创新没有,缺乏思考。
(更新至2016.10.14r)SQL语法知识巩固
2016.9.23r更新
今天去面金蝶的数据库支持岗位,问了很多数据库开发方面的问题,这里再整理学习一下。
-
1.java和c++都是面向对象的语言,为什么很多开发都用java不用c++?
java的平台兼容性更好,使得代码的可利用性和移植性非常好。 -
2.数据库中字段的冗余会导致什么问题,属于违反了第几范式?
第一范式(1NF):指数据库表的每一列都是不可分割的基本数据项。
第二范式(2NF):要求非主键列必须依赖于主键列。(在有些时候,表连接会让计算机做大量的匹配和计算,是比较消耗资源(资源主要是指CPU和内存)。为了提高效率,所以可以违反2NF,出现字段冗余,比如班级(班级编号,班级名称)表,对应带来的问题是可能导致数据的不一致性。)
第三范式(3NF): 非主键列之间必须相互独立 - 3NF可以不满足 -
3.数据库的优化
主要有基于规则的优化(rules)、基于成本的优化(cost)
1)基于规则的优化
通常是基于表查询的优化,方法有:选择最有效率的表顺序,避免select *的出现,用TRUNCATE替代DELETE等
2)基于成本的优化
适当的冗余,增加计算列,提高数据库的运行效率;
建立索引;
存储过程、视图、函数的适当使用;
数据库的表越少越好,表的字段越少越好; -
4.删除一个基本表后,则与基本表相关的:数据和索引也会被删除,视图还存在只是不能用了。
2016.9.22r更新
以后关于sql的知识点就都在这里更新了,今天早上做了数据库支持的一些题目,有以下知识点需要注意。
-
1、下面两个语法是错误的:
age=NULL;age =(select age from table where...) -
2、系统自定义的存储过程
sp_helpdb:用于报告有关指定数据库或所有数据库的信息。 -
3、视图中进行insert、delete、update是否可行
1)insert, 视图中不能包含多个字段值的组合,或者包含使用统计函数的结果。 视图中不能包含DISTINCT或GROUP BY子句。
2)delete, 当一个视图由两个以上基表构成时,不允许删除视图中的数据。
3)update,当Oracle数据库中对于单一表查询创建视图,且不带统计函数,可以进行update;对于多表查询创建视图,不能直接update。 -
4、统计函数sum(),avg(),max()均能忽略字段中的空值,但是count()不能
-
5、sql中变量的赋值
1)局部变量以一个@符号开头。
set @variable_name = value
select @variable_name = value
2)全局变量以两个@@符号作为开头。
set @@variable_name = value,改变全局变量的前提是有super权限
那么使用select和set赋值的区别在于:
返回一行值时用select和set均可以,返回多行时只能用select。
2016.9.20r更新
问题:如果数据库中某张表的数据量很大,那么在建表的时候就要去考虑查询优化的问题,有什么办法?
可以建立索引、建立分区表、设计并行查询,增快查询速度。
(主要讲建立索引为什么可以增快查询速度)
首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。
那么在任何时候都应该加索引么?或者有什么缺点?
这里有几个反例:
- 1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。
- 2、对非唯一的字段,例如“性别”这种大量重复值的字段(这种情况叫可选择性不强),增加索引也没有什么意义。
其解决方法是:使用联合索引
普通建立索引:
create index Stuname on student(name);
以title中的name和title创建索引:
CREATE INDEX idxtitle ON title (title,name) - 3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存储空间的。
- 4、最后还有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新。
2016.9.19r更新
- 1)左连接、右连接、inner连接,full连接
- 2)修改表:
alter table 教师 add 奖金 int
alter table 教师 drop 奖金
alter table 教师 rename 奖金 to 津贴 -
3)表权限的赋予:
1.png - 4)怎样清空表数据,但不删除表结构
delete from tablename或者delete * from table_name
truncate table tablename - 5)外键能不能为空
外键可以为空,为空表示其值还没有确定;
如果不为空,刚必须为主键相同。
1、根据原始表,找出有重复
购买行为的用户id,产品代码,行为类型(申购,认购,定投等)
#其中知识点:
-直接select distinct * 可以筛去所有重复的记录;
-统计每一条重复记录出现的次数,直接用:
select xx,xx,xx,xx,count(*) from table group by xx,xx,xx,xx
--由于导入到数据库之后,所有的数据不知道怎么全增加了两倍,所以先去重并放入ceshi_temp1表中
/*create table ceshi_temp1 as
(select distinct * from ceshi);*/
--找出多次购买的用户id,和基金代码
--create table ceshi_temp2 as
select cus_id,jjdm from ceshi_temp1
where ywdm in ('120','122','139','137')
group by cus_id,jjdm
having count(cus_id)>=2;
--根据有多次购买行为的用户id,反过来找出所有的购买行为信息
select a.cus_id, a.jjdm, a.ywdm,count(*)
from ceshi_temp1 a,
ceshi_temp2 b
where a.cus_id =b.cus_id
group by a.cus_id, a.jjdm, a.ywdm
order by a.cus_id
2、group by 和 over partition by的区别
二者均是统计函数,但 over partition by能够更详细的展现筛选出来的函数的明细。
NAME DEPT SALARY
A 10 1000
B 10 2000
C 20 1500
D 20 3000
E 10 1000
用over partition by 我就可以查询到每位员工本来的具体信息和它所在部门的总工资:
select name,dept,salary,sum(salary) over (partition by dept) total_salary from salary;
name dept salary tatal_salary
A 10 1000 4000
B 10 2000 4000
E 10 1000 4000
C 20 1500 4500
D 20 3000 4500
用goup by 就没办法做到这点,只能查询到每个部门的总工资:
select dept,sum(salary) total_salary from salary group by dept
dept total_salary
10 4000
20 4500