首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >OceanBase SeekDB 是AI 数据库,NO NO NO 人家很可能是指东打西

OceanBase SeekDB 是AI 数据库,NO NO NO 人家很可能是指东打西

作者头像
AustinDatabases
发布2026-03-12 19:35:34
发布2026-03-12 19:35:34
40
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

MySQL之所以普及,并不单单是在服务器市场,更广阔的是单机的市场,也就是线下客户端,应用和数据库部署在一台终端上,而随着MySQL各种各样的“问题”,线下的客户端,单机使用的数据库可选项好像只有PG,再或者Sqlite。

一些国有的项目中,要求必须使用国产数据库产品,之前写过sqlite的一些研究,可sqlite只是一个非常简单的数据库产品,并不是一个可以支持复杂的读写并发的数据库产品。

市场急需一个可以替代MySQL兼容性的国产数据库产品。正好在此时seekdb出来了,我并没有根据他的一些介绍,把他高大上化,恰恰相反seekdb来做一些,低端的,特别接地气的事情。

替换mysql数据库线下的单机产品,所以此次我开始研究seekdb,看看他是否可以作为替换线下单机的MySQL的国产数据库产品。

目前seekdb 支持红帽或类似红帽的操作系统,版本是 7 和 9,跳过了8.不过大部分线下的LINUX系统还是在使用centos7类似的部分。同时更广阔的终端市场是WINDOWS的天下,装机量超大。

所以此次采用centos 7 来作为此次的测试系统,下面是一组实验和测试的截图和代码

seekdb
seekdb

seekdb

seekdb
seekdb

seekdb

安装
安装

安装

客户端登录
客户端登录

客户端登录

安装很简单,直接rpm包安装就可以了,登录页很简单,obclient -h 127.0.0.1 -P 2881 -u root@sys 只需要一条命令

代码语言:javascript
复制
[root@seekdb ~]# obclient -h 127.0.0.1 -P 2881 -u root@sys 
Welcome to the OceanBase.  Commands end with ; or \g.
Your OceanBase connection id is 3221488349
Server version: OceanBase 4.3.5.3 SeekDB (r1.0.0.0) (Built 100000262025111218-5343637512e28c346f938516af53b7879d4d5974 Nov 12 2025)

Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved.

Type 'help;' or '\h'forhelp. Type '\c' to clear the current input statement.

obclient(root@sys)[(none)]> CREATE DATABASE IF NOT EXISTS seekdb_demo;
Query OK, 1 row affected (0.871 sec)

obclient(root@sys)[(none)]> USE seekdb_demo;
Database changed
obclient(root@sys)[seekdb_demo]> CREATE TABLE customers (
    -> customer_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    -> customer_name VARCHAR(100) NOT NULL,
    -> email VARCHAR(100),
    -> phone VARCHAR(30),
    -> city VARCHAR(50),
    -> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -> ) COMMENT='客户表';
Query OK, 0 rows affected (0.883 sec)

obclient(root@sys)[seekdb_demo]> CREATE TABLE products (
    -> product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    -> product_name VARCHAR(100) NOT NULL,
    -> category VARCHAR(50),
    -> price DECIMAL(10,2) NOT NULL,
    -> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -> ) COMMENT='商品表';
Query OK, 0 rows affected (1.190 sec)

obclient(root@sys)[seekdb_demo]> CREATE TABLE orders (
    -> order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    -> customer_id BIGINT NOT NULL,
    -> order_date DATETIME NOT NULL,
    -> total_amount DECIMAL(12,2) NOT NULL,
    -> status VARCHAR(20) DEFAULT 'NEW',
    -> KEY idx_customer_date (customer_id, order_date)
    -> ) COMMENT='订单表';
Query OK, 0 rows affected (1.487 sec)

obclient(root@sys)[seekdb_demo]> CREATE TABLE order_items (
    -> item_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    -> order_id BIGINT NOT NULL,
    -> product_id BIGINT NOT NULL,
    -> quantity INT NOT NULL,
    -> unit_price DECIMAL(10,2) NOT NULL,
    -> KEY idx_order (order_id)
    -> ) COMMENT='订单明细表';
Query OK, 0 rows affected (1.278 sec)

obclient(root@sys)[seekdb_demo]> INSERT INTO customers (customer_name, email, city) VALUES
    -> ('Alice', 'alice@test.com', 'Beijing'),
    -> ('Bob', 'bob@test.com', 'Shanghai'),
    -> ('Carol', 'carol@test.com', 'Shenzhen');
Query OK, 3 rows affected (0.239 sec)
Records: 3  Duplicates: 0  Warnings: 0

obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> INSERT INTO products (product_name, category, price) VALUES
    -> ('Laptop', 'Electronics', 8000.00),
    -> ('Phone', 'Electronics', 5000.00),
    -> ('Desk', 'Furniture', 1200.00);
Query OK, 3 rows affected (0.055 sec)
Records: 3  Duplicates: 0  Warnings: 0

obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> INSERT INTO orders (customer_id, order_date, total_amount, status) VALUES
    -> (1, NOW(), 13000.00, 'PAID'),
    -> (2, NOW(), 5000.00, 'NEW');
Query OK, 2 rows affected (0.081 sec)
Records: 2  Duplicates: 0  Warnings: 0

obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> INSERT INTO order_items (order_id, product_id, quantity, unit_price) VALUES
    -> (1, 1, 1, 8000.00),
    -> (1, 2, 1, 5000.00),
    -> (2, 2, 1, 5000.00);
Query OK, 3 rows affected (0.038 sec)
Records: 3  Duplicates: 0  Warnings: 0

obclient(root@sys)[seekdb_demo]> SELECT * FROM customers;
+-------------+---------------+----------------+-------+----------+---------------------+
| customer_id | customer_name | email          | phone | city     | created_at          |
+-------------+---------------+----------------+-------+----------+---------------------+
|           1 | Alice         | alice@test.com | NULL  | Beijing  | 2025-12-18 15:57:20 |
|           2 | Bob           | bob@test.com   | NULL  | Shanghai | 2025-12-18 15:57:20 |
|           3 | Carol         | carol@test.com | NULL  | Shenzhen | 2025-12-18 15:57:20 |
+-------------+---------------+----------------+-------+----------+---------------------+
3 rows inset (0.021 sec)

obclient(root@sys)[seekdb_demo]> SELECT * FROM orders WHERE status = 'PAID';
+----------+-------------+---------------------+--------------+--------+
| order_id | customer_id | order_date          | total_amount | status |
+----------+-------------+---------------------+--------------+--------+
|        1 |           1 | 2025-12-18 15:57:20 |     13000.00 | PAID   |
+----------+-------------+---------------------+--------------+--------+
1 row inset (0.013 sec)

obclient(root@sys)[seekdb_demo]> explain SELECT
    -> o.order_id,
    -> c.customer_name,
    -> o.total_amount,
    -> o.status
    -> FROM orders o
    -> JOIN customers c ON o.customer_id = c.customer_id;
+-----------------------------------------------------------------------------------------------------+
| Query Plan                                                                                          |
+-----------------------------------------------------------------------------------------------------+
| ===================================================                                                 |
| |ID|OPERATOR           |NAME|EST.ROWS|EST.TIME(us)|                                                 |
| ---------------------------------------------------                                                 |
| |0 |MERGE JOIN         |    |2       |6           |                                                 |
| |1 |├─TABLE FULL SCAN  |c   |3       |3           |                                                 |
| |2 |└─SORT             |    |2       |3           |                                                 |
| |3 |  └─TABLE FULL SCAN|o   |2       |3           |                                                 |
| ===================================================                                                 |
| Outputs & filters:                                                                                  |
| -------------------------------------                                                               |
|   0 - output([o.order_id], [c.customer_name], [o.total_amount], [o.status]), filter(nil), rowset=16 |
|       equal_conds([o.customer_id = c.customer_id]), other_conds(nil)                                |
|       merge_directions([ASC])                                                                       |
|   1 - output([c.customer_id], [c.customer_name]), filter(nil), rowset=16                            |
|       access([c.customer_id], [c.customer_name]), partitions(p0)                                    |
|       is_index_back=false, is_global_index=false,                                                   |
|       range_key([c.customer_id]), range(MIN ; MAX)always true                                       |
|   2 - output([o.order_id], [o.total_amount], [o.status], [o.customer_id]), filter(nil), rowset=16   |
|       sort_keys([o.customer_id, ASC])                                                               |
|   3 - output([o.order_id], [o.customer_id], [o.total_amount], [o.status]), filter(nil), rowset=16   |
|       access([o.order_id], [o.customer_id], [o.total_amount], [o.status]), partitions(p0)           |
|       is_index_back=false, is_global_index=false,                                                   |
|       range_key([o.order_id]), range(MIN ; MAX)always true                                          |
+-----------------------------------------------------------------------------------------------------+
23 rows inset (0.162 sec)

obclient(root@sys)[seekdb_demo]> explain SELECT
    -> c.city,
    -> SUM(o.total_amount) AS city_sales
    -> FROM orders o
    -> JOIN customers c ON o.customer_id = c.customer_id
    -> GROUP BY c.city;
+-----------------------------------------------------------------------------+
| Query Plan                                                                  |
+-----------------------------------------------------------------------------+
| =====================================================                       |
| |ID|OPERATOR             |NAME|EST.ROWS|EST.TIME(us)|                       |
| -----------------------------------------------------                       |
| |0 |HASH GROUP BY        |    |2       |6           |                       |
| |1 |└─MERGE JOIN         |    |2       |5           |                       |
| |2 |  ├─TABLE FULL SCAN  |c   |3       |3           |                       |
| |3 |  └─SORT             |    |2       |3           |                       |
| |4 |    └─TABLE FULL SCAN|o   |2       |3           |                       |
| =====================================================                       |
| Outputs & filters:                                                          |
| -------------------------------------                                       |
|   0 - output([c.city], [T_FUN_SUM(o.total_amount)]), filter(nil), rowset=16 |
|       group([c.city]), agg_func([T_FUN_SUM(o.total_amount)])                |
|   1 - output([c.city], [o.total_amount]), filter(nil), rowset=16            |
|       equal_conds([o.customer_id = c.customer_id]), other_conds(nil)        |
|       merge_directions([ASC])                                               |
|   2 - output([c.customer_id], [c.city]), filter(nil), rowset=16             |
|       access([c.customer_id], [c.city]), partitions(p0)                     |
|       is_index_back=false, is_global_index=false,                           |
|       range_key([c.customer_id]), range(MIN ; MAX)always true               |
|   3 - output([o.customer_id], [o.total_amount]), filter(nil), rowset=16     |
|       sort_keys([o.customer_id, ASC])                                       |
|   4 - output([o.customer_id], [o.total_amount]), filter(nil), rowset=16     |
|       access([o.customer_id], [o.total_amount]), partitions(p0)             |
|       is_index_back=false, is_global_index=false,                           |
|       range_key([o.order_id]), range(MIN ; MAX)always true                  |
+-----------------------------------------------------------------------------+
26 rows inset (0.080 sec)

obclient(root@sys)[seekdb_demo]> EXPLAIN SELECT * FROM orders WHERE customer_id = 1;
+--------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                 |
+--------------------------------------------------------------------------------------------------------------------------------------------+
| =====================================================================                                                                      |
| |ID|OPERATOR        |NAME                     |EST.ROWS|EST.TIME(us)|                                                                      |
| ---------------------------------------------------------------------                                                                      |
| |0 |TABLE RANGE SCAN|orders(idx_customer_date)|1       |7           |                                                                      |
| =====================================================================                                                                      |
| Outputs & filters:                                                                                                                         |
| -------------------------------------                                                                                                      |
|   0 - output([orders.order_id], [orders.customer_id], [orders.order_date], [orders.total_amount], [orders.status]), filter(nil), rowset=16 |
|       access([orders.order_id], [orders.customer_id], [orders.order_date], [orders.total_amount], [orders.status]), partitions(p0)         |
|       is_index_back=true, is_global_index=false,                                                                                           |
|       range_key([orders.customer_id], [orders.order_date], [orders.order_id]), range(1,MIN,MIN ; 1,MAX,MAX),                               |
|       range_cond([orders.customer_id = 1])                                                                                                 |
+--------------------------------------------------------------------------------------------------------------------------------------------+
12 rows inset (0.031 sec)

obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> CREATE INDEX idx_orders_status ON orders(status);
Query OK, 0 rows affected (2.807 sec)

obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> 
obclient(root@sys)[seekdb_demo]> EXPLAIN SELECT * FROM orders WHERE status = 'PAID';
+--------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                 |
+--------------------------------------------------------------------------------------------------------------------------------------------+
| =====================================================================                                                                      |
| |ID|OPERATOR        |NAME                     |EST.ROWS|EST.TIME(us)|                                                                      |
| ---------------------------------------------------------------------                                                                      |
| |0 |TABLE RANGE SCAN|orders(idx_orders_status)|1       |7           |                                                                      |
| =====================================================================                                                                      |
| Outputs & filters:                                                                                                                         |
| -------------------------------------                                                                                                      |
|   0 - output([orders.order_id], [orders.customer_id], [orders.order_date], [orders.total_amount], [orders.status]), filter(nil), rowset=16 |
|       access([orders.order_id], [orders.status], [orders.customer_id], [orders.order_date], [orders.total_amount]), partitions(p0)         |
|       is_index_back=true, is_global_index=false,                                                                                           |
|       range_key([orders.status], [orders.order_id]), range(PAID,MIN ; PAID,MAX),                                                           |
|       range_cond([orders.status = 'PAID'])                                                                                                 |
+--------------------------------------------------------------------------------------------------------------------------------------------+
12 rows inset (0.162 sec)

obclient(root@sys)[seekdb_demo]> SELECT
    -> o.order_id,
    -> c.customer_name,
    -> o.total_amount,
    -> o.status
    -> FROM orders o
    -> JOIN customers c ON o.customer_id = c.customer_id;
+----------+---------------+--------------+--------+
| order_id | customer_name | total_amount | status |
+----------+---------------+--------------+--------+
|        1 | Alice         |     13000.00 | PAID   |
|        2 | Bob           |      5000.00 | NEW    |
+----------+---------------+--------------+--------+
2 rows inset (0.044 sec)

obclient(root@sys)[seekdb_demo]> explain SELECT
    -> o.order_id,
    -> c.customer_name,
    -> o.total_amount,
    -> o.status
    -> FROM orders o
    -> JOIN customers c ON o.customer_id = c.customer_id;
+-----------------------------------------------------------------------------------------------------+
| Query Plan                                                                                          |
+-----------------------------------------------------------------------------------------------------+
| ===================================================                                                 |
| |ID|OPERATOR           |NAME|EST.ROWS|EST.TIME(us)|                                                 |
| ---------------------------------------------------                                                 |
| |0 |MERGE JOIN         |    |2       |6           |                                                 |
| |1 |├─TABLE FULL SCAN  |c   |3       |3           |                                                 |
| |2 |└─SORT             |    |2       |3           |                                                 |
| |3 |  └─TABLE FULL SCAN|o   |2       |3           |                                                 |
| ===================================================                                                 |
| Outputs & filters:                                                                                  |
| -------------------------------------                                                               |
|   0 - output([o.order_id], [c.customer_name], [o.total_amount], [o.status]), filter(nil), rowset=16 |
|       equal_conds([o.customer_id = c.customer_id]), other_conds(nil)                                |
|       merge_directions([ASC])                                                                       |
|   1 - output([c.customer_id], [c.customer_name]), filter(nil), rowset=16                            |
|       access([c.customer_id], [c.customer_name]), partitions(p0)                                    |
|       is_index_back=false, is_global_index=false,                                                   |
|       range_key([c.customer_id]), range(MIN ; MAX)always true                                       |
|   2 - output([o.order_id], [o.total_amount], [o.status], [o.customer_id]), filter(nil), rowset=16   |
|       sort_keys([o.customer_id, ASC])                                                               |
|   3 - output([o.order_id], [o.customer_id], [o.total_amount], [o.status]), filter(nil), rowset=16   |
|       access([o.order_id], [o.customer_id], [o.total_amount], [o.status]), partitions(p0)           |
|       is_index_back=false, is_global_index=false,                                                   |
|       range_key([o.order_id]), range(MIN ; MAX)always true                                          |
+-----------------------------------------------------------------------------------------------------+
23 rows inset (0.052 sec)

这里我们稍微比较一下上面的执行计划,与MYSQL8的执行语句的方式比一下看看有什么差异。数据量比较小,这里只是简单的比较差异

1 SEEKDB 使用了merge join ,这个JOIN 的方法在,mysql 是没有的,MYSQL 目前只有两种多表连接的方式, Nested loop 和 hash join。

2 explain SELECT -> o.order_id, -> c.customer_name, -> o.total_amount, -> o.status -> FROM orders o -> JOIN customers c ON o.customer_id = c.customer_id;

在seekdb 为了连接针对ORDERS 进行了排序的处理,而这个部分在MYSQL 你是想都不要想,从这里简单的看出OCEANBASE的SQL优化执行体系和MYSQL完全不一样,是用心的。

3 执行计划的输出,这个也是非常让人惊喜的,和MYSQL的explain的执行计划粗陋不堪,SEEKDB的执行计划,怎么这么好看。

写到这里,后续还得做测试,对于大一点的数据,基于sstable 和 BTREE 的Oceanbase seekdb 和 Mysql数据处理速度的不同,如果OB 快,那么MYSQL的死刑执行日,也就快了。

最后解释一下题目,线下的终端市场一直是很多数据库厂商不注意的地方,大量的MySQL,PostgreSQL在这一个领域,上亿的装机量那一定是有的,如果是SQLite几十亿的装机量都是有的。

SeekDB 名义是AI数据库,其实我看,线下的MYSQL POSTGRESQL 的市场才是要被侵害的,甚至SQLite 一部分市场,因为SEEKDB的功能更强,安装简单,使用方便,也会被终端体系所接受,国外垄断线下的终端数据库市场的体系可能就此瓦解,加油SEEKDB,备不住你就是第二个线下终端数据库的王者。(嵌入式,终端设备,工业数据库小型终端,小型智能AI数据库等等)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档