【金仓数据库产品体验官】KingbaseES-Oracle兼容性体验
官方下载地址:
https://www.kingbase.com.cn/download.html
下载授权文件
检查系统基本信息
[root@localhost ~]# cat /etc/os-release
[root@localhost ~]# free -m
[root@localhost ~]# df -hl
配置内核参数
[root@localhost ~]# vi /etc/sysctl.conf
添加以下内容
kernel.shmall = 2097152
kernel.shmmax = 4294967295
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
fs.aio-max-nr = 1048576
fs.file-max = 6815744
[root@localhost ~]# sysctl -p
设置系统资源限制
[root@localhost ~]# vi /etc/security/limits.conf
添加以下内容
* soft nofile 65536
* hard nofile 65535
* soft nproc 65536
* hard nproc 65535
* soft core unlimited
* hard core unlimited
创建数据库专用安装用户
[root@localhost ~]# useradd -m kingbase
[root@localhost ~]# passwd kingbase #这里密码要输入强密码
创建安装目录
[root@localhost ~]# sudo mkdir -p /opt/Kingbase/ES/V9
[root@localhost ~]# sudo chown -R kingbase:kingbase /opt/Kingbase/ES/V9
[root@localhost ~]# sudo chmod -R 755 /opt/Kingbase/ES/V9
[root@localhost ~]# mkdir -p /opt/Kingbase/ES/V9/data
[root@localhost ~]# sudo chown -R kingbase:kingbase /opt/Kingbase/ES/V9/data
[root@localhost ~]# sudo chmod -R 755 /opt/Kingbase/ES/V9/data
创建数据目录
[root@localhost ~]# sudo mkdir -p /data/kingbase
[root@localhost ~]# sudo chown -R kingbase:kingbase /data/kingbase
[root@localhost ~]# sudo chmod -R 750 /data/kingbase
挂载安装包
将下载的安装包上传至/root目录下
[root@localhost ~]# mkdir -p /mnt/kingbase
[root@localhost ~]# mount KingbaseES_V009R002C013B0005_Lin64_install.iso /mnt/kingbase
命令行安装步骤
[root@localhost ~]# su - kingbase
[kingbase@localhost ~]$ cd /mnt/kingbase
[kingbase@localhost kingbase]$ sh setup.sh
[kingbase@localhost kingbase]$ /opt/Kingbase/ES/V9/Server/bin/initdb -U "system" -W -D "/opt/Kingbase/ES/V9/data"
[kingbase@localhost data]$ /opt/Kingbase/ES/V9/Server/bin/sys_ctl -D /opt/Kingbase/ES/V9/data -l ks.log start
查看是否启动
[kingbase@localhost data]$ ps -ef|grep kingbase
登录数据库
[kingbase@localhost data]$ /opt/Kingbase/ES/V9/Server/bin/ksql -p 54321 -U system -d kingbase
kingbase=# select version();
kingbase=# select get_license_info();
kingbase=# show database_mode;
1. 数据类型测试(yminterval和dsinterval)
-- 创建包含interval类型的表
kingbase-#CREATE TABLE interval_test (id NUMBER,month_interval YMINTERVAL,day_interval DSINTERVAL
);-- 插入测试数据
kingbase-#INSERT INTO interval_test VALUES (1,INTERVAL '2-3' YEAR TO MONTH, -- 2年3个月INTERVAL '5 10:30:00' DAY TO SECOND -- 5天10小时30分钟
);-- 查询测试
kingbase-#SELECT id,month_interval,day_interval,ADD_MONTHS(SYSDATE, EXTRACT(YEAR FROM month_interval)*12 + EXTRACT(MONTH FROM month_interval)) AS future_date,SYSDATE + day_interval AS future_datetime
FROM interval_test;
2. 虚拟列测试
-- 创建带虚拟列的表
-- 创建基础表(不含虚拟列)
kingbase-#CREATE TABLE employees_base (id NUMBER,first_name VARCHAR2(50),last_name VARCHAR2(50),salary NUMBER(10,2),commission_pct NUMBER(3,2)
);-- 创建视图,包含计算列(模拟虚拟列)
kingbase-#CREATE OR REPLACE VIEW employees AS
SELECT id,first_name,last_name,salary,commission_pct,salary + (salary * NVL(commission_pct, 0)) AS total_compensation
FROM employees_base;-- 插入测试数据
kingbase-#INSERT INTO employees (id, first_name, last_name, salary, commission_pct)
VALUES (1, 'John', 'Doe', 5000, 0.1);kingbase-#INSERT INTO employees (id, first_name, last_name, salary)
VALUES (2, 'Jane', 'Smith', 6000);-- 查询虚拟列
kingbase-#SELECT id, first_name, last_name, salary, total_compensation
FROM employees;
3. 分区表及interval分区自动分裂测试
-- 创建按年的interval分区表
kingbase-#CREATE TABLE sales (sale_id NUMBER,sale_date DATE,amount NUMBER
)
PARTITION BY RANGE (sale_date)
INTERVAL (NUMTOYMINTERVAL(1, 'YEAR'))
(PARTITION p2020 VALUES LESS THAN (TO_DATE('2021-01-01', 'YYYY-MM-DD'))
);-- 插入数据,触发分区自动创建
kingbase-#INSERT INTO sales VALUES (1, TO_DATE('2020-05-15', 'YYYY-MM-DD'), 1000);
kingbase-#INSERT INTO sales VALUES (2, TO_DATE('2021-03-20', 'YYYY-MM-DD'), 1500);
kingbase-#INSERT INTO sales VALUES (3, TO_DATE('2022-11-10', 'YYYY-MM-DD'), 2000);-- 查看分区信息
kingbase-#SELECT table_name, partition_name, high_value
FROM user_tab_partitions
WHERE table_name = 'SALES';
4. Execute Immediate语句测试
-- 启用输出显示
kingbase-#SET client_min_messages = notice;
\set SQLTERM /-- 匿名块执行动态SQL
DO $$
DECLAREv_name VARCHAR(50); -- 金仓更兼容VARCHAR而非VARCHAR2v_id INT := 1;
BEGIN-- 动态查询(使用PostgreSQL风格的$1占位符)EXECUTE 'SELECT ename FROM (SELECT 1 AS id, ''测试用户'' AS ename) WHERE id = $1'INTO v_nameUSING v_id;-- 输出结果(金仓优先支持RAISE NOTICE)RAISE NOTICE '查询结果:%', v_name;
END $$;
/-- 恢复默认设置
\set SQLTERM ;
SET client_min_messages = warning;
5. Returning Into子句测试
-- 1. 先创建兼容的测试表(自增列使用integer类型)
kingbase=#CREATE TABLE test_returning (id integer GENERATED BY DEFAULT AS IDENTITY, -- 金仓支持的自增列类型name VARCHAR2(100)
);-- 2. 配置SQL终止符和输出设置
\set SQLTERM /
SET client_min_messages = notice; -- 启用通知输出-- 3. 执行带RETURNING INTO的插入操作
DO $$
DECLAREv_new_id INT; -- 声明变量接收返回的ID
BEGIN-- 插入数据并通过RETURNING返回自增IDINSERT INTO test_returning (name) VALUES ('测试返回值') RETURNING id INTO v_new_id; -- 核心:将插入的id存入变量-- 输出结果(金仓推荐用RAISE NOTICE)RAISE NOTICE '插入的新ID:%', v_new_id;
END $$;
/-- 4. 验证数据插入结果
SELECT * FROM test_returning;-- 5. 恢复默认设置
\set SQLTERM ;
SET client_min_messages = warning;
6. BULK COLLECT INTO批量数据获取
-- 配置SQL终止符和输出设置
kingbase=#\set SQLTERM /
SET client_min_messages = notice; -- 启用通知输出-- 执行批量数据获取测试
DO $$
DECLARE-- 定义数组类型(金仓plpgsql中用ARRAY替代Oracle的TABLE类型)v_ids INT[]; -- 整数数组,用于存储批量获取的IDi INT; -- 循环变量
BEGIN-- 批量获取ID列表(使用BULK COLLECT INTO兼容语法)SELECT ARRAY_AGG(id) INTO v_ids -- 金仓用ARRAY_AGG聚合为数组FROM (SELECT 1 AS id UNION ALL SELECT 2 AS id UNION ALL SELECT 3 AS id) AS subquery;-- 遍历数组(plpgsql风格的循环)FOREACH i IN ARRAY v_ids LOOPRAISE NOTICE 'ID: %', i; -- 输出每个IDEND LOOP;
END $$;
/-- 恢复默认设置
\set SQLTERM ;
SET client_min_messages = warning;
7、LATERAL连接(关联子查询)
-- 测试LATERAL连接:子查询引用主表字段
kingbase=#WITH users AS ( -- 主表:用户数据SELECT 1 AS user_id, '张三' AS name UNION ALLSELECT 2 AS user_id, '李四' AS name),orders AS ( -- 子表:订单数据SELECT 1 AS order_id, 1 AS user_id, '订单1' AS order_name UNION ALLSELECT 2 AS order_id, 1 AS user_id, '订单2' AS order_name)-- LATERAL连接查询:每个用户取1条订单
kingbase=#SELECT u.name, o.order_name
FROM users u
LEFT JOIN LATERAL (-- 子查询中引用主表的u.user_idSELECT order_name FROM orders WHERE user_id = u.user_id LIMIT 1 -- 金仓兼容LIMIT语法,等价于FETCH FIRST 1 ROW ONLY
) o ON true;
8、多表连接视图的DML操作
-- 1. 创建基础表(含主键和外键约束)
kingbase=#CREATE TABLE dept (dept_id INT PRIMARY KEY,dept_name VARCHAR2(50) NOT NULL
);kingbase=#CREATE TABLE emp (emp_id INT PRIMARY KEY,emp_name VARCHAR2(50) NOT NULL,dept_id INT NOT NULL REFERENCES dept(dept_id) -- 外键非空,确保关联有效性
);-- 2. 插入基础数据
kingbase=#INSERT INTO dept VALUES (1, '技术部');
kingbase=#INSERT INTO dept VALUES (2, '市场部');
kingbase=#INSERT INTO emp VALUES (1, '张三', 1);-- 3. 创建多表连接视图(包含可明确映射到单表的列)
kingbase=#CREATE VIEW emp_dept_view AS
SELECT e.emp_id, e.emp_name, e.dept_id, -- 包含外键列,便于插入时指定关联d.dept_name
FROM emp e
JOIN dept d ON e.dept_id = d.dept_id;-- 4. 通过视图更新数据(UPDATE:仅更新emp表的列)
kingbase=#UPDATE emp_dept_view
SET emp_name = '张三(更新后)'
WHERE emp_id = 1;-- 5. 通过视图插入数据(INSERT:需满足所有基表非空约束)
-- 注意:只能插入到视图中可明确映射到单一基表(此处为emp表)的列
kingbase=#INSERT INTO emp_dept_view (emp_id, emp_name, dept_id)
VALUES (2, '李四', 1); -- 需指定dept_id,满足emp表外键非空约束-- 6. 验证底层表数据是否同步更新
kingbase=#SELECT * FROM emp; -- 查看更新和插入的员工数据
SELECT * FROM emp_dept_view; -- 查看视图数据是否同步
9、HINT调优测试
-- 1. 创建测试表及索引
CREATE TABLE hint_test (id INT PRIMARY KEY,name VARCHAR2(50),dept_id INT,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);-- 创建普通索引
CREATE INDEX idx_hint_dept ON hint_test(dept_id);-- 插入测试数据
INSERT INTO hint_test(id, name, dept_id)
SELECT n, '用户'||n, n%3
FROM generate_series(1, 10000) n; -- 生成10000条测试数据
COMMIT;-- 2. 无HINT的查询(默认可能走索引或全表扫描)
EXPLAIN ANALYZE
SELECT id, name FROM hint_test WHERE dept_id = 1;-- 3. 使用HINT强制全表扫描(Oracle风格/*+ FULL */)
EXPLAIN ANALYZE
SELECT /*+ FULL(ht) */ id, name
FROM hint_test ht
WHERE dept_id = 1;-- 4. 使用HINT强制走指定索引(Oracle风格/*+ INDEX */)
EXPLAIN ANALYZE
SELECT /*+ INDEX(ht idx_hint_dept) */ id, name
FROM hint_test ht
WHERE dept_id = 1;