金仓简介
KingbaseES是一款面向事务处理应用,兼顾简单分析应用的企业级关系型数据库,产品融合了金仓在数据库领域多年的产品研发经验和企业级应用经验,可满足各行业用户多种场景的数据处理需求。
问题记录
安装问题
数据库安装比较传统,参考官方教程即可,稍微需要注意的地方就是字符集以及大小写敏感的设置。
基本概念的理解问题
金仓的一些基本概念主要包括用户、数据库、模式、表空间等,与常用的MySQL还是有些不一样,可参考下面的文章进行初步的了解。
数据迁移问题
使用金仓提供的数据迁移工具从MySQL迁移表数据时,会报“关系 “PRIMARY” 已经存在”的问题,因为在金仓中同一个数据库索引名称不能重复,而MySQL中是可以的而且主键索引名默认为PRIMARY,所以迁移后需要手动添加主键索引。(ps:其他类型索引同理也会有这个问题)
License过期问题 参考文档
试用版的license有一定的使用期限,license过期后金仓数据库将无法运行,此时可前往官方地址下载最新的license文件进行替换。
开发问题
-
数据库报错信息乱码
修改配置文件Kingbase.conf中的lc_messages = en_CN.UTF-8即可。
-
驱动安装问题 参考文档
金仓驱动没有外部maven资源,所以需要从官网下载驱动包放到本地目录,然后从到本地加载。
-
正则匹配
MySQL语法:对象 REGEXP 正则表达式
金仓语法:REGEXP_LIKE(对象, 正则表达式) -
匹配MySQL information_schema中的表
针对MySQL information_schema数据库中的各种表,在金仓中也有。
-
获取自增字段当前值
MySQL语法:SELECT AUTO_INCREMENT-1 FROM information_schema.tables WHERE table_schema = 'tableSchema' AND TABLE_NAME = 'tableName';
金仓语法:
SELECT NEXTVAL('tableSchema.tableName_id_seq') - 1;
-
匹配MySQL DATE_FORMAT()函数
金仓没有DATE_FORMAT()函数,可使用to_char(日期对象, ‘%Y-%m-%d’)代替。
-
匹配MySQL WEEK()函数
金仓没有WEEK()函数,可使用EXTRACT(WEEK FROM 日期对象)代替。
-
匹配MySQL QUARTER()函数
金仓没有QUARTER()函数,可使用EXTRACT(QUARTER FROM 日期对象)代替。
-
匹配MySQL DATE_FORMAT()中%x、%v写法 参考文档
MySQL语法:SELECT DATE_FORMAT('2021-01-01', '%x'), DATE_FORMAT('2021-01-01', '%v');
金仓语法:
select EXTRACT(ISOYEAR FROM DATE '2021-01-01'), EXTRACT(WEEK FROM DATE '2021-01-01');
-
Str=’’失效问题
金仓默认把空字符串当成null,所以如果在sql中使用str=’’会失效。这时可以改写为str is null或者修改kingbase.conf中的ora_input_emptystr_isnull = off。
-
字段必须在 GROUP BY 中出现或者被用于聚合函数
和达梦类似金仓sql中的查询字段也必须出现在group by后面,除非字段被用于聚合函数。
-
使用SQL获取对象创建DDL语句
MySQL语法:show create table tableName;
金仓语法:(ps:需要先执行语句CREATE EXTENSION dbms_metadata;安装扩展)
select dbms_metadata.get_ddl('table', 'tableName', 'tableSchema') from dual;
-
Datax 适配金仓 参考文档
Datax可通过KingbaseesReader和KingbaseesWriter来适配金仓数据库。
-
SpringBatch无法兼容金仓问题 参考文档
SpringBatch不支持达梦数据库,可以使用与金仓相近的PostgreSQL数据库来代替。
-
Sharding-JDBC 4.0.1适配金仓问题
- 初始化sharding-jdbc数据源时会产生“Method com.kingbase8.jdbc.KbDatabaseMetaData.getRowIdLifetime() is not yet implemented”警告,但并不影响程序运行,可忽略。 参考文档
- 使用sharding-jdbc跨表查询count语句会报错 参考文档
解决方案:重写分页拦截器,给count(*)设置别名。
private static SelectItem defaultCountSelectItem() { Function function = new Function(); function.setName("COUNT"); function.setAllColumns(true); SelectExpressionItem selectExpressionItem = new SelectExpressionItem(function); // 唯一修改的地方 selectExpressionItem.setAlias(new Alias("totalCount", true)); return selectExpressionItem; }
- 使用sharding-jdbc跨表分页查询失效问题
解决方案:使用sharding-jdbc提供的spi以便在分页查询的时候可识别国产数据库。
/** * Database type of Kingbase */ public final class KingbaseDatabaseType implements BranchDatabaseType { @Override public DatabaseType getTrunkDatabaseType() { return DatabaseTypes.getActualDatabaseType("PostgreSQL"); } @Override public String getName() { return "Kingbase"; } @Override public Collection<String> getJdbcUrlPrefixAlias() { return Collections.singleton("jdbc:kingbase"); } @Override public DataSourceMetaData getDataSourceMetaData(final String url, final String username) { return new KingbaseDataSourceMetaData(url); } }
/** * Data source meta data */ @Getter public final class KingbaseDataSourceMetaData implements DataSourceMetaData { private static final int DEFAULT_PORT = 54321; private final String hostName; private final int port; private final String catalog; private final String schema; private final static Pattern PATTERN = Pattern.compile("jdbc:(kingbase|kingbase8)://([\\w\\-.]+):?([0-9]*)/([\\w\\-]+)", Pattern.CASE_INSENSITIVE); public KingbaseDataSourceMetaData(final String url) { Matcher matcher = PATTERN.matcher(url); if (!matcher.find()) { throw new UnrecognizedDatabaseURLException(url, PATTERN.pattern()); } hostName = matcher.group(2); port = Strings.isNullOrEmpty(matcher.group(3)) ? DEFAULT_PORT : Integer.parseInt(matcher.group(3)); catalog = matcher.group(4); schema = null; } }