1. 程式人生 > >NoSQL 中一匹黑馬 Clickhouse

NoSQL 中一匹黑馬 Clickhouse

clickhouse

Clickhouse 基本介紹

Clickhouse 是屬於OLAP(聯機分析處理)開源的列儲存資料管理系統。

特點:

 可以線性擴充套件
 簡單,方便 
 高度可靠的 
 容錯(支援多主機非同步複製,可以跨多個數據中心部署,單個節點或整個資料中心的停機時間不會影響系統的讀寫可用性)

功能及應用介紹

功能 應用
深度列儲存 Web app 分析
向量化查詢執行(vectorized query execution) 廣告網路和實時出價
資料壓縮 電信
並行和分散式查詢 資訊保安
實時資料注入 監測和遙測

缺點:

1.  不支援事務
2.  沒有update 和delete 
3.  支援的作業系統有限(只支援ubuntu)

Clickhouse 安裝部署

1.  環境準備
三臺4c8G,分別為10.39.1.36,10.39.1.37,10.39.1.40 ubuntu 14.04.x86x64 
2.  安裝
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4 
sudo mkdir -p /etc/apt/sources.list.d
echo "deb http://repo.yandex.ru/clickhouse/trusty stable main" |
sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
sudo apt-get install clickhouse-server-common clickhouse-client  
sudo service clickhouse-server start  單機版本就可以直接啟動使用了。

叢集配置

ClickHouse deployment to cluster
ClickHouse cluster is a homogenous cluster. Steps to set up

1. Install ClickHouse server on all machines of the cluster
2. Set up cluster configs in configuration file
3. Create local tables on each instance
4. Create a Distributed table
  clickhouse-client 客戶端軟體,叢集的安裝的可以選擇,
  clickhouse-server-common 服務端軟體,必須安裝
  clickhouse-compressor    資料壓縮軟體,叢集的話必須安裝

配置檔案

/etc/clickhouse-server/
 config.xml 配置檔案
 users.xml 使用者許可權配置檔案
 分散式查詢叢集或者複製需要單獨建立一個新的檔案
 touch  /etc/metrika.xml  
 (可以參考) 
 分散式叢集配置
 vim /etc/metrika.xml
  <yandex>
   <clickhouse_remote_servers>
<enncloud>
    <shard>
        <weight>1</weight>
        <internal_replication>false</internal_replication>
        <replica>
            <host>clickhouse01</host>
            <port>9000</port>
        </replica>
        <replica>
            <host>clickhouse02</host>
            <port>9000</port>
        </replica>
        <replica>
            <host>clickhouse03</host>
            <port>9000</port>
        </replica>
    </shard>
    <shard>
        <weight>3</weight>
        <internal_replication>false</internal_replication>
        <replica>
            <host>clickhouse01</host>
            <port>9000</port>
        </replica>
        <replica>
            <host>clickhouse02</host>
            <port>9000</port>
        </replica>
        <replica>
            <host>clickhouse03</host>
            <port>9000</port>
        </replica>
    </shard>
</enncloud>
</clickhouse_remote_servers>
<networks>
  <ip>::/0</ip>
 </networks>


 <clickhouse_compression>
   <min_part_size>10000000000</min_part_size>
   <min_part_size_ratio>0.01</min_part_size_ratio>
   <method>lz4</method>
</clickhouse_compression>

</yandex>

關於<internal_replication>false</internal_replication> false 和true 的設定的區別
如果設定為true,則寫操作將選擇第一個健康副本並將資料寫入它。如果分散式表”檢視”複製表,則使用此選項,換句話說,如果將寫入資料的將複製它們本身。 

 如果設定為false(預設值) 則將資料寫入所有副本。這意味著分散式表複製資料本身,這比使用複製更槽糕,因為沒有檢查副本的一致性,並且隨著時間的推移它們會包含稍微不同的資料。

關閉一臺機器,其他機器還是分散式查詢。

測試: 
 在所有的節點上建立test 表
 CREATE TABLE test (FlightDate Date,Year UInt16) ENGINE = MergeTree(FlightDate,   (Year, FlightDate), 8192);

 建立分散式表並且關聯本地表
 CREATE TABLE test_all AS test ENGINE = Distributed(enncloud, default, test, rand())

往分散式表插入資料,然後在其他節點查詢
insert into test_all (FlightDate,Year)values('2013-10-12',2013);

可以抓包查詢是否是分散式查詢  tcpdump -i any -s 0 -l -w - dst port 9000  
4.  複製的配置
   <yandex>
   <clickhouse_remote_servers>
  <perftest_1shards_3replicas>
    <shard>
        <replica>
            <host>clickhouse01</host>
            <port>9000</port>
         </replica>
         <replica>
            <host>clickhouse02</host>
            <port>9000</port>
         </replica>
         <replica>
            <host>clickhouse03</host>
            <port>9000</port>
         </replica>
    </shard>
   </perftest_1shards_3replicas>
 </clickhouse_remote_servers>

<macros>
   <shard>02</shard>
   <replica>10.39.1.36</replica>
</macros>

<networks>
   <ip>::/0</ip>
</networks>

<clickhouse_compression>
   <min_part_size>10000000000</min_part_size>
   <min_part_size_ratio>0.01</min_part_size_ratio>
   <method>lz4</method>
</clickhouse_compression>

<zookeeper-servers>
     <node index="1">
        <host>10.39.1.36</host>
        <port>2181</port>
    </node>
</zookeeper-servers>

</yandex>

配置詳解
 shard 碎片識別符號,

<replica>10.39.1.36</replica> 10.39.1.36 是識別符號,可以看做是副本識別符號,是獨一無二的,每個節點的識別符號為本機的ip,這樣的話,三個節點的話,每個配置的副本識別符號將為它自身的ip地址。 

建立複製表
CREATE TABLE ontime_replica (FlightDate Date,Year UInt16) ENGINE = ReplicatedMergeTree('/clickhouse_perftest/tables/ontime_replica','{replica}',FlightDate,(Year, FlightDate),8192);

插入資料,在其他節點解析查詢  

介面

啟用遠端介面訪問編輯 config.xml 
 <listen_host>::</listen_host> 

1.  HTTP  interface  
 預設情況下,clcikhouse 伺服器在埠8123 監聽HTTP。 
 URL 長度限制為16KB 

 如果成功,則返回響應碼200 
 如果失敗,則返回響應碼500 

 使用http interface 介面建立表插入資料並刪除表
[email protected]:~# echo 'CREATE TABLE abc (a UInt8) ENGINE = Memory' | POST 'http://10.39.1.36:8123/'
[email protected]:~# echo 'INSERT INTO abc VALUES (1),(2),(3)' | POST 'http://10.39.1.36:8123/'
[email protected]:~# echo '(4),(5),(6)' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc VALUES'
 [email protected]:~# echo '(7),(8),(9)' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc FORMAT Values'
 格式轉換TabSeparated
 [email protected]:~# echo -ne '10\n11\n12\n' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc FORMAT TabSeparated'  
 查詢的結果輸出如下 
[email protected]:~# GET 'http://10.39.1.36:8123/?query=SELECT a FROM abc'
 1
 2
 3
 10
 11
 12
 7
 8
 9
 4
 5
 6


刪除表
echo 'DROP TABLE abc' | POST 'http://10.39.1.36:8123/'


2.  JDBC driver 
   https://github.com/yandex/clickhouse-jdbc 

3.  Third-party client libraries 

4.  Command-line client

語法

 系統中有兩種型別的解析器:一個完整的SQL 解析器(一個遞迴下降解析器)和一個數據格式分析器(一個快速流分析器)。在所有情況下,除了插入查詢,只有完整的SQL解析器使用。 

  建立資料庫
 CREATE DATABASE [IF NOT EXISTS] db_name

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


  建立檢視
  CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]name [ENGINE = engine] [POPULATE] AS SELECT ...

表引擎

    建議使用來自MergeTree家族的儲存引擎(LSM樹)
    表的儲存引擎如下:
1.  TinyLog
  最簡單的表引擎,它將資料儲存在磁碟上,每列儲存在單獨的壓縮檔案中。寫入時,資料會追加到檔案的末尾。
  併發資料訪問不受任何限制: 
  如果您正在從表中讀取並以相同的查詢寫入,讀操作將會出現錯誤。
  如果您同時在多個查詢中寫入表,資料將被破壞。
  使用該表的典型方式是一次寫入:首先只是寫入一次資料,然後根據需要讀取資料,查詢在單個流中執行,該引擎是用於相對較小的表,(最多可推薦1,000,000行)
  適合需要小表,不支援索引。 


 2. Log 
Log 與Tinylog不同之處在於,一個小檔案的“標記”駐留在列檔案中。這些標記寫在每個資料塊上,幷包含偏移量,在哪裡開始讀取檔案以便跳過指定的行數。這使得可以在多個執行緒中讀取表資料。對於併發資料訪問,讀取操作可以同時執行。 
Log 引擎不支援索引。類似的,如果寫入表失敗,則表被損壞,從其讀取返回錯誤,log引擎適用於臨時資料,一次寫入表以及測試或者演示目的。 
3.  Memory 
 記憶體引擎將資料以未壓縮格式儲存在RAM 中。資料以讀取時接收的格式完全相同的形式儲存。併發資料訪問同步,鎖定很短:讀寫操作不會阻塞。
不支援索引,閱讀並行化。 
4.  Merge 
 合併引擎不會自己儲存資料,而是允許同時從任意數量的其他表讀取資料。 
 讀資料自動並行化。不支援寫入表。讀取時,使用例項讀取的表的索引(如果存在)。合併引擎接受引數:資料庫名稱和表的正則表示式。例:
 Merge(hits, '^WatchLog') 
 資料庫將從“hits”資料庫中的表讀取,名稱與正則表示‘^watchLlog’ 匹配。
 而不是資料庫名稱,您可以使用返回字串的常量表達式。例如,currentDatabaase(). 

 正則表示式是re2(類似於PCRE),區分大小寫。
 選擇要讀取的表時,即使與正則表示式匹配,也不會選擇合併表本身。為了避免迴圈。 



虛擬列
虛擬列是由表引擎提供的列,而不考慮定義。(create table 中未指定,但他們對於select 是可以訪問的)

虛擬列與普通列的不同之處在於:
它們沒有在表定義中指定,
無法使用insert 將資料新增到它們。
當使用insert 而不指定列表時,虛擬列將被忽略。 

合併表包含String型別的虛擬列_table。 (如果表已經有一個'_table'列,虛擬列名為'_table1',如果它已經有'_table1',它被命名為'_table2',依此類推)。它包含表的名稱從中讀取資料。

 如果WHERE或PREWHERE子句包含不依賴於其他表列(作為連線元素之一或整個表示式)的“_table”列的條件,則將這些條件用作索引。條件是對錶名的資料集進行讀取資料,讀操作將僅從觸發條件的那些表執行。
5.  分散式引擎
分散式引擎不儲存資料本身,但允許在多個伺服器上進行分散式查詢處理。讀數自動並行化。在讀取期間,使用遠端伺服器的表索引。 
分散式引擎接受引數:伺服器器配置檔案中的叢集名稱,遠端資料庫的名稱,遠端表的名稱
例子:
   Distributed(logs, default, hits[, sharding_key])
  資料將從“日誌”叢集中的所有伺服器從叢集中每個伺服器上的”default。hits” 表中讀取。資料不僅被讀取,而且在遠端伺服器上進行部分處理(在可能的範圍內)
  例如,對於使用group by 的查詢,資料將在遠端伺服器聚合,聚合函式的中間狀態將傳送到請求者伺服器,那麼資料將進一步彙總

 叢集將資料寫入的兩種方法:
   1.   首先,你可以定義哪些伺服器寫入哪些資料,並直接在每個分片上執行寫入。(在分片表”檢視“的表中執行insert)這是最優的解決方案。因為資料可以完全獨立寫入不同的分片
   2.   其次,你可以在分散式表中執行insert,在這種情況下,表將通過伺服器本身分發插入的資料。 
 6. MergeTree 
     Mergetree 是clickhouse 最近的表引擎,它支援主鍵索引和日期,並提供了可能性,實時更新資料。
   Example without sampling support:
   MergeTree(EventDate, (CounterID, EventDate), 8192)

   Example with sampling support:
   MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)
   一個mergetree 型表必須有一個單獨的列包含日期,在這個例子中,它是eventdate 的日期列的型別必須是日期。 
    7.  CollapsingMergeTree 
   該引擎與MergeTree 不同之處在於它允許自動刪除,或者合併時“摺疊”某些行對
   例子:
   CollapsingMergeTree(EventDate, (CounterID, EventDate, intHash32(UniqID), VisitID), 8192, Sign) 

  在這裡sign 是一個列,old 值為-1,new 值為1 
  合併時,每組連續相同的主鍵值(用於排序資料的列)減少為不超過一行,列值為(sign_column=-1), 不超過一行,列值“sign_column=1”.(更改日誌中的條目自己摺疊)

  8.    SummingMergeTree 
       該儲存引擎與MergeTree 的不同之處在於它在合併時總計資料
       SummingMergeTree(EventDate, (OrderID, EventDate, BannerID, ...), 8192)

  9.    AggregatingMergeTree 
  它與MergreTree 不同之處在於,合併將儲存在表中的聚合函式的狀態組合為具有相同主鍵值的行。 
 例子:
 CREATE MATERIALIZED VIEW test.basic
 ENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192)
 AS SELECT
CounterID,
StartDate,
sumState(Sign)    AS Visits,
uniqState(UserID) AS Users
FROM test.visits
GROUP BY CounterID, StartDate;


 INSERT INTO test.visits ...

 SELECT
    StartDate,
    sumMerge(Visits) AS Visits,
uniqMerge(Users) AS Users
 FROM test.basic
 GROUP BY StartDate
 ORDER BY StartDate;

  10.   ReplacingMergeTree 
   它與MergeTree 不同之處在於,它可以在合併時通過主鍵重複資料刪除資料
   例子:
   ReplacingMergeTree(EventDate, (OrderID, EventDate, BannerID, ...), 8192, ver)

  11.   NULL 
    當寫入null 表時,資料將被忽略,從null 表中讀取,響應為空
    但是,你可以在null表上建立例項檢視,因為寫入表的資料將在檢視中顯示

 12.    View 
   用於實現檢視,它不儲存資料,而只儲存指定的select 查詢。從表讀取時,它會執行此查詢(並從表中刪除所有不必要的列)

   a)   MaterializedView 
     用於實現物化檢視。對於儲存資料,它使用在建立檢視時指定的不同引擎。它只是使用這個引擎。

13. Set 
   始終在RAM的資料集。你可以使用insert 在表中插入資料。新元素將被新增到資料集中,而重複的元素將被忽略。
   資料總是位於RAM中,對於insert,插入的資料塊也會寫入到磁碟上的表目錄。當啟動伺服器時,這些資料被載入到RAM中。重啟後,資料保持原樣。

 對於伺服器重新啟動,磁碟上的資料塊可能會丟失或損壞。在後一種情況,你可能需要手動刪除帶有損壞資料的檔案。 

14. Join 
  一個總是位於RAM 中的JOIN 資料結構 
  Join(ANY|ALL, LEFT|INNER, k1[, k2, ...]) 

15. Buffer 
  快取資料寫入RAM,定期將其重新整理到另一個表。在讀操作期間,資料從緩衝器和另一個表同時讀取。 
  例子: 
  CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 16, 10, 100, 10000, 1000000, 10000000, 100000000)
  最大1.6GB 的記憶體消耗 

16. Data replication 
     ReplicatedMergeTree
     ReplicatedCollapsingMergeTree
     ReplicatedAggregatingMergeTree
     ReplicatedSummingMergeTree

     MergeTree 系列中的表僅支援複製。複製在單個表的級別上工作,而不是整個伺服器。伺服器可以同時儲存複製表和非複製表。 

系統表

 system.databases
 system.tables

 system.processes

 system.clusters
 cluster String      - Cluster name.
 shard_num UInt32    - Number of a shard in the cluster, starting from 1.
 shard_weight UInt32 - Relative weight of a shard when writing data.
 replica_num UInt32  - Number of a replica in the shard, starting from 1.
 host_name String    - Host name as specified in the config.
 host_address String - Host's IP address obtained from DNS.
 port UInt16         - The port used to access the server.
 user String         - The username to use for connecting to the server.

 system.merges
 system.settings

 system.zookeeper

表函式

   1.   merge 
   2.   remote 

資料格式

  TabSeparated
   TabSeparatedWithNames
   TabSeparatedWithNamesAndTypes
  TabSeparatedRaw
  BlockTabSeparated
  CSV
  CSVWithNames
  RowBinary
  Pretty
  PrettyCompact
  PrettyCompactMonoBlock
  PrettySpace
  PrettyNoEscapes
  PrettyCompactNoEscapes
  PrettySpaceNoEscapes
  Vertical
  Values
  JSON
  JSONCompact
  JSONEachRow
  TSKV
  XML
  Null

資料型別

1.  整數
  UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
2.  浮點數
  Float32, Float64 
3.  字串
    任意長度的字串,長度不限於此,該值可以包含任意位元組集,包括空位元組。字串型別替換其他DBMS中型別varchar,blob,clob 和其他型別。 

  Cliclhouse 沒有編碼的概念,建議使用UTF-8編碼, 
4.  FixedString(N) 
   N位元組固定長度字串,N必須是嚴格正數的自然數。 
5.  Date
   日期儲存沒有時區,最小值輸出為0000-00-00 
6.  DateTime 
  允許將值與日期型別儲存在相同的範圍,最小輸出為 0000-00-00 00:00:00 
7.  列舉 
  Enum8 or Enum16
8.  Array(T) 
  不建議使用多維陣列,不被很好的支援
9.  元組
   Tuple(T1, T2, ...)
10. 巢狀的資料結構
    Nested(Name1 Type1, Name2 Type2, ...) 
11. 聚合函式
   AggregateFunction(name, types_of_arguments...) 
12. 特殊的資料型別
  特殊的資料型別值無法儲存到結果中的表輸出,而是用作執行查詢的中間結果。 
13. set 
14. Boolean values 
     使用uint8 型別限制的值0 和值 1 

分散式資料查詢

 10.1 分散式叢集測試
   查詢叢集狀態
   select * from system.clusters 


 使用官網的測試資料
 CREATE TABLE a_test 
 (
Year UInt16, 
Quarter UInt8, 
Month UInt8, 
DayofMonth UInt8, 
DayOfWeek UInt8, 
FlightDate Date, 
UniqueCarrier FixedString(7), 
AirlineID Int32, 
Carrier FixedString(2), 
TailNum String, 
FlightNum String, 
OriginAirportID Int32, 
OriginAirportSeqID Int32, 
OriginCityMarketID Int32, 
Origin FixedString(5), 
OriginCityName String, 
OriginState FixedString(2), 
OriginStateFips String, 
OriginStateName String, 
OriginWac Int32, 
DestAirportID Int32, 
DestAirportSeqID Int32, 
DestCityMarketID Int32, 
Dest FixedString(5), 
DestCityName String, 
DestState FixedString(2), 
DestStateFips String, 
DestStateName String, 
DestWac Int32, 
CRSDepTime Int32, 
DepTime Int32, 
DepDelay Int32, 
DepDelayMinutes Int32, 
DepDel15 Int32, 
DepartureDelayGroups String, 
DepTimeBlk String, 
TaxiOut Int32, 
WheelsOff Int32, 
WheelsOn Int32, 
TaxiIn Int32, 
CRSArrTime Int32, 
ArrTime Int32, 
ArrDelay Int32, 
ArrDelayMinutes Int32, 
ArrDel15 Int32, 
ArrivalDelayGroups Int32, 
ArrTimeBlk String, 
Cancelled UInt8, 
CancellationCode FixedString(1), 
Diverted UInt8, 
CRSElapsedTime Int32, 
ActualElapsedTime Int32, 
AirTime Int32, 
Flights Int32, 
Distance Int32, 
DistanceGroup UInt8, 
CarrierDelay Int32, 
WeatherDelay Int32, 
NASDelay Int32, 
SecurityDelay Int32, 
LateAircraftDelay Int32, 
FirstDepTime String, 
TotalAddGTime String, 
LongestAddGTime String, 
DivAirportLandings String, 
DivReachedDest String, 
DivActualElapsedTime String, 
DivArrDelay String, 
DivDistance String, 
Div1Airport String, 
Div1AirportID Int32, 
Div1AirportSeqID Int32, 
Div1WheelsOn String, 
Div1TotalGTime String, 
Div1LongestGTime String, 
Div1WheelsOff String, 
Div1TailNum String, 
Div2Airport String, 
Div2AirportID Int32, 
Div2AirportSeqID Int32, 
Div2WheelsOn String, 
Div2TotalGTime String, 
Div2LongestGTime String, 
Div2WheelsOff String, 
Div2TailNum String, 
Div3Airport String, 
Div3AirportID Int32, 
Div3AirportSeqID Int32, 
Div3WheelsOn String, 
Div3TotalGTime String, 
Div3LongestGTime String, 
Div3WheelsOff String, 
Div3TailNum String, 
Div4Airport String, 
Div4AirportID Int32, 
Div4AirportSeqID Int32, 
Div4WheelsOn String, 
Div4TotalGTime String, 
Div4LongestGTime String, 
Div4WheelsOff String, 
Div4TailNum String, 
Div5Airport String, 
Div5AirportID Int32, 
Div5AirportSeqID Int32, 
Div5WheelsOn String, 
Div5TotalGTime String, 
Div5LongestGTime String, 
Div5WheelsOff String, 
Div5TailNum String
 ) ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192)

2. 建立分散式關聯表
   CREATE TABLE a_all AS  a_test 
 ENGINE = Distributed(perftest_1shards_3replicas, default, a_test, rand());  

3.建立表和分散式關聯表都需要在每個節點執行。 

4. 插入資料到分散式表,在其他節點查詢
    下載的資料匯入到a_all 表中
   for i in *.zip; do echo $i; unzip -cq $i '*.csv' | sed 's/\.00//g' | clickhouse-client --host=clickhouse01 --query="INSERT INTO a_all   FORMAT CSVWithNames"; done

 在其他節點上查詢並且監測是不是分散式    
抓包
      tcpdump -i any -s 0 -l -w - dst port 9000  
1. 查詢總的資料 
         select count(*) from a_all;


2. 查詢1987-1991年每天的航班統計
 SELECT DayOfWeek, count(*) AS c FROM a_all WHERE Year >= 1987 AND Year <= 1991 GROUP BY DayOfWeek ORDER BY c DESC;

3. 查詢延誤在一個小時以上出發的城市
 SELECT OriginCityName, count() AS c, avg(DepDelay >  60) AS delays FROM a_all GROUP BY OriginCityName HAVING c >  100000 ORDER BY delays DESC LIMIT 20

4. 查詢1991 年最後歡迎的目的地
  SELECT     OriginCityName,     DestCityName,     count(*) AS flights,     bar(flights, 0, 20000, 40) FROM ontime_all WHERE Year = 1991 GROUP BY OriginCityName, DestCityName ORDER BY flights DESC LIMIT 20

SELECT     OriginCityName < DestCityName ? OriginCityName : DestCityName AS a,     OriginCityName < DestCityName ? DestCityName : OriginCityName AS b,     count(*) AS flights,     bar(flights, 0, 40000, 40) FROM a_all WHERE Year =  1991 GROUP BY a, b ORDER BY flights DESC LIMIT 20


5. 最受歡迎的出發城市
    SELECT OriginCityName, count(*) AS flights FROM a_all GROUP BY OriginCityName ORDER BY flights DESC LIMIT 20  

6. 建立array   join 
      允許使用陣列或巢狀資料結構執行join。

   CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory

   INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []) 

  SELECT * FROM arrays_test 

  SELECT s, arr FROM arrays_test ARRAY JOIN arr 

  SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a 

  SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped


 陣列聯接也與巢狀的資料結構一起工作,例子
  CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory 

  INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], [])
SELECT * FROM nested_test

 SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest

 SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y

 SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x

 使用arrayEnumerate 函式

  SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num

叢集複製

建立複製表:
     CREATE TABLE ontime_replica (FlightDate Date,Year UInt16) ENGINE = ReplicatedMergeTree('/clickhouse_perftest/tables/ontime_replica','{replica}',FlightDate,(Year, FlightDate),8192);  

 insert into ontime_replica (FlightDate,Year)values('2017-04-18',2017); 
在其他節點查詢
   select * from  ontime_replica  

 十一、 建立使用者
    直接編輯user.xml 檔案
    在<user> 這個範圍中新增  </user>
    如果使用明文密碼,直接寫入到下面的明文密碼處 
    <password> 明文密碼 </password>.

   如果使用SHA256加密的密碼,請使用如下配置 
   Example:    <password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>

  使用下面的命令生成密碼: 
 PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
 第一行地密碼是,第二行是加密過的密碼 SHA256.

 例如如下配置
 <dba>   <password_sha256_hex>ef375dec86573b84efd45187966705c4a7b00d74c6eb8e4b8372e4ea9ebbe796</password_sha256_hex>
           <networks incl="networks" />
           <profile>default</profile>
           <quota>default</quota>
           <allow_databases>
              <database>default</database>
           </allow_databases>
 </dba>

許可權配置: 
readonly 只讀許可權
default   有些許可權