以前一直使用mysql做为存储数据库,虽然中间偶尔使用sqlite做为本地数据库存储,但没有感受多少差异。事实上,咱们每每据说SQL-92标准之类的云云!mysql
后来赶上了oracle,且以其做为主要存储,这下就不得很差好了解其东西了。oracle做为商业数据库里的佼佼者,确定有其过人之处的。sql
本文仅从使用的角度来讲说感觉,并没有其余意思哟。(理解上也并不深刻)数据库
mysql中要使用自增主键很是方便,只须要在建表时增长 auto_increment 关键字便可,样例以下:session
create table tb1 (id int(11) unsigned not null auto_increment);
而在oracle中则不同了,它须要使用另外一个概念:序列号;咱们能够简单将其理解为只有一个列的表,这个表提供了 nextval 的方法,辅助咱们生成自增id,样例以下:oracle
-- 1. 建普通表 create table tb1(id number not null); -- 2. 建立序列,参数比较多,自行查阅资料 create sequence seq_tb1 increment by 1 start with 1 minvalue 1 maxvalue 999999999 -- 3. 插入使用 insert into tb1 (id) values (seq_tb1.nextval)
能够看到,oracle的操做明显多了许多。固然了,自增这个属性,在许多数据库中确实也是不提供的,尤为是分布式数据库递增更难作。因此,要支持这功能,绕路也就在所不免了。less
索引的目的天然是为了提升查询效率,mysql中想要添加索引能够在建表时操做,也能够在后期更改;样例以下:分布式
-- 1. 建表时指定 create table tb1 (username varchar(50), index username (username)); -- 2. 后期更改 alter table tb1 add index username (usrrname);
而在oracle中则不同,它只能在建表完成以后操做;样例以下:工具
CREATE INDEX tb1_username ON tb1(username);
看起来差别不大,但oracle的索引是全局的,即全部表的索引名都不能重复,好比你们都有id索引,但却不能都叫id。性能
咱们建一张表时,确定都须要注释的,不然过两天连咱们本身都不认识其含义了。mysql中在建表或增长字段时直接指定,样例以下:测试
-- 1. 建表时指定 create table tb1(username varchar(50) comment '用户名标识') comment '测试建表'; -- 2. 修改表结构时指定 alter table tb1 add column nickname varchar (100) '昵称';
而oracle中则不太同样,它只能在建表以后和建立字段以后才能进行注释;样例以下:
-- 表注释 comment on table tb1 is '测试建表'; -- 字段注释 comment on tb1.username is '用户名称标识'; -- 删除表注释,置空 -- 删除列注释,置空
我不是说它这设计很差,可是就感受太烦了。
mysql中的分页,使用limit,这也是大多数数据库的选择,样例以下:
select username from tb1 limit 50, 100;
而在oracle中则不太同样,它使用行号去定位记录,通常须要使用嵌套子查询;样例以下:
select * from (select t.*,rownum num from tb1 t where rownum<=100 ) where num>50
性能比limit怎么样我不清楚,反正是写得挺烦的。
查询执行计划,能够看出哪些语句是须要优化的,这个工做实际上仍是比较专业的。但若是想简单看看状况,mysql中能够这样作:
explain select * from tb1 where username='xx' order by id limit 10;
而oracle中要查看执行计划,则须要借助工具或者本身写,样例以下:
-- 1. 执行查询执行计划语句 explain plan for select * from tb1 where username='xx'; -- 2. 查看执行计划结果 select * from table(dbms_xplan.display());
oracle还有其余许多种查看执行计划的方式,就不列举了。也没啥好坏之分,能查看就行。
这个简单说说,mysql有不少工具,sqlyog,navicat,mysqlworkbench。。。
oracle也有不少,plsql,navicat。。。
而具体操做上的差别则根据客户端工具的差别来,无可厚非。
mysql中对超长文本使用text和longtext类型进行处理,和其余字段并无太多差异(不能建有效索引除外)
而oracle中则使用CLOB类型进行存在超长字符,但它有许多限制,普通查询没法显示clob,分号限制等等。但它能够容纳上G的数据。
都支持date,timestamp数据类型。
mysql支持直接使用字符串日期进行条件过滤,默认格式为:yyyy-MM-dd HH:ii:ss 好比:
select * from tb1 where dt>'2020-09-13 12:15:01';
而oracle则要求严格些,要求必须都是日期老式string格式才能比较;
select * from tb1 where dt>to_date('2020-09-13 12:15:01', 'yyyy-MM-dd hi24:mi:ss');
虽然加这么个格式东西也不复杂,但总感受不爽。
mysql中修改字段类型,直接改就好,但有可能失败。
alter table tb1 change column f1_old f1_new int(11) comment 'xxx';
而oracle中则分状况处理,空字段直接改,不容许修改有值字段类型,若是硬要改那就至关麻烦,以下:
-- 空字段类型修改,可任意修改 alter table modify (f1_old number); -- 非空字段类型修改,分类型匹配与不匹配状况 -- 若是类型匹配,可直接改,如nchar(20) -> nvarchar(20) -- 不然不容许修改,只能主动新建字段替换回来,关键是不必定能成功 alter table tb rename column name to name_tmp; /*增长一个和原字段名同名的字段name*/ alter table tb add name varchar2(40); /*将原字段name_tmp数据更新到增长的字段name,可算可能失败*/ update tb set name=trim(name_tmp); /*更新完,删除原字段name_tmp*/ alter table tb drop column name_tmp;
很显然,oracle的作法更严谨,不容许更改字段名称,改类型必须保证正确;哎,但总感受不爽;
group by能够按照某字段去重一些数据,并按须要聚合数据,mysql与oracle都差很少,差异点在于oracle不容许返回group by外的其余字段(或者说不能准确描述的字段),而mysql则会随机返回一个group by的字段值。mysql以下:
select username, avg(score), grade from tb1 group by grade;
oracle中则要求必须肯定某值:
select max(username), avg(score), grade from tb1 group by grade;
看起来oracle是更严谨一些的。
分区表的目的,在于提升查询速度和方便隔离管理。
mysql 建立分区表,Mysql不能自动建立分区,且要求分区字段必须是主键的一部分,若是想自动建立分区,须要使用mysql event事件的方式自动建立分区. 样例以下:
create table tb1 ( id int(11), day datetime not null prmary key (id, day) ) PARTITION BY RANGE (TO_SECONDS(day)) (PARTITION p20200912 VALUES LESS THAN (TO_SECONDS('20200912')) ENGINE = InnoDB, PARTITION p20200913 VALUES LESS THAN (TO_SECONDS('20200913')) ENGINE = InnoDB);
oracle 中建立分区表
create table tb1 ( id NUMBER(20) not null, create_time DATE ) PARTITION BY RANGE (CREATE_TIME) INTERVAL (NUMTODSINTERVAL(1, 'day')) (partition part_t01 values less than(to_date('2020-09-12', 'yyyy-mm-dd')));
明显 oracle 支持得更好些呢。
在作一些大型数据数据分析sql时,with as sql 很是有用,在mysql低版本中是不支持的,只能本身写临时表进行处理。
而oracle则支持该通用语法:
with a as ( select * from tb1 where dt = '20200912' ), b as ( select * from tb2 where dt = '20200912' ) select a.id aid, b.id bid from a join b on a.pid = b.id;
在rdb中,一般事务是指对一批操做的原子性,一致性,隔离性,持久性的体现。大致上mysql与oracle表现是一致的。
mysql是分存储引擎,如innodb,myisam,每一个引擎的事务支持能力不一样,原则不一样,锁实现不一样,如innodb锁行,而myisam 锁表等。
oracle 中在建表时就能够指定事务槽数
-- 建表时指定事务槽数 create table t3 (id int, num int ) INITRANS 6; -- 建立索引时指定事务槽数 create unique index tb1_username_idx on tb1 (username) initrans 6;
查询正在运行的任务状况,可用于查询慢查询的利器。
mysql 中 直接使用 show full processlist 便可;但带条件的查询须要查表:
show full processlist; select * from information_schema.`PROCESSLIST` where duration > 5;
oracle 进程信息:
SELECT b.sid oracleID, b.username Oracle用户, b.serial#, spid 操做系统ID, paddr, sql_text 正在执行的SQL, b.machine 计算机名 FROM v$process a, v$session b, v$sqlarea c WHERE a.addr = b.paddr AND b.sql_hash_value = c.hash_value;
反正我是记不住这么长的sql的。
mysql 中使用 binlog 能够方便的将数据同步到其余地方;
oracle, 好像很复杂的样子, 待研究。