暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【金仓数据库产品体验官】KingbaseES-Mysql兼容版 再度尝鲜体验

山佳数峰寻道 2025-08-01
646

前言

        在数据库国产化替代的大背景下,金仓数据库(Kingbase)作为国产数据库的代表产品之一,其与主流商业数据库的兼容性表现备受关注。本文将深入探讨金仓数据库对Mysqk的兼容特性,通过实际测试体验其兼容程度,为考虑数据库迁移或国产化替代的企业提供参考。金仓KingbaseES数据库提供可插拔异构数据库原生兼容框架,并在此基础上实现MySQL数据库全面兼容。KingbaseES以内核兼容为基础,打造出涵盖内核、工具和接口的全方位MySQL兼容能力。
金仓Mysql兼容版主要包含如下主要特性:
1、高度兼容MySQL语法:
            支持绝大多数MySQL的SQL语法和数据类型、兼容MySQL的常用函数和存储过程语法、支持MySQL特有的特性如INSERT IGNORE、REPLACE INTO等
2、迁移工具支持:
            提供专门的MySQL到金仓的迁移工具、支持表结构、数据、视图、存储过程等对象的自动迁移、提供迁移前后的兼容性检查和评估报告
3、性能优化:
            针对MySQL常见工作负载进行了性能优化、支持类似的索引类型和优化器策略、提供兼容MySQL的性能调优参数
4、开发接口兼容:
            兼容MySQL的JDBC、ODBC接口、支持常用的PHP、Python等语言连接方式、尽量减少应用代码的修改需求

PS:金仓MySQL兼容版本主要覆盖以下方面:
        基础SQL语法(DML/DDL/DCL)
        常用数据类型(包括BLOB/TEXT等)
        事务隔离级别和锁机制
        字符集和排序规则
        常用系统函数和运算符
        存储引擎特性(部分兼容InnoDB特性)

开启体验之旅

1、确认数据库版本和兼容模式
可以看到我们本次得Mysql兼容版本以及模式,OK,环境准备好了,继续操作
2、体验uuid插件使用
插件uuid-ossp加载方式
    create extension uuid-ossp;
    uuid-ossp 是金仓数据库(KingbaseES)中用于生成UUID
    (通用唯一标识符)的扩展模块,
    基于PostgreSQL的uuid-ossp扩展实现。
    --查看扩展信息
    SELECT * FROM sys_available_extensions WHERE name = ‘uuid-ossp’;
    函数名 描述
    uuid_generate_v1() 基于时间戳和MAC地址生成UUID
    示例:SELECT uuid_generate_v1();
    uuid_generate_v3(namespace uuid, name text) 基于命名空间和名称的MD5哈希生成UUID
    示例:SELECT uuid_generate_v3(uuid_ns_url(), ‘example.com’);
    3、创建本次测试基础数据

    关于语句:
    COMMENT ON TABLE employees IS ‘公司员工信息表’;
    原因 :直接通过SQL 在字段后添加 COMMENT 的方式,在KingbaseMysql中是被禁止的

    其他基础数据不做过多展示,接下来我们继续体验:
    4、使用 @ 指定变量名
    在金仓数据库(KingbaseES)中,使用 @ 符号指定变量名是PL/SQL和SQL语句中的常见做法。以下是详细使用方法:
    测试原因:因为之前内部测试使用,在KESV8版本该方式使用会报错
    但是下边是在KingbaseES V009R003C011(Mysql兼容版中执行)
    测试1.在SQL查询中使用变量

      测试2.SQL查询中使用变量– 声明变量
      DECLARE@user_count INT;
      @max_salary DECIMAL(10,2);
      BEGIN
      SELECT COUNT(*INTO @user_count FROM users;
      SELECT MAX(salary) INTO @max_salary FROM employees;
      PRINT '用户总数: ’ || @user_count;
      PRINT '最高薪资: ’ || @max_salary;
      END;
      改写脚本:
        DO $$
        DECLAREuser_count INT;
        max_salary DECIMAL(10,2);
        BEGIN
        SELECT COUNT(*INTO user_count FROM users;
        SELECT MAX(salary) INTO max_salary FROM employees;
        RAISE NOTICE ‘用户总数: %’, user_count;
        RAISE NOTICE ‘最高薪资: %’, max_salary;
        END $$;

        测试3. 在存储过程中使用变量
        CREATE OR REPLACE PROCEDURE update_employee_salary(@emp_id INT, @increase_percent DECIMAL(5,2))
        AS
        BEGIN
        UPDATE employees
        SET salary = salary * (1 + @increase_percent/100)
        WHERE id = @emp_id;

        PRINT '员工ID ’ || @emp_id || ’ 的薪资已更新,涨幅 ’ || @increase_percent || ‘%’;
        END;

        改写脚本:
        CREATE OR REPLACE PROCEDURE update_employee_salary(
        p_emp_id VARCHAR(36),
        p_increase_percent DECIMAL(5,2)
        )
        LANGUAGE plpgsql
        AS $$
        BEGIN
        – 更新员工薪资
        UPDATE employees
        SET salary = salary * (1 + p_increase_percent/100)
        WHERE id = p_emp_id;

        -- 输出消息(金仓数据库使用RAISE NOTICE替代PRINT)
        RAISE NOTICE '员工ID % 的薪资已更新,涨幅 %%%', p_emp_id, p_increase_percent;

        END$$;
        – 调用存储过程
        CALL update_employee_salary(‘6a3a8b40-9c3a-11ed-a8fc-0242ac120002’, 10.0);

        金仓PL/SQL语法要点
        1.变量声明:
        不使用@符号前缀
        基本格式:变量名 数据类型;
        2.代码块结构:
        使用DO $$ … $$包装匿名代码块
        或使用CREATE FUNCTION/PROCEDURE创建命名程序
        3.输出信息:
        使用RAISE NOTICE替代PRINT
        格式:RAISE NOTICE ‘消息模板’, 变量;
        4.变量赋值:
        INTO子句用于将查询结果赋给变量
        也可以使用:=直接赋值:user_count := 100;

        5、关于INSERT IGNORE体验使用
        – 使用IGNORE忽略重复键错误
        INSERT IGNORE INTO public.employees (id, emp_code, emp_name, gender, department_id, hire_date)
        VALUES (uuid()::uuid, ‘EMP001’, ‘张三’, ‘M’, 1, ‘2023-01-15’);


        – 使用LIMIT限制更新行数
        UPDATE employees SET salary = salary * 1.1 WHERE department_id = 1 LIMIT 5;

        6、关于INSERT ON DUPLICATE KEY UPDATE体验使用
        INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
        VALUES (uuid_generate_v4(), ‘EMP001’, ‘张三’, ‘M’, 1, ‘2023-01-15’)
        ON DUPLICATE KEY UPDATE emp_name = VALUES(emp_name), department_id = VALUES(department_id);

        7、DML error logging体验使用
        – 创建错误日志表
        CREATE TABLE err_employees (
        id VARCHAR(36),
        emp_code VARCHAR(20),
        emp_name VARCHAR(50),
        err_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        err_msg VARCHAR(2000)
        );
        – 带错误日志记录的INSERT
        INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
        VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, ‘M’, 2, ‘2023-02-20’)
        LOG ERRORS INTO err_employees REJECT LIMIT 10;

        改写语法:
        DO $$
        BEGIN
        – 尝试插入数据
        INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
        VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, ‘M’, 2, ‘2023-02-20’);

        EXCEPTION WHEN OTHERS THEN
        – 发生错误时记录到错误表
        INSERT INTO err_employees (id, emp_code, emp_name, err_msg)
        VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, SQLERRM);

        RAISE NOTICE '插入失败,错误已记录: %', SQLERRM;

        END $$;

        PS:LOG ERRORS错误日志机制不支持,需采用BEGIN/EXCEPTION块或存储过程实现类似功能

        8、REPLACE INTO语句体验使用
        – 替换已存在员工记录(基于主键或唯一约束)
        REPLACE INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
        VALUES (‘6a3a8b40-9c3a-11ed-a8fc-0242ac120002’, ‘EMP003’, ‘王五’, ‘F’, 3, ‘2023-03-10’);

        9、LOAD DATA INFILE体验使用

        准备测试数据:
        CREATE TABLE IF NOT EXISTS products (
        id INT PRIMARY KEY,
        product_name VARCHAR(100) NOT NULL,
        category VARCHAR(50),
        price DECIMAL(10,2),
        stock INT,
        created_at TIMESTAMP
        );

        data.csv
        “id”,“product_name”,“category”,“price”,“stock”,“created_at”
        1,“笔记本电脑”,“电子产品”,5999.99,50,“2023-01-15 10:30:00”
        2,“智能手机”,“电子产品”,3999.00,100,“2023-01-16 11:15:00”
        3,“无线耳机”,“电子产品”,299.90,200,“2023-01-17 09:45:00”
        4,“办公椅”,“家具”,899.00,30,“2023-01-18 14:20:00”
        5,“台灯”,“家居用品”,159.50,80,“2023-01-19 16:10:00”
        6,“咖啡机”,“厨房电器”,1299.00,25,“2023-01-20 13:25:00”
        7,“运动鞋”,“服装鞋帽”,459.00,60,“2023-01-21 10:50:00”
        测试:

        ##使用COPY命令导入数据:
        COPY products (id, product_name, category, price, stock, created_at)
        FROM ‘/data/soft/data.csv’
        WITH (
        FORMAT csv,
        HEADER true, – 跳过标题行(等价于MySQL的IGNORE 1 ROWS)
        DELIMITER ‘,’,
        QUOTE ‘"’,
        NULL ‘’
        );


        PS:
        LOAD DATA INFILE不完全兼容,需改用COPY命令,必须使用PostgreSQL风格的COPY命令替代MySQL的LOAD DATA INFILE,文件路径权限管理更为严格,缺少IGNORE ROWS语法,改用HEADER true跳过标题行。
        PS:更新,LOAD使用如下方法:
        test=# CREATE TABLE products_new (LIKE products INCLUDING ALL);
        CREATE TABLE
        test=# select * from products_new;
        id | product_name | category | price | stock | created_at
        ----±-------------±---------±------±------±-----------
        (0 rows)

        test=# LOAD DATA INFILE ‘/data/soft/tst.csv’
        test-# INTO TABLE products_new
        test-# FIELDS TERMINATED BY ‘,’
        test-# ENCLOSED BY ‘"’
        test-# LINES TERMINATED BY ‘\n’
        test-# IGNORE 1 LINES;
        ERROR: syntax error at or near “IGNORE”
        LINE 6: IGNORE 1 LINES;
        ^
        test=# LOAD DATA INFILE ‘/data/soft/tst.csv’
        test-# INTO TABLE products_new
        test-# FIELDS TERMINATED BY ‘,’
        test-# ENCLOSED BY ‘"’
        test-# LINES TERMINATED BY ‘\n’;
        COPY 7

        原因:不支持使用IGNORE

        10、GROUP BY WITH ROLLUP体验使用
        – 按部门和性别统计员工数量和平均薪资
        SELECT
        COALESCE(department_id, ‘所有部门’) AS department,
        COALESCE(gender, ‘合计’) AS gender,
        COUNT(*) AS employee_count,
        AVG(salary) AS avg_salary
        FROM employees
        WHERE leave_date IS NULL
        GROUP BY department_id, gender WITH ROLLUP;

        总结

        经过如上体验我们可以得知:
        金仓数据库Mysql兼容模式基础语法支持良好:大多数基础DML语句(INSERT/UPDATE/DELETE/SELECT)与MySQL高度兼容,常见数据类型和基础函数能够正常工作,提供了非常好的兼容性,大大降低了从Mysql迁移至金仓数据库的技术门槛。期待金仓对Mysql的兼容性将进一步提升,为数据库国产化替代提供更加平滑的迁移路径。

        文章转载自山佳数峰寻道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论