数据库:
DB数据库:DateBase
DBMS数据库管理软件:DateBase Management System
关系型数据库:描述两个元素间的关联或对应关系
产品化:Oracle(Oracle商用版权收费) DB2(IBM) Sybase
SQLServer(微软,运行在WindowsNT服务器上)
MySQL(开源免费,多用于中小型网站)
SQL LITE(多用于嵌入式设备)
oracle中注释格式:--
表:1个关系数据库由多个表组成
结构化查询语言:SQL(Structured Query Language)
SQL是执行数据操作、检索、及维护所使用的标准语言
SQL分为:
(常用)DDL数据库定义语言 创建和删除数据库对象
数据库对象通常包含表、视图、索引、序列
CREATE
ALTER
DROP
TRUNCATE
(常用)DML数据操纵语言
用于增删改 操作会影响数据库中的数据
INSERT 增
UPDATE 改
DELETE 删
TCL事务控制语言
维护数据一致性的语句
COMMIT 提交,确认已经进行的数据改变
ROLLBACK 回滚,取消已经进行的数据改变
SAVEPOINT 保存点
(常用)DQL数据查询语言
查数据
SELECT
DCL数据控制语言 执行权限的授予和回收操作
GRANT:授予
PEVOKE
CREATE USER:创建用户
远程登录数据库服务器
命令行工具:Oracle自带的SQl*PLUS
telnet IP 远程连接目标机
SELECT*FROM user_tables;
图形界面工具:SQL Developer
数据库数据类型
oracle中数字类型:
NUMBER(P,S)表示数字类型 P:数字总位数 S:小数点后边的位数
整数:NUMBER(p)
固定长度的字符类型
1.CHAR(N) 表示字符串 N:占用的字节数 不是字符数
(倾向性能)
ename CHAR(20); 表示ename列中最多可存储20个字节的字符串 弊端:容易造成空间浪费
2.VARCHAR2是oracle数据库中独有的类型,其他数据库是VARCHAR
VARCHAR2(N),N表示最多可占用的字节数,最大长度为4000字节
(倾向空间)
DATE定义日期
长度是7个字节 默认格式:DD-MON-RR 如:11-APR-71
hiredate DATE; 表示在hiredate列存的是DATE类型数据
RR\SYS
0-49
50-99
SYS当前系统时间
0-49
本世纪
下世纪
50-99
上世纪
本世纪
创建表:
CREATE TABLE[schema.]table_name(column_name datatype[DEFAULT expr][,....]);
//
如:创建表employee
CREATE TABLE employee(
id NUMBER(4),
name VARCHAR2(20),
gender CHAR(1),
birth DATE,
salary NUMBER(6,2),
job VARCHAR2(30),
deptno NUMBER(2)
);
查看表结构:DESC table_name
(可以看到表中列的名字,对应的类型,长度等)
删除一个表: DROP TABLE table_name
数据库中字符串用单引号,单引号内严格区分大小写
DEFAULT关键字:用于为给定的列(字段)设置默认值
//默认值在字段后边设置,若写 NOT NULL 表示必须给值
数据库中的所有数据类型默认值为null,为空
修改表名:RENAME old_name TO new_name;
增加列(在表的最后一列):ALTER TABLE table_name ADD(column_name datatype[DEFAULT expr][,....]);
//方括号表示可写可不写
如:ALTER TABLE employee ADD(hiredate DATE DEFAULT sysdate); //增加入职时间列,默认值为当前系统时间
删除列(删除某一列): ALTER TABLE table_name DROP(列名);
修改现有列:ALTER TABLE table_name MODIFY(列名 CARCHAR2(40) DEFAULT 'cleak')
修改表字段时的注意事项:
1.尽量不修改字段类型
2.字段长度尽量不要减少
3.修改后的字段 只对以后的数据产生影响
创建一个表emp_copy,将emp表的查询内容复制到emp_copy
CREATE TABLE emp_copy
AS SELECT * FROM emp
DML:
插入数据:INSERT INTO table_name(列名1,列名2,列名3);
//若某列为NOT NULL ,执行INSERT时没有指定该列,则会抛出异常
//不给列名,则默认全列按序插入。
VALUES(1,'碧瑶’,8000)
查询表数据:
SELECT * FROM table_name;查询所有表内容
SELECT id,name,age FROM table_name;
查询选择的表内容
事务控制:提交数据语句:COMMIT
//注意:数据只要没提交,就一直在内存中,不会真正进入数据库
事务控制:回退:ROLLBACK //回退到上一次提交后的状态
插入日期:
默认日期格式:'DD-MON-RR'
插入日期时使用函数:TO_DATE(('2016-10-17',YYYY-MM-DD')
更改数据:
UPDATE table_name SET 列名1=value,列名2=value,...
WHERE 列名='str'; //选择需要修改的部分。若不写WHERE则是全表修改
删除数据:
1.事务控制,可以回退
DELETE FROM table_name
WHERE name='tom';
//若不指定where,则是全表删除
2.直接删除,效率高
删除全部数据:DELETE FROM table_name/TRUNCATE TABLE table_name;
字符串
字符串表示:
CHAR(10 CHAR),20个字节
VARCHAR2(10)等价于CARCHAR2(10 BYTE),指定单位字符:VARCHAR2(10 CHAR),20个字节
每个英文字符占用一个字节,每个中文字符按编码不同,占用2-4个字节
ZHS16GBK:2个字节
UTF-8:2-4个字节
CHAR长度默认1个字节,VARCHAR2必须指定长度,无默认
LONG 表示长字符串,最多达到2GB字符串数据
CLOB 存储定长或变成字符串,最多达到4GB字符串数据
字符串函数:
连接操作:CONCAT或|| (相当于Java中的“+”)
如:CONCAT(char1,char2)/char1 || char2
DUAL:虚表,用来测试表达式结果
如:SELECT 'hello'||'word'
FROM DUAL;
LENGTH(char) :字符串长度
如SELECT LENGTH(name)
FROM table_name;
UPPER(char)、LOWER(char)、INITCAP(char) 字符串大写/字符串小写/单词首字母大写
TRIM(c2 FROM c1) 从c1的前后截去c2
注意:
1. c2只能为单一字符
2. 如果只写c1,就去出c1左右空格,TRIM经常用于去掉字符串前后的空格
LTRIM(c1,c2) 去除c1左边的所有c2 LTRIM(c1) 去除c1左边的空格
RTRIM(c1,c2) 去除c1右边的所有c2 RTRIM(c1) 去除c1右边的空格
LPAD(char1,n,char2)显示n个字符,若char1的长度小于n,则在左边补充n-char1.length个char2.
RPAD(char1,n,char2)显示n个字符,若char1的长度小于n,则在右边补充n-char2.length个char2.
SUBSTR(str,n1,n2) 截取字符串,str字符串,n1:从第几位开始,n2:截取的字符位数,若n2不写,则截取到末尾
Oracle计数索引从1开始
INSTR(char1,char2) 返回char2在char1中第一次出现的位置索引
INSTR(char1,char2,n1,n2) 返回char2在char1从第n1个字符开始找第n2次出现的位置索引
若超出索引,则返回0
NUMBER(P)表示整数
(P,S) p最大数字长度 S:小数点右边最大数字长度
ROUND(m,n)用于四舍五入
m: 要四舍五入的数据
n:取正数则四舍五入到小数点后第n位 ROUND(45.678,,2) = 45.68
n:取0则四舍五入到整数位
ROUND(45.678,,0) = 46
n:取负数则四舍五入到小数点前n位
ROUND(45.678,,-1) = 50 ROUND(45.678,,-2) = 0 ROUND(55.678,,-2) = 100
n:缺省,默认值为0
TRUNC(m,n)用于截取小数点后n位的数字
TRUNC(45.678,2) = 45.67
TRUNC(45.678,0) = 45
TRUNC(45.678,-1) = 40
MOD(m,n)返回m除以n后的余数
n为0则返回m
CEL(n)、FLOOR(n) 返回这个数的最大整数/最小整数
CEIL(45.678) = 46 / FLOOR(45.678) = 45
日期操作
DATE 7字节
SYSTIMESTAMP 可以精确到ns(纳秒)7-11字节
SYSDATE 返回当前系统时间 默认格式DD-MON-RR
TO_DATE(char,fmt,nlsparams) 日期转换
YY 2位数字的年份
YYYY 4位数字表示的年份
MM 2位数字的月份
DAY 周几的全拼
HH24 24小时制
HH12 12小时制
MI 显示分钟
SS 显示秒
TO_CHAR将其他类型数据转换成字符类型,将日期类型数据date按照fmt格式输出字符串
TO_CHAR(sysdate,'yyyy-mm-dd hh:mi:ss');
带-格式
TO_CHAR(sysdate,'yyyy"年"mm"月"dd"日" hh:mi:ss'); 带汉字年月日格式,要使用""包括
日期减法操作,差为相差的天数
sysdate-hirddate
LAST_DAY(date) 返回日期date所在月的最后一天
如: LAST_DAY(sysdate) / LAST_DAY('09年-2月-3日')
ADD_MONTHS(date,i)计算第i月之后的当天
如果i是小数,则会被截取整数后再做运算
如果i是负数,则获得的是减去i个月后的日期值
如:计算员工入职20周年纪念日
SELECT name
ADD_MONTHS(hirdate,20*12) as "20周年"
FROM emp;
MONTH_BETWEEN(date1,date2) 计算date1和date2之间间隔了多少个月
实际运算date1-date2,如果date2比date1晚,会取得负值
FROM DUAL;
SELECT MONTHS_BETWEEN(sysdate,TO_DATE('2012-10-10','YYYY-MM-DD'))
FROM DUAL;
NEXT_DAY(date,char) 返回离date日期最近的下一个周几
char中文环境:直接输入星期几
英文环境:1-7分别表示星期日、一、.....六。
LEAST、GREATEST 称作比较函数,可以有多个参数,返回结果是参数列表中最大或最小的值
LEAST/GREATEST(expr1,expr2,...)
参数类型必须一致,比较之前,参数列表中第二个以后的参数会被隐含的转换成为
第一个参数的数据类型,如果可以比较则继续,不能则报错
如:LEAST(sysdate,'02-4月-15')
EXTRACT(date FROM datetime) 从参数datetime中提取date指定的数据,如提取年、月、日
SELECT EXTRACT(HOUR FROM TIMESTAMP'2008-10-10 10:10:10')
FROM DUAL;
数据库中NULL含义:
即空值
插入NULL值,多用于已设置默认值,插入数据时,若要为空,则可以插入NULL,防止报错
判断是否为NULL值:
Java中 if(str==null){};
数据库中 str IS NULL/ str IS NOT NULL str为空/非空
NULL和任何数字计算,结果为NULL
NULL和任何字符串拼接,为当前字符串
NVL(expr1,expr2) 将NULL替换为给定值
如果expr1为NULL,则返回expr2的实际值
NVL2(expr1,expr2,expr3)
若expr1为NULL返回expr3,若expr1不是NULL返回expr2.
SQL基础查询
SELECT <*,column,...> FROM table; *代表查全列
使用别名: SELECT 字段名 as 别名 (若别名想取小写,或者想取空格用""引上)
使用场景:若SELECT 中的字段是一个表达式,可读性差,就可以使用别名来改善
如:SELECT
TO_CHAR(hiredate,'yyyy-mm-dd') hiredate
FROM emp;
WHERE 操作限制查询结果
如:查询部门10下的员工信息
查询职员表中职位是 SALESMAN 的职员
SELECT * FROM emp
SELECT name,sal,job FROM emp
WHERE deptno = 10;
WHERE job = SALESMAN
使用 >,<,>=,<=,<>不等于,=
查询职员表中薪水低于2000元的职员信息
SELECT name,sal FROM emp
WHERE sal<2000;
使用AND,OR关键字
查询职员表中薪水低于2000元的CLERK职员信息
SELECT name,sal,job FROM emp
WHERE sal<2000 AND job = 'CLERK';
若AND、OR同时使用,AND优先级大于OR 提高 优先级可以加()
如: 薪水大于2000的CLERK职员 或者 SALESMAN职员
sal<2000 AND job = 'CLERK' OR job = 'SALESMAN'
CLERK职员或者SALESMAN中 薪水超过小于2000元的
sal<2000 AND (job = 'CLERK' OR job = 'SALESMAN')
LIKE模糊查询
(区分大小写)
%:0到多个字符
_: 表示单个字符
如:查名字第二个字母为o的员工
SELECT name,job FROM emp
WHERE name LIKE '_o%';
IN/NOT IN 去除符合/不符合列表范围中的数据
如:SELECT name,job FROM emp
WHERE job IN/NOT IN('MANAGER','SALESMAN',‘CLERK’);
BETWEEN...AND..
查询薪水在2000-3000之间的员工
SELECT name,sal FROM emp
WHERE sal BETWEEN 2000 AND 3000;
ANY/ALL 比较操作
>ANY 大于最小
>ALL 大于最大
如:SELECT name,sal FROM emp 大于3500的工资即可
WHERE sal > ANY(3500,4000,4500);
IN/NOT IN:用于等值或不等值比较
ANY/ALL:用于范围比较
查询条件中使用表达式和函数:
SELECT name,sal,job FROM newname
WHERE name = UPPER('rose')/sal*12 > 100000
DISTINCT 去掉重复行
SELECT DISTINCT job FROM newname
排序:ORDER BY (必须写在SELECT语句最后)
如:1.按薪水排序
SELECT * FROM newname
ORDER BY salary DESC (此处加上DESC表示降序)
2.按薪水升序、部门降序排列 (左边的优先级高于右边,即salary相等时,deptno大的排前)
SELECT name,job FROM newname
ORDER BY salary ,deptno DESC
分组函数/多行函数/聚合函数: 多行数据参与运算返回同一行结果
MAX() MIN()
如:查询薪水最高和最低:
SELECT MAX(salary) max_salary,MIN(salary) min_salary FROM emp;
//后边加别名是为了增强可读性
AVG()
SUM()
平均和总和
聚合函数是忽略NULL值即空值的,所以在计算AVG时有问题的 用:SELECT AVG(NVL(salary,0)) FROM emp
COUNT 统计记录条数,即:计数
如:统计编号为4的部门有多少员工
统计有多少员工
常用:SELECT COUNT(*) FROM emp
SELECT COUNT(name) FROM emp
WHERE deptno=20;
GROUNP BY 分组
如:SELECT
//根据部门查询
deptno,MAX(salary),MIN(salary),AVG(salary),SUM(salary)
//此处不能出现其他像id,name,gender等字段,因为是按deptno分组的
FROM newname
GROUP BY deptno; //此处还可以追加 job,gender等字段
HAVING 对分组的进一步限制 也就是二次过滤
如:查看平均工资超过1800的部门,以及平均工资
SELECT
deptno,AVG(sarlary)
FROM newname
GROUP BY deptno
HAVING AVG(salary)>3300;
WHERE和HAVING区别:
WHERE 是用于第一次检索数据时过滤的 写在GROUP BY 前
HAVING 是用于在检索后,进行第二次过滤的,可以使用组函数
不能独立存在,写在GROUP BY后,ORDER BY前
顺序:SELECT-FROM-WHERE-GROUP BY-HAVING-ORDER BY
查询语句执行顺序:
1.from子句:执行顺序为从后往前,从右往左
数据量较小的表尽量放在后面
2.where子句:执行顺序为自下而上、从右往左
将能过滤掉最大数量记录的条件写在where子句的最右
3.group by 执行顺序为从左往右分组
最好在group by前使用where将不需要的记录在group by之前过滤掉
4.having子句:消耗资源
尽量避免使用,having会在检索出所有记录之后才对结果进行过滤,需要排序等操作
5.select子句:少用*号,尽量取字段名称
Oracle在解析过程中,查询数据字段将*号一次转换成所有列名,消耗时间
6.order by子句:执行顺序为从左往右排序,消耗资源
关联查询
关联概念
n张表查询至少需要n-1个连接条件 笛卡尔积:table1*table2的所有记录
SELECT emp.name,dept.dname
等价:SELECT emp.name,dept.dname
FROM emp,dept
FROM emp JOIN dept
WHERE emp.deptno=dept.deptno
ON(emp.deptno=dept.deptno)
自然连接://使用场景:两张表中应当只有一列名字相同才可以使用自然连接
SELECT emp.name,dept.dname
FROM emp
NATURAL JOIN dept
外连接 应用场景:如:在查看dept部门表示,因为在进行与emp员工信息表连接查询是,有些部门不存在任何员工,
导致查询结果该记录被忽略。这是若需要查看所有部门时,就要使用外连接。
SELECT emp.name,dept.dname
FROM emp,RIGHT/LEFT/FULL OUTER JOIN dept 右表为主(显示右表所有)/左表为主(显示左表所有)/两边都补齐(显示两边所有)
ON(emp.deptno=dept.deptno)
自连接:在一张表内实现了主键和外键连接
如:一张表内的员工上下级关系 z.leader:员工对应的领导编号/f.id:所有领导的id
SELECT z.name||'领导是'||f.name
FROM emp z,emp f
WHERE z.leader=f.id
子查询:当前查询需要建立在另一个查询的结果基础之上
子查询建立在WHERE子句中 (先执行小括号里的)
单行单列子查询,多行单列子查询通常用于WHERE子句中
单行单列子查询
> < >= <= = <> 这些都只能使用单行单列子查询
SELECT name
FROM emp
WHERE deptno = (SELECT deptno
//这里只能返回单行
FROM emp)
多行单列子查询
如:查询和tom一个部门的员工:
查询谁的工资低于平均工资
SELECT name
SELECT name
FROM emp
FROM emp
WHERE deptno = (SELECT deptno
WHERE salary <(SELECT AVG(salary)
FROM emp
FROM emp)
WHREE name='tom')
AND name<>'tom'
多行多列子查询通常用于FROM子句中
多行多列子查询
如:查询谁的工资大于salesman最大工资
SELECT name,salary
FROM emp
WHERE salary>ALL(SELECT salary
FROM emp
WHERE job='salesman')
EXISTS 查询判断
查询出数据返回true,反之false
例1:列出那些有员工的部门信息
SELECT deptno,dname FROM dept
WHERE EXISTS(SELECT * FROM emp
WHERE dept.deptno=emp.deptno);
例2:最低工资比3号部门最低工资高的部门
SELECT deptno,MIN(salary) FROM emp
GROUP BY deptno
HAVING MIN(salary)>(SELECT MIN(salary)
//此处不能使用WHERE MIN(salary) 因为WHERE用于第一次查询
FROM emp
而 MIN(salary)不能上来就获得。
WHERE deptno=3)
WHERE子句中不能使用聚合函数
例3:查询比自己部门平均工资高的那些员工
方式一:子查询在WHERE
SELECT deptno,name,salary
FROM emp e1
WHERE e1.salary>(SELECT AVG(salary)
FROM emp e2
WHERE e1.deptno = e2.deptno)
方式二: 子查询在FROM
SELECT name,deptno,salary
FROM emp e,(SELECT deptno,AVG(salary) avg_sal
FROM emp
GROUP BY deptno) a
WHERE e.deptno = a.deptno
AND e.salary > a.avg_sal
//在from子句中出现了子查询,那么意味着要将子查询的结果当做一张表去看待,
从中再次查询想要的结果。那么就应当注意:
子查询的SELECT语句中,出现了非字段名的字段(通常是表达式或函数),那么一定要给他们加上别名。
子查询在SELECT:
SELECT name,salary,(SELECT dname
FROM dept d
WHERE d.deptno = e.deptno)
FROM emp e
分页查询(此处为Oracle分页查询)
ROWNUM 行号
SELECT ROWNUM,id,name,gender
FROM emp
WHERE ROWNUM>3;//此处错误
//ROWNUM不能再第一次查询时作为where条件。ROWNUM有数据了才有值,where里出现:有值才有数据
分页查询
1.排序
总体过程:
SELECT deptno,name,salary
SELECT *
FROM emp
FROM (
ORDER BY deptno
SELECT ROWNUM rn,e.*
2.编号
FROM (
SELECT ROWNUM rn,e.*
SELECT deptno,name,salary
FROM () e
FROM emp
3.取范围
ORDER BY deptno
SELECT *
) e
FROM ()
)
WHERE rn BETWEEN 1 AND 5
WHERE rn BETWEEN 1 AND 5
分页的起始和结束 page:页数,pagesize: 每页的行数
(page-1)*pagesize+1 start
page*pagesize
end
DECODE
类似于Java中的switch case
如,分别给指定员工计算薪水
SELECT name,job,salary,
DECODE(job,
'manager',salary*1.2,
'boss',salary*1.3,
'clerk',salary*1.1,
salary
),bonus
FROM emp
DECODE 中 CASE...WHEN...THEN...语句
(和上边等价)
SELECT name,job,salary,
CASE job WHEN 'manager' THEN salary*1.2
WHEN 'boss' THEN salary*1.3
WHEN 'clerk' THEN salary*1.1
ELSE salary END
newsalary
FROM emp
利用DECODE自定义排序
SELECT * FROM emp
ORDER BY DECODE(name,
'henada',1,
'kakaxi',2,
'tom',3,
'boss',4,
5)
利用DECODE自定义分组
如:把3部门分一组,其他部门分另一组,并分别求出两组工资总和
SELECT DECODE(deptno,3,'组1','组2'),SUM(salary)
FROM emp
GROUP BY DECODE(deptno,
3,'组1',
'组2')
ROW_NUMBER 分组后将各组按某一个属性排序
1.SELECT name,salary,deptno,ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY salary DESC) as rank
FROM emp
2.RANK():生成组内不连续且不唯一的编号
3.DENSE_RANK()生成组内连续但不唯一的编号
SELECT name,salary,deptno,RANK() OVER(PARTITION BY deptno ORDER BY salary DESC) as rank
FROM emp
集合操作
并集:UNION/UNION ALL 既满足x,又满足y(UNION ALL中间交集出现两次,大于UNION中间交集出现一次)
SELECT name,job,salary FROM emp1
WHERE job='namager'
UNION
SELECT name,job,sal FROM emp2
WHERE salary>=2500;
交集:INTERSECT
SELECT name,job,salary FROM emp1
WHERE job='namager'
INTERSECT
SELECT name,job,sal FROM emp2
WHERE salary>=2500;
差集:MINUS (我有你没有的)
SELECT name,job,salary FROM emp1
WHERE job='namager'
MINUS
SELECT name,job,sal FROM emp2
WHERE salary>=2500;
ROLLUP 递减分组查询
如:按年、月、日排序后,查询每天、每月、每年销售额,以及总销售额
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM sales_table
GROUP BY ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id
CUBE 组合分组 比较全面
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM sales_table
GROUP BY CUBE(year_id,month_id,day_id) //此处3个属性,规律:2的3次方
ORDER BY year_id,month_id,day_id //则组合出8个分组:ymd,ym,yd,md,y,m,d,整体
GROUPING SETS
根据自己需求自己定义分组 比较灵活
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM sales_table
GROUP BY GROUPING SETS((year_id,month_id,day_id),(year_id,month_id))//查年-月-日、和年-月的分组
ORDER BY year_id,month_id,day_id
视图
什么是视图:本质:只包含映射到基表的一个查询语句
视图目的:简化复杂查询,隐藏一些数据
创建视图:CREATE VIEW view_name AS subquery(子查询语句);
试图创建后,可以像操作表一样操作视图,主要是查询sbuquery是select查询语句
对应的表称作基表
简单视图:没有以下这些
复杂视图:包含单行函数、表达式、分组函数或group by子句
连接试图:select语句是基于多个表
授权创建视图:
管理员通过DCL语句:GRANT CREAT VIEW TO lurenjia;
创建简单视图:
如:创建一个视图显示部门3中的员工
CREATE VIEW v_emp_3
AS SELECT deptno,name,salary
FROM emp
WHERE deptno=3;
WITH CHECK OPTION
查询视图结构:DESC view_name;
查看视图:SELECT * FROM view_name
修改视图内容后名字替换:如果有这个名字,就替换,不存在就替换
CREATE OR REPLACE VIEW v_emp_3
AS SELECT deptno,name,gender
FROM emp
WHERE deptno=3;
尽量避免使用DML操作视图,几乎不成功,因为视图可能只是表的一部分映射数据
删除视图时只能删除现有视图里能查到的记录
DML操作一般只能应用于简单视图,影响到基表数据
复杂视图不允许DML操作
DML操作不能违反基表的约束条件
创建具有CHECK OPTION约束的视图
最后加上 WITH CHECK OPTION
目的:插入和修改数据时数据必须得能显示到视图才行
创建具有READ ONLY约束的视图
最后加上 WITH READ ONLY
目的:限制对视图进行DML操作
查询USER_VIEWS获取相关信息
USER_OBJECTS:查询所有创建的数据库对象
USER_VIEWS:查询所有创建的视图对象
USER_UPDATE_COLUMNS:查询哪些列可以插入、修改或删除
在数据字典USER_OBJECTS中查询所有视图名称
SELECT object_name FR OM user_objects
WHERE object_type = 'VIEW';//查询所有表名称:'TABLE'
创建复杂视图
CREATE VIEW v_emp_salary
AS
SELECT d.deptno,avg(e.salary) avg_salary,sum(e.salary) sum_salary,
max(e.salary) max_salary, min(e.salary) min_salary
FROM emp e JOIN dept d
ON e.deptno = d.deptno
GROUP BY d.deptno;
删除视图:
删除视图不会影响表的数据
如:DROP VIEW view_name;
序列:
序列(SEQUENCE):用来生成唯一数字值的数据库对象
目的:用来生成主键值
1.UUID
2.SELECT sys_guid() FROM DUAL:生成一个32位的字符串序列值
若使用此,则此列数据类型用 char
(Java中UUID36位使用:String uuid = UUID.randomUUID().toString();
若也要统一到32位,则去掉4个-, uuid.replaceALL("-","");)
创建序列:
CREATE SEQUENCE sequence_name
START WITH i INCREMENT BY j
//i:起始数字 j:步进
MAXVALUE m | NOMAXVALUE
//设置最大值
MINVALUE n | NOMINVALUE
//设置最小值
CYCLE | NOCYCLE //是否循环 默认:NOCYCLE
CACHE p | NOCACHE
/是否缓存 默认缓存20个数据
序列中有两个伪列
NEXTVAL:获取序列的下个值
CURRVAL:获取序列的当前值
CREATE SEQUENCE emp_seq
START WITH 100
INCREMENT BY 10;
SELECT emp_seq.NEXTVAL FROM DUAL
SELECT emp_seq.CURRVAL FROM DUAL
将序列值作为主键插入表
INSERT INTO emp (id,name,salary,deptno)
VALUES(emp_seq.NEXTVAL,'ice',4700,7)
删除序列:DROP SEQUENCE emp_seq
索引:
索引是为了提高查询效率的一种机制
索引记录中存有索引关键字和指向表中数据的指针(地址)
创建索引:
//注意:一般索引加到表中经常查询用到的列(column)
CREATE INDEX index_name //index_name:索引名称
ON table(column);
//table:表名 column:列名
如:CREATE INDEX idx_emp_name ON emp(name);
创建复合索引(多列索引):
如:CREATE INDEX idx_emp_job_salary ON emp(job,salary);
创建基于函数的索引:
CREATE INDEX idx_emp_upper_name ON emp((UPPER(name));
修改索引(重建索引): 相当于刷新,一般用于数据频繁操作,需要定期重建索引
ALTER INDEX idx_emp_name REBUILD;
删除索引:
DROP INDEX index_name;
索引注意:
1.为经常出现在WHERE子句中的列创建索引
2.建索引列的顺序和ORDER BY中顺序一致
3.为经常作为表连接条件的列上创建索引
4.不要经常在DML操作的表上建立索引
5.不要在小表上建立索引
6.删除很少被使用的、不合理的索引
约束:
约束(COMSTRAINT)的全称是约束条件,数据表上强制执行的数据校验规则
约束条件:
1.非空约束 NOT NULL 简称 NN
(1)只能应用于列级约束,声明列同时给约束
CREATE TABLE employees(
eid NUMBER(6),
name VARCHAR2(30) NOT NULL,
salary NUMBER(7,2),
hiredate DATE
CONSTRAINT employees_hiredate_nn NOT NULL
);
(2)修改表时,定义添加非空约束
如:ALTER TABLE employees
MODIFY(eid NUMBER(6) NOT NULL);
(3)修改表时,取消非空约束
如:ALTER TABLE employees
MODIFY(eid NUMBER(6) NULL);
2.唯一性约束 UNIQUE 简称 UK
(1)用于保证字段或者字段的组合不出现重复值,但允许是NULL值
可以在建表时建立,也可以建表后建立
CREATE TABLE employees(
eid NUMBER(6),
name VARCHAR2(30) UNIQUE, //列级约束
email VARCHAR2(50),
salary NUMBER(7,2),
hiredate DATE,
CONSTRAINT employees_email_uk UNIQUE(email)--表级约束
);
(2)建表之后增加唯一性约束条件
ALTER TABLE employees
ADD CONSTRAINT employees_name_uk UNIQUE(name);
3.主键约束 PRIMARY KEY 简称 PK
一个表上只能建立一个主键 非空且唯一
逐渐选取原则:
1.主键一般是对系统无意义的数据
2.永远不要更新主键
3.主键不应包含动态变化的数据,如时间戳
4.主键应自动生成,尽量建立在单列上
如:CREATE TABLE employees2(
eid NUMBER(6) PRIMARY KEY,
name VARCHAR2(30),
email VARXHAR2(50),
salary NUMBER(7,2),
hiredate DATE
);
(2)建表之后增加主键约束条件
ALTER TABLE employees3
ADD CONSTRAINT employees3_eid_pk PRIMARY KEY(eid);
4.外键约束 FOREIGN KEY 简称 FK
一般是表级约束,保存另一张表主键值
如:先建表,在建表后建立外键约束条件
dept表:主表或父表
emp表:从表或子表
CREATE TABLE employees4(
eid NUMBER(6) ,
name VARCHAR2(30),
deptno NUMBER(6,2),
salary NUMBER(7,2)
);
ALTER TABLE employees4
ADD CONSTRAINT employees4_deptno_fk
FOREIGN KEY (deptno) REFERENCES dept(deptno);
简化开发,维护数据时不用考虑外键约束
5.检查约束 CHECK 简称CK
1.一般是表级约束
2.添加检查约束,添加后,插入数据时不能违反约束
如:员工薪水必须大于2000元,小于10000
ALTER TABLE employees4
ADD CONSTRAINT employees4_salary_check
CHECK(salary>2000 AND salary<10000);
3.删除约束:
ALTER TABLE employees4
DROP CONSTRAINT employees4_salary_check
查看emp表的约束的名字、约束的类型和约束条件
SELECT constraint_name,constraint_type,serch_condition
FROM user_constraints
WHERE table_name = 'emp';
SELECT * FROM ALL_TABLES;系统里有权限的表
SELECT * FROM DBA_TABLES; 系统表
SELECT * FROM USER_TABLES; 当前用户下的表
<结束>
CREATE TABLE account(
id NUMBER(9) NOT NULL,
remmber_id NUMBER(9),
login_name VARCHAR(30) NOT NULL,
login_passwd VARCHAR2(8) NOT NULL,
status CHAR(1) NOT NULL,
create_date DATE DEFAULT SYSDATE,
pause_date DATE,
close_date DATE,
real_name VARCHAR2(20) NOT NULL,
idcard_no CHAR(18) NOT NULL,
birthdate DATE,
gender CHAR(1) NOT NULL,
occupation VARCHAR2(50),
telephone VARCHAR2(15) NOT NULL,
email VARCHAR2(50),
mailaddress VARCHAR2(50),
zipcode CHAR(6),
qq VARCHAR2(15),
last_login_time DATE,
last_login_ip VARCHAR2(15)
)
RENAME account TO t_account;
ALTER TABLE t_account ADD(bak VARCHA2(50));
ALTER TABLE t_account MODIFY(bak VARCHAR2(40));
ALTER TABLE t_account DROP(bak);
SELECT * FROM t_account;
INSERT INTO t_account(id,login_name,login_passwd,create_date,
real_name,idcard_no,telephone)
VALUES(1,'shiyl',256528,TO_DATE('2008-01-28','YY-MM-DD'),
'shiyuanli','410323199925254410','15456548565');
UPDATE t_account
SET login_passwd='801206'
WHERE id=1;
DELETE FROM t_account
WHERE id=1;
MySQL安装配置:
安装完后配置在bin目录下找到MySQLinstanceconfig.exe文件开始配置
选择标准配置
dos命令进入本地数据库:mysql -uroot -p -P3306 -h127.0.0.1