ClickHouse 查询语言介绍

查询

CREATE DATABASE

创建 ‘db_name’ 数据库.

CREATE DATABASE [IF NOT EXISTS]

一个数据库是库中表的一个目录.如果包含“IF NOT EXISTS” ,此数据库已经存在,则查询将不返回错误。

CREATE TABLE

CREATE TABLE 查询有几种形式.

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name [ON CLUSTER cluster](  name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2], ...) ENGINE = engine

在数据库 ‘db’ 中或者当前的数据库中如果 ‘db’没有被设置(结构被指定在引擎中)创建一个表名为 ‘name’ 的表,表的结构是一个列描述的列表. If 如果索引通过引擎来支持, 他们将被提示作为表引擎的参数.

列描述是最简单的名称类型.例如:RegionID UInt32. 对于默认值,表达式能够被定义.

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name AS [db2.]name2 [ENGINE = engine]

创建一个表与另外一个表有相同的结构.你能为表指定不同的引擎.如果引擎没有被指定,相同的引擎将被用在 ‘db2.name2’ 表上.

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name ENGINE = engine AS SELECT ...

创建一个表,其结构类似SELECT查询语句的结果,带有'engine'引擎,使用Select结果来填充数据.

如果 IF NOT EXISTS 被指定,如果表存在,则查询不返回任何错误。在这种情况下,查询不做任何事情.

默认值

列描述符能够指定一个表达式为一个默认值,方式之一是: DEFAULT 表达式, MATERIALIZED 表达式, ALIAS 表达式. 例如: URLDomain String DEFAULT domain(URL).

如果一个表达式的默认值没有被定义, 对于数值型,默认值将被设置为0, 对于字符串,默认值将被设置为空字符串;对于数组将被设置为空数组;日期将被设置为0000-00-00 或者or 0000-00-00 00:00:00. NULLs 不支持.

如果默认表达式被定义, 列类型是可选的. 如果没有一个显式的类型,默认的表达式类型将被使用.例如: EventDate DEFAULT toDate(EventTime) -  ‘Date’ 类型将被用于‘EventDate’ 列.

如果数据类型和默认表达式被定义.此表达式将被转换到特定的类型,使用类型转换函数. 例如: Hits UInt32 DEFAULT 0 与下面是等价的 Hits UInt32 DEFAULT toUInt32(0).

默认表达式能够被定义作为任意的表达式,表的常量或列.当创建和更改表结构时, 它将检查表达式不包含 loops. 对于 INSERT语句, 它将检查表达式是可解析的 - 参数传递之后,所有的列能够被计算.

DEFAULT 表达式

默认值. 如果INSERT 语句没有指定后续的列,他们将通过计算后续的表达式来填充.

MATERIALIZED 表达式


Materialized 表达式. 此列并不指定在INSERT语句中,因为他们经常被计算.对于一个INSERT 语句,没有列的列表,这些列不被考虑。另外,此列并不被替换,当在时SELECT查询中,使用asterisk. 这保持了使用SELECT *  INSERT 插入表之后的不变性.


查询解析器

ClickHouse目前有两种解析器:一个是SQL解析器(递归下降分析器),一个数据格式解析器(快速流解析器),第二个仅用于INSERT语句。因此,Insert语句使用了上述两种解析器。

INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')

INSERT INTO t VALUES部分使用SQL解析器,DATA部分使用流解析器。

数据可以使用任意格式,当接收到请求后,服务器将不超过’max_query_size’的部分放在RAM中解析(默认为1MB),剩余部分则使用流解析器。ClickHouse和MySQL一样,对于比较大的INSERT语句不存在解析和处理问题。

在INSERT语句中使用使用Values格式时,数据看上去和SELECT语句的表达式解析类似,但区别很大。Values的格式限制多很多。 接下来我们要讲SQL解析器,对于解析的更多信息,可以参考格式章节(https://clickhouse.yandex/reference_en.html#Formats) 。

空白行

语法结构之间可以有任意数量的空白字符,包括空格,缩进,换行,CR,form feed。

注释

可以编写SQL和C风格的注释: 从头到行尾,空格可以省略 C风格:从//,允许多行。

关键字

类似SELECT这种的关键字是大小写不敏感的,但和标准SQL不同,其他关键字(包括列名,方法名等)都是大小写敏感的。关键字使用的单词不是预留的,可以在其他命名中使用,它们仅在合适的上下文中被解析为关键字。

标识符

不用引号的标识符首字符必须是拉丁字符或下划线,后面可以是拉丁字符,下划线或数字,即满足如下的正则表达式:

^[a-zA-Z_][0-9a-zA-Z_]*$


例如这些是合法标识符:x,1, X_y__Z123

引号中的标识符:和MySQL一样,使用id的形式,中间可以使用任意字符,特殊字符(比如`符号本身)可以使用反斜杠转义。转义规则和字符串常量相同。推荐使用没有括号的标识符。

常量

包括数字常量,字符串常量和混合常量

数字常量

数字常量的解析方式顺序:

—首先使用64位有符号数,使用'strtoull'方法

—如果不成功,则使用64位无符号数,'strtoll'方法

—如果不成功,则使用浮点数,'strtod'方法

—最后不成功则返回错误

响应数据则使用结果能够适应的最小类型,例如1使用Uint8,而256使用Uint16,更多信息则请参考上一篇文章 ClickHouse 数据类型介绍

字符串常量

字符串常量必须使用单引号。特殊字符可以使用反斜杠转义。转义字符都带有特殊的含义:

\b, \f, \r, \n, \t, \0, \a, \v, \xHH

其他情况下,对于任意字符c,\c被转成字符c本身,也就是\表示\,'表示'字符。

混合常量

数组中支持混合常量和元组,混合常量示例:[1, 2, 3],元组示例:(1, 'Hello, world!', 2)

事实上他们不是常量,而是使用了数组构造函数或元组构造函数的表达式。更多信息参考操作符Operators

数组至少包含一个元素,元组至少包含两个元素。元组是专门用于匹配IN语句中的SELECT请求结果的。通常情况下不能被存储到数据库中(Memory表除外)。

函数

函数就是一个标识符,后面跟着一串(可能为空)用小括号括起来的参数。和标准的SQL不同,即使是空的参数列表,也必须带有括号,比如now()。

函数分为普通函数和聚合函数。某些聚合函数带有两组参数,比如quantile(0.9)(x)。这种聚合函数被称为参数化函数,第一组参数就是参数化方法中的参数。对于没有带参数的聚合方法语法就和普通方法一样。

运算符

运算符在解析请求时会被转换为对应的函数,同时考虑运算符的优先级和结合性,例如 1+2+3+4被转换为 plus(plus(1, multiply(2, 3)), 4),更多内容请参考操作符

数据类型和表引擎

在CREATE语句中,数据类型和表引擎写法和标识符及函数一致。也就是说他们可能含有参数列表,也可能不含。更多信息参考上一篇文章ClickHouse 数据类型介绍

别名

在SELECT请求中,表达式可以使用AS语法指定别名。表达式在AS左边,别名在AS右边。和标准SQL不同,别名不仅仅可以在表达式顶层指定,也可以用在任意的语句中。例如:

表达式

表达式具体为函数,标识符,常量,运算符等,包在括号中,放在子查询内。表达式可以包含别名。多个表达式使用逗号分隔。函数和运算符也可以使用表达式作为参数。

SQL语句操作

DDL::Create Database

CREATE DATABASE [IF NOT EXISTS] db_name


创建一个名为db_name的数据库,数据库仅仅是一系列表的目录。指定了 IF NOT EXISTS后,如果数据库已经存在,语句不会返回错误。

DDL::Create Table

建表请求有多种格式

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name

(

name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],

name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],

...

) ENGINE = engine

在DB数据库中简历一个name的表,如果没有指定DB则使用当前数据库。结构是括号中指定的格式,引擎使用指定的引擎。表结构是所有列描述的列表。如果引擎支持索引,可以在引擎的参数中指定。

列描述最简单的情况是"name type",例如RegionID UInt32,也可以用表达式指定默认值,下面会有详细说明。

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name AS [db2.]name2 [ENGINE = engine]


这个语句使用另一个表的结构建表,如果没有指定引擎,则会使用db2.name2的引擎。

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name ENGINE = engine AS SELECT ...


上面的语句使用SELECT的结果作为结构建表,同时把SELECT结果的数据插入表中,引擎可以单独指定。

在所有上面的方法中,IF NOT EXISTS可以发挥作用。

默认值

列可以使用下面的语法指定一个默认值:DEFAULT expr, MATERIALIZED expr, ALIAS expr。 例如URLDomain String DEFAULT domain(URL)

如果没有指定默认值,对于数字会默认为0,字符串为空字符串,数组为空数组,日期为0000-00-00,时间为0000-00-00 00:00:00,不支持NULL如果指定了默认值,类型可以省略,这种情况下使用默认值的类型,例如EventDate DEFAULT toDate(EventTime),EventDate的类型会被设置为Date。

如果明确指定了类型,默认值的会被转换为目标类型。 例如Hits UInt32 DEFAULT 0 和 Hits UInt32 DEFAULT toUInt32(0)是完全相同的。默认值的表达式中也可以使用表常量和其他列。建表和修改表结构时,会检查是否包含循环,INSERT语句中,会检查是否表达式中的所有列都已经传入了。

"DEFAULT expr"表示普通的默认值,如果INSERT语句没有指定相应列,会自动使用表达式的值填充

"MATERIALIZED expr"表示“物化列”,这样的列不允许在INSERT中指定,因为它必须计算得来。对于没有指定列的INSERT语句,这些列不会被考虑在内,使用SELECT *时,这些列也不会返回,因为将SELECT * 的结果使用不指定列的INSERT语句插入式很常见的行为,会引发问题。

"ALIAS expr"是指别名,这样的列根本不会被存储起来。不能够使用INSERT插入数据,也不会包括在SELECT * 的返回值中,如果别名是在请求解析阶段展开的,可以使用在SELECT语句中。

当使用ALTER请求来添加新列时,这些列的老数据不会被写入。当读取的老数据没有这些新列的值时,默认情况下会在线计算。然而如果这些表达式使用了没有在SELECT语句中出现的列,这些列会被读取到,当然仅在需要的情况下。

如果向表中添加了新列,但是后来又修改了默认表达式,老数据的值将会更新。当运行后台合并操作时,原来没有值的列会在合并后被写入。不允许为嵌套的数据结构设置默认值。

临时表

如果指定了TEMPORARY,将会创建临时表,临时表的特征:

连接结束或中断时,临时表会消失。

临时表只能使用内存引擎,其它引擎不支持临时表。

临时表不能指定数据库,他们是在数据库外创建的。

如果临时表和普通表的名字相同,请求没有指定DB的名字时,临时表会被使用。

在分布式处理中,一个请求用到的临时表会传给远程的服务器。

通常情况下,临时表不是手动建立的,而是使用外部数据,或使用分布式的IN语句时来自动创建。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容