以前一直使用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, 好像很複雜的樣子, 待研究。