sequence 序列、synonym同义词、DBLink连接、索引index、view视图、数据建模、PL/SQL 语言
接着前天的多表连接、子查询、分组查询等知识点,今天继续分享心得知识点。
sequence 序列
--序列可以让主键自动增长
--使用的时候,要先创建
create sequence stu_seq;
create table tb_class(
id int primary key,
code varchar(20)
);
insert into tb_class values(stu_seq.nextval,'java091');
select * from tb_class;
insert into tb_class values(stu_seq.nextval,'java09');
--synonym同义词
--先创建,后使用
create synonym myclass for tb_class;
select * from myclass;--用myclass代替了tb_class表,也就是别名。
select * from tb_class;
---- DBLink连接
--找到oracle的安装路径
--C:\oracle\product\11.1.0\db_1\NETWORK\ADMIN
--1、listener.ora监听器
--2、sqlnet.ora网络
--3、tnsnames.ora tns配置文件
--创建连接
create database link hello
connect to system identified by "1234"
using '(DESCRIPTION=
(ADDRESS_LIST=(
ADDRESS=(PROTOCOL=TCP)(HOST=10.25.161.113)(PORT=1521))
)
(CONNECT_DATA=(SERVER=DEDICATED)
(SERVICE_NAME=Oracle)
)
)';
select * from scott.emp@hello;
如何优化你的数据库查询?
1、数据库的查询方式,三种:
--全表扫描,最慢,select * from tb_stu;
--利用索引扫描,快,推荐使用。方式是key-value
--共享语句:必须建立在全表扫描的基础上,已经查询过的数据留在缓存中,直接去缓存中查找。
index索引
作用:在数据库中用来加速对于表的查询。(也就是优化数据库)
原理:通过使用快速路径访问方法快速定位数据,减少磁盘的I/O.
特点2个:与表独立存放,但不能独立存在,必须属于某个表。
由数据库自动维护,当表被删除时,该表上的索引自动被删除。
--索引的建立
自动:当建立一个表的时候,定义主键primary key或者unique约束条件时,数据库自动创建索引。
手动:用户可以创建索引加速查询(最好是指定经常要查询的字段)
--怎么工作的:当创建索引的时候,oracle 会默认建立一张与当前表相关的索引页,里面保存了索引字段和对应的真实的磁盘地址,当用户发送sql
语句带来索引的时候,oracle会到索引页中查询索引字段,直接定位磁盘的IO,提取数据。
select * from tb_stu;
insert into tb_stu values(1,'jss',1);
--创建索引index
create index 索引名 on 表名(需要索引的字段);
create index 索引名 on 表名(索引字段);
eg:
create index stu_index on tb_stu(name);
select * from tb_stu where name="翠花";
--多使用共享语句,可以到达sql语句的优化。
--特殊的:当sql语句中包含not in ,<>不等于,is not null,like '%%'的时候不会建立索引。
in:会堆成一堆or,可以使用表的索引。
not in :强烈推荐不使用。因为它不能应用表中的索引。
<>操作符 不等于:是永远不会有用到索引的,因此它只会建立全表查询。(优化的方案:用其他相同功能的代替,比如:a<>0,改成a<0 or a>0,a<>’’ 改为 a>’’)
is null或者is not null (判断字段是否为空):判断字段是否为空一般也是不应用索引的,优化方法跟<>一样。
like :like操作符可以应用通配符查询,但是用的不好则会产生性能上的问题。
优化方案:如LIKE ‘%001%’ 这种查询不会引用索引,会产生全表扫描,
而LIKE ‘001%’则会引用范围索引。进行范围的查询,性能肯定大大提高。
create table aaa (
comm int default 0,
status varchar(20) default '已发'
);
create table bbb (
email varchar(50) default '[email protected]'
);
select * from aaa where comm is null; -- 不会用到 index
select * from bbb where email = '[email protected]'; -- 会用到 index
--视图:
- 创建表空间
create tablespace Jss
datafile 'F:\dataspace\jss.dbf'
size 20M
autoextend on; -- 自动扩展,如果容量不够的话,则自动加
-- 千万记得:不能手动到路径下把生成的 xxx.dbf 文件删掉。
-- 如果需要删除表空间
drop tablespace jss including contents and datafiles;
-- 查询所有的表空间
select * from DBA_tablespaces;
-- 查询所有的数据文件
select * from Dba_Data_Files;
-- 创建用户
create user lin -- 用户名
identified by 1234 -- 密码
default tablespace jss -- 对应的表空间
temporary tablespace temp -- 临时表空间
-- 删除用户
drop user jss;
-- 查询所有的用户
select * from Dba_Users;
-- 给用户加锁和解锁
alter user jss account lock;
alter user jss account unlock;
-- 操作权限
-- 连接权限
grant connect to jss;
-- 如果 jss 有连接权限,可以指定给 admin 账户
grant connect to jss with admin option;
-- 如果想要放大权限的话,可以指定 DBA 权限给它
grant dba to jss with admin option;
grant dba to jss with admin option;
-- 收回权限
revoke connect from jss;
revoke dba from jss;
创建用户的时候通过dba赋予的权限,创建视图的时候会报:没有权限。
--解决方案:使用system登录,再给用户赋予权限。
grant create any table to jss with admin option;
grant create any view to jss with admin option;
graant select any table to jss with admin option;
--看看视图是怎么样让查询变的简单的:
select deptno 部门, sum(sal) 总薪资, max(sal) 最大值--注意要给别名,不然会出错
from scott.emp
group by deptno;
create view aaa
as
select deptno 部门, sum(sal) 总薪资, max(sal) 最大值--注意要给别名,不然会出错
from scott.emp
group by deptno;
接着:
select * from aaa;
--复杂视图(多个表)
create view bbb
as
select d.dname 部门, d.loc 地址, e.*
from scott.dept d, scott.emp e
where d.deptno = e.deptno
select * from bbb;
--删除视图
drop view aaa;
--注意:可以通过视图操作表,但是不建议。
软件开发过程:
1. 需求调研,与客户进行沟通
2. 需求分析,将现实工作中的动作模拟到计算机
数据建模
3. 开发
4. 测试
5. 上线部署
从关系数据库的表中删除冗余信息的过程称为规范化,
是得到高效的关系型数据库表的逻辑结构最好和最容易的方法。
获得数据规范化的方法: 三范式
第一范式:必须要有主键,并且每个属性值,都是不可再分的最小数据单位,
则称R是第一范式的关系。
第二范式:所有非主关键字都完全依赖于主关键字(通常用于联合主键)
第三范式:非主关键字不能依赖于其他非主关键字(通常用于一个主键)
-- 有 N 个班级,有 N 个学生,有 N 门课程
-- 一个班可以有多个学生,一个学生只能属于一个班,
-- 一个学生可以选修多门课程,一门课程可以被多个学生选修
数据建模
1. 根据三个范式
2. 分析实体之间的关系, ER 图 Entity-Reference(画出来看,会明显很多)
一对一:一个人只有一个身份证,唯一外键关联或者主键关联。
一对多:一个班级可以有多个学生。一个学生只属于一个班级(clazz - student)
关联:一对多使用主外键关联,通常在多方(student)建立外键
多对多:一个学生可以选择多门课程,一门课程可以被多个学生选修 (student - course)
关联:多对多通常使用中间表(再多建一张表存储)关联数据
通常中间表会有两张表的id作为联合主键,并且作为外键指向关联表
下面有个实例:
网上购书
图书表: id、书名、出版社、出版时间、价格、作者、描述
用户表:id、姓名、地址、电话、email
订单表: id、编号code
-- 用户表
create table tb_user (
id int primary key,
name varchar(20) not null,
address varchar(50) default '广州天河',
phone varchar(20) unique,
email varchar(20) unique
);
insert into tb_user
values (1, '翠花', '中国香港', '13800138000', '[email protected]');
insert into tb_user
values (2, '春花', '中国台湾', '13800138001', '[email protected]');
-- 图书表
create table tb_book (
id int primary key,
title varchar(50) not null,
publication varchar(20) not null,
publictime date,
price number,
author varchar(20),
note varchar(100)
)
insert into tb_book
values (1, 'Java 从入门到放弃', '电子工业出版社', sysdate, 100, 'Jss', '很好的书');
insert into tb_book
values (2, 'Python 从入门到放弃', '电子工业出版社', sysdate, 120, 'Jss', '很好的书');
insert into tb_book
values (3, 'C++ 从入门到放弃', '电子工业出版社', sysdate, 99, 'Jss', '很好的书');
-- 订单表
create table tb_order (
id int primary key,
orderno varchar(30) not null,
user_id int,
foreign key (user_id) references tb_user(id)
);
insert into tb_order
values (1, '001', 1);
insert into tb_order
values (2, '002', 1);
insert into tb_order
values (3, '003', 2);
-- 订单和书籍是多对多的关系,创建中间表维护关联关系
create table tb_order_book (
order_id int,
book_id int,
count int,
primary key(order_id, book_id),
foreign key(order_id) references tb_order(id),
foreign key(book_id) references tb_book(id)
);
insert into tb_order_book
values (1, 1, 2);
insert into tb_order_book
values (2, 1, 5);
insert into tb_order_book
values (3, 3, 10);
select * from tb_user;
select * from tb_book;
select * from tb_order;
3. 查询“翠花”的详细信息,包括:
用户信息、订单信息、购买书籍名称、购买的数量
select u.name 名字, o.orderno 订单号, b.title 图书名称, ob.count 数量
from tb_user u, tb_order o, tb_book b, tb_order_book ob
where u.id = o.user_id
and b.id = ob.book_id
and o.id = ob.order_id
and u.name = '翠花';
- PL/SQL 也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL),是 Oracle 数据库对 SQL 语句的扩展。 PL/SQL 只有 Oracle 数据库有。
-- MySQL 目前不支持 PL/SQL 的,但支持 Navicat Premium。
-- 实际开发中,我们一般都是通过 Java 代码来处理数据
-- 将处理好的结果,再交给 SQL 去执行即可。
-- 语法格式
declare -- 声明部分
-- 定义变量
begin -- 开始
-- 主要内容
exception -- 处理异常
end; -- 结束
declare --声明
begin--开始,主要内容
end;结束
--打印语句
begin
--包.方法(存储过程)
dbms_output.put_line('jss打游戏打不过人家。。。');
end;
--定义变量
declare
vid int;
vname varchar(20):='jss';--:=是赋值
begin
dbms_output.put_line('jss打游戏打不过人家。。。');
end;
--复杂类型
declare
vid int;
vname varchar(20);
type car is record(--复杂类型的声明:type car is record
id int,
name varchar(20),
price number
);
--如果要给复杂类型数据赋值,需要给它一个变量才可以。
vcar car;
begin
--declare处声明,begin处赋值
vname:='jss';
vcar.name:='BMW X6';
dbms_output.put_line(vname||'就算有'||vcar.name||'jss打游戏打不过人家。。。');--连接字符用||
end;
PL/SQL的使用:插入数据、查询数据、for循环,if else逻辑语句
--插入数据
declare
vid int:=1;
vname varchar(20):='花花';
begin
insert into tb_stu(id,name) values (vid,vname);
end;
--查询数据(查询在声明变量中有的字段)
declare
vid int:=1;
vname varchar(20);
begin
select name into vname from tb_stu where id=vid;
dbms_output.put_line(vname);
end;
--if else逻辑语句
--if
declare
i number:=10;
begin
if(i=10) then
dbms_output.put_line('此处打印出10...');
end if;--要给if 结束语句end if;
end;--每句后面都加个;来去隔开。
--if else
declare
i number:=20;
begin
if(i=10) then
dbms_output.put_line('此处打印出10...');
else
dbms_output.put_line('此处打印的不是10...');
end if;--要给if 结束语句end if;
end;
--if...else if
declare
i number:=20;
begin
if(i=10) then
dbms_output.put_line('此处打印出10...');
else if(i=20)
dbms_output.put_line('此处打印的是20...');
else
dbms_output.put_line('此处打印出不是10,也不是20...');
end if;--要给if 结束语句end if;
end;
--loop循环
declare
i number:=0;
begin
loop
i:=i+1;
dbms_output.put_line('jss...');
exit when i=5;
end loop;
end;
--for循环
declare
i number:=0;
begin
for i in 1..6--for用来指定条件
loop
dbms_output.put_line('jss...');
end loop;
end;
--while循环
declare
i number:=0;
begin
while i<6
loop
dbms_output.put_line('cuihua..');
i:=i+1;
end loop;
end;