談談mysql和oracle的使用感覺 -- 差別

  以前一直使用mysql做爲存儲數據庫,雖然中間偶爾使用sqlite做爲本地數據庫存儲,但沒有感受多少差異。事實上,咱們每每據說SQL-92標準之類的云云!mysql

  後來趕上了oracle,且以其做爲主要存儲,這下就不得很差好了解其東西了。oracle做爲商業數據庫裏的佼佼者,確定有其過人之處的。sql

  本文僅從使用的角度來講說感覺,並沒有其餘意思喲。(理解上也並不深刻)數據庫

 

1. 自增主鍵

  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

  

2. 建立索引

  索引的目的天然是爲了提升查詢效率,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。性能

 

3. 字段表註釋

  咱們建一張表時,確定都須要註釋的,不然過兩天連咱們本身都不認識其含義了。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 '用戶名稱標識';
    -- 刪除表註釋,置空
    -- 刪除列註釋,置空

  我不是說它這設計很差,可是就感受太煩了。

 

4. 分頁實現

  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怎麼樣我不清楚,反正是寫得挺煩的。

 

5. 查詢執行計劃

  查詢執行計劃,能夠看出哪些語句是須要優化的,這個工做實際上仍是比較專業的。但若是想簡單看看狀況,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還有其餘許多種查看執行計劃的方式,就不列舉了。也沒啥好壞之分,能查看就行。

 

6. 客戶端可視化工具

  這個簡單說說,mysql有不少工具,sqlyog,navicat,mysqlworkbench。。。

  oracle也有不少,plsql,navicat。。。

  而具體操做上的差別則根據客戶端工具的差別來,無可厚非。

 

7. 對超長文本的處理

  mysql中對超長文本使用text和longtext類型進行處理,和其餘字段並無太多差異(不能建有效索引除外)

  而oracle中則使用CLOB類型進行存在超長字符,但它有許多限制,普通查詢沒法顯示clob,分號限制等等。但它能夠容納上G的數據。

 

8. 日期字段查詢

  都支持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');

  雖然加這麼個格式東西也不復雜,但總感受不爽。

 

9. 修改字段類型

  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的作法更嚴謹,不容許更改字段名稱,改類型必須保證正確;哎,但總感受不爽;

 

10. group by 聚合

  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是更嚴謹一些的。

 

11. 分區表建立

  分區表的目的,在於提升查詢速度和方便隔離管理。

  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 支持得更好些呢。

 

12. with as 用法

  在作一些大型數據數據分析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;

 

13. 事務支持

  在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;

 

14. 進程信息查詢

  查詢正在運行的任務狀況,可用於查詢慢查詢的利器。

  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的。

 

15. 數據同步

  mysql 中使用 binlog 能夠方便的將數據同步到其餘地方;

  oracle, 好像很複雜的樣子, 待研究。

相關文章
相關標籤/搜索