文章目录
一、OceanBase 简介与安装配置指南
1.1 OceanBase 核心特点
OceanBase 是由阿里巴巴集团自主研发的分布式关系型数据库,具有以下显著特点:
特性 | 说明 | 技术优势 |
---|---|---|
高可用性 | 采用 Paxos 协议实现多副本强一致性 | 自动故障检测与恢复,RTO<30秒 |
水平扩展 | 分布式架构支持在线扩容 | 可扩展至数千节点,PB级数据 |
兼容性 | 高度兼容 MySQL/Oracle 语法 | 降低迁移成本,学习曲线平缓 |
低成本 | 基于普通服务器构建 | 相比传统数据库硬件成本降低70% |
混合负载 | 同时支持 OLTP 和 OLAP | 一套系统满足交易与分析需求 |
1.2 架构解析
OceanBase 采用"分区-副本-节点"三级分布式架构:
关键组件说明:
- OBProxy:智能路由代理,自动识别SQL并路由到正确节点
- OBServer:数据库服务进程,包含SQL引擎、存储引擎等模块
- RootService:集群管理节点,负责元数据管理和调度
1.3 安装部署实战
1.3.1 硬件要求
以生产环境为例的典型配置:
组件 | CPU | 内存 | 磁盘 | 网络 | 数量 |
---|---|---|---|---|---|
OBServer | 16核+ | 64GB+ | SSD 500GB+ | 万兆 | 3+ |
OBProxy | 8核 | 16GB | 100GB | 千兆 | 2+ |
1.3.2 安装步骤详解
步骤1:环境准备
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 设置内核参数
echo "* soft nofile 655350" >> /etc/security/limits.conf
echo "* hard nofile 655350" >> /etc/security/limits.conf
# 设置时钟同步(所有节点)
yum install -y chrony
systemctl enable chronyd
systemctl start chronyd
步骤2:安装OceanBase
# 下载安装包(以4.0版本为例)
wget https://mirrors.aliyun.com/oceanbase/community/stable/el/7/x86_64/oceanbase-ce-4.0.0.0-1.el7.x86_64.rpm
# 安装主程序
rpm -ivh oceanbase-ce-4.0.0.0-1.el7.x86_64.rpm
# 初始化目录
mkdir -p /data/ob/{data,redo,clog}
步骤3:集群初始化
-- 启动observer进程
cd /home/admin/oceanbase && bin/observer -i eth0 -p 2881 -P 2882 -z zone1 -n obcluster -d /data/ob/data -r '10.0.0.1:2882:2881;10.0.0.2:2882:2881;10.0.0.3:2882:2881' -c 1 -l info -o "memory_limit=64G,datafile_size=100G,config_additional_dir=/data/ob/clog"
-- 连接至sys租户
obclient -h127.0.0.1 -P2881 -uroot@sys -p
-- 设置root密码
ALTER USER root IDENTIFIED BY 'OceanBase123';
-- 创建资源池
CREATE RESOURCE POOL pool1 UNIT='unit1', UNIT_NUM=1, ZONE_LIST=('zone1');
-- 创建租户
CREATE TENANT obtest RESOURCE_POOL_LIST=('pool1') SET ob_tcp_invited_nodes='%', parallel_servers_target=10;
1.3.3 配置验证
-- 查看集群状态
SELECT * FROM __all_server;
-- 验证分区分布
SELECT * FROM __all_virtual_partition_info;
-- 检查资源使用
SELECT * FROM __all_virtual_sysstat WHERE name LIKE '%memory%';
二、OceanBase 基础 SQL 语法入门
2.1 数据查询(SELECT)
2.1.1 基础查询语法
-- 基本查询结构
SELECT
[DISTINCT] column1, column2, ...
FROM
table_name
[WHERE
condition]
[GROUP BY
column1, column2, ...]
[HAVING
group_condition]
[ORDER BY
column1 [ASC|DESC], ...]
[LIMIT
offset, row_count];
2.1.2 实际案例演示
案例1:电商订单查询
-- 创建订单表
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY,
user_id INT NOT NULL,
order_amount DECIMAL(10,2),
order_time DATETIME,
status VARCHAR(20)
) PARTITION BY HASH(order_id) PARTITIONS 4;
-- 插入测试数据
INSERT INTO orders VALUES
(1001, 101, 299.00, '2023-05-01 10:00:00', 'completed'),
(1002, 102, 599.00, '2023-05-02 11:30:00', 'shipped'),
(1003, 101, 1299.00, '2023-05-03 14:15:00', 'processing');
-- 基础查询
SELECT order_id, user_id, order_amount
FROM orders
WHERE status = 'completed'
ORDER BY order_time DESC
LIMIT 10;
-- 聚合查询
SELECT
user_id,
COUNT(*) AS order_count,
SUM(order_amount) AS total_amount,
AVG(order_amount) AS avg_amount
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 1;
2.2 数据操作(INSERT/UPDATE/DELETE)
2.2.1 INSERT 语句详解
-- 基本语法
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
-- 批量插入
INSERT INTO orders (order_id, user_id, order_amount, order_time, status)
VALUES
(1004, 103, 399.00, NOW(), 'processing'),
(1005, 104, 899.00, NOW(), 'shipped');
-- 从其他表插入
INSERT INTO order_archive
SELECT * FROM orders
WHERE order_time < '2023-01-01';
2.2.2 UPDATE 语句实战
-- 基本语法
UPDATE table_name
SET column1 = value1, column2 = value2, ...
[WHERE condition];
-- 订单状态更新案例
UPDATE orders
SET status = 'completed',
finish_time = NOW()
WHERE order_id = 1003
AND status = 'processing';
-- 带子查询的更新
UPDATE user_stat u
SET u.total_orders = (
SELECT COUNT(*) FROM orders o
WHERE o.user_id = u.user_id
);
2.2.3 DELETE 语句注意事项
-- 基本语法
DELETE FROM table_name
[WHERE condition];
-- 删除特定订单
DELETE FROM orders
WHERE status = 'cancelled'
AND order_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
-- 全表删除(慎用!)
TRUNCATE TABLE order_backup;
性能提示:OceanBase 的 DELETE 操作实际上是标记删除,空间不会立即释放,需要通过合并(Major Freeze)来回收空间。
三、OceanBase 数据类型详解
3.1 数值类型对比
类型 | 存储空间 | 范围 | 精度 | 适用场景 |
---|---|---|---|---|
TINYINT | 1字节 | -128~127 | 精确 | 状态值、枚举 |
SMALLINT | 2字节 | -32768~32767 | 精确 | 小型ID、计数器 |
INT | 4字节 | ±21亿 | 精确 | 主键、常用整数 |
BIGINT | 8字节 | ±922亿亿 | 精确 | 分布式ID、大计数器 |
DECIMAL(m,n) | 变长 | 最大m=65 | 精确 | 金融金额、高精度计算 |
FLOAT | 4字节 | ±3.4E+38 | 7位 | 科学计算 |
DOUBLE | 8字节 | ±1.8E+308 | 15位 | 普通浮点运算 |
3.2 字符串类型最佳实践
案例:用户信息表设计
CREATE TABLE users (
user_id BIGINT PRIMARY KEY,
username VARCHAR(64) NOT NULL COMMENT '用户名,最长64字符',
password CHAR(64) NOT NULL COMMENT 'SHA256加密后的密码,固定长度',
mobile CHAR(11) COMMENT '手机号,固定11位',
profile_json TEXT COMMENT '用户画像JSON数据',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) COMMENT='用户基本信息表';
字符串类型选择建议:
- 确定长度的字段用CHAR(如身份证、手机号)
- 变长字段用VARCHAR(节省空间)
- 超长文本用TEXT(如文章内容)
- 存储JSON数据建议用JSON类型(OceanBase 3.x+支持)
3.3 日期时间类型详解
类型对比表:
类型 | 格式 | 范围 | 存储空间 | 特点 |
---|---|---|---|---|
DATE | YYYY-MM-DD | 1000-01-01~9999-12-31 | 3字节 | 纯日期 |
TIME | HH:MM:SS | -838:59:59~838:59:59 | 3字节 | 时间间隔 |
DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 8字节 | 本地时间 |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01~2038-01-19 03:14:07 | 4字节 | 时区转换 |
YEAR | YYYY | 1901~2155 | 1字节 | 年份值 |
日期函数示例:
-- 获取当前时间
SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP();
-- 日期计算
SELECT
order_id,
DATE_ADD(order_time, INTERVAL 3 DAY) AS expect_delivery_date,
DATEDIFF(NOW(), order_time) AS days_passed
FROM orders;
-- 日期格式化
SELECT
order_id,
DATE_FORMAT(order_time, '%Y年%m月%d日 %H时%i分') AS formatted_time
FROM orders;
四、OceanBase 运算符使用指南
4.1 运算符优先级完整列表
优先级 | 运算符 | 说明 |
---|---|---|
1 | ! | 逻辑非 |
2 | - (unary) | 负号 |
3 | ^ | 按位异或 |
4 | *, /, DIV, %, MOD | 乘除取模 |
5 | +, - | 加减 |
6 | <<, >> | 位移 |
7 | & | 按位与 |
8 | | | 按位或 |
9 | =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN | 比较运算 |
10 | BETWEEN, CASE, WHEN, THEN, ELSE | 区间判断 |
11 | NOT | 逻辑非 |
12 | AND, && | 逻辑与 |
13 | OR, || | 逻辑或 |
4.2 特殊运算符详解
4.2.1 安全等于运算符(<=>)
与普通=的区别:
SELECT
NULL = NULL, -- 结果为NULL
NULL <=> NULL; -- 结果为1(TRUE)
-- 实际应用:查找未设置手机号的用户
SELECT * FROM users WHERE mobile <=> NULL;
4.2.2 正则表达式运算符(REGEXP)
-- 查找符合中国大陆手机号格式的用户
SELECT * FROM users
WHERE mobile REGEXP '^1[3-9][0-9]{9}$';
-- 查找复杂密码(包含大小写字母和数字)
SELECT * FROM users
WHERE password REGEXP '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])';
五、OceanBase 常用函数大全
5.1 字符串函数实战
常用字符串操作:
-- 拼接字符串
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
-- 格式化显示
SELECT
order_id,
LPAD(order_id, 8, '0') AS formatted_id,
RPAD(username, 20, '.') AS padded_name
FROM orders JOIN users USING(user_id);
-- JSON处理(OceanBase 3.x+)
SELECT
user_id,
JSON_EXTRACT(profile_json, '$.age') AS age,
JSON_CONTAINS(profile_json, '"vip"', '$.tags') AS is_vip
FROM users;
5.2 数值计算函数
金融计算案例:
-- 贷款计算器函数
CREATE FUNCTION calculate_loan(
principal DECIMAL(10,2),
annual_rate DECIMAL(5,2),
months INT
) RETURNS DECIMAL(10,2)
BEGIN
DECLARE monthly_rate DECIMAL(10,6);
DECLARE payment DECIMAL(10,2);
SET monthly_rate = annual_rate / 12 / 100;
SET payment = principal * monthly_rate * POW(1 + monthly_rate, months) /
(POW(1 + monthly_rate, months) - 1);
RETURN ROUND(payment, 2);
END;
-- 使用示例
SELECT
loan_id,
amount,
calculate_loan(amount, rate, term) AS monthly_payment
FROM loans;
5.3 高级分析函数
窗口函数应用:
-- 用户消费排名分析
SELECT
user_id,
order_id,
order_amount,
SUM(order_amount) OVER(PARTITION BY user_id) AS user_total,
RANK() OVER(PARTITION BY user_id ORDER BY order_amount DESC) AS amount_rank,
order_amount / SUM(order_amount) OVER(PARTITION BY user_id) AS amount_ratio
FROM orders
WHERE order_time BETWEEN '2023-01-01' AND '2023-12-31';
六、OceanBase 表创建与管理
6.1 表设计规范
电商系统表示例:
CREATE TABLE products (
product_id BIGINT NOT NULL AUTO_INCREMENT,
product_name VARCHAR(200) NOT NULL,
category_id INT NOT NULL,
price DECIMAL(10,2) NOT NULL,
cost DECIMAL(10,2),
stock INT DEFAULT 0,
weight DECIMAL(8,2) COMMENT '重量(kg)',
is_active TINYINT(1) DEFAULT 1,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
description TEXT,
PRIMARY KEY (product_id),
KEY idx_category (category_id),
KEY idx_name (product_name(20))
) ENGINE=OceanBase
PARTITION BY HASH(product_id) PARTITIONS 8
COMMENT='商品基本信息表';
6.2 分区表设计
时间范围分区案例:
CREATE TABLE order_history (
order_id BIGINT,
user_id INT,
amount DECIMAL(10,2),
order_time DATETIME,
PRIMARY KEY (order_id, order_time)
) PARTITION BY RANGE(TO_DAYS(order_time)) (
PARTITION p202201 VALUES LESS THAN (TO_DAYS('2022-02-01')),
PARTITION p202202 VALUES LESS THAN (TO_DAYS('2022-03-01')),
PARTITION p202203 VALUES LESS THAN (TO_DAYS('2022-04-01')),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- 添加新分区
ALTER TABLE order_history ADD PARTITION (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01'))
);
-- 合并分区
ALTER TABLE order_history REORGANIZE PARTITION p202201,p202202 INTO (
PARTITION p2022q1 VALUES LESS THAN (TO_DAYS('2022-04-01'))
);
七、OceanBase 约束使用指南
7.1 约束类型对比
约束类型 | 作用 | 特点 | 示例 |
---|---|---|---|
PRIMARY KEY | 唯一标识 | 非空且唯一,自动创建索引 | id INT PRIMARY KEY |
FOREIGN KEY | 参照完整性 | 关联其他表的主键 | FOREIGN KEY (dept_id) REFERENCES departments(id) |
UNIQUE | 唯一性约束 | 允许NULL值,创建唯一索引 | email VARCHAR(100) UNIQUE |
CHECK | 条件检查 | 验证数据有效性 | age INT CHECK (age >= 18) |
NOT NULL | 非空约束 | 禁止NULL值 | name VARCHAR(50) NOT NULL |
DEFAULT | 默认值 | 插入时自动填充 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
7.2 外键约束实战
订单系统外键示例:
-- 创建主表
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
customer_name VARCHAR(100) NOT NULL,
credit_rating DECIMAL(3,1)
) COMMENT='客户主表';
-- 创建从表
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
amount DECIMAL(10,2),
CONSTRAINT fk_customer
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE RESTRICT
ON UPDATE CASCADE
) COMMENT='订单表';
-- 外键操作测试
INSERT INTO customers VALUES(1, '张三', 4.5);
INSERT INTO orders VALUES(1001, 1, '2023-05-01', 299.00); -- 成功
INSERT INTO orders VALUES(1002, 2, '2023-05-02', 599.00); -- 失败,客户2不存在
UPDATE customers SET customer_id = 101 WHERE customer_id = 1; -- 自动级联更新orders表
八、OceanBase 索引创建与优化
8.1 索引类型详解
索引类型 | 特点 | 适用场景 | 创建语法 |
---|---|---|---|
B-Tree索引 | 平衡树结构,支持范围查询 | 高基数列、等值查询 | CREATE INDEX idx_name ON table(col) |
唯一索引 | 保证列值唯一性 | 业务唯一约束 | CREATE UNIQUE INDEX idx_name ON table(col) |
复合索引 | 多列组合索引 | 多条件查询 | CREATE INDEX idx_name ON table(col1,col2) |
函数索引 | 基于函数结果的索引 | 频繁使用函数的查询 | CREATE INDEX idx_name ON table(SUBSTR(col,1,10)) |
全文索引 | 文本内容搜索 | 大文本字段搜索 | CREATE FULLTEXT INDEX idx_name ON table(col) |
8.2 索引优化案例
电商查询优化示例:
-- 原始查询(性能较差)
SELECT * FROM products
WHERE category_id = 5
AND price BETWEEN 100 AND 500
ORDER BY sales_volume DESC
LIMIT 20;
-- 优化方案1:创建复合索引
CREATE INDEX idx_category_price_sales ON products(category_id, price, sales_volume);
-- 优化方案2:使用覆盖索引
CREATE INDEX idx_category_price_cover ON products(category_id, price, product_id, product_name);
-- 优化后查询
SELECT product_id, product_name, price
FROM products
WHERE category_id = 5
AND price BETWEEN 100 AND 500
ORDER BY price
LIMIT 20;
索引使用分析:
-- 查看索引使用情况
EXPLAIN SELECT * FROM products WHERE category_id = 5;
-- 索引效率监控
SELECT
table_name,
index_name,
rows_read,
rows_inserted,
rows_updated,
rows_deleted
FROM oceanbase.__all_virtual_table_stat
WHERE table_name = 'products';
九、OceanBase 视图创建与使用
9.1 视图管理实战
销售分析视图示例:
-- 创建视图
CREATE VIEW sales_summary AS
SELECT
u.user_id,
u.username,
u.register_time,
COUNT(o.order_id) AS order_count,
SUM(o.order_amount) AS total_amount,
MAX(o.order_time) AS last_order_time
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.username, u.register_time
WITH CHECK OPTION;
-- 使用视图查询
SELECT * FROM sales_summary
WHERE total_amount > 1000
ORDER BY total_amount DESC
LIMIT 100;
-- 查看视图定义
SHOW CREATE VIEW sales_summary;
-- 修改视图
CREATE OR REPLACE VIEW sales_summary AS
SELECT
u.user_id,
u.username,
-- 新增用户等级字段
CASE
WHEN SUM(o.order_amount) > 10000 THEN 'VIP'
WHEN SUM(o.order_amount) > 5000 THEN 'Gold'
ELSE 'Standard'
END AS user_level,
COUNT(o.order_id) AS order_count,
SUM(o.order_amount) AS total_amount
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.username;
9.2 物化视图优化
-- 创建物化视图(OceanBase企业版支持)
CREATE MATERIALIZED VIEW mv_product_sales
REFRESH COMPLETE ON DEMAND
ENABLE QUERY REWRITE
AS
SELECT
p.product_id,
p.product_name,
p.category_id,
COUNT(o.order_id) AS sales_count,
SUM(o.quantity) AS total_quantity,
SUM(o.amount) AS total_amount
FROM products p
JOIN order_items o ON p.product_id = o.product_id
GROUP BY p.product_id, p.product_name, p.category_id;
-- 自动查询重写
SET QUERY_REWRITE_ENABLED=ON;
-- 原始查询会被重写到物化视图
SELECT
p.product_name,
SUM(o.amount) AS total_sales
FROM products p
JOIN order_items o ON p.product_id = o.product_id
GROUP BY p.product_name;
十、OceanBase 基础查询进阶
10.1 复杂查询优化
多表连接优化案例:
-- 低效写法(嵌套子查询)
SELECT u.user_id, u.username
FROM users u
WHERE u.user_id IN (
SELECT DISTINCT o.user_id
FROM orders o
WHERE o.order_amount > 1000
);
-- 优化方案1:使用JOIN
SELECT DISTINCT u.user_id, u.username
FROM users u
JOIN orders o ON u.user_id = o.user_id
WHERE o.order_amount > 1000;
-- 优化方案2:使用EXISTS
SELECT u.user_id, u.username
FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.user_id = u.user_id
AND o.order_amount > 1000
);
-- 执行计划对比
EXPLAIN SELECT ...; -- 分别查看三种写法的执行计划
10.2 分布式查询原理
OceanBase 的分布式查询处理流程:
分布式查询优化建议:
- 尽量使用分区键作为查询条件
- 避免大表全表扫描
- 合理设置JOIN顺序(小表驱动大表)
- 使用HINT指定执行计划(如
/*+ LEADING(t1 t2) USE_NL(t2) */
)
结语
通过本指南的系统学习,您已经掌握了OceanBase数据库的基础核心知识。作为分布式数据库,OceanBase在架构设计、SQL语法、性能优化等方面与传统单机数据库有着显著区别。建议在实际工作中:
- 充分利用分布式特性设计表结构和查询
- 定期监控分区分布和资源使用情况
- 根据业务特点选择合适的索引策略
- 关注OceanBase的版本更新,及时应用新特性
后续可深入学习OceanBase的高级特性如分布式事务、存储过程开发、性能调优等内容,以充分发挥其在大规模数据场景下的优势。