1. 介紹
是由螞蟻集團(Ant Group,原螞蟻金服)自主研發的分布式關系型數據庫。它旨在解決海量數據存儲和高并發訪問的問題,特別適合金融級應用場景,如支付寶等對數據一致性、可靠性和性能有極高要求的服務。以下是關于 OceanBase 數據庫的一些關鍵特點和優勢:
1.1 核心特性
1. 分布式架構
- 水平擴展:OceanBase 支持通過增加服務器節點來線性擴展系統容量,從而應對不斷增長的數據量和用戶請求。
- 多副本機制:為了保證數據的高可用性和容災能力,OceanBase 實現了多副本策略,確保即使部分節點故障也不會影響整個系統的正常運行。
2. 高性能
- SQL 引擎優化:針對 SQL 查詢進行了深度優化,支持復雜的事務處理和分析查詢,能夠在保證 ACID 特性的前提下提供高效的讀寫性能。
- 全局一致性:利用 Paxos 協議實現分布式事務的一致性管理,確保跨多個數據中心的數據同步和一致性。
3. 高可用性
- 自動故障轉移:當主副本發生故障時,能夠快速切換到備用副本繼續服務,減少了業務中斷時間。
- 異地多活:支持跨地域部署,使得不同地區的用戶可以就近訪問數據,降低了網絡延遲,并增強了災難恢復的能力。
4. 兼容 MySQL/Oracle
- MySQL 兼容性:提供了良好的 MySQL 協議兼容性,使得從傳統 MySQL 數據庫遷移到 OceanBase 變得更加容易。
- Oracle 兼容性:部分版本也增加了對 Oracle 數據庫語法的支持,方便企業平滑遷移。
5. 低成本
- 硬件成本低:由于采用了普通的 X86 架構服務器作為集群節點,相比專用硬件設備大大降低了采購成本。
- 運維成本低:簡化了管理和維護流程,減少了人工干預的需求,提高了自動化程度。
1.2 應用場景
OceanBase 廣泛應用于支付清算、電子錢包、轉賬匯款、信貸風控等領域,尤其是在需要處理大量交易且對響應速度和數據安全有嚴格要求的地方表現優異。此外,隨著云服務的發展,OceanBase 也開始向云端延伸,為更多中小企業提供靈活可靠的數據庫解決方案。
1.3 社區與生態
OceanBase 不僅是一個商業產品,也有活躍的開源社區版(OceanBase Community Edition),鼓勵開發者和技術愛好者參與到項目的開發和完善中來。同時,圍繞 OceanBase 形成了豐富的工具鏈和服務體系,包括但不限于監控報警、備份恢復、性能調優等工具,以及專業的技術支持團隊。
2. 安裝
安裝要求:需要6G內存,14G磁盤空間。
2.1 鏡像下載
下載oceanbase-ce鏡像,這里只體驗社區兼容MySQL版本的,兼容Oracle版本是企業版,商用,一般接觸不到。如果企業要用,也是由廠商技術支持直接安裝,一般接觸不到這個鏡像源。
# 下載oceanbase-ce鏡像
docker pull oceanbase/oceanbase-ce
2.2 啟動容器
docker run -p 2881:2881 \--name oceanbase \--restart=always \-e MODE=MINI \-e OB_TENANT_PASSWORD=123456 \-d oceanbase/oceanbase-ce
2.3 安裝監測
啟動后可實時觀察日志是否成功安裝
docker logs -f oceanbase
2.4 連接數據庫
oceanbase-ce 鏡像安裝了OceanBase數據庫客戶端obclient,所以可以使用obclient客戶端或其他方式。
# 1. 進入容器
docker exec -it oceanbase bash# 無密碼方式
obclient -uroot@sys -h127.0.0.1 -P2881# 有密碼方式
obclient -uroot@sys -h127.1 -P2881 -p123456
3. SQL語句
SQL的英文是Structured Query Language,簡稱SQL,是一種操作關系型數據庫的結構化查詢語言。操作數據庫,最經常使用就是查詢操作。
1、OceanBase數據庫也兼容Oracle語法,這個社區版不支持;
2、OceanBase數據庫的SQL語句不區分大小寫,關鍵字建議使用大寫;
3、SQL語句可以使用單行或多行書寫,以分號結尾
4、注釋
單行注釋
- 單行注釋# 單行注釋
多行注釋
/*
多行注釋
多行注釋
*/
4. SQL分類
分類 | 說明 | 作用 | 備注 |
---|---|---|---|
DDL | 數據定義語言 | 用來對數據庫、表、列的定義 | data definition language |
DML | 數據操作語言 | 用來對數據庫中表的數據進行增、刪、改操作 | data manipulation language |
DQL | 數據查詢語言 | 用來對數據庫中表的數據進行查詢 | data query language |
DCL | 數據控制語言 | 用來對數據庫的控制(用戶創建、權限控制) | data control language |
5. DDL
5.1 庫的DDL
一個功能,一般都是四個動作,增刪改查。
展示所有的數據庫
show databases;
創建數據庫
create database 數據庫名稱 charset=utf8;
create database if not exists 數據庫名稱 charset=utf8; # 使得SQL語句更加強健、健壯。
示例:
create database db1 charset=utf8;
create database if not exists db1 charset=utf8;
刪除數據庫
drop database 數據庫名稱;
drop database if exists 數據庫名稱;
示例:
drop database test;
drop database if exists test;
使用數據庫
use 數據庫名稱;
查詢正在使用的數據庫
select database();
小結:
命令 | 作用 | 示例 |
---|---|---|
show databases; | 查看所有數據庫 | show databases; |
create database if not exists 數據庫名 charset=utf8; | 創建數據庫 | create database if not exists db1 charset=utf8; |
use 數據庫名; | 使用數據庫 | use db1; |
select database(); | 查看當前使用的數據庫 | select database(); |
drop database if exists 數據庫名; | 刪除數據庫 | drop database if exists db1; |
5.2 表、列的DDL
列的內容可以是數字、字符串、時間等,由數據類型約束
在滿足業務需求的請求下,數據類型范圍選擇越小的。
數值數據類型
數據類型 | 字節數 | 有符號 | 無符號 |
---|---|---|---|
tinyint | 1個字節 | -128~127 | 0~255 |
smallint | 2個字節 | -32768~32767 | 0~65535 |
mediumint | 3個字節 | -8388608~8388607 | 0~16777215 |
int | 4個字節 | -2147483648~2147483647 | 0~4294967295 |
bigint | 8個字節 | -263~263-1 | 0~2^64-1 |
float | 單精度,4個字節 | -231~231-1 | 0~2^32-1 |
double | 雙精度,8個字節 | ||
decimal[M, D] | 雙精度,8個字節 |
decimal(5,2),表示共5位數字,其中2位是小數,比如:888.88
字符串數據類型
數據類型 | 長度 | 用途 |
---|---|---|
char(size) | 最大255個字符 | 數據是定長,如md5的密碼,郵編,手機號,身份證號等 |
varchar(size) | 最大65535個字節 | 存放一般內容長度 |
tinytext | 最大255個字節 | |
text | 最大65535個字節 | |
mediumtext | 最大16777215個字節 | 大段文本時,如新聞、文章、論文等 |
longtext | 最大4294967295個字節 | 大段文本時,如新聞、文章、論文等 |
1、VARCHAR(size):0~65535字節 可變長度字符串,最大65532字節,1-3個字節用于記錄大小【utf8編碼size最大21844字符,gbk編碼最大32766字符 】
2、查詢速度:char > varchar
3、text與char、varchar不同的是,text不可以有默認值,能用varchar的地方不用text
日期+時間數據類型
數據類型 | 格式 |
---|---|
date | 年-月-日,如:2024-4-8 |
datetime | 年-月-日 時:分:秒,如:2024-4-8 16:17:40 |
timestamp | 年-月-日 時:分:秒,如:2024-4-8 16:17:40 |
time | 時:分:秒,如:16:17:40 |
year | 年,如:2024 |
datetime保存時間的范圍: 1000-01-01 00:00:00
到 9999-12-31 23:59:59
timestamp保存時間的范圍: 1970-01-01 00:00:01
到 2038-01-19 03:14:07
展示當前數據庫所有表
show tables;
描述表結構
desc 表名;
查看表的創建語句
show create table 表名;show create table user;
創建表
create table 表名(字段名1 數據類型,字段名2 數據類型,...字段名n 數據類型 # 最后一個不需要逗號(,)
);示例:
create table if not exists user(id tinyint,username varchar(32),age tinyint
);
刪除表
drop table 表名稱;
drop table if exists 表名稱;
修改表、列
# 修改表名
alter table 原來的表名 rename to 新的表名;示例:
alter table user rename to users;# 增加一列
alter table 表名 add 列名 數據類型;示例:
alter table users add height float;# 修改列數據類型
alter table 表名 modify 列名 新數據類型;示例:
alter table users modify id int;# 修改列名和數據類型
alter table 表名 change 列名 新列名 新數據類型;示例:
alter table users change id no tinyint;# 刪除列
alter table 表名 drop 列名;示例:
alter table users drop height;
小結:
命令 | 作用 |
---|---|
show tables; | 查看當前數據庫中所有表 |
desc 表名; | 查看表結構 |
show create table 表名; | 查看表的創建語句 |
alter table 表名 rename to 新的表名; | 修改表名 |
alter table 表名 add 列名 類型; | 添加字段 |
alter table 表名 modify 列名 類型及約束; | 修改字段數據類型 |
alter table 表名 change 原名 新名 類型及約束; | 修改字段名和數據類型 |
alter table 表名 drop 列名; | 刪除字段 |
drop table 表名; | 刪除表 |
6. DML
6.1 添加數據
添加指定列數據
insert into 表名(列名1,列名2...) values(值1,值2...);
添加全部列數據
insert into 表名 values(值1,值2...);示例:
insert into users values(1, 'zhangsan', 18);
批量添加指定列數據
insert into 表名(列名1,列名2...) values(值1,值2...),(值1,值2...)...;
批量添加全部列數據
insert into 表名 values(值1,值2...),(值1,值2...)...;示例:
insert into users values(1, 'lisi', 18),(1, 'wanger', 19);
6.2 修改數據
修改表數據
update 表名 set 列名1=值1 列名2=值2...[where條件];示例:
update users set no=2 where username='lisi';
注:如果不加where條件,就是對該表所有行內容進行修改
6.3 刪除數據
刪除表數據
delete from 表名 [where條件]示例:
delete from users where username='wanger';
注:如果不加where條件,就是對該表所有行內容進行刪除
7. DQL
完整語法
SELECT字段列表
FROM表名列表
WHERE條件列表
GROUP BY分組字段
HAVING分組后條件
ORDER BY排序字段
LIMIT分頁限定
- 創建數據庫
create database if not exists db1- 創建數據庫表
use db1;create table if not exists stu(id int(11),username varchar(32),sex tinyint(1),age tinyint(3),math tinyint(3),chinese tinyint(3)
);- 添加數據
insert into stu values(1,'小張',1,16,75,86),(2,'小李',1,16,76,86),(3,'小王',0,17,76,87),(4,'小胡',0,17,77,87),(5,'小丘',0,18,77,88),(6,'小劉',0,18,80,90);
7.1 基礎查詢
- 查詢指定字段
select id,username from stu;- 查詢表所有字段
select * from stu;- 去除重復記錄
select distinct sex from stu;- 字段取別名
select id,sex as gender,math shuxue from stu;
7.2 條件查詢
select 字段列表 from 表名 where條件
where后面支持多種運算符
運算符 | 功能描述 |
---|---|
比較運算符 | =、>、>=、<、<=、!=、<> |
邏輯運算符 | and、&&、or、||、not |
模糊查詢 | like |
范圍查詢 | between…and…、in(…) |
空判斷 | is null、is not null |
模糊查詢使用like關鍵字,可以使用通配符進行占位
_:代表單個任意字符
%:代表任意個字符
正則表達式
select * from stu where class_id REGEXP '1|7';
7.3 排序查詢
select 字段列表 from 表名 order by 排序字段名1 [,排序字段2]...;
注:排序方式有上序ASC,降序DESC,默認情況下是升序ASC
select * from stu order by math desc,chinese desc;
7.4 聚合函數
在進行查詢操作時,往往需要對一整列進行運算,例如成績的平均分
函數名 | 功能 |
---|---|
count(列名) | 統計數量(一般選用不為null的列) |
max(列名) | 最大值 |
min(列名) | 最小值 |
sum(列名) | 求和 |
avg(列名) | 平均值 |
select 聚合函數 from 表名;
注:NULL值不參與聚合函數運算
7.5 分組查詢
select 字段列表 from 表名 [where分組前的條件限定] group by 分組字段名 [having 分組后的條件過濾];
注:分組之后,查詢的字段為聚合函數和分組字段,查詢其他字段無任何意義
select sex,max(math),max(chinese) from stu group by sex;
7.6 分頁查詢
select 字段列表 from 表名 limit 查詢起始索引,查詢條目數
注:limit關鍵字中,查詢起始索引是從0開始的
8. 約束
約束是作用于數據庫表中列上的規則,用于限制添加數據的行為。從而保證數據庫中數據的正確性、有效性和完整性。
8.1 約束分類
約束類型 | 關鍵字 | 功能 |
---|---|---|
非空約束 | NOT NULL | 保證列中所有數據不能有NULL值 |
唯一約束 | UNIQUE | 保證列中所有數據各不相同 |
主鍵約束 | PRIMARY KEY | 主鍵是一行數據的唯一標識,要求非空且唯一 |
默認約束 | DEFAULT | 保存數據時,未指定值則采用默認值 |
外鍵約束 | FOREIGN KEY | 外鍵用來讓兩個表數據建立關聯,保證數據的一致性和完整性 |
檢查約束 | CHECK | 保證列中的值滿足某一條件 |
create table if not exists stu(id int(11) unsigned auto_increment primary key not null,username varchar(32) not null unique,sex tinyint(1) default 1 not null,age tinyint(3) not null,math tinyint(3) default 0 not null,chinese tinyint(3) default 0 not null
);
9. 多表查詢
一次性從多張表中查詢需要的數據
create table class(class_id int(11) unsigned auto_increment primary key not null,class_name varchar(32) not null unique
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;create table stu(stu_id int(11) unsigned auto_increment primary key not null,class_id int(11) not null,stu_name varchar(32) not null unique
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;insert into class(class_name) values('一班'),('二班');insert into stu(class_id,stu_name) values(1,'小張'),(1,'小李'),(2,'小孫'),(2,'小楊');
在MySQL中多表查詢分為連接查詢和子查詢,連接查詢又分為內連接和外連接,內連接又分為隱式內連接和顯示內連接,外連接又分為左外連接和右外連接。
9.1 內連接查詢
- 隱式內連接查詢
select 字段列表 from 表1,表2... where 條件;- 顯式內連接查詢
select 字段列表 from 表1 [inner] join 表2 on 條件;
示例
- 隱式內連接查詢
select * from class,stu where class.class_id=stu.class_id;- 顯式內連接查詢
select * from class inner join stu on class.class_id=stu.class_id;
9.2 外連接查詢
左外連接查詢:相當于查詢A表所有數據和交集部分數據
右外連接查詢:相當于查詢B表所有數據和交集部分數據
- 左外連接查詢
select 字段列表 from 表1 left [outer] join 表2 on 條件;- 右外連接查詢
select 字段列表 from 表1 right [outer] join 表2 on 條件;
示例
select * from stu left outer join class on stu.class_id=class.class_id;select * from stu right outer join class on stu.class_id=class.class_id;
9.3 子查詢
指查詢中嵌套有查詢
子查詢語句結果是單行單列,子查詢語句作為條件值,使用>、>=、<、<=、=、!=等進行條件判斷。
# class_id 大于 1班的class_id的學生
select * from stu where class_id > (select class_id from class where class_name='一班');
子查詢語句結果是多行單列,子查詢語句作為條件值,使用in等關鍵字進行條件判斷
# 查詢存在班級的學生
select * from stu where class_id in (select class_id from class);
子查詢語句結果是多行多列,子查詢語句作為虛擬表
select * from stu,(select * from class) c where stu.class_id=c.class_id;
10. 事務
使用場景:轉賬、下單扣庫存
語法:
# 開啟事務
start transaction;
或
begin;-- 執行各種操作# 回滾事務
rollback;# 提交事務
commit;
事務特征:
1、原子性,事務是不可分割最小操作單位,要么同時成功,要么同時失敗
2、一致性,事務完成時,必須使所有數據都保持一致狀態
3、隔離性,多個事務之間,操作可見性
4、持久性,事務一旦提交或回滾,它對數據庫中數據的改變是永久的
10.1 隔離級別
數據庫事務的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。在事務的并發操作中可能會出現臟讀,不可重復讀,幻讀。
讀未提交(Read uncommitted):
解釋:
一個事務讀到了另一個事務還沒有提交的數據。
例如:
A給B轉賬,
A轉給B,10萬,點轉賬,但未點確認
B查賬戶看到10萬
A及時發現,點撤回,修改為1萬,再點轉賬,再點確認
分析:
A給B最終轉賬是1萬,但是在過程中,B能看到過程數據。這就是臟讀。
讀已提交(Read committed):
解釋:
一個事務要等另一個事務提交后才能讀取數據。
例如:
父親的銀行卡有10萬
兒子拿著這個銀行卡去買單,同時父親準備轉款(開啟事務)。此時兒子看到銀行卡里有10萬
等兒子看完有10萬后,錢被父親轉走,并提交
收費系統準備在這個銀行卡扣款,再次檢測,發現卡里沒有錢了
分析:
這就是讀已提交,若有事務對數據進行更新操作時,讀操作事務要等待這個更新操作事務提交后才能讀取數據,可以解決臟讀問題。
這個例子中,有讀兩次卡里的錢,一次是10萬,一次是沒有錢了,這就是不可重復讀。
可重復讀(Repeatable read):
解釋:
同一事務下,事務在執行期間,多次讀取同一數據時,能夠保證讀取到的數據是一致的。
例如:
父親的銀行卡有10萬
兒子拿著這個銀行卡去買單,此時兒子看到銀行卡里有10萬,這個時候父親想轉賬,發現轉不了
等兒子買完單,父親才能夠實行轉賬行為
分析:
讀數據的時候,不允許該數據有寫數據的事務。因為寫數據會改變數據。這樣子就解決了不可重復讀的問題。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。
什么時候會出現幻讀?
解釋:
一個事務讀取到了另一個事務新增的數據
例如:
兒子某一天去消費,花了8千元,然后他的父親去查看他今天的消費記錄(全表掃描,兒子事務開啟),看到確實是花了8千元,就在這個時候,兒子花了1萬買了一部電腦,即新增INSERT了一條消費記錄,并提交。當父親打印兒子的消費記錄清單時(兒子事務提交),發現花了1.8萬元,似乎出現了幻覺,這就是幻讀。
串行化(Serializable):
解釋:
它是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免臟讀、不可重復讀與幻讀。但是這種事務隔離級別效率最低,比較耗費數據庫性能,一般不推薦使用。
小結:
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
讀未提交 | 可能出現 | 可能出現 | 可能出現 |
讀已提交 | 不會出現 | 可能出現 | 可能出現 |
可重復讀 | 不會出現 | 不會出現 | 可能出現 |
串行化 | 不會出現 | 不會出現 | 不會出現 |
隔離級別查詢
-- MySQL8以前
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;-- MySQL8開始
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;
修改隔離級別
-- 建議開發者在修改時,僅修改當前session隔離級別即可
-- REPEATABLE-READ,MySQL默認級別
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE-READ
11. 函數
11.1 數學函數
函數 | 含義 |
---|---|
abs(x) | 返回x的絕對值 |
rand() | 返回0到1的隨機數 |
mod(x,y) | 返回x除以y以后的余數 |
power(x,y) | 返回x的y次方 |
round(x) | 返回離x最近的整數 |
round(x,y) | 保留x的y位小數四舍五入后的值 |
sqrt(x) | 返回x的平方根 |
truncate(x,y) | 返回數字 x 截斷為 y 位小數的值 |
ceil(x) | 返回大于或等于 x 的最小整數 |
floor(x) | 返回小于或等于 x 的最大整數 |
greatest(x1,x2…) | 返回返回集合中最大的值 |
least(x1,x2…) | 返回返回集合中最小的值 |
11.2 字符串函數
函數 | 含義 |
---|---|
trim() | 返回去除指定格式的值 |
concat(x,y) | 將提供的參數 x 和 y 拼接成一個字符串 |
substr(x,y) | 獲取從字符串 x 中的第 y 個位置開始的字符串,跟substring()函數作用相同 |
substr(x,y,z) | 獲取從字符串 x 中的第 y 個位置開始長度為z 的字符串 |
length(x) | 返回字符串 x 的長度 |
replace(x,y,z) | 將字符串 z 替代字符串 x 中的字符串 y |
upper(x) | 將字符串 x 的所有字母變成大寫字母 |
lower(x) | 將字符串 x 的所有字母變成小寫字母 |
left(x,y) | 返回字符串 x 的前 y 個字符 |
right(x,y) | 返回字符串 x 的后 y 個字符 |
repeat(x,y) | 將字符串 x 重復 y 次 |
space(x) | 返回 x 個空格 |
strcmp(x,y) | 比較 x 和 y,返回的值可以為-1,0,1 |
reverse(x) | 將字符串 x 反轉 |
11.3 日期函數
函數 | 含義 |
---|---|
current_date() | 當前日期 |
current_time() | 當前時間 |
current_timestamp() | 當前時間戳 |
12. DCL
12.1 用戶管理
創建用戶
CREATE USER '用戶名'@'主機名' IDENTIFIED BY '密碼';
-- 實例:
CREATE USER 'java'@'%' IDENTIFIED BY 'asd123crl';
刪除用戶
drop user 用戶名@IP;
-- 實例:
drop user 'java'@'%';
修改密碼
UPDATE `user` SET `Password` = PASSWORD('新密碼') WHERE `User` = '用戶名';
-- 實例:
UPDATE `user` SET `Password` = PASSWORD('asd123') WHERE `User` = 'java';
12.2 權限管理
常用權限:
- 表數據: select, update, delete, insert
- 表結構: create, alert, drop
- 外鍵: references
- 創建臨時表: create temporary tables
- 操作索引: index
- 視圖: create view, show view
- 存儲過程: create routine, alert routine, execute
- 所有權限: all
查看用戶權限命令
SHOW GRANTS FOR '用戶名'@'主機名';
-- 實例:
SHOW GRANTS FOR 'root'@'%';
給用戶授予權限
在MySQL中使用GRANT命令給用戶授權,如果用戶不存在,GRANT會自動創建用戶,并進行授權。
GRANT 權限列表 ON 數據庫名.表名 TO '用戶名'@'主機名'; -- 權限列表中如果有多個權限則用逗號,隔開-- 授權所有庫的所有表的所有權限
GRANT ALL ON *.* TO '用戶名'@'主機名';
-- 示例:給張三賦予db_test數據庫students表的查詢權限
GRANT SELECT ON db_test.students TO 'zhangsan'@'localhost';
-- 刷新權限
flush privileges
撤銷權限
REVOKE 權限列表 ON 數據庫名.表名 FROM '用戶名'@'主機名';
-- 示例:撤銷張三在db_test.students表的查詢權限
REVOKE SELECT ON db_test.students FROM 'zhangsan'@'localhost';
-- 刷新權限
flush privileges
13. 備份與還原
備份語法:
mysqldump -h 服務器 -u 用戶名 -p -B 數據庫名1 數據庫2 數據庫n > 備份文件.sql
示例:
mysqldump -u root -p -B test > /backup/123.sql
還原語法:
mysqldump -h 服務器 -u 用戶名 -p密碼 --databases 數據庫名 < 備份文件.sql# 進入數據庫后
source 備份文件.sql;
示例:
mysqldump -u root -p --databases test < /backup/123.sql
一般系統推薦的字符集和排序規則
# 字符集
utf8mb4# 排序規則,不區分大小寫
utf8mb4_general_cli
字符集(Character Set):utf8mb4
排序規則 | 字符序(Collate):utf8mb4_general_cli 或 utf8mb4_bin