首页 > 代码库 > 数据库相关

数据库相关

【数据库系统概述】
常用的数据库有MySql、oracle等。不同数据库都支持sql标准,并且不同数据库在sql标准的基础上进行了一些扩充。
对于数据库的学习包括:sql>过程、触发器等内容,其中重要程度如下:
sql>过程、触发器等
oracle数据库:
1、oracle的开发部分,包含两个部分:sql+plsql编程
2、oracle管理部分,数据库配置和运行维护
【oracle简介】
oracle默认有sys和system两个用户,其中
sys: 超级管理员,拥有操作数据库的所有权限
system:普通管理员
注意:安装oracle后会出现多个服务,可以设置为手动启动
重要的两个服务为:
1、数据库监听服务,如果要通过远程客户端(如sql develop等)连接数据库,或者直接用程序连接数据库,那么此服务必须打开
2、数据库实力服务:每个数据库都会有这种服务名称如:OracleServiceSID
【sqlplus简介】
sqlplus 首先将sql语句放到缓冲区,然后将缓冲区的sql语句提交到数据库执行;
oracle12c 之中默认数据找不到,需要对数据进行恢复,找scott.sql文件目录下为数据
通过修改SCOTT.sql修改恢复数据
数据配置执行顺序为:
1、打开sqlplus /nolog
2、运行C##scott.sql
【sqlplus 常用命令】
1、格式化命令:
数据显示出现换行问题,出现数据分页:
1、首先要解决屏幕宽度:set linesize 300
set pagesize 30
2、方便编写长数据库脚本,可以调用记事本:ed,可以在技术本中编辑查询命令,随后可以使用@ 标记执行数据库脚本
sqlplus执行sql脚本的方法:使用@+脚本
3、连接操作
用户之间可以互相切换
CONN 用户名/密码【as sysdba】
可以通过show user查询当前用户
在sys中查询Scott中的表,需要添加用户名在表明前
select * from tab;查询所有的表
查看数据表的结构DESC:desc emp;
执行host命令:host+命令
host dir;

关于原始用户的问题:
恢复原始数据:
1、登陆sys用户: conn sys/Oracle123456 as sysdba
2、查看现在的容器名称:show con_name;
返回值为:CDB$ROOT 为一个CDB容器
3、改变容器为PDB: alter session set container=pdborcl;
4、打开pdb数据库:
alter database pdborcl OPEN;
5、查看用户
打开sh和scott用户
6、切换回cdb
alter session set container=cdb$root


语法:
SELECT[DISTINCT] *|列名 [as] 列别名,列名 [as] 列别名.... FROM 表名 表别名
使用as设置别名,别名最好不要使用中文
简单查询中两个字句:
1、select字句
distinct 表示去除重复列,仅限于所有列的内容都相同
2、from子句
关于字句的执行顺序:
1、from字句,确定数据来源
2、select字句,确定要显示的列
select中的四则运算:
当参与运算的数值中含有null值时,结果返回为null
查询月薪、日薪等
select sal+comm msal from emp;
添加常量列:
select ‘y‘ as cl from emp;
利用“||”进行字符串连接
select ‘编号是:‘||empno||‘姓名是:‘||ename from emp; 字符串是用单引号引起来
【限定查询】

1、语法:
SELECT[DISTINCT] *|列名 [as] 列别名,列名 [as] 列别名.... FROM 表名 表别名 where 条件语句
连接多个条件的逻辑运算符:and or not

限定查询有三个字句,执行步骤为:
1、执行from字句,来控制数据的来源
2、执行where字句,使用限定对数据行过滤
3、执行select字句,来确定数据列

常用限定运算符:
1、关系运算符,确定大小相等关系的比较
select * from emp where sal《=2000
select * from emp where ename=‘smith‘
在使用关系运算符判断字符串时需要注意大小写,并且字符串用单引号;字符串可以直接用“=”比较
不等于符号“<>”和"!="两种操作形式
select * from emp where ename!=‘JAMES‘;
select * from emp where ename<>‘JAMES‘;
工资范围1500到3000
select * from emp where sal>1500 and sal<3000;
销售人员基本工资高于1200
select * from emp where sal>1200 and job=‘saleman‘;

范围查询
between and 操作符 包含最大值和最小值
查询出1981年雇员的全部信息;则范围是1981-1-1--1987-12-31
select * from emp where hiredate between ‘01-1月-81‘ and ‘31-12月-81‘;

判断内容是否为null:IS NULL/IS NOT NULL(只能这样判断)
注意:null不能用等号判断
select * from emp where empno=7369 and comm is null;

列表范围查找:IN/NOT IN
所谓列表范围是指给定了用户的几个值,必须在这些值范围内
select * from emp where empno IN(7369,7788);
select * from emp where empno not IN(7369,7788);
注意:
关于null的问题,如果在in操作符中包含null;不会影响最终的查询结果,如果在not in中包含null,直接的后果是没有任何数据显示
select * from emp where empno not IN(7369,null);数据库系统的限制,not in 中有null不返回任何值

【模糊查询】
like/not like
like字句中可以使用连个通配符:
百分号%:可以匹配任意类型和长度的字符,如果是中文则使用两个百分号%%;(出现一次0次或者多次)
下划线_:匹配单个任意字符,它常用来限制表达式的长度(出现一次)

以J开头的:
select * from emp where ename LIKE ‘J%‘;
查询字母中任意位置包含J,前后都有的问题用百分号
select * from emp where ename LIKE ‘%J%‘;
名字长度大于六个字符的:
select * from emp where ename like‘_____%‘;
LIKE可以用于数字或者时间类型上面,关键字为空表示查询全部

【数据排序显示】
order by 默认升序
传统数据查询的时候只会设置的逐渐排列,如果希望对指定的列进行排序,就需要使用order by 排序
语法:
SELECT[DISTINCT] *|列名 [as] 列别名,列名 [as] 列别名.... FROM 表名 表别名 where 条件语句 order by ASC|DESC
ASC:升序
DESC:降序
在所有sql字句中order by是放在查询语句的最后一行,是最后一个执行的字句,
select * from emp where sal>1000 order by sal asc;
范例:按照工资高到底排序,工资相同,按照雇佣日期早到晚
select * from emp order by sal desc,hiredate;

【单行函数】
语法:
function_name[列] 表达式[参数1,参数2]
单行函数主要分为以下几种:
1、字符函数
以字符数据为主(字符串)
UPPER()和LOWER()函数转换大小写;ABCD
SELECT UPPER(‘abcd‘) from dual;
select LOWER(ENAME) FROM EMP;
SUBSTR()函数
select substr(‘abc‘,2) from dual;--返回bc
select substr(‘abc‘,-1) from dual;--返回c;负数是从后面数为oracle特有的,下标从1开始
ASCII码:
select ascii(‘A‘) from emp; 65
select chr(100) from dual; d
trim函数:
select ltrim(‘ adf‘) from dual;去掉左边空格
select rtrim(‘ adf ‘) from dual;去掉右边空格
select trim(‘ adf ‘) from dual;去掉空格
填充:
LPAD
select lpad(‘ad‘,4,‘*‘) from dual; **ad
查找函数:
instr
select instr(‘floor‘,‘oo‘) from dual; 3
select instr(‘floor‘,‘QQ‘) from dual; 0
2、数值函数
round 四舍五入
select round(123.456) from dual; 123 不保留小数
select round(123.456,2) from dual;123.46 保留两位小数
select round(123.456,-2) from dual; 100 整数部分取整
trunc 截取位数
select trunc(123.456,2) from dual; 123.45
mod 取模
select mod(10,3) from dual; 1

3、日期函数
日期的计算操作和日期函数的使用
1、取得当前日期:利用sysdate伪列取得当前时间
select sysdate from dual;20-8月 -16
默认情况下只包含了年月日三个内容,可以通过修改默认的语言方式来修改日期格式
日期的算数运算:
若干天前的日期:日期-数字=日期
select sysdate-3 from dual; 17-8月 -16

若干天后的日期:日期+数字=日期
select sysdate+3 from dual;23-8月 -16

两个日期的天数间隔:日期-日期
select trunc(sysdate-hiredate) from emp; 雇佣天数

日期的计算函数:
ADD_MONTHS()函数
select add_months(sysdate, 3) from dual;20-11月-16 三个月之后的日期
select add_months(sysdate, -3) from dual;20-5月 -16 三个月之前的日期
NEXT_DAY()函数
select NEXT_DAY(sysdate, ‘星期日‘) from dual; 查询下一个星期日
last_day()函数
select last_day(sysdate) from dual; 本月的最后一天31-8月 -16
查询当月倒数第三天雇佣的
select ename from emp where hiredate=last_day(sysdate)-2;
Month_between()月数
select trunc(MONTHS_BETWEEN(sysdate, hiredate)/12) 雇佣年数 from emp;
范例:计算出某一个雇员目前为止雇佣的年数,月数,天数**

1、需要查询的表:emp
select ename,trunc(months_between(sysdate,hiredate)/12) years,
trunc(mod(months_between(sysdate,hiredate),12)) months,sysdate-(last_day(add_months(sysdate,-1))+1) days from emp;
select ename,month_between(sysdate,hiredate)/12 years

4、转换函数
主要使用的数据类型:字符、数字和日期(时间戳)
TO_CHAR()
将date类型变成字符串:
select to_char(sysdate,‘yyyy-MM-dd hh24:mi:ss‘) from dual; 2016-08-20 20:26:25
select to_char(sysdate,‘FMyyyy-MM-dd hh24:mi:ss‘) from dual; 2016-8-20 20:30:14 去除前导0
查询出每年二月份雇佣的雇员信息
select * from emp where to_char(hiredate,‘MM‘)=2;
拆分日期;
select ename ,empno,to_char(hiredate,‘yyyy‘) 年,to_char(hiredate,‘MM‘) 月,to_char(hiredate,‘dd‘) 日 from emp
where to_char(hiredate,‘MM‘)=2;ALLEN 7499 1981 02 20
TO_CHAR()格式化数字:
TO_DATE()函数;字符串-->日期比较少
TO_TIMESTAMP()
TO_NUMBER()基本不用
select to_number(‘09‘) from dual; oracle中支持自动的类型转换,select 09 from dual; 结果相同

5、通用函数:oracle提供的特色函数
NVL()函数用于处理null值
范例:查询年薪;有null参与的运算结果为null
select nvl(sysdate-null,sysdate) from dual 20-8月 -16 为null的时候为sysdate
NVL2()函数
select nvl2(comm, sal+comm,sal) from emp
NULLIF,相同的结果返回空

DECODE()函数
oracle最有特色的函数之一,类似于if else,但是判断的内容都是一个具体的值
select DECODE(2,1, ‘Ground‘, 2,‘Air‘,‘默认值‘) from dual; 如果值为1,返回Ground,如果值为2,返回air,没有匹配的返回“默认值”
注意:使用decode()函数判断,所有可能出现的数值都要判断,没有判断的内容为null,

oracle9i后引入case表达式,根据给定的列或者字段依次判断
select ename,sal,
case job
when ‘clerk‘ then sal*1.1
when ‘salesman‘ then sal*1.2
else
sal*1.5
end 新工资
from emp;

【多表查询】复杂查询
多表查询先使用笛卡儿积的方式查出所有记录,再通过条件进行筛选
语法:
SELECT [DISTINCT] *|列明 as 列明 from 表名,表明2... where 条件语句
笛卡儿积问题:
select * from emp; 14条记录
select * from dept; 4条记录
select * from dept ,emp;56条记录4*16
隐藏掉笛卡儿积列:使用关联字段
select * from dept t ,emp e where t.deptno=e.deptno; 显示14行
注:数据量很大的时候一般不用多表查询,因为笛卡儿积肯定是存在的,关联字段只是隐藏掉笛卡儿积的记录,并没有消除笛卡儿积
范例:
查询每个雇员的编号,姓名,职位,基本工资,部门名称,部门职位信息
1、确定所需要的表:
emp表:雇员编号,姓名,职位,基本工资
dept表:部门名称,部门职位信息
2、确定关联字段
emp.deptno=dept.deptno
select e.empno,e.ename,e.job,e.sal,d.dname,d.loc
from emp e,dept d
where e.deptno=d.deptno;
按照sql语句的执行步骤编写:FROM WHERE SELECT
范例:查出每个雇员的编号,姓名,雇佣日期,基本工资,工资等级
1、确定所需要的表:
emp:雇员的编号,姓名,雇佣日期,基本工资
salgrade:工资等级
2、确定关联字段
sal
select e.ename,e.hiredate,e.sal,s.grade
from emp e,salgrade s
where sal between losal and hisal;
范例:查询出每个雇员的姓名、职位、基本工资、部门名称、工资等级
1、确定所需要的表:
2、确定关联字段
步骤一:查出雇员信息
步骤二:查出部门表(消除笛卡儿积)
步骤三:查出工资等级表
步骤四:等级换成中文
select e.ename,e.job,e.sal,d.dname,s.grade,
case s.grade
when 1 then ‘第五等‘
when 2 then ‘第四等‘
when 3 then ‘第三等‘
when 4 then ‘第二等‘
when 5 then ‘第一等‘
end sg
from emp e,dept d,salgrade s
where e.deptno=d.deptno and sal between losal and hisal;

【多表查询】表的连接操作
目标:清楚表的连接区别:内链接和外连接
内连接:通过关联字段等值判断进行连接,消除关联字段不相等的连接,来隐藏笛卡儿积现象
范例:内外链接的区别:
1、添加一个没有部门信息的雇员
2、执行以下查询语句
select * from emp,dept where emp.deptno=dept.deptno;
没有部门信息的员工没有显示,如果希望emp或者dept表中的数据显示完整,那么可以利用外连接
范例:使用做外连接希望emp信息全部显示:

外连接:如果想要某一个表的字段全部显示,则可以使用外连接通过"(+)"进行控制,只能在oracle中使用(+)
此符号只能实现左边外连接或者右外连接
左外连接:select * from emp e left outer join dept d on e.deptno=d.deptno;
右外连接:select * from emp e right outer join dept d on e.deptno=d.deptno;
全外连接:select * from emp e full outer join dept d on e.deptno=d.deptno;
注意:只能在oracle中使用(+)进行外连接

自身关联:
emp中mgr字段表示雇员的领导信息:
如果要显示领导信息,需要利用雇员表和雇员表自己的连接操作完成
范例:查询出雇员表中的雇员姓名、编号和上级领导的编号和姓名

对于没有领导信息的雇员,对应领导信息全部使用null进行连接
King没有mgr信息,没有显示;解决方法外连接

范例:查询在1981年雇佣的全部雇员编号、姓名、雇佣日期(年月日显示)、工作领导姓名,月工资,年工资(基本工资+佣金)工资等级,部门编号,名称,位置,同时要求这些雇员的月工资在1500-3500之间,
最后按照年工资进行降序排列,工资相同,按照工作排序
1、确定所需要的数据表
2、确定已知的关联字段
数据的集合运算
集合运算是一种二目运算符,一共包含四种运算符,并差交笛卡儿积:
语法如下:
查询语句
[union|union all |intersect|minus]
查询语句
select * from dept; 4条结果
select * from dept where deptno=10; 一条结果
两个查询结果返回的结果结构相同
union(并集)返回若干个查询结果的全部内容,但是重复元祖不显示
select * from dept union
select * from dept where deptno=10; 4条结果
union all(并集)返回若干个查询结果的全部内容,重复元祖也会显示
select * from dept union all
select * from dept where deptno=10; 5条结果
范例:查询所有销售和办事员的信息
select * from emp where job in(‘clerk‘,‘salesman‘);
select * from emp where job=‘clerk‘ or job = ‘salesman‘;
注意:尽量使用union或者union all来代替or,集合操作时,各个查询的结果结构一定要相同
select * from emp where job=‘clerk‘
union
select * from emp where job= ‘salesman‘;

minus(差集) 返回若干个查询结果中的不同部分
intersect(交集)返回若干个查询结果中的相同部分


分组统计查询:
1、统计函数
掌握标准统计函数的使用:
COUNT(*|distinct 列)求出全部的记录数
count中的参数可以使用*也可以使用字段和dinstinct
select count(*),count(empno) from emp; empno没有null值,结果一样
select count(*),count(mgr) from emp;15,14
范例:count(*)、count(字段)、count(dinstinct)有什么区别
1、全部统计
2、不统计null值
3、不统计重复值
尽量不使用*,所有函数在没有数据的时候都是返回null;但是count在没有数据的时候返回0,所以在java中是不需要对结果进行判断的


SUM()求和
AVG()平均值
MAX()最大值
MIN()最小值
median()中间值
STDDEV()标准差

范例统计处公司最早雇佣的和最晚雇佣的
雇佣日期使用的是date类型,但是在Oracle中的函数是可以进行数据类型的互相转换的,最早雇佣的hiredate值一定是最小的
select min(hiredate) zuizao,max(hiredate) zuiwan from emp;

单字段分组查询
掌握group by的使用
需求一:公司中要求每个部门一组进行拔河比赛
需要部门列的内容需要重复
select * from emp
job和deptno有重复内容,最好对有重复内容的列进行分组
需求二:在一个班级中要求男女各一组进行辩论比赛
语法:
select 分组字段|统计函数 from 表明 group by 分组字段
分组使用group by子句时,但是此时SELECT子句允许出现的就是分组字段和统计函数***
范例:统计处每个部门的人数
select deptno ,count(empno)
from emp
group by deptno;
范例:统计出每种职位的最低和最高工资
select job,min(sal),max(sal)
from emp
group by job;
掌握分组查询的使用限制(最为麻烦的地方为此处的限制)
注意事项一:
如果一个查询之中不存在group by 子句,select子句中只允许出现统计函数,其他任何字段都不允许出现
select deptno ,count(*) from emp; 提示”不是单组分组函数“错误
注意事项二:
在统计查询之中(存在group by子句) select子句中只允许出现分组字段(group by后面的字段)和统计函数其他任何字段都不允许出现
注意事项三:
所有的统计函数允许嵌套使用,但是一旦使用了嵌套的统计函数之后,select字句中不允许出现任何字段,包括分组字段
范例:
求出每个部门平均工资最高的工资
按照部门分组,而后统计处每个部门的平均数值,那么针对这些统计结果求出一个最大值
范例:
查询每个部门的名称、部门人数、平均工资,平均服务年限
1、确定所需要的数据表
2、确定已知的字段关联


字句执行顺序
from where group by select order by
范例:查询出公司各个工资等级雇员的数量和平均工资
1、确定所需要的表
2、确定关联字段
范例:统计处领取佣金和不领取佣金雇员的平均工资、平均服务年限、雇员人数
1、
2、
多字段分组:
既然可以在group by子句中出现多个分组字段,那么在select子句中也可以出现多个字段
范例:要求查询出每个部门的详细信息
包含字段:部门编号、名称、位置、平均工资、总工资、最高工资、最低工资、部门人数。(使用多字段分组)
1、确定已知的数据表
2、确定关联字段
having子句
掌握having字句的使用
当需要对group by分组之后的数据再进行过滤,则只能通过having子句完成
注意:having子句必须和group by子句一起使用
查询出所有平均工资大于2000的职位信息、平均工资和雇员人数
select job,round(avg(sal)),count(empno)
from emp
group by job having avg(sal)>2000
语句的执行顺序 from、where、group by, having, order by
范例:
列出至少有一个员工的所有部门编号,名称,并统计出这些部门的平均工资、最低工资、最高工资
1、确定所需要的数据表
2、确定已知的关联字段:
子查询
子查询中的语法格式并没有任何新的技术,类似于java的内部类,而且在开发之中,子查询的使用绝对是比较多的
复杂查询=限定查询+多表查询+统计查询+子查询,在笔试之中出现较多的部分。
范例:查询公司之中工资最低的雇员的完整信息
select * from emp where sal=(select min(sal) from emp);
根据返回的数据类型一共分为四种:
单行单列
单行多列
多行多列
多行单列
多行多列
子查询出现的地方:
1、where
单行单列
范例:查询出基本工资比allen工资低的员工

范例:查询出基本工资高于公司平均工资的雇员

范例:查找出于ALLEN工作相同,并且接你工资高于雇员编号7521的全部雇员信息
范例:查询出与SCOTT从事同一工作并且工资相同的雇员(返回单行两列)
select * from emp where (job,sal)=(select job,sal from emp where ename=‘SCOTT‘);
select * from emp where (job,sal)=(select job j,sal s from emp where ename=‘SCOTT‘); 列不对应
范例:查询出与7566工作相同并且领导相同的雇员
范例:查询出于ALLEN同一工作并且同一年雇佣的雇员信息
多行单列:
如果子查询返回的是多行单列,主要使用三种操作符:in,any,all,not in
范例:查询出与每个部门最低工资相同的全部雇员信息
范例:查询出不与每个部门中最低工资相同的全部雇员信息
注意:如果在in中子查询的结果又in,如果在not in中子查询返回数据有null就表示不会有任何数据返回
any操作符
=any:功能和in相同,但是<>any不等价于not in;
>any比最大值要大
<any比最小值要小
范例:
all操作符
空数据判断
exists用于判断是否有数据返回
select * from emp where exists(select * from emp where empno=9999);子查询没有内容,不返回
select * from emp where exists(select * from emp); 有结果返回,数据会全部返回
2、having,一定表示操作会执行分组
在having中的子查询一般会返回单行单列,是以一个数值的方式返回
范例:查询部门编号、雇员人数、平均工资,并且要求部门平均工资高于公司的平均工资
范例:查询每个部门平均工资最高的部门名称以及平均工资(在统计函数嵌套使用时select字句中不允许出现任何字段,包括分组字段)
3、from 主要功能是确定数据的来源,来源都是数据表(行+列的集合),所以一般都是多行多列子查询
范例:查询出每个部门的编号、名称、位置、部门人数、平均工资(可以使用多表查询和子查询两种方法)
使用子查询来代替多表查询来避免笛卡儿积,所以优先使用子查询
范例:查询出所有在部门‘sales’工作的员工编号、姓名、基本工资、奖金、职位、雇佣日期、部门的最高和最低工资
1、确定所需要的数据表

对于统计函数的使用限制:
单独使用:不允许出现任何字段
和group by一起使用:允许出现分组字段
范例:查询出所有的新近高于公司平均薪金的员工编号、姓名、基本工资、职位、雇佣日期、所在部门名称、位置、上级领导姓名、公司的等级、部门人数、平均工资、平均服务年限。
1、确定所需要的数据表
2、确定已知的关联字段
范例:列出公司各个部门的经理姓名、薪金、部门名称、部门人数、部门的平均工资
1、确定数据表
2、确定关联字段
4、select用的比较少
范例:查询出部门编号,部门名称,部门人数,部门平均工资
with子句
可以使用with创建临时表查询
范例:查询每个部门的编号,名称、位置、部门平均工资,人数(使用with)
范例:查询每个部门工资最高的雇员编号、姓名、职位、雇佣日期、工资、部门编号、部门名称,最终的显示结果按照部门编号排序

分析函数:
理解分析函数的主要语法:
理解分窗的使用
删除语法:
delect from 表明 where
更新语法:
update 表明 set a=b where
【事务处理】
指同一个session中的所有sql语句整体执行
服务器通过session来区分不同的用户,每一个session对应一个用户
原子性、一致性、隔离性和持久性
session---缓存
更新操作要commit之后才会生效
ROLLBACK回滚,savepoint+保存点名称
锁的基本概念
锁指的是不同的session同时操作了同一资源发生的问题
两个session执行同样的update操作语句:
两种锁:
行级锁:
特点:当一个事务执行了相应的数据操作后如果此事务没有提交,那么会一直以独占的方式锁定这些操作的数据,其他事务要一直到此事务释放后才能进行操作
表级锁:

 

数据库相关