ClickHouse数据库之特殊需求

标签: Clickhouse 分类: 数据库 创建时间:2020-06-15 04:43:11 更新时间:2023-10-20 11:23:25

1.中文ANSI编码

clickhouse官方文档中,提到了如果要存储文本,建议使用UTF-8编码:(参考文章7)

若需存储文本,我们建议使用 UTF-8 编码。至少,如果你的终端使用UTF-8(推荐),这样读写就不需要进行任何的转换了。

还有一句话就是(参考文章7):“ClickHouse 没有编码的概念。字符串可以是任意的字节集,按它们原本的方式进行存储和输出。” 也就是说,你存到数据中的字符编码是什么,那么取出来的就是什么,clickhouse不会进行转换。如果你想存UTF-8字符,那就用UTF-8的字符进行存储,如果你想存gb2312的字符集,那就直接从数据库中查出来相应的字符然后用相应的字符编码存进去就好了。

如果一定要将UTF-8编码转为其他的字符串编码,比如转为ANSI编码,这里有个函数:convertCharset(s, from, to),例如:将utf-8转为GB2312编码

1
select convertCharset(SiteName, 'UTF-8', 'GB2312') as s from gdnx.siteinfo

虽然可以转为GB2312编码,但是没有ANSI编码

参考文章:
1.Clickhouse 基础知识 - 函数 (这里也有几个示例说明convertCharset函数的用法,文章中还提到了其他的一些函数,比如算术函数、比较、逻辑、类型转换、日期时间等内容)
2.Ansi,UTF8,Unicode编码(续)
3.字符编码Unicode、UTF-8和ANSI
4.utf-8文件转为ansi文件 python实现
5.Formats for Input and Output Data
6.Ansi Sql兼容性的ClickHouse SQL方言
7.字符串
8.Functions for Working with Strings
9.convertCharset(s, from, to) (这篇官方文档比较有用)
10.The convertCharset (s, ‘utf-8’, ‘utf-16’) doesn’t seem to work properly (这是一个例子)
11.编码函数

2.UPDATE和DELETE

官方介绍上,OLAP的典型的应用场景,有一条就是:不修改已添加的数据。但是如果你非得想让clickhouse实现更新和删除操作怎么办,也不是不可能,最新的更新中,增加了对数据的UPDATE/DELETE操作。

根据参考文章3,clickhouse的SQL语句和标准的ANSI SQL的兼容性文档中可以看出,clickhouse不支持定位更新和删除,但是支持批量的更新或者删除,这是一个新的功能,所以我在官方文档中ALTER的SQL参考中(参考文章7),相对于DROP COLUMN、CLEAR COLUMN等操作,并没有作为一项重要的功能单独的列出来如何进行更新和删除。

1
2
3
4
5
/*批量删除*/
ALTER TABLE <table_name> DELETE WHERE <filter>;

/*批量更新*/
ALTER TABLE <table_name> UPDATE col1 = expr1, ... WHERE <filter>;

这个功能是新出的,但是有别于传统的SQL更新和删除操作,在下列情况下无法正常工作:
(1) Updating the index column
更新索引列。索引列不能被更新。

(2) Distributed table updates
对分布式表的更新不起作用。如果一个表是分布式的,那么更新语句也会不起作用,更多的就是使用手动在多个分布式环境中进行更新操作。

(3) Frequent and point(single row) updates
频繁的更新或者是单行更新。不能期望clickhouse像传统的数据库mysql一样,进行单行或者频繁的更新,这个本来就不是数据仓库擅长干的事。

3.数据迁移

数据库中数据迁移,因为服务器升级等原因,想要将位于虚拟机A中Clickhouse迁移到位于Docker中的Clickhouse中。
使用remote函数进行数据迁移

1
2
3
4
5
6
7
8
9
10
11
## 导出建表sql
clickhouse-client --host="<old host>" --port="<old port>" --user="<old user name>" --password="<old password>" --query="SHOW CREATE TABLE <database_name>.<table_name>" > table.sql

## 在新的服务器中新键数据库
CREATE DATABASE IF NOT EXISTS <database_name>

## 在新的数据库中新键表
clickhouse-client --host="<new host>" --port="<new port>" --user="<new user name>" --password="<new password>" < table.sql

## 使用remote进行数据迁移
insert into <new_database>.<new_table> select * from remote('old_endpoint', <old_database>.<old_table>, '<username>', '<password>');
参考文章:
1.在ClickHouse之间进行数据迁移 (元数据的迁移、通过remote函数进行数据迁移、通过文件导出导入方式进行数据迁移)
2.Clickhouses数据迁移工具:Clickhouse-copier介绍 (主要介绍了使用Clickhouse自带的Clickhouse-copier工具进行复制的操作,但是我使用的是单机版的Clickhouse,没有安装zookeeper,所以我嫌麻烦。数据迁移的三种方法:(1) DETACH/FREEZE分区,进行SCP拷贝,然后再ATTACH;(2) 利用remote函数; (3) clickhouse-copier工具;)

问题

(1) Exception: Syntax error: failed at position 98 (‘'): 'Asia/Shanghai'), endTime DateTime('Asia/Shanghai'), reportGenerateTime DateTime('Asia/Shanghai'), results Nullable(VARCHAR)) ENGINE = MergeTree() O. Unrecognized token: ‘'

这个主要是因为其中的 DateTime('Asia/Shanghai') 中的斜杠,把全部的斜杠去掉就可以了,变成 DateTime(‘Asia/Shanghai’)

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。