python3 array为什么不能放不同类型的数据_来自俄罗斯的凶猛彪悍的分析数据库ClickHouse...
點擊上方藍色字體,選擇“設為星標”
回復”資源“獲取更多資源大數據技術與架構點擊右側關注,大數據開發領域最強公眾號!暴走大數據點擊右側關注,暴走大數據!ClickHouse相關文章推薦:
戰斗民族開源 | ClickHouse萬億數據雙中心的設計與實踐你需要懂一點ClickHouse的基礎知識趣頭條實戰 | 基于Flink+ClickHouse構建實時數據平臺Prometheus+Clickhouse實現業務告警基于ClickHouse的用戶行為分析實踐ClickHouse 是一款由俄羅斯Yandex公司開源的OLAP數據庫,擁有者卓越的性能表現,在官方公布的基準測試中,ClickHouse的平均響應速度是Vertica的2.63倍、InfiniDB的17倍、MonetDB的27倍、Hive的126倍、MySQL的429倍以及Greenplum的10倍。
自2016年開源以來,ClickHouse一直保持著飛速的發展,是目前業界公認的OLAP數據庫黑馬,已在頭條、阿里、騰訊、新浪、青云等眾多公司得以應用。
作為一款分析型數據庫,ClickHouse提供了許多數據類型,它們可以劃分為基礎類型、復合類型和特殊類型。其中基礎類型使ClickHouse具備了描述數據的基本能力,而另外兩種類型則使ClickHouse的數據表達能力更加豐富立體。
本文主要來談ClickHouse的復合類型,ClickHouse提供了數組、元組、枚舉和嵌套四類復合類型。這些類型通常是其他數據庫原生不具備的特性。擁有了復合類型之后,ClickHouse的數據模型表達能力更強了。
Array
數組有兩種定義形式,常規方式array(T):
SELECT array(1, 2) as a , toTypeName(a)┌─a───┬─toTypeName(array(1, 2))─┐
│ [1,2] │ Array(UInt8) ?????????????│
└─────┴────────────────┘
或者簡寫方式[T]:
SELECT [1, 2]通過上述的例子可以發現,在查詢時并不需要主動聲明數組的元素類型。因為ClickHouse的數組擁有類型推斷的能力,推斷依據:以最小存儲代價為原則,即使用最小可表達的數據類型。例如在上面的例子中,array(1, 2)會通過自動推斷將UInt8作為數組類型。但是數組元素中如果存在Null值,則元素類型將變為Nullable,例如:
?SELECT [1, 2, null] as a , toTypeName(a)
┌─a──────┬─toTypeName([1, 2, NULL])─┐
│ [1,2,NULL] │ Array(Nullable(UInt8)) ???│
└────────┴─────────────────┘
細心的讀者可能已經發現,在同一個數組內可以包含多種數據類型,例如數組[1, 2.0]是可行的。但各類型之間必須兼容,例如數組[1, '2']則會報錯。
在定義表字段時,數組需要指定明確的元素類型,例如:
CREATE TABLE Array_TEST (????c1 Array(String)
) engine = Memory
2. Tuple
元組類型由1~n個元素組成,每個元素之間允許設置不同的數據類型,且彼此之間不要求兼容。元組同樣支持類型推斷,其推斷依據仍然以最小存儲代價為原則。與數組類似,元組也可以使用兩種方式定義,常規方式tuple(T):
SELECT tuple(1,'a',now()) AS x, toTypeName(x)┌─x─────────────────┬─toTypeName(tuple(1, 'a', now()))─┐
│ (1,'a','2019-08-28 21:36:32') │ Tuple(UInt8, String, DateTime) ???│
└───────────────────┴─────────────────────┘
或者簡寫方式(T):
SELECT (1,2.0,null) AS x, toTypeName(x)┌─x──────┬─toTypeName(tuple(1, 2., NULL))───────┐
│ (1,2,NULL) │ Tuple(UInt8, Float64, Nullable(Nothing)) │
└───────┴──────────────────────────┘
在定義表字段時,元組也需要指定明確的元素類型:
CREATE TABLE Tuple_TEST (????c1 Tuple(String,Int8)
) ENGINE = Memory;
元素類型和泛型的作用類似,可以進一步保障數據質量。在數據寫入的過程中會進行類型檢查。例如,寫入INSERT INTO Tuple_TEST VALUES( ('abc' , 123) )是可行的,而寫入INSERT INTO Tuple_TEST VALUES( ('abc' , 'efg') )則會報錯。
3. Enum
ClickHouse支持枚舉類型,這是一種在定義常量時經常會使用的數據類型。ClickHouse提供了Enum8和Enum16兩種枚舉類型,它們除了取值范圍不同之外,別無二致。枚舉固定使用(String:Int) Key/Value鍵值對的形式定義數據,所以Enum8和Enum16分別會對應(String:Int8)和(String:Int16),例如:
CREATE TABLE Enum_TEST (????c1 Enum8('ready' = 1, 'start' = 2, 'success' = 3, 'error' = 4)
) ENGINE = Memory;
在定義枚舉集合的時候,有幾點需要注意。首先,Key和Value是不允許重復的,要保證唯一性。其次,Key和Value的值都不能為Null,但Key允許是空字符串。在寫入枚舉數據的時候,只會用到Key字符串部分,例如:
INSERT INTO Enum_TEST VALUES('ready');INSERT INTO Enum_TEST VALUES('start');
數據在寫入的過程中,會對照枚舉集合項的內容逐一檢查。如果Key字符串不在集合范圍內則會拋出異常,比如執行下面的語句就會出錯:
INSERT INTO Enum_TEST VALUES('stop');可能有人會覺得,完全可以使用String代替枚舉,為什么還需要專門的枚舉類型呢?這是出于性能的考慮。因為雖然枚舉定義中的Key屬于String類型,但是在后續對枚舉的所有操作中(包括排序、分組、去重、過濾等),會使用Int類型的Value值。
4. Nested
嵌套類型,顧名思義是一種嵌套表結構。一張數據表,可以定義任意多個嵌套類型字段,但每個字段的嵌套層級只支持一級,即嵌套表內不能繼續使用嵌套類型。對于簡單場景的層級關系或關聯關系,使用嵌套類型也是一種不錯的選擇。例如,下面的nested_test是一張模擬的員工表,它的所屬部門字段就使用了嵌套類型:
CREATE TABLE nested_test (????name String,
????age ?UInt8 ,
????dept Nested(
????????id UInt8,
????????name String
????)
) ENGINE = Memory;
ClickHouse的嵌套類型和傳統的嵌套類型不相同,導致在初次接觸它的時候會讓人十分困惑。以上面這張表為例,如果按照它的字面意思來理解,會很容易理解成nested_test與dept 是一對一的包含關系,其實這是錯誤的。不信可以執行下面的語句,看看會是什么結果:
INSERT INTO nested_test VALUES ('nauu',18, 10000, '研發部');Exception on client:
Code: 53. DB::Exception: Type mismatch in IN or VALUES section. Expected: Array(UInt8). Got: UInt64
注意上面的異常信息,它提示期望寫入的是一個Array數組類型。
現在大家應該明白了,嵌套類型本質是一種多維數組的結構。嵌套表中的每個字段都是一個數組,并且行與行之間數組的長度無須對齊。所以需要把剛才的INSERT語句調整成下面的形式:
INSERT INTO nested_test VALUES ('bruce' , 30 , [10000,10001,10002], ['研發部','技術支持中心','測試部']);--行與行之間,數組長度無須對齊
INSERT INTO nested_test VALUES ('bruce' , 30 , [10000,10001], ['研發部','技術支持中心']);
需要注意的是,在同一行數據內每個數組字段的長度必須相等。例如,在下面的示例中,由于行內數組字段的長度沒有對齊,所以會拋出異常:
INSERT INTO nested_test VALUES ('bruce' , 30 , [10000,10001], ['研發部','技術支持中心','測試部']);
DB::Exception: Elements 'dept.id' and 'dept.name' of Nested data structure 'dept' (Array columns) have different array sizes..
在訪問嵌套類型的數據時需要使用點符號,例如:
SELECT name, dept.id, dept.name FROM nested_test
┌─name─┬─dept.id──┬─dept.name─────────────┐
│ bruce │ [16,17,18] │ ['研發部','技術支持中心','測試部'] │
└────┴───────┴────────────────────┘
關于作者:
朱凱,ClickHouse貢獻者之一,ClickHouse布道者,資深架構師,十多年IT從業經驗,對大數據領域主流技術與解決方案有深入研究,擅長分布式系統的架構設計與整合。曾主導過多款大數據平臺級產品的規劃、設計與研發工作,一線實戰經驗豐富。現就職于遠光軟件股份有限公司,任大數據事業部平臺開發部總經理。著有《企業級大數據平臺構建:架構與實現》?《ClickHouse原理解析與應用實踐》等書。
國內首本全方位講解ClickHouse的技術書,這是一本可幫助讀者深度理解并全面掌握ClickHouse運行原理并進行實踐開發的工具書,涵蓋了ClickHouse的時代背景、發展歷程、核心概念、基礎功能、運行原理、實踐指導等多個維度的內容。一本書幫你駕馭ClickHouse。
版權聲明:
本文為大數據技術與架構整理,原作者獨家授權。未經原作者允許轉載追究侵權責任。編輯|冷眼丶微信公眾號|import_bigdata歡迎點贊+收藏+轉發朋友圈素質三連文章不錯?點個【在看】吧!??
總結
以上是生活随笔為你收集整理的python3 array为什么不能放不同类型的数据_来自俄罗斯的凶猛彪悍的分析数据库ClickHouse...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wifi6路由器怎么设置如何使用wifi
- 下一篇: python package和目录_Py