ClickHouse主键设置

英文地址

https://medium.com/@f1yegor/clickhouse-primary-keys-2cf2a45d7324

译文

问题

  1. How many columns primary key could have? And what is layout of data on storage drive? Is there any theoretical/practical limits?
  2. Could columns with missing data at some rows be part of primary key?

存储格式

列式存储

列式存储图

相对于行存储,在读取的时候可以减少IO开销,但是在写入的时候会相对比较麻烦点。

MergeTree 存储结构

MegreeTree文件结构

Columns.txt记录的每一列的信息。
columns.txt结构

每一列都有一个bin文件和mrk文件,其中bin文件是实际的数据存储
primary.idx存储主键信息,结构与mrk一样,类似于一个稀疏索引。


索引结构

在MergeTree进行查询的时候,最关键的在于定位Block。根据主键进行查询的时候性能会比较好,但是在进行非主键的查询的时候,由于是按照列存储的关系,会进行一次全扫描。

源码分析

Columns

含义:表示内存中的列,使用IColumn接口,这个接口提供用于实现各种关系操作符的辅助方法,但是几乎所有的操作都是不可变的,不会改变原始列,但是可以创建一个新的修改列。
不同的IColumn实现福别不同的内存布局。内存布局退出时一个连续的数组,但是也有特殊的,比如String,Array等就是使用两个向量来组成的。

Field

Field是一个enum

        enum Which
        {
            Null    = 0,
            UInt64  = 1,
            Int64   = 2,
            Float64 = 3,
            UInt128 = 4,
            Int128  = 5,

            /// Non-POD types.

            String  = 16,
            Array   = 17,
            Tuple   = 18,
            Decimal32  = 19,
            Decimal64  = 20,
            Decimal128 = 21,
            AggregateFunctionState = 22,
        };

IDataType

负责序列化与反序列化,读写二进制或者文本形式的列或者单个值构成的块。IDataType直接与表中的数据类型相对应
IDataTypeIColumn之间的关联并不大,不同类型的IDatatType可以使用相同的IColumn来表示。
IDataType仅仅存储源数据

Block

Block是表示内存中表的子集(Chunk)的子集,由{IColumn,IDataType,列名}三元组构成。
在查询执行期间,数据是按照Block进行处理的,

Block Streams

Block Streams用于处理数据,Block Streams从某个地方读取数据,并进行数据转换,或者将数据写入到某个地方。
IBlockInputStream具有read方法,而IBlockOutputStream具有write方法。

IO

使用ReadBufferWriteBuffer两个抽象类,来替代iostream。这两个类实现用于处理文件、文件描述符、socket,也可以用于进行压缩

Table

table由IStorage接口表示,这个接口实现对应不同的表引擎,实现也不一样。比如StorageMergeTree,StorageMemory
IStorage最主要的方法就是write read alter rename drop等方法

你可能感兴趣的:(ClickHouse主键设置)