脚本宝典收集整理的这篇文章主要介绍了Oracle知识学习记录(一),脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
表空间
图1:
图2:
双击 windows2003中的 Windows Server 2003 Enterprise EdITion.vmx
外部虚拟网卡:192.168.80.6
虚拟机内部:192.168.80.10
orcl /root
安装成功后无图形界面,可再cmd窗口输入:SQLplus System/root 出现SQL> 代表连接数据库成功
将instantclient_12_1放到D盘,在cmd窗口,进入D盘的instantclient_12_1目录,输入sqlplus system/root@192.168.80.10:1521/orcl
配置tnsnames.ora
配置环境变量:TNS_ADMIN
配置编码集:
--创建表空间
create tablespace waterboss
datafile 'c:waterboss.dbf'
size 100m
autoextend on
next 10m;
--创建用户
create user wateruser
identified by root--密码
default tablespace waterboss;
--给wateruser赋予bda权限
grant dba to wateruser;
数据类型:
(1)CHAR : 固定长度的字符类型,最多存储 2000 个字节
(2)VArchAR2 :可变长度的字符类型,最多存储 4000 个字节
(3)LONG : 大文本类型。最大可以存储 2 个 G
数值型
NUMBER : 数值类型
例如:NUMBER(5) 最大可以存的数为 99999
NUMBER(5,2) 最大可以存的数为 999.99
日期型
(1)DATE:日期时间型,精确到秒
(2)TIMESTamP:精确到秒的小数点后 9 位
二进制型(大数据类型)
(1)CLOB : 存储字符,最大可以存 4 个 G
--创建业主表
create table t_owners(
id number Primary key,
name VARchar2(30),
addressid number,
housenumber varchar2(30),
watermeter varchar2(30),
adddate date,
ownertyPEid number
);
ALTER TABLE 表名称 ADD(列名 1 类型 [DEFAULT 默认值],列名 1 类型
[DEFAULT 默认值]...)
--追加字段
ALTER TABLE T_OWNERS ADD
(
REMARK VARCHAR2(20),
OUTDATE DATE
)
ALTER TABLE 表名称 MODIFY(列名 1 类型 [DEFAULT 默认值],列名 1 类型
[DEFAULT 默认值]...)
--修改字段类型
ALTER TABLE T_OWNERS MODIFY
(
REMARK CHAR(20),
OUTDATE TIMESTAMP
)
ALTER TABLE 表名称 rename COLUMN 原列名 TO 新列名
ALTER TABLE T_OWNERS RENAME COLUMN OUTDATE TO EXITDATE
--删除一个字段
ALTER TABLE 表名称 DROP COLUMN 列名
--删除多个字段
ALTER TABLE 表名称 DROP (列名 1,列名 2...)
--删除字段
ALTER TABLE T_OWNERS DROP COLUMN REMARK
DROP TABLE 表名称
比较 truncate 与 delete 实现数据删除?
整库导出命令
exp system/root full=y -- 添加参数 full=y 就是整库导出
执行命令后会在当前目录下生成一个叫 EXPDAT.DMP,此文件为备份文件。 如果想指定备份文件的名称,则添加 file 参数即可,命令如下
exp system/root file=water.dmp(文件名) full=y
**整库导入命令 **
imp system/root full=y
此命令如果不指定 file 参数,则默认用备份文件 EXPDAT.DMP 进行导入 如果指定 file 参数,则按照 file 指定的备份文件进行恢复
imp system/root full=y file=water.dmp
按用户导出
exp system/root owner=wateruser file=wateruser.dmp
按用户导入
imp system/root file=wateruser.dmp Fromuser=wateruser
按表导出
exp wateruser/root file=a.dmp tables=t_account,a_area
用 tables 参数指定需要导出的表,如果有多个表用逗号分割即可
按表导出
imp wateruser/root file=a.dmp tables=t_account,a_area
--整条记录去重
select distinct t.addressid,t.ownertypeid from t_owners t ;
--伪劣 rowid(物理地址)
select rowid,t.* from t_owners t;
--伪劣 rownum(查询记录的行号)
select rownum,t.* from t_owners t where t.id>3;
--取和:sum()
select sum(a.usenum) from t_account a where a.year='2012';
--取平均值:avg()
select avg(a.usenum) from t_account a where a.year='2012';
--最大值
select max(a.usenum) from t_account a where a.year='2012';
--最小值
select min(a.usenum) from t_account a where a.year='2012';
--count
select count(1) from t_account a where a.year='2012';
--分组
select a.areaid,sum(a.money) from t_account a group by a.areaid;
--分组后条件查询 having
select a.areaid,sum(a.money) from t_account a group by a.areaid having sum(a.money)>169000;
--内连接
select a.name 业主名,
b.name 业主类型,
c.name 地址,
d.name 区域,
e.name 收费员
from t_owners a, t_ownertype b, t_address c, t_area d, t_operator e
where a.ownertypeid = b.id
and a.addressid = c.id
and c.areaid = d.id
and c.operatorid = e.id;
--左连接(左表数全部展示出来,右表显示空)
--sql1999语法
select ow.name, ac.year, ac.month, ac.money
from t_owners ow left join t_account ac
on ow.id = ac.owneruuid;
--oracle语法
select ow.name, ac.year, ac.month, ac.money
from t_owners ow , t_account ac
where ow.id = ac.owneruuid(+);
--右连接(右表数全部展示出来,左表显示空)
--sql1999语法
select ow.name, ac.year, ac.month, ac.money
from t_owners ow right join t_account ac
on ow.id = ac.owneruuid;
--oracle语法
select ow.name, ac.year, ac.month, ac.money
from t_owners ow , t_account ac
where ow.id(+) = ac.owneruuid;
from 后面:查询语句的查询结果可作为一张表
select查出的结果作为字段值
rownum:按行扫描,给出行号,一层查询只能用<,<=
select * from (select rownum r, a.* from t_account a where a.year = '2012')
where r <= 20 and r > 10;--两层查询
select *
from (select rownum r, t.*
from (select *
from t_account a
where a.year = '2012'
order by a.usenum desc) t)
where r <= 20
and r > 10;--三层查询
--字符函数
select length('asd') from dual ;--3
--substr 第2个参数:从下标开始截取;第3个参数:截取几位
select substr('abcdef',2,4) from dual;--bcde
select concat('ab','cd') from dual;--abcd
select 'a'||'b'||'c' from dual;--abc
--数值函数
--四舍五入,只有一个参数时四舍五入为整数
select round(100.456,2) from dual;--100.46
--截取,只有一个参数时截取到整数
select trunc(100.456,2) from dual;--100.45
--取模
select mod(10,3) from dual;--1
--日期函数
select sysdate from dual;--2021/10/18 17:32:27
--一个月后的日期
select add_months(sysdate,1) from dual;--2021/11/18 17:33:25
--月的最后一天
select last_day(sysdate) from dual;--2021/10/31 17:35:14
select last_day(sysdate-18) from dual;--2021/9/30 17:36:02
--截取
select trunc(sysdate) from dual;--2021/10/18
--截取到年(的第一天)
select trunc(sysdate,'yyyy') from dual;--2021/1/1
--截取到月(的第一天)
select trunc(sysdate,'mm') from dual;--2021/10/1
--截取到时
select trunc(sysdate,'hh') from dual;--2021/10/18 17:00:0
--截取到分
select trunc(sysdate,'mi') from dual;--2021/10/18 17:37:00
--转换函数
--to_char 数字转字符串
select to_char(100) from dual;
--to_char 日期转字符串
select sysdate from dual;--2021/10/18 17:54:53
select to_char(sysdate,'yyyy-mm-dd HH:mi:ss') from dual;--2021-10-18 05:55:40
--to_date 字符串转日期
select to_date('2020-10-10','yyyy-mm-dd') from dual;--2020/10/10
select to_date('20201010','yyyymmdd') from dual;--2020/10/10
--to_number 字符串转数字
select to_number('200') from dual;
--其他函数
--nvl(param1,param2)如果第一个参数是null,返回第二个参数,否则返回第一个参数
select nvl(null,0) from dual;--0
select nvl(100,0) from dual;--100
--nvl2(param1,param2,param3)如果第一个参数是null,返回第三个参数,否则返回第二个参数
select nvl2(200,100,0) from dual;--100
select nvl2(null,100,0) from dual;--0
select nvl2(a.maxnum,to_char(maxnum),'上限') from t_PRicetable a where a.ownertypeid='1';
--decode
select a.name,
a.ownertypeid,
decode(a.ownertypeid, 1, '居民', 2, '行政单位', 3, '商业','其他')
from t_owners a;
--case when then else end
select a.name,
a.ownertypeid,
case a.ownertypeid
when 1 then
'居民'
when 2 then
'行政单位'
when 3 then
'商业'
else
'其他'
end
from t_owners a;
--行列转换
select (select b.name from t_area b where b.id=a.areaid) 区域,
sum(case when a.month='01' then money else 0 end ) 一月,
sum(case when a.month='02' then money else 0 end ) 二月,
sum(case when a.month='03' then money else 0 end ) 三月,
sum(case when a.month='04' then money else 0 end ) 四月,
sum(case when a.month='05' then money else 0 end ) 五月,
sum(case when a.month='06' then money else 0 end ) 六月,
sum(case when a.month='07' then money else 0 end ) 七月,
sum(case when a.month='08' then money else 0 end ) 八月,
sum(case when a.month='09' then money else 0 end ) 九月,
sum(case when a.month='10' then money else 0 end ) 十月,
sum(case when a.month='11' then money else 0 end ) 十一月,
sum(case when a.month='12' then money else 0 end ) 十二月
from t_account a
where a.year = '2012' group by a.areaid;
--行列转换
select (select b.name from t_area b where b.id=a.areaid) 区域,
sum(case when a.month>='01' and a.month<='03' then money else 0 end ) 第一季度,
sum(case when a.month>='04' and a.month<='06' then money else 0 end ) 第二季度,
sum(case when a.month>='07' and a.month<='09' then money else 0 end ) 第三季度,
sum(case when a.month>='10' and a.month<='12' then money else 0 end ) 第四季度
from t_account a
where a.year = '2012' group by a.areaid;
--decode
select (select b.name from t_area b where b.id=a.areaid) 区域,
sum(decode (a.month,01,money,02,money,03,money, 0 )) 第一季度,
sum(decode (a.month,04,money,05,money,06,money, 0 )) 第二季度,
sum(decode (a.month,07,money,08,money,09,money, 0 )) 第三季度,
sum(decode (a.month,10,money,11,money,12,money, 0 )) 第四季度
from t_account a
where a.year = '2012' group by a.areaid;
--分析函数
--rank() 值相同,排名相同,排名跳跃
select rank() over(order by t.usenum desc) 排名, t.* from t_account t ;
--dense_rank( )值相同,排名相同,排名连续
select dense_rank() over(order by t.usenum desc) 排名, t.* from t_account t ;
--row_number() 值相同,排名连续
select row_number() over(order by t.usenum desc) 排名, t.* from t_account t ;
--row_number() 分页(由rownum的三层查询变为两层)
select * from(
select row_number() over(order by t.usenum desc) r, t.* from t_account t)
where r<=20 and r>10;
--集合运算
--union 去重
select * from t_owners t where t.id <8
union
select * from t_owners t where t.id >5;
--union all 有重复记录
select * from t_owners t where t.id <8
union all
select * from t_owners t where t.id >5;
--intersect 交集
select * from t_owners t where t.id <8
intersect
select * from t_owners t where t.id >5;
--minus 差集
select * from t_owners t where t.id <8
minus
select * from t_owners t where t.id >5;
视图是一个虚表,可以将多表查询sql定义为一个视图
使用视图的优点:
创建视图:
CREATE [OR REPLACE] [FORCE] VIEW view_name
AS subquery
[WITH CHECK OPTION ]
[WITH READ ONLY]
OR REPLACE :若所创建的试图已经存在,ORACLE 自动重建该视图;
FORCE :不管基表是否存在 ORACLE 都会自动创建该视图;
subquery :一条完整的 SELECT 语句,可以在该语句中定义别名;
WITH CHECK OPTION :插入或修改的数据行必须满足视图定义的约束;
WITH READ ONLY :该视图上不能进行任何 DML 操作。
删除视图:
DROP VIEW view_name
--创建视图 :业主类型为 1 的业主信息
create or replace view view_owners1 as
select * from t_owners a where a.ownertypeid='1';
总结:视图是虚表,存放的是sql语句并非数据,对视图的操作就是对表的操作,修改视图后表的数据会跟着变,修改表数据后视图数据也会变
--根据地址表(T_ADDRESS)创建视图 VIEW_ADDRESS2 ,内容为区域 ID为 2 的记录。
create or replace view view_address2 as
select * from t_address a where a.areaid='2'
with check option;
--错误语法,with check option不能修改视图中的条件的值
update view_address2 a set a.AREAID='3' where a.ID='3';
--创建只读视图 :业主类型为 1 的业主信息
create or replace view view_owners1 as
select * from t_owners a where a.ownertypeid='1'
with read only;
--只读视图不能修改,会报错
update view_owners1 a set a.NAME='范小冰' where a.ID='1';
--创建带错误的视图
create force view view_test as
select * from test;
--复杂视图(多表关联)
--创建视图,查询显示业主编号,业主名称,业主类型名称
create or replace view view_owners as
select o.id 业主编号,o.name 业主名称,ot.name 业主类型名称
from t_owners o,t_ownertype ot where o.ownertypeid=ot.id;
--修改成功
update view_owners a set a.业主名称='范小冰' where a.业主编号='1';
--修改失败(错误原因见下图),只有键保留表的列才可修改
update view_owners a set a.业主类型名称='业主' where a.业主编号='1';
键保留表:
一个表的主键在视图中也是主键,则这个表是键保留表
在我们这个例子中,视图中存在两个表,业主表(T_OWNERS)和业主类型表 (T_OWNERTYPE), 其中 T_OWNERS 表就是键保留表,因为 T_OWNERS 的 主键也是作为视图的主键。键保留表的字段是可以更新的,而非键保留表是不能 更新的。
--复杂视图(聚合函数)
--创建视图,按年月统计水费金额
create view view_accoutsum as
select a.year, a.month, sum(a.money) money
from t_account a
group by a.year, a.month
order by a.year, a.month;
--此例用到聚合函数,没有键保留表,无法执行 update 。
update view_accoutsum a set a.money='10000'
where a.year='2012' and a.month='03' ;
视图是一个虚拟的表,存放的sql语句;物化视图类似于实体表,会存放具体的数据。
物化视图与普通的视图相比的区别是物化视图是建立的副本,它类似于一张 表,需要占用存储空间。而对一个物化视图查询的执行效率与查询一个表是一样 的。
视图不占存储空间,查询慢;物化视图占存储空间,查询快
CREATE METERIALIZED VIEW view_name
[BUILD IMMEDIATE | BUILD DEFERred ]
REFRESH [FAST|complete|FORCE]
[
ON [COMMIT |DEMAND ] | START WITH (start_time) NEXT
(next_time)
]
AS
subquery
BUILD DEFERRED 则在创建时不生成数据,以后根据需要再生成数据。
默认为 BUILD IMMEDIATE。
REFRESH 后跟着指定的刷新方法有三种:FAST、COMPLETE、FORCE。
FAST 刷新采用增量刷新,只刷新自上次刷新以后进行的修改。
COMPLETE 刷新对整 个物化视图进行完全的刷新。
如果选择 FORCE 方式,则 Oracle 在刷新时会去判 断是否可以进行快速刷新,如果可以则采用 FAST 方式,
否则采用 COMPLETE 的方式。
FORCE 是默认的方式。
刷新的模式有两种:ON DEMAND 和 ON COMMIT。
ON DEMAND 指需要 手动刷新物化视图(默认)。
ON COMMIT 指在基表发生 COMMIT 操作时自动 刷新。
--创建手动刷新的物化视图
--需求:查询地址 ID,地址名称和所属区域名称
create MATErialized view mv_address as
select ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;
--查询物化视图
select * from mv_address;
--这时,我们向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(8,'西三旗',2,2);
commit;
--插入后查询基表t_address,发现多了一条记录
select * from t_address;
--查询物化视图mv_address,发现没有新增记录,因为默认是手动刷新
select * from mv_address;
--需要通过下面的语句(PL/SQL),手动刷新物化视图
Begin
DBMS_MVIEW.refresh('MV_ADDRESS','C');
END;
--或者在命令窗口通过下面的命令手动刷新物化视图:
SQL> EXEC DBMS_MVIEW.refresh('mv_address','C')
PL/SQL procedure successfully completed
--执行完后发现物化视图多了一条记录
--创建自动刷新的物化视图
--需求:查询地址 ID,地址名称和所属区域名称
create materialized view mv_address2
refresh
on commit
as
select ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;
--这时,我们向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(10,'西五旗',2,2);
--查询物化视图,发现多了一条记录
select * from mv_address2;
--创建时不生成数据的物化视图
create materialized view mv_address3
build deferred
refresh
on commit
as
select ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;
--这时,我们向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(11,'西六旗',2,2);
commit;
--查询物化视图,发现没有记录
select * from mv_address3;
--第一次时,手动刷新数据,以后会自动刷新
begin
dbms_mview.refresh('mv_address3','C');
end;
--这时,我们再向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(12,'西七旗',2,2);
commit;
--再次查询物化视图,发现自动新增一条西七旗记录
select * from mv_address3;
--4.创建增量刷新的物化视图
--创建增量刷新的物化视图前提1:
--创建基表的日志(创建的物化视图日志名称为 MLOG$_表名称)
create materialized view log on t_address with rowid;
create materialized view log on t_area with rowid;
----创建增量刷新的物化视图前提2:列出rowid
create materialized view mv_address4
refresh fast
as
select ad.rowid adrowid,ar.rowid arrowid,ad.id,ad.name,ar.name arname
from t_address ad,t_area ar
where ad.areaid=ar.id;
--查询物化视图,共12条数据
select * from mv_address4;
--这时,我们向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(13,'西八旗',2,2);
commit;
--这时,我们向基表地址表(T_ADDRESS)中插入一条新记录
insert into t_address values(14,'西九旗',2,2);
commit;
--这时,删除id是13的数据
delete from t_address where id=13;
commit;
--观察日志表(见下图),日志表的数据在刷新后会删除
--手动刷新
begin
dbms_mview.refresh('MV_ADDRESS4','C');
END;
--再次查询物化视图,发现已新增id为14的数据
select * from mv_address4;
日志表截图如下:
SNAPTIME$$:用于表示刷新时间。
DMLTYPE$$:用于表示 DML 操作类型,I 表示 INSERT,D 表示 DELETE,U 表示 UPDATE。
OLD_NEW$$:用于表示这个值是新值还是旧值。N(EW)表示新值,O(LD) 表示旧值,U 表示 UPDATE 操作。
CHANGE_VECTOR$$:表示修改矢量,用来表示被修改的是哪个或哪几个字段。 此列是 RAW 类型,其实 Oracle 采用的方式就是用每个 BIT 位去映射一个列。 插入操作显示为:FE, 删除显示为:OO 更新操作则根据更新字段的位置而显示 不同的值。
Oracle提供的用于产生一系列唯一数字的数据库对象
通过序列的伪列来访问序列的值 :
NEXTVAL 返回序列的下一个值
CURRVAL 返回序列的当前值
--创建简单序列
create sequence test;
--查询下一个序列
select test.nextval from dual;
--查询当前序列
select test.currval from dual;
注意:我们在刚建立序列后,无法提取当前值,只有先提取下一个值时才能再次 提取当前值。
CREATE SEQUENCE sequence //创建序列名称
[INCREMENT BY n] //递增的序列值是 n 如果 n 是正数就递增,如果是负数就递减 默
认是 1
[START WITH n] //开始的值,递增默认是 minvalue 递减是 maxvalue
[{MAXVALUE n | NOMAXVALUE}] //最大值
[{MINVALUE n | NOMINVALUE}] //最小值
[{CYCLE | NOCYCLE}] //循环/不循环
[{CACHE n | NOCACHE}];//分配并存入到内存中
--复杂序列-有最大值的非循环序列
create sequence seq_test
increment by 5
start with 5
minvalue 1
maxvalue 20;
select seq_test.nextval from dual
结果:5,10,15,20
注意: 开始值不能小于最小值 ;序列超过maxvalue会报错
--复杂序列-有最大值的循环序列
create sequence seq_test2
increment by 1
start with 5
minvalue 1
maxvalue 25
cycle;
select seq_test2.nextval from dual;
结果:5,6,...24,25,1,2,...24,25,1,2,...24,25...
**注意:循环的序列,第一次循环是从开始值开始循环,而第二次循 环是从最小值开始循环。 **
--复杂序列--带缓存的序列
create sequence seq_test3
increment by 10
start with 10
minvalue 10
maxvalue 100
cycle
cache 10;
执行报错:
我们的 cache 是 10,每次增长值是 10。这样 10 次缓存提取出 的数是 100 (10*10)
minvalue是10,maxvalue是100时,之间的数为90个; 把最小值减 1,或把最大值加 1,都可以通过。
--复杂序列--带缓存的序列
create sequence seq_test3
increment by 10
start with 10
minvalue 10
maxvalue 101--修改为101
cycle
cache 10;
select seq_test3.nextval from dual;
结果:10,20,30,...100,10,20,30,...100...
--修改序列(不能更改序列的 START WITH 参数 )
--语法:ALTER SEQUENCE 序列名称 MAXVALUE 5000 CYCLE;
alter sequence seq_test3 maxvalue 102;
--删除序列
--语法: DROP SEQUENCE 序列名称;
drop sequence test;
同义词是基对象的一个别名,包含公共同义词( PUBLIC修饰)和私有同义词 。
公共同义词:数据库的所有用户都能访问;
私有同义词: 只允许特定用户或有基对象访问权限的用户进行访问
create [public] synonym 同义词名 for object;
object 表示表,视图,序列等我们要 创建同义词的对象的名称。
--私有同义词
create synonym owner for t_owners;
--通过同义词查询t_owners
select * from owner;
私有同义词只有当前用户可以使用
--公有同义词
create public synonym owner2 for t_owners;
--通过同义词查询t_owners
select * from owner2;
公有同义词所有用户可以使用
create index 索引名称 on 表名(列名);
--我们经常要根据业主名称搜索业主信息,所以我们基于业主表的 name 字段来建立索引
create index index_owners_name on t_owners(name);
--索引性能测试
--创建一个两个字段的表
create table indextest(
id number,
name varchar2(30)
);
select * from indextest;
--编写 PL/SQL 插入100万条数据
begin
for x in 1..1000000
loop
insert into indextest values(x,'AA'||x);
end loop
commit;
end;
--根据 name 列创建索引
create index index_test_name on indextest(name);
--用id和name查询同一条记录,观察查询时间
select * from indextest a where a.id='765432';--最小时间0.047
select * from indextest a where a.name='AA765432';--最小时间0.015
--用name索引查询快于用id查询
如果需要在某个表某个列创建索引,而这列的值是不会重复的。这时我们可 以创建唯一索引
唯一索引语法:
create unique index 索引名称 on 表名(列名);
--在业主表的水表编号一列创建唯一索引
create unique index index_owners_meter on t_owners(watermeter);
--语法:
create index 索引名称 on 表名(列名,列名.....);
--复合索引-根据地址和门牌号对业主表创建索引
create index index_owners_ah on t_owners(addressid,housenumber);
应用场景:
当某个字段的值为连续增长的值,如果构建标准索引,会形成歪脖子树。这样会增加查询的层数,性能会下降。建立反向键索引,可以使索引的值变 得不规则,从而使索引树能够均匀分布。
--语法:
create index 索引名称 on 表名(列名) reverse;
使用场景:位图索引适合创建在低基数列上
位图索引不直接存储 ROWID,而是存储字节位到 ROWID 的映射
优点:减少响应时间,节省空间占用
--语法:
create bitmap index 索引名称 on 表名(列名);
--我们在 T_owners 表的 ownertypeid 列上建立位图索引,
create bitmap index index_owners_ownertypeid on t_owners(ownertypeid);
以上是脚本宝典为你收集整理的Oracle知识学习记录(一)全部内容,希望文章能够帮你解决Oracle知识学习记录(一)所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。