数据库:1.能长久保存 2.支持共享 3.能够尽可能减少冗余的集合
数据库管理系统:创建,维护,管理和使用数据库的软件
数据库系统:数据库,数据库管理系统,dba(管理员),程序员,服务器,应用,用户
oracle和mysql的区别:???
逻辑模型:层次
网状
关系:oracle端口为:1521;Mysql端口为:3306
关系就是表——sql(结构化查询语言)
mysql命令:MySQL-uroot-proot
net start mysql 启动服务
net stop mysql 关闭服务
存储引擎(特点):InnoDB:支持外键,支持事务,性能较慢
MyISAM:不支持外键,不支持事务,性能较快
oracle登录的命令:sqlplus scott/tiger 登录
show user 显示用户
alter user scott account unlock 解锁
alter user scott identified by tiger 制定默认密码
conn sys/1 as sysdba 切换管理员用户
ctrl + c 退出
SQL:DQL:数据查询语言
DML:数据操作语言
DCL:数据控制语言
DDL:数据定义语言
TPL:事务处理语言
Oracle导表:
Cmd:
1 Sqlplus sys/1 as sysdba:以管理员身份登录
2 create user test01 identified by test01 :
创建test01用户,密码为test01
3 alter user test01 identufied by 123456 :
修改用户密码为123456
4 grant create session, resource,connect to test01:
给用户分配权限
我笔记本的oracle到D:\oracle\product\10.2.0\db_1\BIN中的sqlplus.exe中改:
DQL:
简单查询:
select [distinct]*|{列名|表达式 [as] [列别名][…]}
from 表名;
子句:select :数据显示
from:数据源
语法:表达式:算术表达式:计算
字符串表达式:拼接和裁剪
null值参与任何算术或者比较运算的结果都为null(可以用NVL函数解决)
限制查询:
select [distinct] *|{列名|表达式 [as] [列别名][,...]}
from 表名
[where 逻辑表达式]
逻辑表达式: 关系表达式 [逻辑运算符...]
关系表达式:{列名|表达式} 比较运算符 {列名|表达式}
比较运算符:> < = >= !=
特殊比较运算符:
between and
in
is null
日期的比较???(mysql中是我们常用的日期格式,Oracle中把日期格式改为‘31-4月-2019’或者用to_date函数把字符串改成日期类型)
like 通配符: % :任意长度的任意字符
_ :一个长度的任意字符
escape:注册转义字符
忽略大小写 MySQL
逻辑运算符:
not > and > or
运算符优先级:算术>比较>特殊比较>not>and>or
排序
排序:
select [distinct] *|{列名|表达式 [as] [列别名][,...]}
from 表名
[where 逻辑表达式]
[order by 列名|表达式|列别名 [desc] [,...]];
自定义排序?
## 连接:
笛卡尔积:两个表只写了from则连接;但是没有条件会导致两个的所有行都进行匹配,匹配的结果是两个表的数据条数的 乘积
```sql
连接分类:
内连接:
外连接:由于条件导致(null值)部分数据被去笛卡尔积,但是还想要显示
sql99:
交叉连接:oracle笛卡尔积
select *
from emp CROSS join dept;
自然连接:select * from emp NATURAL join dept (默认对两个表内字段名相等且数据类型相等的列进行等值比较)
using连接:select * from emp join dept using(deptno) (数据类型可以不相等)
on连接:
select *
from emp a,dept b,salgrade c
where a.deptno = b.deptno and a.sal between c.losal and c.hisal;
select *
from emp a join dept
on a.deptno = dept.deptno
join salgrade c
on a.sal between c.losal and c.hisal
外连接:左外:左边表数据无法出现(已有数据无法出现)
右外:右边......
select a.ename ,b.ename
from emp a left outer join emp b
on a.mgr = b.empno;
select a.ename,b.dname
from emp a right join dept b
on a.deptno = b.deptno;
例子:--查询所有的员工信息和部门信息:
select *
from emp,dept
where dept.deptno = emp.deptno
--查询所有员工的姓名,工资,和工资等级信息:
select ename, sal , grade,losal,hisal
from emp ,salgrade
where sal between losal and hisal
oracle外连接:外连接的方向看表之间个的方向,+在左边表的条件则右外连接
–查询员工的姓名,员工的领导编号,领导的姓名,领导的员工编号
```sql
select a.ename,a.mgr ,b.ename,b.empno
from emp a ,emp b
where a.mgr = b.empno(+);
oracle全外连接 sql99 full outer join ?? oracle,mysql自己能不能
三表连接:
– 查询员工的信息,部门的信息 和工资等级的信息
```sql
select *
from emp ,dept ,salgrade
where emp.deptno = dept.deptno and sal between losal and hisal
## 函数
函数:
自定义函数:自学
系统函数:
单行函数:调用时一行数据返回一个结果
!!多行函数(分组函数):调用时无论给多少行数据只返回一个结果
语法:函数调用: 函数名(实参列表) ——实参 :(列名|表达式)
dual:虚表
5:
字符类型
upper lower initcap CONCAT('a','b','c')
select CONCAT_WS('$','a','b','c');
!select substr('abcdefg',2,3) from dual;
!select instr('abcded','d',1,2) from dual;
select rpad('abc',10,'*') from dual;
!select replace('abcde','b','$') from dual;
!trim:select trim(both 'B' from 'B asdb B' ) from dual;
select trim( ' asdb ' ) from dual;
!length:oracle:select length('abc啊') from dual; 字符个数
mysql:select length('abc啊'); 字节数
select CHAR_LENGTH('abc啊');字符个数
select REPEAT('a',3) ;
select REVERSE('abcde') ;
数字类型
select abs(-1);
select mod(-8,-3);
select CEIL (1.1);
select FLOOR(1.9);
select ROUND(1.66666 ,3);
select TRUNCATE(1.91,1);
select RAND();
日期类型
!select now();
!select sysdate from dual; --当前系统时间
时间差
SELECT TIMESTAMPDIFF(MONTH,'2009-12-01 11:11:11','2009-09-01 11:11:12');
select months_between(sysdate,hiredate ) from emp;
增加月份:
select ADD_MONTHS('29-2月-2000',10) from dual;
SELECT DATE_ADD('2014-11-13',INTERVAL 1 MONTH);
转换类型
oracle:
!to_char(date,'yyyy-mm-dd')
!to_date('2015-1-1' ,'yyyy-mm-dd')
select to_number(to_char(sal,'999,999,999.00'),'999,999,999.00' )+1 from emp;
Mysql:
SELECT DATE_FORMAT(NOW(),'%Y/%m/%d %h-%i-%s');
-- 字符串转时间
select str_to_date('2016-01-02', '%Y-%m-%d %H')+1;
转金融
select FORMAT(sal,2) from emp;
!!!通用类型
oracle:
!nvl: select nvl(comm,0)+sal from emp;
!case:
decode:替换
select decode(sign(sal - 1000),
-1,
'x丝',
0,
'能活',
decode(sign(sal - 2000),
-1,
'能活',
0,
'能活',
decode(sign(sal - 3000),
'-1',
'高富帅',
0,
'高富帅',
'逆天了')))
from emp;
mysql:
!ifnull:select ifnull(comm,0)+sal from emp;
case:
自定义排序:
通用:
select ename, job
from emp
order by case job
when 'PRESIDENT' then
1
when 'ANALYST' then
2
when 'MANAGER' then
3
when 'CLERK' then
4
else
5
end
mysql:
select ename ,job from emp
order by FIELD(job,'PRESIDENT','ANALYST','MANAGER','CLERK','SALESMAN')
多行函数:所有多行函数忽略空值
sum,avg,count,max,min
函数名( [distinct ]列名|表达式)
!count(1):统计行数
分组语句:
1.每个后面的名词放到group by 中
2.如果select中有多行函数和列,把列放到group by中
3.group by 中没有的列不允许在select中出现
分组条件:
having:补充where,只能写带分组函数的条件
多行函数嵌套:
oracle:只能嵌套一次,select中不允许有任何列
select avg(count(1))
from emp
group by deptno
mysql?子查询
# 子查询:
```sql
--1查询Smith所在部门其他员工的姓名
select ename
from emp
where deptno = (select deptno from emp where ename = 'SMITH')
and ename != 'SMITH'
--2查询存在员工的部门的工作地点
select loc from dept where deptno in (select deptno from emp)
--3查询工资为全公司最高的员工的部门名称
select dname
from dept
where deptno in
(select deptno from emp where sal = (select max(sal) from emp))
-- 查询高于公司平均工资的员工的岗位
select distinct job from emp where sal > (select avg(sal) from emp
相关子查询注意点:
1.相关子查询在select中生成的新的列只能有一列,否则会产生值过多的错
2.相关子查询不能放在FROM语句中,一般都是在select 和 where 子句中
3.相关子查询必须根据主查询数据行一个一个确认出来,不需要去笛卡尔积。
ROWNUM注意点:
1. rownum是在查询结果输时才生成 eg.
Select * from emp where rownum>2 (此查询时查不到任何记录的,因为rownum 默认是从1开始的, 也就是说第一条记录是1满足不了rownum>2 的条件,第二条数据依然不满足rownum>2的条件,以此类推,一直没有满足条件的记录) 所以一般情况下,rownum只能执行rownum< <= 的条件
2. 当rownum和order by 一起使用时,rownum是在记录输出时生成,而order by子句是在最后执行(order by是在所有数据生成之后再给数据排序),所以当两者一起使用时输出的rownum实际上已经被order by 排了序
3. 当有嵌套时,需要用rownum的别名rn来实现 rn>5
例子:-- 2.按照每页显示5条记录,分别查询工资最高的第1页,第2页,第3页信息,
--要求显示员工姓名、入职日期、部门名称、工资。
```sql
select *
from (select rownum rn, ename, sal, hiredate, dname
from (select *
from emp, dept
where emp.deptno = dept.deptno
order by sal)
where rownum <= 15)
where rn > 10
子查询的经典题型:
– 查询部门最低工资高于10号部门最低工资的部门的编号、名称及部门最低工资。(输出项中有最低工资或者平均工资之类的要考虑是用group by 的子查询,还是用相关子查询,group by 的子查询生成的最低工资可以在别处使用,而相关子查询生成的最低工资在别处使用不了)
select a.deptno, dname, deptnominsal
from emp a,
dept,
(select deptno, min(sal) deptnominsal from emp group by deptno) b
where a.deptno = dept.deptno
and a.deptno = b.deptno
and deptnominsal > (select min(sal) from emp where deptno = 10)
– 查询员工工资为其部门最低工资的员工的编号和姓名及工资。
select empno,ename,sal
from emp a
where sal in (select min(sal) from emp b where a.deptno=b.deptno)
–.查询大于本部门平均工资的员工姓名,工资,所在部门平均工资,高于部门平均工资的额度。
select ename,sal, deptnoavgsal,sal-deptnoavgsal
from emp a ,(select deptno,avg(sal) deptnoavgsal from emp group by deptno) b
where a.deptno=b.deptno and a.sal>deptnoavgsal
deptnoavgsal 如果还会被调用,那么就要用group by,如果不会被调用,那么可以用相关子查询
(通过多表连接他们已经在一张表中,又通过去笛卡尔积他们又在同一行中,所以可以一起比较。a.sal>deptnoavgsal不需要用相关子查询来比较)
–查询比本职位平均工资高的员工姓名、职位,部门名称,部门平均工资(jia ru bi ji)
方法一
select ename,
job,
dname,
(select avg(sal) from emp c where a.deptno = c.deptno) deptnoavgsal
from emp a, dept
where a.deptno = dept.deptno
and sal > (select avg(sal) from emp b where a.job = b.job)
方法二
select ename, job, dname, deptnoavgsal
from emp a,
dept,
(select deptno, avg(sal) deptnoavgsal
from emp
group by deptno) b
where a.deptno = dept.deptno
and a.deptno = b.deptno
and sal > (select avg(sal) from emp c where a.job = c.job)
DML:
delete:删除数据
delete from emp
delete from emp where deptno=(select deptno from emp where ename='SMITH')
insert:插入数据
insert into dept values('50','hehe','haha')
insert into dept (deptno,dname,loc) values ('50','hehe','haha')
insert into manager select * from emp where job ='MANAGER'
insert into emp_dept select emp.*,dname,loc from emp,dept where emp.deotno=dept.deptno
update:修改数据
update emp set deptno=20 where empno=7782
update emp set deptno=20
update emp set deptno=10,sal=sal+100 where deptno=20
update emp a set sal=(select avg(sal) from emp b where a.depnto=b.deptno)
where not exists(select 1 from emp b where a.deptno=b.deptno and b.sal<a.sal)
Mysql:修改和删除的数据默认是自动提交 ,可以通过set global autocommit=0;命令设置成不自动提交
TPL事务处理:commit,rollback,savapoint
事务:主要用来对组成事务的DML语句的操作结果进行确认和取消
作用:处理数据一致性问题,事务结束:提交(全部操作成功),回滚(全部操作失败)
特性:一致性,原子性,永久性,隔离性
DDL:数据定义
包括:create,alter,drop,truncate,
create(建表):1.自建
create table tab1 ( tab_column1 int ,
tab_column2 char(4),
tab_column3 varchar(40),
)
2.用别表的样式
create table tab2 as select * from emp;
alter:
alter table tab1 add tab_column4 date ;
alter table tab1 drop tab_column4;
alter table tab1 modify tab_column3 int; ##modify只能修改字段类型
alter table tab1 change tab_column3 tab_column30 date; ##change可以修改字段名和字段类型
truncate ,delete, drop 区别?
truncate(DDL):删除全表数据,性能强,无法恢复(表还在)
delete (DML):删除可选数据,性能差,被事务控制 (表还在)
drop:删除表内数据和结构,可以通过归档还原(表不在)
char和varchar区别?
char:固定长度,如果输入的数据长度不够,会自动用空格补上
varchar:可变长度
varchar和varbinary区别?
varchar:忽略大小写
varbinary:不忽略大小写
clob和blob区别?
clob:字符文件
blob:二进制文件
约束
定义:保证数据的完整性,设置在单个字段或者多个字段组合上,使写入这些字段的数据必须必须符合约束的限制
常见类型有五种:
- 非空:not null
- 唯一:unique (默认送索引)
- 主键:primary key 所有行数据唯一,且不能有空值(一个表只能有一个,默认送索引)
- 外键:foreign key 外键列的值必须在主键表参照列值得范围内,或者为空;外键参照的列必须是主键(mysql),或者是唯一键(效果:主对于主键表如果值被引用不可以被删除;对于外键表只能从引用表的列中取值)
- 检验:check(mysql没有,用enum)
mysql的自增列也必须是主键
手写约束:
create table student(
sid number constraint student_pk primary key,
sname varchar2(20) not null,
tell number(13) unique,
age number(3) check (age >10),
classid number ,
constraint student_class_fk foreign key(classid) references class(classid)
)
view: 视图的本质是有自我权限的查询语句,优点可以管理自我权限,不占空间
or replace:更新
mysql:
自增列auto_increment 必须是主键
索引:提高查询性能
索引是加在某列上
使用索引的条件:
- 1.数据量超过10万
- 2.查询的量不能占总量太多
- 3.不能频繁修改