国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Doris-簡介、架構(gòu)、編譯、安裝和數(shù)據(jù)表的基本使用

這篇具有很好參考價值的文章主要介紹了Doris-簡介、架構(gòu)、編譯、安裝和數(shù)據(jù)表的基本使用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄

  • 1、Doris簡介
  • 2、Doris網(wǎng)址
  • 3、Doris架構(gòu)
  • 3、編譯和安裝
    • 3.1、軟硬件需求
    • 3.2、編譯
      • 3.2.1、安裝Docker環(huán)境
      • 3.2.2、使用Docker 開發(fā)鏡像編譯
    • 3.3、集群部署
      • 3.3.1、創(chuàng)建目錄并拷貝編譯后的文件
      • 3.3.2、部署 FE 節(jié)點(diǎn)
      • 3.3.3、配置 BE 節(jié)點(diǎn)
      • 3.3.4、在 FE 中添加所有 BE 節(jié)點(diǎn)
      • 3.3.5、啟動 BE
      • 3.3.6、部署 FS_Broker(可選)
    • 3.4、擴(kuò)容和縮容
      • 3.4.1 FE 擴(kuò)容和縮容
      • 3.4.2 BE 擴(kuò)容和縮容
      • 3.4.3 Broker 擴(kuò)容縮容
  • 4、數(shù)據(jù)表的基本使用
    • 4.1、創(chuàng)建用戶和數(shù)據(jù)庫
    • 4.2、Doris中數(shù)據(jù)表的基本概念
      • 4.2.1、Row&Column
      • 4.2.2、Partition&Tablet
    • 4.3、建表示例
      • 4.3.1、建表語法
      • 4.3.2、字段類型
      • 4.3.3、Doris建表示例
        • 4.3.3.1、Range Partition
        • 4.3.3.2、 List Partition
      • 4.3.4、數(shù)據(jù)劃分
        • 4.3.4.1、列定義
        • 4.3.4.2、分區(qū)與分桶
          • 4.3.4.2.1、Partition
          • 4.3.4.2.2、Bucket
          • 4.3.4.2.3、使用復(fù)合分區(qū)的場景
          • 4.3.4.2.4、多列分區(qū)
        • 4.3.4.3、PROPERTIES
          • 4.3.4.3.1 replication_num
          • 4.3.4.3.2、storage_medium & storage_cooldown_time
        • 4.3.4.4、ENGINE
      • 4.3.5 數(shù)據(jù)模型
        • 4.3.5.1 Aggregate 模型
          • 4.3.5.1.2 示例二:保留明細(xì)數(shù)據(jù)
          • 4.3.5.1.3 示例三:導(dǎo)入數(shù)據(jù)與已有數(shù)據(jù)聚合
        • 4.3.5.2 Uniq 模型
        • 4.3.5.3 Duplicate 模型
        • 4.3.5.4 數(shù)據(jù)模型的選擇建議
      • 4.3.6 動態(tài)分區(qū)
        • 4.3.6.1 原理
        • 4.3.6.2 使用方式
        • 4.3.6.3 動態(tài)分區(qū)規(guī)則參數(shù)
          • 4.3.6.3.1 主要參數(shù)
          • 4.3.6.3.2 創(chuàng)建歷史分區(qū)的參數(shù)
          • 4.3.6.3.3 創(chuàng)建歷史分區(qū)規(guī)則
          • 4.3.6.3.4 創(chuàng)建歷史分區(qū)舉例
          • 4.3.6.3.5 注意事項(xiàng)
        • 4.3.6.4 示例
      • 4.3.7 Rollup
        • 4.3.7.1 基本概念
        • 4.3.7.2 Aggregate 和 Uniq 模型中的 ROLLUP
        • 4.3.7.3 Duplicate 模型中的 ROLLUP
          • 4.3.7.3.1 前綴索引
          • 4.3.7.3.2 ROLLUP 調(diào)整前綴索引
        • 4.3.7.4 ROLLUP 的幾點(diǎn)說明
      • 4.3.8 物化視圖
        • 4.3.8.1 適用場景
        • 4.3.8.2 優(yōu)勢
        • 4.3.8.3 物化視圖 VS Rollup
        • 4.3.8.4 物化視圖原理
          • 4.3.8.4.1 創(chuàng)建物化視圖
          • 4.3.8.4.2 查詢
          • 4.3.8.4.3 查詢自動匹配
          • 4.3.8.4.4 最優(yōu)路徑選擇
          • 4.3.8.4.5 查詢改寫
          • 4.3.8.4.6 使用及限制
        • 4.3.8.5 案例演示
          • 4.3.8.5.1 案例一
          • 4.3.8.5.2 案例二:計(jì)算廣告的 pv、uv
          • 4.3.8.5.3 案例三
      • 4.3.9 修改表
        • 4.3.9.1 rename
        • 4.3.9.2 partition
        • 4.3.9.3 rollup
        • 4.3.9.4 表結(jié)構(gòu)變更
      • 4.3.10 刪除數(shù)據(jù)(Delete)
        • 4.3.10.1 DELETE FROM Statement(條件刪除)
        • 4.3.10.2 DROP PARTITION Statement(刪除分區(qū))

1、Doris簡介

Doris是由百度大數(shù)據(jù)研發(fā),是一個現(xiàn)代化的MPP(Massively Parallel Processing)大規(guī)模并行處理的分析型數(shù)據(jù)庫產(chǎn)品。僅需亞秒級響應(yīng)時間即可獲得查詢結(jié)果,有效地支持實(shí)時數(shù)據(jù)分析。
Apache Doris 的分布式架構(gòu)非常簡潔,易于運(yùn)維,并且可以支持 10PB 以上的超大數(shù)據(jù)集。
Apache Doris 可以滿足多種數(shù)據(jù)分析需求,例如固定歷史報表,實(shí)時數(shù)據(jù)分析,交互式
數(shù)據(jù)分析和探索式數(shù)據(jù)分析等。
doris,大數(shù)據(jù),數(shù)據(jù)庫?

doris,大數(shù)據(jù),數(shù)據(jù)庫?

2、Doris網(wǎng)址

1、官網(wǎng)地址
2、文檔查看地址
3、下載地址
4、github地址

3、Doris架構(gòu)

?

doris,大數(shù)據(jù),數(shù)據(jù)庫
Doris 的架構(gòu)很簡潔,只設(shè)FE(Frontend)、BE(Backend)兩種角色、兩個進(jìn)程,不依賴于外部組件,方便部署和運(yùn)維,F(xiàn)E、BE都可線性擴(kuò)展。

?

  • Frontend(FE),存儲、維護(hù)集群元數(shù)據(jù);負(fù)責(zé)接收、解析查詢請求,規(guī)劃查詢計(jì)劃,調(diào)度查詢執(zhí)行,返回查詢結(jié)果。主要有三個角色:
    1)Leader 和Follower:主要是用來達(dá)到元數(shù)據(jù)的高可用,保證單節(jié)點(diǎn)宕機(jī)的情況下,元數(shù)據(jù)能夠?qū)崟r地在線恢復(fù),而不影響整個服務(wù)。
    2)Observer:用來擴(kuò)展查詢節(jié)點(diǎn),同時起到元數(shù)據(jù)備份的作用。如果在發(fā)現(xiàn)集群壓力非常大的情況下,需要去擴(kuò)展整個查詢的能力,那么可以加observer 的節(jié)點(diǎn)。observer 不參與任何的寫入,只參與讀取。

  • Backend(BE),負(fù)責(zé)物理數(shù)據(jù)的存儲和計(jì)算;依據(jù)FE 生成的物理計(jì)劃,分布式地執(zhí)行查詢。
    數(shù)據(jù)的可靠性由BE 保證,BE 會對整個數(shù)據(jù)存儲多副本或者是三副本。副本數(shù)可根據(jù)需求動態(tài)調(diào)整。

  • MySQLClient:Doris借助MySQL協(xié)議,用戶使用任意MySQL的ODBC/JDBC以及MySQL的客戶端,都可以直接訪問Doris。

  • Broker:Broker為一個獨(dú)立的無狀態(tài)進(jìn)程。封裝了文件系統(tǒng)接口,提供Doris讀取遠(yuǎn)端存儲系統(tǒng)中文件的能力,包括HDFS,S3,BOS等。

3、編譯和安裝

3.1、軟硬件需求

概述
Doris 作為一款開源的 MPP 架構(gòu) OLAP 數(shù)據(jù)庫,能夠運(yùn)行在絕大多數(shù)主流的商用服務(wù)器上。為了能夠充分運(yùn)用 MPP 架構(gòu)的并發(fā)優(yōu)勢,以及 Doris 的高可用特性,我們建議 Doris 的部署遵循以下需求:
Linux 操作系統(tǒng)版本需求

Linux 系統(tǒng) 版本
CentOS 7.1 及以上
Ubuntu 16.04 及以上

軟件需求

軟件 版本
Java 1.8 及以上
GCC 4.8.2 及以上

操作系統(tǒng)安裝要求
設(shè)置系統(tǒng)最大打開文件句柄數(shù)

vi /etc/security/limits.conf 
* soft nofile 65536
* hard nofile 65536

時鐘同步
Doris 的元數(shù)據(jù)要求時間精度要小于5000ms,所以所有集群所有機(jī)器要進(jìn)行時鐘同步,避免因?yàn)闀r鐘問題引發(fā)的元數(shù)據(jù)不一致導(dǎo)致服務(wù)出現(xiàn)異常。

關(guān)閉交換分區(qū)(swap)
Linux交換分區(qū)會給Doris帶來很嚴(yán)重的性能問題,需要在安裝之前禁用交換分區(qū)

Liunx文件系統(tǒng)
這里我們推薦使用ext4文件系統(tǒng),在安裝操作系統(tǒng)的時候,請選擇ext4文件系統(tǒng)。
開發(fā)測試環(huán)境

模塊 CPU 內(nèi)存 磁盤 網(wǎng)絡(luò) 實(shí)例數(shù)量
Frontend 8核+ 8GB+ SSD 或 SATA,10GB+ * 千兆網(wǎng)卡 1
Backend 8核+ 16GB+ SSD 或 SATA,50GB+ * 千兆網(wǎng)卡 1-3 *

生產(chǎn)環(huán)境

模塊 CPU 內(nèi)存 磁盤 網(wǎng)絡(luò) 實(shí)例數(shù)量(最低要求)
Frontend 16核+ 64GB+ SSD 或 RAID 卡,100GB+ * 萬兆網(wǎng)卡 1-3 *
Backend 16核+ 64GB+ SSD 或 SATA,100G+ * 萬兆網(wǎng)卡 3 *

注1:
1、FE 的磁盤空間主要用于存儲元數(shù)據(jù),包括日志和 image。通常從幾百 MB 到幾個 GB 不等。
2、BE 的磁盤空間主要用于存放用戶數(shù)據(jù),總磁盤空間按用戶總數(shù)據(jù)量 * 3(3副本)計(jì)算,然后再預(yù)留額外 40% 的空間用作后臺 compaction 以及一些中間數(shù)據(jù)的存放。
3、一臺機(jī)器上可以部署多個 BE 實(shí)例,但是只能部署一個 FE。如果需要 3 副本數(shù)據(jù),那么至少需要 3 臺機(jī)器各部署一個 BE 實(shí)例(而不是1臺機(jī)器部署3個BE實(shí)例)。多個FE所在服務(wù)器的時鐘必須保持一致(允許最多5秒的時鐘偏差)
4、測試環(huán)境也可以僅適用一個 BE 進(jìn)行測試。實(shí)際生產(chǎn)環(huán)境,BE 實(shí)例數(shù)量直接決定了整體查詢延遲。
5、所有部署節(jié)點(diǎn)關(guān)閉 Swap。
6、FE 角色分為 Follower 和 Observer,(Leader 為 Follower 組中選舉出來的一種角色,以下統(tǒng)稱 Follower)。
FE 節(jié)點(diǎn)數(shù)據(jù)至少為1(1 個 Follower)。當(dāng)部署 1 個 Follower 和 1 個 Observer 時,可以實(shí)現(xiàn)讀高可用。當(dāng)部署 3 個 Follower 時,可以實(shí)現(xiàn)讀寫高可用(HA)。
7、Follower 的數(shù)量必須為奇數(shù),Observer 數(shù)量隨意。
8、根據(jù)以往經(jīng)驗(yàn),當(dāng)集群可用性要求很高時(比如提供在線業(yè)務(wù)),可以部署 3 個 Follower 和 1-3 個 Observer。如果是離線業(yè)務(wù),建議部署 1 個 Follower 和 1-3 個 Observer。
9、Broker 是用于訪問外部數(shù)據(jù)源(如 HDFS)的進(jìn)程。通常,在每臺機(jī)器上部署一個 broker 實(shí)例即可。

默認(rèn)端口號:

實(shí)例名稱 端口名稱 默認(rèn)端口 通訊方向 說明
BE be_port 9060 FE --> BE BE 上 thrift server 的端口,用于接收來自 FE 的請求
BE webserver_port 8040 BE <–> BE BE 上的 http server 的端口
BE heartbeat_service_port 9050 FE --> BE BE 上心跳服務(wù)端口(thrift),用于接收來自 FE 的心跳
BE brpc_port 8060 FE <–> BE, BE <–> BE BE 上的 brpc 端口,用于 BE 之間通訊
FE http_port 8030 FE <–> FE,用戶 <–> FE FE 上的 http server 端口
FE rpc_port 9020 BE --> FE, FE <–> FE FE 上的 thrift server 端口,每個fe的配置需要保持一致
FE query_port 9030 用戶 <–> FE FE 上的 mysql server 端口
FE edit_log_port 9010 FE <–> FE FE 上的 bdbje 之間通信用的端口
Broker broker_ipc_port 8000 FE --> Broker, BE --> Broker Broker 上的 thrift server,用于接收請求

當(dāng)部署多個 FE 實(shí)例時,要保證 FE 的 http_port 配置相同。
部署前請確保各個端口在應(yīng)有方向上的訪問權(quán)限。
IP 綁定
因?yàn)橛卸嗑W(wǎng)卡的存在,或因?yàn)榘惭b過 docker 等環(huán)境導(dǎo)致的虛擬網(wǎng)卡的存在,同一個主機(jī)可能存在多個不同的 ip。當(dāng)前 Doris 并不能自動識別可用 IP。所以當(dāng)遇到部署主機(jī)上有多個 IP 時,必須通過 priority_networks 配置項(xiàng)來強(qiáng)制指定正確的 IP。

priority_networks 是 FE 和 BE 都有的一個配置,配置項(xiàng)需寫在 fe.conf 和 be.conf 中。該配置項(xiàng)用于在 FE 或 BE 啟動時,告訴進(jìn)程應(yīng)該綁定哪個IP。示例如下:

priority_networks=10.1.3.0/24

這是一種 CIDR 的表示方法。FE 或 BE 會根據(jù)這個配置項(xiàng)來尋找匹配的IP,作為自己的 localIP。

注意:當(dāng)配置完 priority_networks 并啟動 FE 或 BE 后,只是保證了 FE 或 BE 自身的 IP 進(jìn)行了正確的綁定。而在使用 ADD BACKEND 或 ADD FRONTEND 語句中,也需要指定和 priority_networks 配置匹配的 IP,否則集群無法建立。舉例:

BE 的配置為:priority_networks=10.1.3.0/24

但是在 ADD BACKEND 時使用的是:ALTER SYSTEM ADD BACKEND “192.168.0.1:9050”;

則 FE 和 BE 將無法正常通信。

這時,必須 DROP 掉這個添加錯誤的 BE,重新使用正確的 IP 執(zhí)行 ADD BACKEND。

FE 同理。

BROKER 當(dāng)前沒有,也不需要 priority_networks 這個選項(xiàng)。Broker 的服務(wù)默認(rèn)綁定在 0.0.0.0 上。只需在 ADD BROKER 時,執(zhí)行正確可訪問的 BROKER IP 即可。

表名大小寫敏感性設(shè)置
doris默認(rèn)為表名大小寫敏感,如有表名大小寫不敏感的需求需在集群初始化時進(jìn)行設(shè)置。表名大小寫敏感性在集群初始化完成后不可再修改。

詳細(xì)參見 變量 中關(guān)于lower_case_table_names變量的介紹。

3.2、編譯

安裝Doris,需要先通過源碼編譯,主要有兩種方式:使用Docker開發(fā)鏡像編譯(推薦)、直接編譯。直接編譯的方式,可以參考官網(wǎng):https://doris.apache.org/zh-CN/installing/compilation.html

3.2.1、安裝Docker環(huán)境

1)Docker要求CentOS系統(tǒng)的內(nèi)核版本高于3.10,首先查看系統(tǒng)內(nèi)核版本是否滿足

uname -r

2)使用root權(quán)限登錄系統(tǒng),確保yum包更新到最新

sudo yum update -y

3)假如安裝過舊版本,先卸載舊版本

sudo yum remove docker docker-common docker-selinux docker-engine

4)安裝yum-util工具包和devicemapper驅(qū)動依賴

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

5)設(shè)置yum源(加速yum下載速度)

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

如果連接超時,可以使用alibaba的鏡像源:

sudo yum-config-manager --add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

6)查看所有倉庫中所有docker版本,并選擇特定版本安裝,一般可直接安裝最新版

yum list docker-ce --showduplicates | sort -r

7)安裝docker
(1)安裝最新穩(wěn)定版本的方式:

sudo yum install docker-ce -y #安裝的是最新穩(wěn)定版本,因?yàn)閞epo中默認(rèn)只開啟stable倉庫

(2)安裝指定版本的方式:

sudo yum install -y
#例如:
sudoyum install docker-ce-20.10.11.ce -y

8)啟動并加入開機(jī)啟動

sudo systemctl start docker #啟動
docker sudo systemctl enable docker #加入開機(jī)自啟動

9)查看Version,驗(yàn)證是否安裝成功

docker version

若出現(xiàn)Client和Server兩部分內(nèi)容,則證明安裝成功。

3.2.2、使用Docker 開發(fā)鏡像編譯

1)下載源碼并解壓
通過wget下載(或者手動上傳下載好的壓縮包)。

wget
https://dist.apache.org/repos/dist/dev/incubator/doris/0.15/0.15.0-rc04/apache-doris-0.15.0-incubating-src.tar.gz

解壓到/opt/software/

tar -zxvf apache-doris-0.15.0-incubating-src.tar.gz -C /opt/software

2)下載 Docker 鏡像

docker pull apache/incubator-doris:build-env-for-0.15.0

可以通過以下命令查看鏡像是否下載完成。

docker images

3)掛載本地目錄運(yùn)行鏡像
以掛載本地 Doris 源碼目錄的方式運(yùn)行鏡像,這樣編譯的產(chǎn)出二進(jìn)制文件會存儲在宿主
機(jī)中,不會因?yàn)殓R像退出而消失。同時將鏡像中 maven 的 .m2 目錄掛載到宿主機(jī)目錄,以
防止每次啟動鏡像編譯時,重復(fù)下載 maven 的依賴庫。

docker run -it
-v /opt/software/.m2:/root/.m2
-v /opt/software/apache-doris-0.15.0-incubating-src/:/root/apachedoris-0.15.0-incubating-src/
\ apache/incubator-doris:build-env-for-0.15.0

4)切換到 JDK 8

alternatives --set java java-1.8.0-openjdk.x86_64
alternatives --set javac java-1.8.0-openjdk.x86_64
export JAVA_HOME=/usr/lib/jvm/java-1.8.0

5)準(zhǔn)備 Maven 依賴
編譯過程會下載很多依賴,可以將我們準(zhǔn)備好的 doris-repo.tar.gz 解壓到 Docker 掛載的
對應(yīng)目錄,來避免下載依賴的過程,加速編譯。

tar -zxvf doris-repo.tar.gz -C /opt/software

也可以通過指定阿里云鏡像倉庫來加速下載:

vim /opt/software/apache-doris-0.15.0-incubating-src/fe/pom.xml


在<repositories>標(biāo)簽下添加:
<repository>
 <id>aliyun</id>
 <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
vim /opt/software/apache-doris-0.15.0-incubating-src/be/pom.xml
在<repositories>標(biāo)簽下添加:
<repository>
 <id>aliyun</id>
 <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>

6)編譯 Doris

sh build.sh

如果是第一次使用 build-env-for-0.15.0 或之后的版本,第一次編譯的時候要使用如下命令:

sh build.sh --clean --be --fe --ui

因?yàn)?build-env-for-0.15.0 版本鏡像升級了 thrift(0.9 -> 0.13),需要通過–clean 命令強(qiáng)制
使用新版本的 thrift 生成代碼文件,否則會出現(xiàn)不兼容的代碼。

3.3、集群部署

主機(jī) 1 主機(jī) 2 主機(jī) 3
FE(LEADER) FE(FOLLOWER) FE(OBSERVER)
BE BE BE
BROKER BROKER BROKER

生產(chǎn)環(huán)境建議 FE 和 BE 分開。

3.3.1、創(chuàng)建目錄并拷貝編譯后的文件

1)創(chuàng)建目錄并拷貝編譯后的文件

mkdir /opt/module/apache-doris-0.15.0 cp -r
/opt/software/apache-doris-0.15.0-incubating-src/output
/opt/module/apache-doris-0.15.0

2)修改可打開文件數(shù)(每個節(jié)點(diǎn))

sudo vim /etc/security/limits.conf

  • soft nofile 65535
  • hard nofile 65535
  • soft nproc 65535
  • hard nproc 65535

重啟永久生效,也可以用 ulimit -n 65535 臨時生效。

3.3.2、部署 FE 節(jié)點(diǎn)

1)創(chuàng)建 fe 元數(shù)據(jù)存儲的目錄

mkdir /opt/module/apache-doris-0.15.0/doris-meta

2)修改 fe 的配置文件

vim /opt/module/apache-doris-0.15.0/fe/conf/fe.conf
#配置文件中指定元數(shù)據(jù)路徑: meta_dir = /opt/module/apache-doris-0.15.0/doris-meta
#修改綁定 ip(每臺機(jī)器修改成自己的 ip) priority_networks = 192.168.8.101/24

注意:
? 生產(chǎn)環(huán)境強(qiáng)烈建議單獨(dú)指定目錄不要放在 Doris 安裝目錄下,最好是單獨(dú)的磁盤(如果有 SSD 最好)。
? 如果機(jī)器有多個 ip, 比如內(nèi)網(wǎng)外網(wǎng), 虛擬機(jī) docker 等, 需要進(jìn)行 ip 綁定,才能正確識
別。
? JAVA_OPTS 默認(rèn) java 最大堆內(nèi)存為 4GB,建議生產(chǎn)環(huán)境調(diào)整至 8G 以上。
3)啟動 hadoop1 的 FE

/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --daemon

3.3.3、配置 BE 節(jié)點(diǎn)

1)分發(fā) BE

scp -r /opt/module/apache-doris-0.15.0/be hadoop2:/opt/module scp -r
/opt/module/apache-doris-0.15.0/be hadoop3:/opt/module

2)創(chuàng)建 BE 數(shù)據(jù)存放目錄(每個節(jié)點(diǎn))

mkdir /opt/module/apache-doris-0.15.0/doris-storage1 mkdir
/opt/module/apache-doris-0.15.0/doris-storage2

3)修改 BE 的配置文件(每個節(jié)點(diǎn))

vim /opt/module/apache-doris-0.15.0/be/conf/be.conf
#配置文件中指定數(shù)據(jù)存放路徑: storage_root_path = /opt/module/apache-doris-0.15.0/dorisstorage1;/opt/module/apache-doris-0.15.0/doris-storage2
#修改綁定 ip(每臺機(jī)器修改成自己的 ip) priority_networks = 192.168.8.101/24

注意:
? storage_root_path 默認(rèn)在 be/storage 下,需要手動創(chuàng)建該目錄。多個路徑之間使用英文狀
態(tài)的分號;分隔(最后一個目錄后不要加)。
? 可以通過路徑區(qū)別存儲目錄的介質(zhì),HDD 或 SSD。可以添加容量限制在每個路徑的末尾,通過英文狀態(tài)逗號,隔開,如:
storage_root_path=/home/disk1/doris.HDD,50;/home/disk2/doris.SSD,10;/home/disk2/doris
說明:
/home/disk1/doris.HDD,50,表示存儲限制為 50GB,HDD;
/home/disk2/doris.SSD,10,存儲限制為 10GB,SSD;
/home/disk2/doris,存儲限制為磁盤最大容量,默認(rèn)為 HDD
? 如果機(jī)器有多個 IP, 比如內(nèi)網(wǎng)外網(wǎng), 虛擬機(jī) docker 等, 需要進(jìn)行 IP 綁定,才能正確識別。

3.3.4、在 FE 中添加所有 BE 節(jié)點(diǎn)

BE 節(jié)點(diǎn)需要先在 FE 中添加,才可加入集群??梢允褂?mysql-client 連接到 FE。
1)安裝 MySQL Client
(1)創(chuàng)建目錄

mkdir /opt/software/mysql-client/

(2)上傳相關(guān)以下三個 rpm 包到/opt/software/mysql-client/
? mysql-community-client-5.7.28-1.el7.x86_64.rpm
? mysql-community-common-5.7.28-1.el7.x86_64.rpm
? mysql-community-libs-5.7.28-1.el7.x86_64.rpm
(3)檢查當(dāng)前系統(tǒng)是否安裝過 MySQL

sudo rpm -qa|grep mariadb
#如果存在,先卸載
sudo rpm -e --nodeps mariadb mariadb-libs mariadb-server

(4)安裝

rpm -ivh /opt/software/mysql-client/*

2)使用 MySQL Client 連接 FE

mysql -h hadoop1 -P 9030 -uroot

默認(rèn) root 無密碼,通過以下命令修改 root 密碼。

SET PASSWORD FOR ‘root’ = PASSWORD(‘000000’);

3)添加 BE

ALTER SYSTEM ADD BACKEND “hadoop1:9050”;
ALTER SYSTEM ADD BACKEND “hadoop2:9050”;
ALTER SYSTEM ADD BACKEND “hadoop3:9050”;

4)查看 BE 狀態(tài)

SHOW PROC ‘/backends’;

3.3.5、啟動 BE

1)啟動 BE(每個節(jié)點(diǎn))

/opt/module/apache-doris-0.15.0/be/bin/start_be.sh --daemon

2)查看 BE 狀態(tài)

mysql -h hadoop1 -P 9030 -uroot -p
SHOW PROC ‘/backends’;

Alive 為 true 表示該 BE 節(jié)點(diǎn)存活。

3.3.6、部署 FS_Broker(可選)

Broker 以插件的形式,獨(dú)立于 Doris 部署。如果需要從第三方存儲系統(tǒng)導(dǎo)入數(shù)據(jù),需要部署相應(yīng)的 Broker,默認(rèn)提供了讀取 HDFS、百度云 BOS 及 Amazon S3 的 fs_broker。fs_broker 是無狀態(tài)的,建議每一個 FE 和 BE 節(jié)點(diǎn)都部署一個 Broker。
1)編譯 FS_BROKER 并拷貝文件
(1)進(jìn)入源碼目錄下的 fs_brokers 目錄,使用 sh build.sh 進(jìn)行編譯
(2)拷貝源碼 fs_broker 的 output 目錄下的相應(yīng) Broker 目錄到需要部署的所有節(jié)點(diǎn)上,改名為: apache_hdfs_broker。建議和 BE 或者 FE 目錄保持同級。
方法同 2.2。
2)啟動 Broker

/opt/module/apache-doris-0.15.0/apache_hdfs_broker/bin/start_broker.sh
–daemon

3)添加 Broker
要讓 Doris 的 FE 和 BE 知道 Broker 在哪些節(jié)點(diǎn)上,通過 sql 命令添加 Broker 節(jié)
點(diǎn)列表。
(1)使用 mysql-client 連接啟動的 FE,執(zhí)行以下命令:

mysql -h hadoop1 -P 9030 -uroot -p
ALTER SYSTEM ADD BROKER broker_name “hadoop1:8000”,“hadoop2:8000”,“hadoop3:8000”;

其中 broker_host 為 Broker 所在節(jié)點(diǎn) ip;broker_ipc_port 在 Broker 配置文件中的
conf/apache_hdfs_broker.conf。
4)查看 Broker 狀態(tài)
使用 mysql-client 連接任一已啟動的 FE,執(zhí)行以下命令查看 Broker 狀態(tài):

SHOW PROC “/brokers”;

注:在生產(chǎn)環(huán)境中,所有實(shí)例都應(yīng)使用守護(hù)進(jìn)程啟動,以保證進(jìn)程退出后,會被自動拉
起,如 Supervisor(opens new window)。如需使用守護(hù)進(jìn)程啟動,在 0.9.0 及之前版本中,
需要修改各個 start_xx.sh 腳本,去掉最后的 & 符號。從 0.10.0 版本開始,直接調(diào)用 sh
start_xx.sh 啟動即可。

3.4、擴(kuò)容和縮容

Doris 可以很方便的擴(kuò)容和縮容 FE、BE、Broker 實(shí)例。

3.4.1 FE 擴(kuò)容和縮容

可以通過將 FE 擴(kuò)容至 3 個以上節(jié)點(diǎn)來實(shí)現(xiàn) FE 的高可用。
1)使用 MySQL 登錄客戶端后,可以使用 sql 命令查看 FE 狀態(tài),目前就一臺 FE

mysql -h hadoop1 -P 9030 -uroot -p

SHOW PROC ‘/frontends’;

也可以通過頁面訪問進(jìn)行監(jiān)控,訪問 8030,賬戶為 root,密碼默認(rèn)為空不用填寫。
2)增加 FE 節(jié)點(diǎn)
FE 分為 Leader,F(xiàn)ollower 和 Observer 三種角色。 默認(rèn)一個集群,只能有一個 Leader,可以有多個 Follower 和 Observer。其中 Leader 和 Follower 組成一個 Paxos 選擇組,如果Leader 宕機(jī),則剩下的 Follower 會自動選出新的 Leader,保證寫入高可用。Observer 同步Leader 的數(shù)據(jù),但是不參加選舉。
如果只部署一個 FE,則 FE 默認(rèn)就是 Leader。在此基礎(chǔ)上,可以添加若干 Follower 和Observer。

ALTER SYSTEM ADD FOLLOWER “hadoop2:9010”;

ALTER SYSTEM ADD OBSERVER “hadoop3:9010”;

3)配置及啟動 Follower 和 Observer
第一次啟動時,啟動命令需要添加參–helper leader 主機(jī): edit_log_port:
(1)分發(fā) FE,修改 FE 的配置(同 2.4.2)

scp -r /opt/module/apache-doris-0.15.0/fe hadoop2:/opt/module/
apache-doris-0.15.0

scp -r /opt/module/apache-doris-0.15.0/fe hadoop3:/opt/module/
apache-doris-0.15.0

(2)在 hadoop2 啟動 Follower

/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --helper
hadoop1:9010 --daemon

(3)在 hadoop3 啟動 Observer

/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --helper
hadoop1:9010 --daemon

4)查看運(yùn)行狀態(tài)
使用 mysql-client 連接到任一已啟動的 FE。

SHOW PROC ‘/frontends’;

5)刪除 FE 節(jié)點(diǎn)命令

ALTER SYSTEM DROP FOLLOWER[OBSERVER] “fe_host:edit_log_port”;

注意:刪除 Follower FE 時,確保最終剩余的 Follower(包括 Leader)節(jié)點(diǎn)為奇數(shù)。

3.4.2 BE 擴(kuò)容和縮容

1)增加 BE 節(jié)點(diǎn)
在 MySQL 客戶端,通過 ALTER SYSTEM ADD BACKEND 命令增加 BE 節(jié)點(diǎn)。
2)DROP 方式刪除 BE 節(jié)點(diǎn)(不推薦)

ALTER SYSTEM DROP BACKEND “be_host:be_heartbeat_service_port”;

注意:DROP BACKEND 會直接刪除該 BE,并且其上的數(shù)據(jù)將不能再恢復(fù)?。?!所以我們強(qiáng)烈不推薦使用 DROP BACKEND 這種方式刪除 BE 節(jié)點(diǎn)。當(dāng)你使用這個語句時,會有對應(yīng)的防誤操作提示。
3)DECOMMISSION 方式刪除 BE 節(jié)點(diǎn)(推薦)

ALTER SYSTEM DECOMMISSION BACKEND
“be_host:be_heartbeat_service_port”;

? 該命令用于安全刪除 BE 節(jié)點(diǎn)。命令下發(fā)后,Doris 會嘗試將該 BE 上的數(shù)據(jù)向其他 BE 節(jié)點(diǎn)遷移,當(dāng)所有數(shù)據(jù)都遷移完成后,Doris 會自動刪除該節(jié)點(diǎn)。
? 該命令是一個異步操作。執(zhí)行后,可以通過 SHOW PROC ‘/backends’; 看到該 BE 節(jié)點(diǎn)的 isDecommission 狀態(tài)為 true。表示該節(jié)點(diǎn)正在進(jìn)行下線。
? 該命令不一定執(zhí)行成功。比如剩余 BE 存儲空間不足以容納下線 BE 上的數(shù)據(jù),或者剩余機(jī)器數(shù)量不滿足最小副本數(shù)時,該命令都無法完成,并且 BE 會一直處于
isDecommission 為 true 的狀態(tài)。
? DECOMMISSION 的進(jìn)度,可以通過 SHOW PROC ‘/backends’; 中的 TabletNum 查看,如果正在進(jìn)行,TabletNum 將不斷減少。
? 該操作可以通過如下命令取消:

CANCEL DECOMMISSION BACKEND “be_host:be_heartbeat_service_port”;

取消后,該 BE 上的數(shù)據(jù)將維持當(dāng)前剩余的數(shù)據(jù)量。后續(xù) Doris 重新進(jìn)行負(fù)載均衡。

3.4.3 Broker 擴(kuò)容縮容

Broker 實(shí)例的數(shù)量沒有硬性要求。通常每臺物理機(jī)部署一個即可。Broker 的添加和刪除可以通過以下命令完成:

ALTER SYSTEM ADD BROKER broker_name “broker_host:broker_ipc_port”;

ALTER SYSTEM DROP BROKER broker_name “broker_host:broker_ipc_port”;

ALTER SYSTEM DROP ALL BROKER broker_name;

Broker 是無狀態(tài)的進(jìn)程,可以隨意啟停。當(dāng)然,停止后,正在其上運(yùn)行的作業(yè)會失敗,重試即可。

4、數(shù)據(jù)表的基本使用

4.1、創(chuàng)建用戶和數(shù)據(jù)庫

1)創(chuàng)建test用戶

mysql -h hadoop1 -P 9030 -uroot -p
create user ‘test’ identified by ‘test’;

2)創(chuàng)建數(shù)據(jù)庫

create database test_db;

3)用戶授權(quán)

grant all on test_db to test;

4.2、Doris中數(shù)據(jù)表的基本概念

在Doris中,數(shù)據(jù)都以關(guān)系表(Table)的形式進(jìn)行邏輯上的描述。

4.2.1、Row&Column

一張表包含行(Row)和列(Column)。Row 即用戶的一行數(shù)據(jù)。Column 用于描述一行數(shù)據(jù)中不同的字段。

  • 在默認(rèn)的數(shù)據(jù)模型中,Column 只分為排序列和非排序列。存儲引擎會按照排序列對數(shù)據(jù)進(jìn)行排序存儲,并建立稀疏索引,以便在排序數(shù)據(jù)上進(jìn)行快速查找。
  • 而在聚合模型中,Column 可以分為兩大類:Key 和 Value。從業(yè)務(wù)角度看,Key 和Value 可以分別對應(yīng)維度列和指標(biāo)列。從聚合模型的角度來說,Key 列相同的行,會聚合成一行。其中 Value 列的聚合方式由用戶在建表時指定。

4.2.2、Partition&Tablet

在 Doris 的存儲引擎中,用戶數(shù)據(jù)首先被劃分成若干個分區(qū)(Partition),劃分的規(guī)則通常是按照用戶指定的分區(qū)列進(jìn)行范圍劃分,比如按時間劃分。而在每個分區(qū)內(nèi),數(shù)據(jù)被進(jìn)一
步的按照 Hash 的方式分桶,分桶的規(guī)則是要找用戶指定的分桶列的值進(jìn)行 Hash 后分桶。每個分桶就是一個數(shù)據(jù)分片(Tablet),也是數(shù)據(jù)劃分的最小邏輯單元。

  • Tablet 之間的數(shù)據(jù)是沒有交集的,獨(dú)立存儲的。Tablet 也是數(shù)據(jù)移動、復(fù)制等操作的最小物理存儲單元。
  • Partition 可以視為是邏輯上最小的管理單元。數(shù)據(jù)的導(dǎo)入與刪除,都可以或僅能針對一個 Partition 進(jìn)行。

4.3、建表示例

4.3.1、建表語法

使用 CREATE TABLE 命令建立一個表(Table)。更多詳細(xì)參數(shù)可以查看:

help create table;

建表語法:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, …]
[, index_definition1[, index_definition12,]])
[ENGINE = [olap|mysql|broker|hive]]
[key_desc]
[COMMENT “table comment”];
[partition_desc]
[distribution_desc]
[rollup_index]
[PROPERTIES (“key”=“value”, …)]
[BROKER PROPERTIES (“key”=“value”, …)];

Doris建表是一個同步命令,命令返回成功,即表示建表成功。
Doris 支持支持單分區(qū)和復(fù)合分區(qū)兩種建表方式。
1)復(fù)合分區(qū):既有分區(qū)也有分桶
第一級稱為 Partition,即分區(qū)。用戶可以指定某一維度列作為分區(qū)列(當(dāng)前只支持整型和時間類型的列),并指定每個分區(qū)的取值范圍。
第二級稱為 Distribution,即分桶。用戶可以指定一個或多個維度列以及桶數(shù)對數(shù)據(jù)進(jìn)行 HASH 分布。
2)單分區(qū):只做 HASH 分布,即只分桶。

4.3.2、字段類型

字段類型名 類型字節(jié)單位 長度
TINYINT 1 字節(jié) 范圍:-2^7 + 1 ~ 2^7 - 1
SMALLINT 2 字節(jié) 范圍:-2^15 + 1 ~ 2^15 - 1
INT 4 字節(jié) 范圍:-2^31 + 1 ~ 2^31 - 1
BIGINT 8 字節(jié) 范圍:-2^63 + 1 ~ 2^63 - 1
LARGEINT 16 字節(jié) 范圍:-2^127 + 1 ~ 2^127 - 1
FLOAT 4 字節(jié) 支持科學(xué)計(jì)數(shù)法
DOUBLE 12 字節(jié) 支持科學(xué)計(jì)數(shù)法
DECIMAL[(precision, scale)] 16 字節(jié) 保證精度的小數(shù)類型。默認(rèn)是DECIMAL(10, 0)precision: 1 ~ 27scale: 0 ~ 9其中整數(shù)部分為 1 ~ 18不支持科學(xué)計(jì)數(shù)法
DATE 3 字節(jié) 范圍:0000-01-01 ~ 9999-12-31
DATETIME 8 字節(jié) 范圍:0000-01-01 00:00:00 ~ 9999-12-31 23:59:59
CHAR[(length)] 定長字符串。長度范圍:1 ~ 255。默認(rèn)為 1
VARCHAR[(length)] 變長字符串。長度范圍:1 ~ 65533
BOOLEAN 與 TINYINT 一樣,0 代表 false,1 代表 true
HLL 1~16385 個字節(jié) hll 列類型,不需要指定長度和默認(rèn)值、長度根據(jù)數(shù)據(jù)的聚合程度系統(tǒng)內(nèi)控制,并且 HLL 列只能通過 配 套 的 hll_union_agg 、Hll_cardinality、hll_hash 進(jìn)行查詢或使用
BITMAP bitmap 列類型,不需要指定長度和默認(rèn)值。表示整型的集合,元素最大支持到 2^64 - 1
STRING 變長字符串,0.15 版本支持,最大支持 2147483643 字節(jié)(2GB-4),長度還受 be 配置string_type_soft_limit, 實(shí)際能存儲的最大長度取兩者最小值。只能用在 value 列,不能用在 key 列和分區(qū)、分桶列

注意:聚合模型在定義字段類型后,可以指定字段的 agg_type 聚合類型,如果不指定,則該列為 key 列。否則,該列為value 列, 類型包括:SUM、MAX、MIN、REPLACE。

4.3.3、Doris建表示例

4.3.3.1、Range Partition
CREATE TABLE IF NOT EXISTS example_db.expamle_range_tbl
(
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `date` DATE NOT NULL COMMENT "數(shù)據(jù)灌入日期時間",
 `timestamp` DATETIME NOT NULL COMMENT "數(shù)據(jù)灌入的時間戳",
 `city` VARCHAR(20) COMMENT "用戶所在城市",
 `age` SMALLINT COMMENT "用戶年齡",
 `sex` TINYINT COMMENT "用戶性別",
 `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 
00:00:00" COMMENT "用戶最后一次訪問時間",
 `cost` BIGINT SUM DEFAULT "0" COMMENT "用戶總消費(fèi)",
 `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用戶最大停留時間",
 `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用戶最小停留時間"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`,`date`,`timestamp`,`city`,`age`,`sex`)
partition by range(`date`)
(
PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
 PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
 PARTITION `p201703` VALUES LESS THAN ("2017-04-01")
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 
PROPERTIES
(
"replication_num" = "3",
 "storage_medium" = "SSD",
 "storage_cooldown_time" = "2018-01-01 12:00:00"
)

 

?

4.3.3.2、 List Partition
CREATE TABLE IF NOT EXISTS example_db.expamle_list_tbl
(
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `date` DATE NOT NULL COMMENT "數(shù)據(jù)灌入日期時間",
 `timestamp` DATETIME NOT NULL COMMENT "數(shù)據(jù)灌入的時間戳",
 `city` VARCHAR(20) COMMENT "用戶所在城市",
 `age` SMALLINT COMMENT "用戶年齡",
 `sex` TINYINT COMMENT "用戶性別",
 `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 
00:00:00" COMMENT "用戶最后一次訪問時間",
 `cost` BIGINT SUM DEFAULT "0" COMMENT "用戶總消費(fèi)",
 `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用戶最大停留時間",
 `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用戶最小停留時
間"
)
ENGINE=olap
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY LIST(`city`)
(
 PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"),
 PARTITION `p_usa` VALUES IN ("New York", "San Francisco"),
 PARTITION `p_jp` VALUES IN ("Tokyo")
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
 "replication_num" = "3",
 "storage_medium" = "SSD",
 "storage_cooldown_time" = "2018-01-01 12:00:00"
);

?

4.3.4、數(shù)據(jù)劃分

4.3.4.1、列定義

以 AGGREGATE KEY 數(shù)據(jù)模型為例進(jìn)行說明。更多數(shù)據(jù)模型參閱 Doris 數(shù)據(jù)模型。
列的基本類型,可以通過在 mysql-client 中執(zhí)行 HELP CREATE TABLE; 查看。
AGGREGATE KEY 數(shù)據(jù)模型中,所有沒有指定聚合方式(SUM、REPLACE、MAX、
MIN)的列視為 Key 列。而其余則為 Value 列。
定義列時,可參照如下建議:
? Key 列必須在所有 Value 列之前。
? 盡量選擇整型類型。因?yàn)檎皖愋偷挠?jì)算和查找比較效率遠(yuǎn)高于字符串。
? 對于不同長度的整型類型的選擇原則,遵循夠用即可。
? 對于 VARCHAR 和 STRING 類型的長度,遵循 夠用即可。
? 所有列的總字節(jié)長度(包括 Key 和 Value)不能超過 100KB。

4.3.4.2、分區(qū)與分桶

Doris 支持兩層的數(shù)據(jù)劃分。第一層是 Partition,支持 Range 和 List 的劃分方式。第二層是 Bucket(Tablet),僅支持 Hash 的劃分方式。
也可以僅使用一層分區(qū)。使用一層分區(qū)時,只支持 Bucket 劃分。

4.3.4.2.1、Partition

? Partition 列可以指定一列或多列。分區(qū)類必須為 KEY 列。多列分區(qū)的使用方式在后面介紹。
? 不論分區(qū)列是什么類型,在寫分區(qū)值時,都需要加雙引號。
? 分區(qū)數(shù)量理論上沒有上限。
? 當(dāng)不使用 Partition 建表時,系統(tǒng)會自動生成一個和表名同名的,全值范圍的
Partition。該 Partition 對用戶不可見,并且不可刪改。
1) Range 分區(qū)
分區(qū)列通常為時間列,以方便的管理新舊數(shù)據(jù)。不可添加范圍重疊的分區(qū)。
Partition 指定范圍的方式
? VALUES LESS THAN (…) 僅指定上界,系統(tǒng)會將前一個分區(qū)的上界作為該分區(qū)的下界,生成一個左閉右開的區(qū)間。分區(qū)的刪除不會改變已存在分區(qū)的范圍。刪除分區(qū)可能出現(xiàn)空洞。
? VALUES […) 指定同時指定上下界,生成一個左閉右開的區(qū)間。
通過 VALUES […) 同時指定上下界比較容易理解。這里舉例說明,當(dāng)使用 VALUES
LESS THAN (…) 語句進(jìn)行分區(qū)的增刪操作時,分區(qū)范圍的變化情況:
(1)如上 expamle_range_tbl 示例,當(dāng)建表完成后,會自動生成如下 3 個分區(qū):

p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)

(2)增加一個分區(qū) p201705 VALUES LESS THAN (“2017-06-01”),分區(qū)結(jié)果如下:

p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
p201705: [2017-04-01, 2017-06-01)

(3)此時刪除分區(qū) p201703,則分區(qū)結(jié)果如下:

p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

注意到 p201702 和 p201705 的分區(qū)范圍并沒有發(fā)生變化,而這兩個分區(qū)之間,出現(xiàn)了一個空洞:[2017-03-01, 2017-04-01)。即如果導(dǎo)入的數(shù)據(jù)范圍在這個空洞范圍內(nèi),是無法導(dǎo)入的。
(4)繼續(xù)刪除分區(qū) p201702,分區(qū)結(jié)果如下:

p201701: [MIN_VALUE, 2017-02-01)
p201705: [2017-04-01, 2017-06-01)

空洞范圍變?yōu)椋篬2017-02-01, 2017-04-01)
(5)現(xiàn)在增加一個分區(qū) p201702new VALUES LESS THAN (“2017-03-01”),分區(qū)結(jié)果如下:

p201701: [MIN_VALUE, 2017-02-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

可以看到空洞范圍縮小為:[2017-03-01, 2017-04-01)
(6)現(xiàn)在刪除分區(qū) p201701,并添加分區(qū) p201612 VALUES LESS THAN (“2017-01-01”),
分區(qū)結(jié)果如下:

p201612: [MIN_VALUE, 2017-01-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)

即出現(xiàn)了一個新的空洞:[2017-01-01, 2017-02-01)
2)List 分區(qū)
分 區(qū) 列支 持 BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE,
DATETIME, CHAR, VARCHAR 數(shù)據(jù)類型,分區(qū)值為枚舉值。只有當(dāng)數(shù)據(jù)為目標(biāo)分區(qū)枚舉值其中之一時,才可以命中分區(qū)。不可添加范圍重疊的分區(qū)。
Partition 支持通過 VALUES IN (…) 來指定每個分區(qū)包含的枚舉值。下面通過示例說明,
進(jìn)行分區(qū)的增刪操作時,分區(qū)的變化。
(1)如上 example_list_tbl 示例,當(dāng)建表完成后,會自動生成如下 3 個分區(qū):

p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_jp: (“Tokyo”)

(2)增加一個分區(qū) p_uk VALUES IN (“London”),分區(qū)結(jié)果如下:

p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_jp: (“Tokyo”)
p_uk: (“London”)

(3)刪除分區(qū) p_jp,分區(qū)結(jié)果如下:

p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_uk: (“London”)

4.3.4.2.2、Bucket

(1)如果使用了 Partition,則 DISTRIBUTED … 語句描述的是數(shù)據(jù)在各個分區(qū)內(nèi)的劃分規(guī)則。如果不使用 Partition,則描述的是對整個表的數(shù)據(jù)的劃分規(guī)則。
(2)分桶列可以是多列,但必須為 Key 列。分桶列可以和 Partition 列相同或不同。
(3)分桶列的選擇,是在 查詢吞吐 和 查詢并發(fā) 之間的一種權(quán)衡:
① 如果選擇多個分桶列,則數(shù)據(jù)分布更均勻。
如果一個查詢條件不包含所有分桶列的等值條件,那么該查詢會觸發(fā)所有分桶同時掃描,這樣查詢的吞吐會增加,單個查詢的延遲隨之降低。這個方式適合大吞吐低并發(fā)的查詢場景。
② 如果僅選擇一個或少數(shù)分桶列,則對應(yīng)的點(diǎn)查詢可以僅觸發(fā)一個分桶掃描。
此時,當(dāng)多個點(diǎn)查詢并發(fā)時,這些查詢有較大的概率分別觸發(fā)不同的分桶掃描,各個查詢之間的 IO 影響較小(尤其當(dāng)不同桶分布在不同磁盤上時),所以這種方式適合高并發(fā)的點(diǎn)查詢場景。
(4)分桶的數(shù)量理論上沒有上限。

4.3.4.2.3、使用復(fù)合分區(qū)的場景

以下場景推薦使用復(fù)合分區(qū)
(1)有時間維度或類似帶有有序值的維度,可以以這類維度列作為分區(qū)列。分區(qū)粒度可以根據(jù)導(dǎo)入頻次、分區(qū)數(shù)據(jù)量等進(jìn)行評估。
(2)歷史數(shù)據(jù)刪除需求:如有刪除歷史數(shù)據(jù)的需求(比如僅保留最近 N 天的數(shù)據(jù))。
使用復(fù)合分區(qū),可以通過刪除歷史分區(qū)來達(dá)到目的。也可以通過在指定分區(qū)內(nèi)發(fā)送 DELETE 語句進(jìn)行數(shù)據(jù)刪除。
(3)解決數(shù)據(jù)傾斜問題:每個分區(qū)可以單獨(dú)指定分桶數(shù)量。如按天分區(qū),當(dāng)每天的數(shù)據(jù)量差異很大時,可以通過指定分區(qū)的分桶數(shù),合理劃分不同分區(qū)的數(shù)據(jù),分桶列建議選擇區(qū)分度大的列。

4.3.4.2.4、多列分區(qū)
4.3.4.3、PROPERTIES

在建表語句的最后 PROPERTIES 中,可以指定以下兩個參數(shù):

4.3.4.3.1 replication_num

每個 Tablet 的副本數(shù)量。默認(rèn)為 3,建議保持默認(rèn)即可。在建表語句中,所有 Partition 中的 Tablet 副本數(shù)量統(tǒng)一指定。而在增加新分區(qū)時,可以單獨(dú)指定新分區(qū)中 Tablet 的副本數(shù)量。
副本數(shù)量可以在運(yùn)行時修改。強(qiáng)烈建議保持奇數(shù)。
最大副本數(shù)量取決于集群中獨(dú)立 IP 的數(shù)量(注意不是 BE 數(shù)量)。Doris 中副本分布的原則是,不允許同一個 Tablet 的副本分布在同一臺物理機(jī)上,而識別物理機(jī)即通過 IP。所以,即使在同一臺物理機(jī)上部署了 3 個或更多 BE 實(shí)例,如果這些 BE 的 IP 相同,則依然只能設(shè)置副本數(shù)為 1。
對于一些小,并且更新不頻繁的維度表,可以考慮設(shè)置更多的副本數(shù)。這樣在 Join 查詢時,可以有更大的概率進(jìn)行本地數(shù)據(jù) Join。

4.3.4.3.2、storage_medium & storage_cooldown_time

BE 的數(shù)據(jù)存儲目錄可以顯式的指定為 SSD 或者 HDD(通過 .SSD 或者 .HDD 后綴區(qū)分)。建表時,可以統(tǒng)一指定所有 Partition 初始存儲的介質(zhì)。注意,后綴作用是顯式指定磁盤介質(zhì),而不會檢查是否與實(shí)際介質(zhì)類型相符。
默認(rèn)初始存儲介質(zhì)可通過 fe 的配置文件 fe.conf 中指定 default_storage_medium=xxx,如果沒有指定,則默認(rèn)為 HDD。如果指定為 SSD,則數(shù)據(jù)初始存放在 SSD 上。
如果沒有指定 storage_cooldown_time,則默認(rèn) 30 天后,數(shù)據(jù)會從 SSD 自動遷移到 HDD 上。如果指定了 storage_cooldown_time,則在到達(dá)storage_cooldown_time 時間后,數(shù)據(jù)才會遷移。

注意,當(dāng)指定 storage_medium 時,如果 FE 參數(shù)enable_strict_storage_medium_check 為False 該參數(shù)只是一個“盡力而為”的設(shè)置。即使集群內(nèi)沒有設(shè)置 SSD 存儲介質(zhì),也不會報錯,而是自動存儲在可用的數(shù)據(jù)目錄中。 同樣,如果 SSD 介質(zhì)不可訪問、空間不足,都可能導(dǎo)致數(shù)據(jù)初始直接存儲在其他可用介質(zhì)上。而數(shù)據(jù)到期遷移到 HDD 時,如果 HDD 介質(zhì)不 可 訪 問 、 空 間 不 足 , 也 可 能 遷 移 失 敗 ( 但 是 會 不 斷 嘗 試 ) 。 如 果 FE 參 數(shù)enable_strict_storage_medium_check 為 True 則當(dāng)集群內(nèi)沒有設(shè)置 SSD 存儲介質(zhì)時,會報錯Failed to find enough host in all backends with storage medium is SSD。

4.3.4.4、ENGINE

本示例中,ENGINE 的類型是 olap,即默認(rèn)的 ENGINE 類型。在 Doris 中,只有這個ENGINE 類型是由 Doris 負(fù)責(zé)數(shù)據(jù)管理和存儲的。其他 ENGINE 類型,如 mysql、broker、es 等等,本質(zhì)上只是對外部其他數(shù)據(jù)庫或系統(tǒng)中的表的映射,以保證 Doris 可以讀取這些數(shù)據(jù)。而 Doris 本身并不創(chuàng)建、管理和存儲任何非 olap ENGINE 類型的表和數(shù)據(jù)。

4.3.5 數(shù)據(jù)模型

Doris 的數(shù)據(jù)模型主要分為 3 類:Aggregate、Uniq、Duplicate

4.3.5.1 Aggregate 模型

表中的列按照是否設(shè)置了 AggregationType,分為 Key(維度列)和 Value(指標(biāo)列)。沒有設(shè)置 AggregationType 的稱為 Key,設(shè)置了 AggregationType 的稱為 Value。
當(dāng)我們導(dǎo)入數(shù)據(jù)時,對于 Key 列相同的行會聚合成一行,而 Value 列會按照設(shè)置的AggregationType 進(jìn)行聚合。AggregationType 目前有以下四種聚合方式:
? SUM:求和,多行的 Value 進(jìn)行累加。
? REPLACE:替代,下一批數(shù)據(jù)中的 Value 會替換之前導(dǎo)入過的行中的 Value。
REPLACE_IF_NOT_NULL :當(dāng)遇到 null 值則不更新。
? MAX:保留最大值。
? MIN:保留最小值。
數(shù)據(jù)的聚合,在 Doris 中有如下三個階段發(fā)生:
(1)每一批次數(shù)據(jù)導(dǎo)入的 ETL 階段。該階段會在每一批次導(dǎo)入的數(shù)據(jù)內(nèi)部進(jìn)行聚合。
(2)底層 BE 進(jìn)行數(shù)據(jù) Compaction 的階段。該階段,BE 會對已導(dǎo)入的不同批次的數(shù)據(jù)進(jìn)行進(jìn)一步的聚合。
(3)數(shù)據(jù)查詢階段。在數(shù)據(jù)查詢時,對于查詢涉及到的數(shù)據(jù),會進(jìn)行對應(yīng)的聚合。數(shù)據(jù)在不同時間,可能聚合的程度不一致。比如一批數(shù)據(jù)剛導(dǎo)入時,可能還未與之前已存在的數(shù)據(jù)進(jìn)行聚合。但是對于用戶而言,用戶只能查詢到聚合后的數(shù)據(jù)。即不同的聚合程度對于用戶查詢而言是透明的。用戶需始終認(rèn)為數(shù)據(jù)以最終的完成的聚合程度存在,而不應(yīng)假設(shè)某些聚合還未發(fā)生。(可參閱聚合模型的局限性一節(jié)獲得更多詳情。)
3.5.1.1 示例一:導(dǎo)入數(shù)據(jù)聚合
1)建表

CREATE TABLE IF NOT EXISTS test_db.example_site_visit
(
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `date` DATE NOT NULL COMMENT "數(shù)據(jù)灌入日期時間",
 `city` VARCHAR(20) COMMENT "用戶所在城市",
 `age` SMALLINT COMMENT "用戶年齡",
 `sex` TINYINT COMMENT "用戶性別",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 
00:00:00" COMMENT "用戶最后一次訪問時間",
 `last_visit_date_not_null` DATETIME REPLACE_IF_NOT_NULL DEFAULT 
"1970-01-01 00:00:00" COMMENT "用戶最后一次訪問時間",
 `cost` BIGINT SUM DEFAULT "0" COMMENT "用戶總消費(fèi)",
 `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用戶最大停留時間",
 `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用戶最小停留時
間"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;

?

2)插入數(shù)據(jù)

insert into test_db.example_site_visit values\
(10000,'2017-10-01','北京',20,0,'2017-10-01 06:00:00','2017-10-01 
06:00:00',20,10,10),\
(10000,'2017-10-01','北京',20,0,'2017-10-01 07:00:00','2017-10-01 
07:00:00',15,2,2),\
(10001,'2017-10-01','北京',30,1,'2017-10-01 17:05:45','2017-10-01 
07:00:00',2,22,22),\
(10002,'2017-10-02',' 上 海 ',20,1,'2017-10-02 
12:59:12',null,200,5,5),\
(10003,'2017-10-02','廣州',32,0,'2017-10-02 11:20:00','2017-10-02 
11:20:00',30,11,11),\
(10004,'2017-10-01','深圳',35,0,'2017-10-01 10:00:15','2017-10-01 
10:00:15',100,3,3),\
(10004,'2017-10-03','深圳',35,0,'2017-10-03 10:20:22','2017-10-0310:20:22',11,6,6);


?

注意:Insert into 單條數(shù)據(jù)這種操作在 Doris 里只能演示不能在生產(chǎn)使用,會引發(fā)寫阻塞.
3)查看表

select * from test_db.example_site_visit;

可以看到,用戶 10000 只剩下了一行聚合后的數(shù)據(jù)。而其余用戶的數(shù)據(jù)和原始數(shù)據(jù)保持一致。經(jīng)過聚合,Doris 中最終只會存儲聚合后的數(shù)據(jù)。換句話說,即明細(xì)數(shù)據(jù)會丟失,用戶不能夠再查詢到聚合前的明細(xì)數(shù)據(jù)了。

4.3.5.1.2 示例二:保留明細(xì)數(shù)據(jù)

1)建表

CREATE TABLE IF NOT EXISTS test_db.example_site_visit2
(
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `date` DATE NOT NULL COMMENT "數(shù)據(jù)灌入日期時間",
 `timestamp` DATETIME COMMENT "數(shù)據(jù)灌入時間,精確到秒",
 `city` VARCHAR(20) COMMENT "用戶所在城市",
 `age` SMALLINT COMMENT "用戶年齡",
 `sex` TINYINT COMMENT "用戶性別",
 `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 
00:00:00" COMMENT "用戶最后一次訪問時間",
 `cost` BIGINT SUM DEFAULT "0" COMMENT "用戶總消費(fèi)",
 `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用戶最大停留時間",
 `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用戶最小停留時
間"
)
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;

?

2)插入數(shù)據(jù)

insert into test_db.example_site_visit2 values(10000,'2017-10-
01','2017-10-01 08:00:05',' 北 京 ',20,0,'2017-10-01 
06:00:00',20,10,10),\
(10000,'2017-10-01','2017-10-01 09:00:05','北京',20,0,'2017-10-01 
07:00:00',15,2,2),\
(10001,'2017-10-01','2017-10-01 18:12:10','北京',30,1,'2017-10-01 
17:05:45',2,22,22),\
(10002,'2017-10-02','2017-10-02 13:10:00','上海',20,1,'2017-10-02 
12:59:12',200,5,5),\
(10003,'2017-10-02','2017-10-02 13:15:00','廣州',32,0,'2017-10-02 
11:20:00',30,11,11),\
(10004,'2017-10-01','2017-10-01 12:12:48','深圳',35,0,'2017-10-01 
10:00:15',100,3,3),\
(10004,'2017-10-03','2017-10-03 12:38:20','深圳',35,0,'2017-10-03 
10:20:22',11,6,6);

3)查看表

select * from test_db.example_site_visit2;

存儲的數(shù)據(jù),和導(dǎo)入數(shù)據(jù)完全一樣,沒有發(fā)生任何聚合。這是因?yàn)?,這批數(shù)據(jù)中,因?yàn)榧尤肓?timestamp 列,所有行的 Key 都不完全相同。也就是說,只要保證導(dǎo)入的數(shù)據(jù)中,每一行的 Key 都不完全相同,那么即使在聚合模型下,Doris 也可以保存完整的明細(xì)數(shù)據(jù)。

4.3.5.1.3 示例三:導(dǎo)入數(shù)據(jù)與已有數(shù)據(jù)聚合

1)往實(shí)例一中繼續(xù)插入數(shù)據(jù)

insert into test_db.example_site_visit values(10004,'2017-10-03','
深圳',35,0,'2017-10-03 11:22:00',null,44,19,19),\
(10005,'2017-10-03','長沙',29,1,'2017-10-03 18:11:02','2017-10-03 
18:11:02',3,1,1);

2)查看表

select * from test_db.example_site_visit;

可以看到,用戶 10004 的已有數(shù)據(jù)和新導(dǎo)入的數(shù)據(jù)發(fā)生了聚合。同時新增了 10005 用戶的數(shù)據(jù)。

4.3.5.2 Uniq 模型

在某些多維分析場景下,用戶更關(guān)注的是如何保證 Key 的唯一性,即如何獲得 Primary Key 唯一性約束。因此,我們引入了 Uniq 的數(shù)據(jù)模型。該模型本質(zhì)上是聚合模型的一個特例,也是一種簡化的表結(jié)構(gòu)表示方式。
1)建表

CREATE TABLE IF NOT EXISTS test_db.user
(
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `username` VARCHAR(50) NOT NULL COMMENT "用戶昵稱",
 `city` VARCHAR(20) COMMENT "用戶所在城市",
 `age` SMALLINT COMMENT "用戶年齡",
 `sex` TINYINT COMMENT "用戶性別",
 `phone` LARGEINT COMMENT "用戶電話",
 `address` VARCHAR(500) COMMENT "用戶地址",
 `register_time` DATETIME COMMENT "用戶注冊時間"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;

2)插入數(shù)據(jù)

insert into test_db.user values\
(10000,'wuyanzu',' 北 京 ',18,0,12345678910,' 北 京 朝 陽 區(qū) ','2017-10-01 
07:00:00'),\
(10000,'wuyanzu',' 北 京 ',19,0,12345678910,' 北 京 朝 陽 區(qū) ','2017-10-01 
07:00:00'),\
(10000,'zhangsan','北京',20,0,12345678910,'北京海淀區(qū)','2017-11-15 
06:10:20');

3)查詢表

select * from test_db.user;

Uniq 模型完全可以用聚合模型中的 REPLACE 方式替代。其內(nèi)部的實(shí)現(xiàn)方式和數(shù)據(jù)存儲方式也完全一樣.

4.3.5.3 Duplicate 模型

在某些多維分析場景下,數(shù)據(jù)既沒有主鍵,也沒有聚合需求。Duplicate 數(shù)據(jù)模型可以滿足這類需求。數(shù)據(jù)完全按照導(dǎo)入文件中的數(shù)據(jù)進(jìn)行存儲,不會有任何聚合。即使兩行數(shù)據(jù)完全相同,也都會保留。 而在建表語句中指定的 DUPLICATE KEY,只是用來指明底層數(shù)據(jù)按照那些列進(jìn)行排序。
1)建表

CREATE TABLE IF NOT EXISTS test_db.example_log
(
 `timestamp` DATETIME NOT NULL COMMENT "日志時間",
 `type` INT NOT NULL COMMENT "日志類型",
 `error_code` INT COMMENT "錯誤碼",
 `error_msg` VARCHAR(1024) COMMENT "錯誤詳細(xì)信息",
 `op_id` BIGINT COMMENT "負(fù)責(zé)人 id",
 `op_time` DATETIME COMMENT "處理時間"
)
DUPLICATE KEY(`timestamp`, `type`)
DISTRIBUTED BY HASH(`timestamp`) BUCKETS 10;

2)插入數(shù)據(jù)

insert into test_db.example_log values\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01 
08:00:05'),\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01 
08:00:05'),\
('2017-10-01 08:00:05',2,404,'not found page', 101, '2017-10-01 
08:00:06'),\
('2017-10-01 08:00:06',2,404,'not found page', 101, '2017-10-01 
08:00:07');

3)查看表

select * from test_db.example_log;

4.3.5.4 數(shù)據(jù)模型的選擇建議

因?yàn)閿?shù)據(jù)模型在建表時就已經(jīng)確定,且無法修改。所以,選擇一個合適的數(shù)據(jù)模型非常重要。
(1)Aggregate 模型可以通過預(yù)聚合,極大地降低聚合查詢時所需掃描的數(shù)據(jù)量和查詢的計(jì)算量,非常適合有固定模式的報表類查詢場景。但是該模型對 count(*) 查詢很不友好。同時因?yàn)楣潭?Value 列上的聚合方式,在進(jìn)行其他類型的聚合查詢時,需要考慮語意正確性。
(2)Uniq 模型針對需要唯一主鍵約束的場景,可以保證主鍵唯一性約束。但是無法利用 ROLLUP 等預(yù)聚合帶來的查詢優(yōu)勢(因?yàn)楸举|(zhì)是 REPLACE,沒有 SUM 這種聚合方式)。
(3)Duplicate 適合任意維度的 Ad-hoc 查詢。雖然同樣無法利用預(yù)聚合的特性,但是不受聚合模型的約束,可以發(fā)揮列存模型的優(yōu)勢(只讀取相關(guān)列,而不需要讀取所有 Key 列)
3.5.5 聚合模型的局限性
這里我們針對 Aggregate 模型(包括 Uniq 模型),來介紹下聚合模型的局限性。
在聚合模型中,模型對外展現(xiàn)的,是最終聚合后的數(shù)據(jù)。也就是說,任何還未聚合的數(shù)據(jù)(比如說兩個不同導(dǎo)入批次的數(shù)據(jù)),必須通過某種方式,以保證對外展示的一致性。我們舉例說明。
假設(shè)表結(jié)構(gòu)如下:

ColumnName Type AggregationType Comment
user_id LARGEINT 用戶 id
date DATE 數(shù)據(jù)灌入日期
cost BIGINT SUM 用戶總消費(fèi)

假設(shè)存儲引擎中有如下兩個已經(jīng)導(dǎo)入完成的批次的數(shù)據(jù):
batch 1

user_id date cost
10001 2017-11-20 50
10002 2017-11-21 39

batch 2

user_id date cost
10001 2017-11-20 1
10001 2017-11-21 5
10003 2017-11-22 22

可以看到,用戶 10001 分屬在兩個導(dǎo)入批次中的數(shù)據(jù)還沒有聚合。但是為了保證用戶只能查詢到如下最終聚合后的數(shù)據(jù):

user_id date cost
10001 2017-11-20 51
10001 2017-11-21 5
10002 2017-11-21 39
10003 2017-11-22 22

在查詢引擎中加入了聚合算子,來保證數(shù)據(jù)對外的一致性。

另外,在聚合列(Value)上,執(zhí)行與聚合類型不一致的聚合類查詢時,要注意語意。比如我們在如上示例中執(zhí)行如下查詢:

SELECT MIN(cost) FROM table;

得到的結(jié)果是 5,而不是 1。

同時,這種一致性保證,在某些查詢中,會極大的降低查詢效率。

我們以最基本的 count(*) 查詢?yōu)槔?/p>

SELECT COUNT(*) FROM table;

在其他數(shù)據(jù)庫中,這類查詢都會很快的返回結(jié)果。因?yàn)樵趯?shí)現(xiàn)上,我們可以通過如“導(dǎo)入時對行進(jìn)行計(jì)數(shù),保存 count 的統(tǒng)計(jì)信息”,或者在查詢時“僅掃描某一列數(shù)據(jù),獲得 count值”的方式,只需很小的開銷,即可獲得查詢結(jié)果。但是在 Doris 的聚合模型中,這種查詢開銷非常大。

上面的例子,select count(*) from table; 的正確結(jié)果應(yīng)該為 4。但如果我們只掃描 user_id 這一列,如果加上查詢時聚合,最終得到的結(jié)果是 3(10001, 10002, 10003)。而如果不加查詢時聚合,則得到的結(jié)果是 5(兩批次一共 5 行數(shù)據(jù))??梢娺@兩個結(jié)果都是不對的。

為了得到正確的結(jié)果,我們必須同時讀取 user_id 和 date 這兩列的數(shù)據(jù),再加上查詢時聚合,才能返回 4 這個正確的結(jié)果。也就是說,在 count() 查詢中,Doris 必須掃描所有的AGGREGATE KEY 列(這里就是 user_id 和 date),并且聚合后,才能得到語意正確的結(jié)果。當(dāng)聚合列非常多時,count()查詢需要掃描大量的數(shù)據(jù)。

因此,當(dāng)業(yè)務(wù)上有頻繁的 count() 查詢時,我們建議用戶通過增加一個值恒為 1 的,聚合類型為 SUM 的列來模擬 count()。如剛才的例子中的表結(jié)構(gòu),我們修改如下:

ColumnName Type AggregateType Comment
user_id BIGINT 用戶 id
date DATE 數(shù)據(jù)灌入日期
cost BIGINT SUM 用戶總消費(fèi)
count BIGINT SUM 用于計(jì)算 count

增加一個 count 列,并且導(dǎo)入數(shù)據(jù)中,該列值恒為 1。則 select count() from table; 的結(jié)果等價于 select sum(count) from table;。而后者的查詢效率將遠(yuǎn)高于前者。不過這種方式也有使用限制,就是用戶需要自行保證,不會重復(fù)導(dǎo)入 AGGREGATE KEY 列都相同的行。否則,select sum(count) from table; 只能表述原始導(dǎo)入的行數(shù),而不是 select count() from table; 的語義。

另一種方式,就是 將如上的 count 列的聚合類型改為 REPLACE,且依然值恒為 1。那么 select sum(count) from table; 和 select count(*) from table; 的結(jié)果將是一致的。并且這種方式,沒有導(dǎo)入重復(fù)行的限制。

4.3.6 動態(tài)分區(qū)

動態(tài)分區(qū)是在 Doris 0.12 版本中引入的新功能。旨在對表級別的分區(qū)實(shí)現(xiàn)生命周期管理(TTL),減少用戶的使用負(fù)擔(dān)。

目前實(shí)現(xiàn)了動態(tài)添加分區(qū)及動態(tài)刪除分區(qū)的功能。動態(tài)分區(qū)只支持 Range 分區(qū)。

4.3.6.1 原理

在某些使用場景下,用戶會將表按照天進(jìn)行分區(qū)劃分,每天定時執(zhí)行例行任務(wù),這時需要使用方手動管理分區(qū),否則可能由于使用方?jīng)]有創(chuàng)建分區(qū)導(dǎo)致數(shù)據(jù)導(dǎo)入失敗,這給使用方帶來了額外的維護(hù)成本。

通過動態(tài)分區(qū)功能,用戶可以在建表時設(shè)定動態(tài)分區(qū)的規(guī)則。FE 會啟動一個后臺線程,根據(jù)用戶指定的規(guī)則創(chuàng)建或刪除分區(qū)。用戶也可以在運(yùn)行時對現(xiàn)有規(guī)則進(jìn)行變更。

4.3.6.2 使用方式

動態(tài)分區(qū)的規(guī)則可以在建表時指定,或者在運(yùn)行時進(jìn)行修改。當(dāng)前僅支持對單分區(qū)列的分區(qū)表設(shè)定動態(tài)分區(qū)規(guī)則。
建表時指定:

CREATE TABLE tbl1
(...)
PROPERTIES
(
 "dynamic_partition.prop1" = "value1",
 "dynamic_partition.prop2" = "value2",
 ...
)

運(yùn)行時修改

ALTER TABLE tbl1 SET
(
 "dynamic_partition.prop1" = "value1",
 "dynamic_partition.prop2" = "value2",
  ...
)
4.3.6.3 動態(tài)分區(qū)規(guī)則參數(shù)
4.3.6.3.1 主要參數(shù)

動態(tài)分區(qū)的規(guī)則參數(shù)都以 dynamic_partition. 為前綴:

dynamic_partition.enable 是否開啟動態(tài)分區(qū)特性,可指定 true 或 false,默認(rèn)為 true
dynamic_partition.time_unit 動態(tài)分區(qū)調(diào)度的單位,可指定 HOUR、DAY、WEEK、MONTH。HOUR,后綴格式為 yyyyMMddHH,分區(qū)列數(shù)據(jù)類型不能為DATE。DAY,后綴格式為 yyyyMMdd。WEEK,后綴格式為 yyyy_ww。即當(dāng)前日期屬于這一年的第幾周。MONTH,后綴格式為 yyyyMM。
dynamic_partition.time_zone 動態(tài)分區(qū)的時區(qū),如果不填寫,則默認(rèn)為當(dāng)前機(jī)器的系統(tǒng)的時區(qū)
dynamic_partition.start 動態(tài)分區(qū)的起始偏移,為負(fù)數(shù)。根據(jù) time_unit 屬性的不同,以當(dāng)天(星期/月)為基準(zhǔn),分區(qū)范圍在此偏移之前的分區(qū)將會被刪除。如果不填寫默認(rèn)值為 Interger.Min_VALUE 即-2147483648,即不刪除歷史分區(qū)
dynamic_partition.end 動態(tài)分區(qū)的結(jié)束偏移,為正數(shù)。根據(jù) time_unit 屬性的不同,以當(dāng)天(星期/月)為基準(zhǔn),提前創(chuàng)建對應(yīng)范圍的分區(qū)
dynamic_partition.prefix 動態(tài)創(chuàng)建的分區(qū)名前綴
dynamic_partition.buckets 動態(tài)創(chuàng)建的分區(qū)所對應(yīng)分桶數(shù)量
dynamic_partition.replication_num 動態(tài)創(chuàng)建的分區(qū)所對應(yīng)的副本數(shù)量,如果不填寫,則默認(rèn)為該表創(chuàng)建時指定的副本數(shù)量。
dynamic_partition.start_day_of_week 當(dāng) time_unit 為 WEEK 時,該參數(shù)用于指定每周的起始點(diǎn)。取值為 1 到 7。其中 1 表示周一,7 表示周日。默認(rèn)為 1,即表示每周以周一為起始點(diǎn)
dynamic_partition.start_day_of_month 當(dāng) time_unit 為 MONTH 時,該參數(shù)用于指定每月的起始日期。取值為 1 到 28。其中 1 表示每月 1 號,28 表示每月 28 號。默認(rèn)為 1,即表示每月以 1 號位起始點(diǎn)。暫不支持以 29、30、31 號為起始日,以避免因閏年或閏月帶來的歧義
4.3.6.3.2 創(chuàng)建歷史分區(qū)的參數(shù)

? dynamic_partition.create_history_partition
默認(rèn)為 false。當(dāng)置為 true 時,Doris 會自動創(chuàng)建所有分區(qū),當(dāng)期望創(chuàng)建的分區(qū)個數(shù)大于 max_dynamic_partition_num 值時,操作將被禁止。當(dāng)不指定 start 屬性時,該參數(shù)不生效。
? dynamic_partition.history_partition_num
當(dāng) create_history_partition 為 true 時,該參數(shù)用于指定創(chuàng)建歷史分區(qū)數(shù)量。默認(rèn)值為 -1, 即未設(shè)置。

? dynamic_partition.hot_partition_num
指定最新的多少個分區(qū)為熱分區(qū)。對于熱分區(qū),系統(tǒng)會自動設(shè)置其 storage_medium 參數(shù)為 SSD,并且設(shè)置 storage_cooldown_time。

hot_partition_num 是往前 n 天和未來所有分區(qū)

我們舉例說明。假設(shè)今天是 2021-05-20,按天分區(qū),動態(tài)分區(qū)的屬性設(shè)置為:
hot_partition_num=2, end=3, start=-3。則系統(tǒng)會自動創(chuàng)建以下分區(qū),并且設(shè)置 storage_medium 和 storage_cooldown_time 參數(shù):

p20210517 : ["2021-05-17", "2021-05-18") storage_medium=HDD 
storage_cooldown_time=9999-12-31 23:59:59
p20210518 : ["2021-05-18", "2021-05-19") storage_medium=HDD 
storage_cooldown_time=9999-12-31 23:59:59
p20210519 : ["2021-05-19", "2021-05-20") storage_medium=SSD 
storage_cooldown_time=2021-05-21 00:00:00
p20210520 : ["2021-05-20", "2021-05-21") storage_medium=SSD 
storage_cooldown_time=2021-05-22 00:00:00
p20210521 : ["2021-05-21", "2021-05-22") storage_medium=SSD 
storage_cooldown_time=2021-05-23 00:00:00
p20210522 : ["2021-05-22", "2021-05-23") storage_medium=SSD 
storage_cooldown_time=2021-05-24 00:00:00
p20210523 : ["2021-05-23", "2021-05-24") storage_medium=SSD 
storage_cooldown_time=2021-05-25 00:00:00

? dynamic_partition.reserved_history_periods
需要保留的歷史分區(qū)的時間范圍。當(dāng) dynamic_partition.time_unit 設(shè)置為
“DAY/WEEK/MONTH” 時,需要以 [yyyy-MM-dd,yyyy-MM-dd],[…,…] 格式進(jìn)行設(shè)置。當(dāng)dynamic_partition.time_unit 設(shè)置為 “HOUR” 時,需要以 [yyyy-MM-dd HH:mm:ss,yyyyMM-dd HH:mm:ss],[…,…] 的格式來進(jìn)行設(shè)置。如果不設(shè)置,默認(rèn)為 “NULL”。

我們舉例說明。假設(shè)今天是 2021-09-06,按天分類,動態(tài)分區(qū)的屬性設(shè)置為:

time_unit=“DAY/WEEK/MONTH”, \ end=3, \ start=-3,
reserved_history_periods=“[2020-06-01,2020-06-20],[2020-10-
31,2020-11-15]”。

則系統(tǒng)會自動保留:

[“2020-06-01”,“2020-06-20”], [“2020-10-31”,“2020-11-15”]

或者

time_unit=“HOUR”, \ end=3, \ start=-3,
reserved_history_periods=“[2020-06-01 00:00:00,2020-06-01 03:00:00]”.

則系統(tǒng)會自動保留:

[“2020-06-01 00:00:00”,“2020-06-01 03:00:00”]

這兩個時間段的分區(qū)。其中,reserved_history_periods 的每一個 […,…] 是一對設(shè)置項(xiàng),兩者需要同時被設(shè)置,且第一個時間不能大于第二個時間``。

4.3.6.3.3 創(chuàng)建歷史分區(qū)規(guī)則

假設(shè)需要創(chuàng)建的歷史分區(qū)數(shù)量為 expect_create_partition_num,根據(jù)不同的設(shè)置具體數(shù)量如下:
(1)create_history_partition = true
① dynamic_partition.history_partition_num 未設(shè)置,即 -1.
則 expect_create_partition_num = end - start;
② dynamic_partition.history_partition_num 已設(shè)置
則 expect_create_partition_num = end - max(start, -histoty_partition_num);
(2)create_history_partition = false
不會創(chuàng)建歷史分區(qū),expect_create_partition_num = end - 0;
(3)當(dāng) expect_create_partition_num > max_dynamic_partition_num(默認(rèn) 500)時,禁止創(chuàng)建過多分區(qū)。

4.3.6.3.4 創(chuàng)建歷史分區(qū)舉例

假設(shè)今天是 2021-05-20,按天分區(qū),動態(tài)分區(qū)的屬性設(shè)置為:create_history_partition=true, end=3, start=-3, history_partition_num=1,則系統(tǒng)會自動創(chuàng)建以下分區(qū):
p20210519
p20210520
p20210521
p20210522
p20210523
history_partition_num=5,其余屬性與 1 中保持一直,則系統(tǒng)會自動創(chuàng)建以下分區(qū):
p20210517
p20210518
p20210519
p20210520
p20210521
p20210522
p20210523
history_partition_num=-1 即不設(shè)置歷史分區(qū)數(shù)量,其余屬性與 1 中保持一直,則系統(tǒng)
會自動創(chuàng)建以下分區(qū):
p20210517
p20210518
p20210519
p20210520
p20210521
p20210522
p20210523

4.3.6.3.5 注意事項(xiàng)

動 態(tài) 分 區(qū) 使 用 過 程 中 , 如 果 因 為 一 些 意 外 情 況 導(dǎo) 致 dynamic_partition.start 和
dynamic_partition.end 之間的某些分區(qū)丟失,那么當(dāng)前時間與 dynamic_partition.end 之間的
丟失分區(qū)會被重新創(chuàng)建,dynamic_partition.start 與當(dāng)前時間之間的丟失分區(qū)不會重新創(chuàng)建。

4.3.6.4 示例

1)創(chuàng)建動態(tài)分區(qū)表
分區(qū)列 time 類型為 DATE,創(chuàng)建一個動態(tài)分區(qū)規(guī)則。按天分區(qū),只保留最近 7 天的分
區(qū),并且預(yù)先創(chuàng)建未來 3 天的分區(qū)。

create table student_dynamic_partition1
(id int,
time date,
name varchar(50),
age int
)
duplicate key(id,time)
PARTITION BY RANGE(time)()
DISTRIBUTED BY HASH(id) buckets 10
PROPERTIES(
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-7",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "10",
"replication_num" = "1"
);

?

2)查看動態(tài)分區(qū)表調(diào)度情況

SHOW DYNAMIC PARTITION TABLES;

? LastUpdateTime: 最后一次修改動態(tài)分區(qū)屬性的時間
? LastSchedulerTime: 最后一次執(zhí)行動態(tài)分區(qū)調(diào)度的時間
? State: 最后一次執(zhí)行動態(tài)分區(qū)調(diào)度的狀態(tài)
? LastCreatePartitionMsg: 最后一次執(zhí)行動態(tài)添加分區(qū)調(diào)度的錯誤信息
? LastDropPartitionMsg: 最后一次執(zhí)行動態(tài)刪除分區(qū)調(diào)度的錯誤信息
3)查看表的分區(qū)

SHOW PARTITIONS FROM student_dynamic_partition1;

4)插入測試數(shù)據(jù),可以全部成功(修改成對應(yīng)時間)

insert into student_dynamic_partition1 values(1,'2022-03-3111:00:00','name1',18);
insert into student_dynamic_partition1 values(1,'2022-04-01
11:00:00','name1',18);
insert into student_dynamic_partition1 values(1,'2022-04-02 
11:00:00','name1',18);

5)設(shè)置創(chuàng)建歷史分區(qū)

ALTER TABLE student_dynamic_partition1 SET 
("dynamic_partition.create_history_partition" = "true");

查看分區(qū)情況

SHOW PARTITIONS FROM student_dynamic_partition1;

6)動態(tài)分區(qū)表與手動分區(qū)表相互轉(zhuǎn)換
對于一個表來說,動態(tài)分區(qū)和手動分區(qū)可以自由轉(zhuǎn)換,但二者不能同時存在,有且只有一種狀態(tài)。
(1)手動分區(qū)轉(zhuǎn)換為動態(tài)分區(qū)
如果一個表在創(chuàng)建時未指定動態(tài)分區(qū),可以通過 ALTER TABLE 在運(yùn)行時修改動態(tài)分區(qū)相關(guān)屬性來轉(zhuǎn)化為動態(tài)分區(qū),具體示例可以通過 HELP ALTER TABLE 查看。
注意:如果已設(shè)定 dynamic_partition.start,分區(qū)范圍在動態(tài)分區(qū)起始偏移之前的歷史分區(qū)將會被刪除。
(2)動態(tài)分區(qū)轉(zhuǎn)換為手動分區(qū)

ALTER TABLE tbl_name SET ("dynamic_partition.enable" = "false") 

關(guān)閉動態(tài)分區(qū)功能后,Doris 將不再自動管理分區(qū),需要用戶手動通過 ALTER TABLE 的方式創(chuàng)建或刪除分區(qū)。

4.3.7 Rollup

ROLLUP 在多維分析中是“上卷”的意思,即將數(shù)據(jù)按某種指定的粒度進(jìn)行進(jìn)一步聚合。

4.3.7.1 基本概念

在 Doris 中,我們將用戶通過建表語句創(chuàng)建出來的表稱為 Base 表(Base Table)。Base 表中保存著按用戶建表語句指定的方式存儲的基礎(chǔ)數(shù)據(jù)。

在 Base 表之上,我們可以創(chuàng)建任意多個 ROLLUP 表。這些 ROLLUP 的數(shù)據(jù)是基于 Base 表產(chǎn)生的,并且在物理上是獨(dú)立存儲的。

ROLLUP 表的基本作用,在于在 Base 表的基礎(chǔ)上,獲得更粗粒度的聚合數(shù)據(jù)。

4.3.7.2 Aggregate 和 Uniq 模型中的 ROLLUP

因?yàn)?Uniq 只是 Aggregate 模型的一個特例,所以這里我們不加以區(qū)別。
1)以 4.3.5.1.2 中創(chuàng)建的 example_site_visit2 表為例。
(1)查看表的結(jié)構(gòu)信息

desc example_site_visit2 all;

(2)比如需要查看某個用戶的總消費(fèi),那么可以建立一個只有 user_id 和 cost 的 rollup

alter table example_site_visit2 add rollup 
rollup_cost_userid(user_id,cost);

(3)查看表的結(jié)構(gòu)信息

desc example_site_visit2 all;

(4)然后可以通過 explain 查看執(zhí)行計(jì)劃,是否使用到了 rollup

explain SELECT user_id, sum(cost) FROM example_site_visit2 GROUP BY 
user_id;

Doris 會自動命中這個 ROLLUP 表,從而只需掃描極少的數(shù)據(jù)量,即可完成這次聚合查詢。
(5)通過命令查看完成狀態(tài)

SHOW ALTER TABLE ROLLUP;

2)示例 2:獲得不同城市,不同年齡段用戶的總消費(fèi)、最長和最短頁面駐留時間
(1)創(chuàng)建 ROLLUP

alter table example_site_visit2 add rollup 
rollup_city_age_cost_maxd_mind(city,age,cost,max_dwell_time,min_d
well_time);

(2)查看 rollup 使用

explain SELECT city, age, sum(cost), max(max_dwell_time), 
min(min_dwell_time) FROM example_site_visit2 GROUP BY city, age;
explain SELECT city, sum(cost), max(max_dwell_time), 
min(min_dwell_time) FROM example_site_visit2 GROUP BY city;
explain SELECT city, age, sum(cost), min(min_dwell_time) FROM 
example_site_visit2 GROUP BY city, age;

(3)通過命令查看完成狀態(tài)

SHOW ALTER TABLE ROLLUP;
4.3.7.3 Duplicate 模型中的 ROLLUP

因?yàn)?Duplicate 模型沒有聚合的語意。所以該模型中的 ROLLUP,已經(jīng)失去了“上卷”
這一層含義。而僅僅是作為調(diào)整列順序,以命中前綴索引的作用。下面詳細(xì)介紹前綴索引,
以及如何使用 ROLLUP 改變前綴索引,以獲得更好的查詢效率。

4.3.7.3.1 前綴索引

不同于傳統(tǒng)的數(shù)據(jù)庫設(shè)計(jì),Doris 不支持在任意列上創(chuàng)建索引。Doris 這類 MPP 架構(gòu)的 OLAP 數(shù)據(jù)庫,通常都是通過提高并發(fā),來處理大量數(shù)據(jù)的。
本質(zhì)上,Doris 的數(shù)據(jù)存儲在類似 SSTable(Sorted String Table)的數(shù)據(jù)結(jié)構(gòu)中。該結(jié)構(gòu)是一種有序的數(shù)據(jù)結(jié)構(gòu),可以按照指定的列進(jìn)行排序存儲。在這種數(shù)據(jù)結(jié)構(gòu)上,以排序列作為條件進(jìn)行查找,會非常的高效。

在 Aggregate、Uniq 和 Duplicate 三種數(shù)據(jù)模型中。底層的數(shù)據(jù)存儲,是按照各自建表語句中,AGGREGATE KEY、UNIQ KEY 和 DUPLICATE KEY 中指定的列進(jìn)行排序存儲的。而前綴索引,即在排序的基礎(chǔ)上,實(shí)現(xiàn)的一種根據(jù)給定前綴列,快速查詢數(shù)據(jù)的索引方式。

我們將一行數(shù)據(jù)的前 36 個字節(jié) 作為這行數(shù)據(jù)的前綴索引。當(dāng)遇到 VARCHAR 類型時,前綴索引會直接截斷。舉例說明:
1)以下表結(jié)構(gòu)的前綴索引為 user_id(8 Bytes) + age(4 Bytes) + message(prefix 20 Bytes)。

ColumnName Type
user_id BIGINT
age INT
message VARCHAR(100)
max_dwell_time DATETIME
min_dwell_time DATETIME

2)以下表結(jié)構(gòu)的前綴索引為 user_name(20 Bytes)。即使沒有達(dá)到 36 個字節(jié),因?yàn)橛龅絍ARCHAR,所以直接截斷,不再往后繼續(xù)。

ColumnName Type
user_name VARCHAR(20)
age INT
message VARCHAR(100)
max_dwell_time DATETIME
min_dwell_time DATETIME

3)當(dāng)我們的查詢條件,是前綴索引的前綴時,可以極大的加快查詢速度。比如在第一個例子中,我們執(zhí)行如下查詢:

SELECT * FROM table WHERE user_id=1829239 and age=20;

該查詢的效率會遠(yuǎn)高于如下查詢:

SELECT * FROM table WHERE age=20;

所以在建表時,正確的選擇列順序,能夠極大地提高查詢效率。

4.3.7.3.2 ROLLUP 調(diào)整前綴索引

因?yàn)榻ū頃r已經(jīng)指定了列順序,所以一個表只有一種前綴索引。這對于使用其他不能命中前綴索引的列作為條件進(jìn)行的查詢來說,效率上可能無法滿足需求。因此,我們可以通過創(chuàng)建 ROLLUP 來人為的調(diào)整列順序。舉例說明。
Base 表結(jié)構(gòu)如下:

ColumnName Type
user_id BIGINT
age INT
message VARCHAR(100)
max_dwell_time DATETIME
min_dwell_time DATETIME

我們可以在此基礎(chǔ)上創(chuàng)建一個 ROLLUP 表:

ColumnName Type
age INT
user_id BIGINT
message VARCHAR(100)
max_dwell_time DATETIME
min_dwell_time DATETIME

可以看到,ROLLUP 和 Base 表的列完全一樣,只是將 user_id 和 age 的順序調(diào)換了。那么當(dāng)我們進(jìn)行如下查詢時:

SELECT * FROM table where age=20 and message LIKE "%error%";

會優(yōu)先選擇 ROLLUP 表,因?yàn)?ROLLUP 的前綴索引匹配度更高。

4.3.7.4 ROLLUP 的幾點(diǎn)說明

? ROLLUP 最根本的作用是提高某些查詢的查詢效率(無論是通過聚合來減少數(shù)據(jù)量,還是修改列順序以匹配前綴索引)。因此 ROLLUP 的含義已經(jīng)超出了“上卷”的范圍。這也是為什么在源代碼中,將其命名為 Materialized Index(物化索引)的原因。
? ROLLUP 是附屬于 Base 表的,可以看做是 Base 表的一種輔助數(shù)據(jù)結(jié)構(gòu)。用戶可以在 Base 表的基礎(chǔ)上,創(chuàng)建或刪除 ROLLUP,但是不能在查詢中顯式的指定查詢某ROLLUP。是否命中 ROLLUP 完全由 Doris 系統(tǒng)自動決定。
? ROLLUP 的數(shù)據(jù)是獨(dú)立物理存儲的。因此,創(chuàng)建的 ROLLUP 越多,占用的磁盤空間也就越大。同時對導(dǎo)入速度也會有影響(導(dǎo)入的 ETL 階段會自動產(chǎn)生所有
ROLLUP 的數(shù)據(jù)),但是不會降低查詢效率(只會更好)。
? ROLLUP 的數(shù)據(jù)更新與 Base 表是完全同步的。用戶無需關(guān)心這個問題。
? ROLLUP 中列的聚合方式,與 Base 表完全相同。在創(chuàng)建 ROLLUP 無需指定,也不能修改。
? 查詢能否命中 ROLLUP 的一個必要條件(非充分條件)是,查詢所涉及的所有列(包括 select list 和 where 中的查詢條件列等)都存在于該 ROLLUP 的列中。否則,查詢只能命中 Base 表。
? 某些類型的查詢(如 count(*))在任何條件下,都無法命中 ROLLUP。具體參見接下來的聚合模型的局限性一節(jié)。
? 可以通過 EXPLAIN your_sql; 命令獲得查詢執(zhí)行計(jì)劃,在執(zhí)行計(jì)劃中,查看是否命中 ROLLUP。
? 可以通過 DESC tbl_name ALL; 語句顯示 Base 表和所有已創(chuàng)建完成的 ROLLUP。

4.3.8 物化視圖

物化視圖就是包含了查詢結(jié)果的數(shù)據(jù)庫對象,可能是對遠(yuǎn)程數(shù)據(jù)的本地 copy,也可能是一個表或多表 join 后結(jié)果的行或列的子集,也可能是聚合后的結(jié)果。說白了,就是預(yù)先存儲查詢結(jié)果的一種數(shù)據(jù)庫對象。

在 Doris 中的物化視圖,就是查詢結(jié)果預(yù)先存儲起來的特殊的表。
物化視圖的出現(xiàn)主要是為了滿足用戶,既能對原始明細(xì)數(shù)據(jù)的任意維度分析,也能快速的對固定維度進(jìn)行分析查詢。

4.3.8.1 適用場景

? 分析需求覆蓋明細(xì)數(shù)據(jù)查詢以及固定維度查詢兩方面。
? 查詢僅涉及表中的很小一部分列或行。
? 查詢包含一些耗時處理操作,比如:時間很久的聚合操作等。
? 查詢需要匹配不同前綴索引。

4.3.8.2 優(yōu)勢

? 對于那些經(jīng)常重復(fù)的使用相同的子查詢結(jié)果的查詢性能大幅提升。
? Doris 自動維護(hù)物化視圖的數(shù)據(jù),無論是新的導(dǎo)入,還是刪除操作都能保證 base 表和物化視圖表的數(shù)據(jù)一致性。無需任何額外的人工維護(hù)成本。
? 查詢時,會自動匹配到最優(yōu)物化視圖,并直接從物化視圖中讀取數(shù)據(jù)。
自動維護(hù)物化視圖的數(shù)據(jù)會造成一些維護(hù)開銷,會在后面的物化視圖的局限性中展開說明。

4.3.8.3 物化視圖 VS Rollup

在沒有物化視圖功能之前,用戶一般都是使用 Rollup 功能通過預(yù)聚合方式提升查詢效率的。但是 Rollup 具有一定的局限性,他不能基于明細(xì)模型做預(yù)聚合。
物化視圖則在覆蓋了 Rollup 的功能的同時,還能支持更豐富的聚合函數(shù)。所以物化視圖其實(shí)是 Rollup 的一個超集。
也就是說,之前 ALTER TABLE ADD ROLLUP 語法支持的功能現(xiàn)在均可以通過
CREATE MATERIALIZED VIEW 實(shí)現(xiàn)。

4.3.8.4 物化視圖原理

Doris 系統(tǒng)提供了一整套對物化視圖的 DDL 語法,包括創(chuàng)建,查看,刪除。DDL 的語法和 PostgreSQL, Oracle 都是一致的。但是 Doris 目前創(chuàng)建物化視圖只能在單表操作,不支持 join.

4.3.8.4.1 創(chuàng)建物化視圖

首先要根據(jù)查詢語句的特點(diǎn)來決定創(chuàng)建一個什么樣的物化視圖。并不是說物化視圖定義和某個查詢語句一模一樣就最好。這里有兩個原則:
(1)從查詢語句中抽象出,多個查詢共有的分組和聚合方式作為物化視圖的定義。
(2)不需要給所有維度組合都創(chuàng)建物化視圖。
首先第一個點(diǎn),一個物化視圖如果抽象出來,并且多個查詢都可以匹配到這張物化視圖。
這種物化視圖效果最好。因?yàn)槲锘晥D的維護(hù)本身也需要消耗資源。
如果物化視圖只和某個特殊的查詢很貼合,而其他查詢均用不到這個物化視圖。則會導(dǎo)致這張物化視圖的性價比不高,既占用了集群的存儲資源,還不能為更多的查詢服務(wù)。
所以用戶需要結(jié)合自己的查詢語句,以及數(shù)據(jù)維度信息去抽象出一些物化視圖的定義。
第二點(diǎn)就是,在實(shí)際的分析查詢中,并不會覆蓋到所有的維度分析。所以給常用的維度組合創(chuàng)建物化視圖即可,從而到達(dá)一個空間和時間上的平衡。
通過下面命令就可以創(chuàng)建物化視圖了。創(chuàng)建物化視圖是一個異步的操作,也就是說用戶成功提交創(chuàng)建任務(wù)后,Doris 會在后臺對存量的數(shù)據(jù)進(jìn)行計(jì)算,直到創(chuàng)建成功。
具體的語法可以通過下面命令查看:HELP CREATE MATERIALIZED VIEW
這里以一個銷售記錄表為例:
doris,大數(shù)據(jù),數(shù)據(jù)庫?
比如我們有一張銷售記錄明細(xì)表,存儲了每個交易的時間,銷售員,銷售門店,和金額。
提交完創(chuàng)建物化視圖的任務(wù)后,Doris 就會異步在后臺生成物化視圖的數(shù)據(jù),構(gòu)建物化視圖。
在構(gòu)建期間,用戶依然可以正常的查詢和導(dǎo)入新的數(shù)據(jù)。創(chuàng)建任務(wù)會自動處理當(dāng)前的存量數(shù)據(jù)和所有新到達(dá)的增量數(shù)據(jù),從而保持和 base 表的數(shù)據(jù)一致性。用戶不需關(guān)心一致性問題.

4.3.8.4.2 查詢

doris,大數(shù)據(jù),數(shù)據(jù)庫?
物化視圖創(chuàng)建完成后,用戶的查詢會根據(jù)規(guī)則自動匹配到最優(yōu)的物化視圖。
比如我們有一張銷售記錄明細(xì)表,并且在這個明細(xì)表上創(chuàng)建了三張物化視圖。一個存儲了不同時間不同銷售員的售賣量,一個存儲了不同時間不同門店的銷售量,以及每個銷售員的總銷售量。
當(dāng)查詢 7 月 19 日,各個銷售員都買了多少錢的話。就可以匹配 mv_1 物化視圖。直接對 mv_1 的數(shù)據(jù)進(jìn)行查詢。

4.3.8.4.3 查詢自動匹配

doris,大數(shù)據(jù),數(shù)據(jù)庫?
物化視圖的自動匹配分為下面兩個步驟:
(1)根據(jù)查詢條件刪選出一個最優(yōu)的物化視圖:這一步的輸入是所有候選物化視圖表的元數(shù)據(jù),根據(jù)查詢的條件從候選集中輸出最優(yōu)的一個物化視圖
(2)根據(jù)選出的物化視圖對查詢進(jìn)行改寫:這一步是結(jié)合上一步選擇出的最優(yōu)物化視圖,進(jìn)行查詢的改寫,最終達(dá)到直接查詢物化視圖的目的。
doris,大數(shù)據(jù),數(shù)據(jù)庫?
其中 bitmap 和 hll 的聚合函數(shù)在查詢匹配到物化視圖后,查詢的聚合算子會根據(jù)物化視圖的表結(jié)構(gòu)進(jìn)行一個改寫。詳細(xì)見實(shí)例 2

4.3.8.4.4 最優(yōu)路徑選擇

doris,大數(shù)據(jù),數(shù)據(jù)庫?
這里分為兩個步驟:
(1)對候選集合進(jìn)行一個過濾。只要是查詢的結(jié)果能從物化視圖數(shù)據(jù)計(jì)算(取部分行,部分列,或部分行列的聚合)出都可以留在候選集中,過濾完成后候選集合大小>=1.
(2)從候選集合中根據(jù)聚合程度,索引等條件選出一個最優(yōu)的也就是查詢花費(fèi)最少物化視圖。
這里再舉一個相對復(fù)雜的例子,來體現(xiàn)這個過程:
doris,大數(shù)據(jù),數(shù)據(jù)庫?
候選集過濾目前分為 4 層,每一層過濾后去除不滿足條件的物化視圖。
比如查詢 7 月 19 日,各個銷售員都買了多少錢,候選集中包括所有的物化視圖以及 base表共 4 個:
第一層過濾先判斷查詢 where 中的謂詞涉及到的數(shù)據(jù)是否能從物化視圖中得到。也就是銷售時間列是否在表中存在。由于第三個物化視圖中根本不存在銷售時間列。所以在這一層過濾中,mv_3 就被淘汰了。

第二層是過濾查詢的分組列是否為候選集的分組列的子集。也就是銷售員 id 是否為表中分組列的子集。由于第二個物化視圖中的分組列并不涉及銷售員 id。所以在這一層過濾中,mv_2 也被淘汰了。

第三層過濾是看查詢的聚合列是否為候選集中聚合列的子集。也就是對銷售額求和是否能從候選集的表中聚合得出。這里 base 表和物化視圖表均滿足標(biāo)準(zhǔn)。
最后一層是過濾看查詢需要的列是否存在于候選集合的列中。由于候選集合中的表均滿足標(biāo)準(zhǔn),所以最終候選集合中的表為 銷售明細(xì)表,以及 mv_1,這兩張。

doris,大數(shù)據(jù),數(shù)據(jù)庫?
候選集過濾完后輸出一個集合,這個集合中的所有表都能滿足查詢的需求。但每張表的查詢效率都不同。這時候就需要再這個集合根據(jù)前綴索引是否能匹配到,以及聚合程度的高低來選出一個最優(yōu)的物化視圖。
從表結(jié)構(gòu)中可以看出,base 表的銷售日期列是一個非排序列,而物化視圖表的日期是一個排序列,同時聚合程度上 mv_1 表明顯比 base 表高。所以最后選擇出 mv_1作為該查詢的最優(yōu)匹配。
doris,大數(shù)據(jù),數(shù)據(jù)庫?
最后再根據(jù)選擇出的最優(yōu)解,改寫查詢。
剛才的查詢選中 mv_1 后,將查詢改寫為從 mv_1 中讀取數(shù)據(jù),過濾出日志為 7 月 19 日的 mv_1 中的數(shù)據(jù)然后返回即可。

4.3.8.4.5 查詢改寫

doris,大數(shù)據(jù),數(shù)據(jù)庫?

有些情況下的查詢改寫還會涉及到查詢中的聚合函數(shù)的改寫。
比如業(yè)務(wù)方經(jīng)常會用到 count distinct 對 PV UV 進(jìn)行計(jì)算。
例如;
廣告點(diǎn)擊明細(xì)記錄表中存放哪個用戶點(diǎn)擊了什么廣告,從什么渠道點(diǎn)擊的,以及點(diǎn)擊的時間。并且在這個 base 表基礎(chǔ)上構(gòu)建了一個物化視圖表,存儲了不同廣告不同渠道的用戶bitmap 值。
由于 bitmap union 這種聚合方式本身會對相同的用戶 user id 進(jìn)行一個去重聚合。當(dāng)用戶查詢廣告在 web 端的 uv 的時候,就可以匹配到這個物化視圖。匹配到這個物化視圖表后就需要對查詢進(jìn)行改寫,將之前的對用戶 id 求 count(distinct) 改為對物化視圖中 bitmap union列求 count。
所以最后查詢?nèi)∥锘晥D的第一和第三行求 bitmap 聚合中有幾個值。

4.3.8.4.6 使用及限制

doris,大數(shù)據(jù),數(shù)據(jù)庫?
(1)目前支持的聚合函數(shù)包括,常用的 sum,min,max count,以及計(jì)算 pv ,uv, 留存率,等常用的去重算法 hll_union,和用于精確去重計(jì)算 count(distinct)的算法bitmap_union。
(2)物化視圖的聚合函數(shù)的參數(shù)不支持表達(dá)式僅支持單列,比如: sum(a+b)不支持。
(3)使用物化視圖功能后,由于物化視圖實(shí)際上是損失了部分維度數(shù)據(jù)的。所以對表的 DML 類型操作會有一些限制:
如果表的物化視圖 key 中不包含刪除語句中的條件列,則刪除語句不能執(zhí)行。
比如想要刪除渠道為 app 端的數(shù)據(jù),由于存在一個物化視圖并不包含渠道這個字段,則這個刪除不能執(zhí)行,因?yàn)閯h除在物化視圖中無法被執(zhí)行。這時候你只能把物化視圖先刪除,然后刪除完數(shù)據(jù)后,重新構(gòu)建一個新的物化視圖。
(4)單表上過多的物化視圖會影響導(dǎo)入的效率:導(dǎo)入數(shù)據(jù)時,物化視圖和 base 表數(shù)據(jù)是同步更新的,如果一張表的物化視圖表超過 10 張,則有可能導(dǎo)致導(dǎo)入速度很慢。這就像單次導(dǎo)入需要同時導(dǎo)入 10 張表數(shù)據(jù)是一樣的。
(5)相同列,不同聚合函數(shù),不能同時出現(xiàn)在一張物化視圖中,比如:select sum(a), min(a) from table 不支持。
(6)物化視圖針對 Unique Key 數(shù)據(jù)模型,只能改變列順序,不能起到聚合的作用,所以在 Unique Key 模型上不能通過創(chuàng)建物化視圖的方式對數(shù)據(jù)進(jìn)行粗粒度聚合操作.

4.3.8.5 案例演示
4.3.8.5.1 案例一

1)創(chuàng)建一個 Base 表

create table sales_records(
record_id int,
 seller_id int,
 store_id int,
 sale_date date,
 sale_amt bigint
) 
distributed by hash(record_id) 
properties("replication_num" = "1");

插入數(shù)據(jù)

insert into sales_records values(1,2,3,'2020-02-02',10);

2)基于這個 Base 表的數(shù)據(jù)提交一個創(chuàng)建物化視圖的任務(wù)

create materialized view store_amt as 
select store_id, sum(sale_amt) 
from sales_records 
group by store_id;

3)檢查物化視圖是否構(gòu)建完成
由于創(chuàng)建物化視圖是一個異步的操作,用戶在提交完創(chuàng)建物化視圖任務(wù)后,需要異步的
通過命令檢查物化視圖是否構(gòu)建完成。
SHOW ALTER TABLE MATERIALIZED VIEW FROM test_db; (Version 0.13)
查看 Base 表的所有物化視圖

desc sales_records all;

4)檢驗(yàn)當(dāng)前查詢是否匹配到了合適的物化視圖

EXPLAIN SELECT store_id, sum(sale_amt) FROM sales_records GROUP BY 
store_id;

5)刪除物化視圖語法

DROP MATERIALIZED VIEW 物化視圖名 on Base 表名;
4.3.8.5.2 案例二:計(jì)算廣告的 pv、uv

假設(shè)用戶的原始廣告點(diǎn)擊數(shù)據(jù)存儲在 Doris,那么針對廣告 PV, UV 查詢就可以通過創(chuàng)建 bitmap_union 的物化視圖來提升查詢速度。
1)創(chuàng)建 base 表

create table advertiser_view_record(
time date, 
advertiser varchar(10), 
channel varchar(10), 
user_id int
) 
distributed by hash(time) 
properties("replication_num" = "1");

插入數(shù)據(jù)

insert into advertiser_view_record values('2020-02-
02','a','app',123);

2)創(chuàng)建物化視圖

create materialized view advertiser_uv as 
select advertiser, channel, bitmap_union(to_bitmap(user_id)) 
from advertiser_view_record 
group by advertiser, channel;

在 Doris 中,count(distinct) 聚合的結(jié)果和 bitmap_union_count 聚合的結(jié)果是完全一致的。而 bitmap_union_count 等于 bitmap_union 的結(jié)果求 count,所以如果查詢中涉及到count(distinct) 則通過創(chuàng)建帶 bitmap_union 聚合的物化視圖方可加快查詢。
因?yàn)楸旧?user_id 是一個 INT 類型,所以在 Doris 中需要先將字段通過函數(shù) to_bitmap 轉(zhuǎn)換為 bitmap 類型然后才可以進(jìn)行 bitmap_union 聚合。
3)查詢自動匹配

SELECT advertiser, channel, count(distinct user_id) 
FROM advertiser_view_record 
GROUP BY advertiser, channel;
  • 1
  • 2
  • 3

會自動轉(zhuǎn)換成。

SELECT advertiser, channel, bitmap_union_count(to_bitmap(user_id)) 
FROM advertiser_uv 
GROUP BY advertiser, channel;

4)檢驗(yàn)是否匹配到物化視圖

explain SELECT advertiser, channel, count(distinct user_id) FROM 
advertiser_view_record GROUP BY advertiser, channel;

在 EXPLAIN 的結(jié)果中,首先可以看到 OlapScanNode 的 rollup 屬性值為 advertiser_uv。
也就是說,查詢會直接掃描物化視圖的數(shù)據(jù)。說明匹配成功。其次對于 user_id 字段求 count(distinct)被改寫為求bitmap_union_count(to_bitmap)。也就是通過 bitmap 的方式來達(dá)到精確去重的效果。

4.3.8.5.3 案例三

用戶的原始表有(k1, k2, k3)三列。其中 k1, k2 為前綴索引列。這時候如果用戶查詢條件中包含 where k1=1 and k2=2 就能通過索引加速查詢。
但是有些情況下,用戶的過濾條件無法匹配到前綴索引,比如 where k3=3。則無法通過索引提升查詢速度。
創(chuàng)建以 k3 作為第一列的物化視圖就可以解決這個問題。
1)查詢
explain select record_id,seller_id,store_id from sales_records
where store_id=3;
2)創(chuàng)建物化視圖

create materialized view mv_1 as 
select 
 store_id,
 record_id,
 seller_id,
 sale_date,
 sale_amt
from sales_records;

通過上面語法創(chuàng)建完成后,物化視圖中既保留了完整的明細(xì)數(shù)據(jù),且物化視圖的前綴索引為 store_id 列。
3)查看表結(jié)構(gòu)

desc sales_records all;

4)查詢匹配

explain select record_id,seller_id,store_id from sales_records 
where store_id=3;

這時候查詢就會直接從剛才創(chuàng)建的 mv_1 物化視圖中讀取數(shù)據(jù)。物化視圖對 store_id是存在前綴索引的,查詢效率也會提升。

4.3.9 修改表

使用 ALTER TABLE 命令可以對表進(jìn)行修改,包括 partition 、rollup、schema change、
rename 和 index 五種。語法:

ALTER TABLE [database.]table
alter_clause1[, alter_clause2, ...];

alter_clause 分為 partition 、rollup、schema change、rename 和 index 五種。

4.3.9.1 rename

1)將名為 table1 的表修改為 table2

ALTER TABLE table1 RENAME table2;

2)將表 example_table 中名為 rollup1 的 rollup index 修改為 rollup2

ALTER TABLE example_table RENAME ROLLUP rollup1 rollup2;

3)將表 example_table 中名為 p1 的 partition 修改為 p2

ALTER TABLE example_table RENAME PARTITION p1 p2;
4.3.9.2 partition

1)增加分區(qū), 使用默認(rèn)分桶方式
現(xiàn)有分區(qū) [MIN, 2013-01-01),增加分區(qū) [2013-01-01, 2014-01-01),

ALTER TABLE example_db.my_table
ADD PARTITION p1 VALUES LESS THAN ("2014-01-01");

2)增加分區(qū),使用新的分桶數(shù)

ALTER TABLE example_db.my_table
ADD PARTITION p1 VALUES LESS THAN ("2015-01-01")
DISTRIBUTED BY HASH(k1) BUCKETS 20;

3)增加分區(qū),使用新的副本數(shù)

ALTER TABLE example_db.my_table
ADD PARTITION p1 VALUES LESS THAN ("2015-01-01")
("replication_num"="1");

4)修改分區(qū)副本數(shù)

ALTER TABLE example_db.my_table
MODIFY PARTITION p1 SET("replication_num"="1");

5)批量修改指定分區(qū)

ALTER TABLE example_db.my_table
MODIFY PARTITION (p1, p2, p4) SET("in_memory"="true");

6)批量修改所有分區(qū)

ALTER TABLE example_db.my_table
MODIFY PARTITION (*) SET("storage_medium"="HDD");

7)刪除分區(qū)

ALTER TABLE example_db.my_table
DROP PARTITION p1;

8)增加一個指定上下界的分區(qū)

ALTER TABLE example_db.my_table
ADD PARTITION p1 VALUES [("2014-01-01"), ("2014-02-01"));
4.3.9.3 rollup

1)創(chuàng)建 index: example_rollup_index,基于 base index(k1,k2,k3,v1,v2)。列式存儲。

ALTER TABLE example_db.my_table
ADD ROLLUP example_rollup_index(k1, k3, v1, v2);

2)創(chuàng)建 index: example_rollup_index2,基于 example_rollup_index(k1,k3,v1,v2)

ALTER TABLE example_db.my_table
ADD ROLLUP example_rollup_index2 (k1, v1)
FROM example_rollup_index;

3)創(chuàng)建 index: example_rollup_index3, 基于 base index (k1,k2,k3,v1), 自定義 rollup 超時時間一小時。

ALTER TABLE example_db.my_table
ADD ROLLUP example_rollup_index(k1, k3, v1)
PROPERTIES("timeout" = "3600");

4)刪除 index: example_rollup_index2

ALTER TABLE example_db.my_table
DROP ROLLUP example_rollup_index2;
4.3.9.4 表結(jié)構(gòu)變更

使用 ALTER TABLE 命令可以修改表的 Schema,包括如下修改:
? 增加列
? 刪除列
? 修改列類型
? 改變列順序
以增加列為例:
1)我們新增一列 uv,類型為 BIGINT,聚合類型為 SUM,默認(rèn)值為 0:

ALTER TABLE table1 ADD COLUMN uv BIGINT SUM DEFAULT '0' after pv;

2)提交成功后,可以通過以下命令查看作業(yè)進(jìn)度:

SHOW ALTER TABLE COLUMN;

當(dāng)作業(yè)狀態(tài)為 FINISHED,則表示作業(yè)完成。新的 Schema 已生效。
3)查看新的 Schema

DESC table1;

4)可以使用以下命令取消當(dāng)前正在執(zhí)行的作業(yè):

CANCEL ALTER TABLE ROLLUP FROM table1;

5)更多可以參閱: HELP ALTER TABLE
https://doris.apache.org/zh-CN/sql-reference/sql-statements/Data%20Definition/ALTER%20TABLE.html

4.3.10 刪除數(shù)據(jù)(Delete)

Doris 目前可以通過兩種方式刪除數(shù)據(jù):DELETE FROM 語句和 ALTER TABLE DROP
PARTITION 語句。

4.3.10.1 DELETE FROM Statement(條件刪除)

delete from 語句類似標(biāo)準(zhǔn) delete 語法,具體使用可以查看 help delete; 幫助。
語法:

DELETE FROM table_name [PARTITION partition_name]
WHERE
column_name1 op { value | value_list } [ AND column_name2 op { value 
| value_list } ...];

如:
delete from student_kafka where id=1;
注意事項(xiàng)。
(1)該語句只能針對 Partition 級別進(jìn)行刪除。如果一個表有多個 partition 含有需要刪除的數(shù)據(jù),則需要執(zhí)行多次針對不同 Partition 的 delete 語句。而如果是沒有使用Partition 的表,partition 的名稱即表名。
(2)where 后面的條件謂詞只能針對 Key 列,并且謂詞之間,只能通過 AND 連接。
如果想實(shí)現(xiàn) OR 的語義,需要執(zhí)行多條 delete。
(3)delete 是一個同步命令,命令返回即表示執(zhí)行成功。
(4)從代碼實(shí)現(xiàn)角度,delete 是一種特殊的導(dǎo)入操作。該命令所導(dǎo)入的內(nèi)容,也是一
個新的數(shù)據(jù)版本,只是該版本中只包含命令中指定的刪除條件。在實(shí)際執(zhí)行查詢時,會根據(jù)
這些條件進(jìn)行查詢時過濾。所以,不建議大量頻繁使用 delete 命令,因?yàn)檫@可能導(dǎo)致查詢
效率降低。
(5)數(shù)據(jù)的真正刪除是在 BE 進(jìn)行數(shù)據(jù) Compaction 時進(jìn)行的。所以執(zhí)行完 delete 命
令后,并不會立即釋放磁盤空間。
(6)delete 命令一個較強(qiáng)的限制條件是,在執(zhí)行該命令時,對應(yīng)的表,不能有正在進(jìn)行的導(dǎo)入任務(wù)(包括 PENDING、ETL、LOADING)。而如果有 QUORUM_FINISHED 狀態(tài)的導(dǎo)入任務(wù),則可能可以執(zhí)行。
(7)delete 也有一個隱含的類似 QUORUM_FINISHED 的狀態(tài)。即如果 delete 只在多數(shù)副本上完成了,也會返回用戶成功。但是會在后臺生成一個異步的 delete job(Async Delete Job),來繼續(xù)完成對剩余副本的刪除操作。如果此時通過 show delete 命令,可以看到這種任務(wù)在 state 一欄會顯示 QUORUM_FINISHED。

4.3.10.2 DROP PARTITION Statement(刪除分區(qū))

該命令可以直接刪除指定的分區(qū)。因?yàn)?Partition 是邏輯上最小的數(shù)據(jù)管理單元,所以使用 DROP PARTITION 命令可以很輕量的完成數(shù)據(jù)刪除工作。并且該命令不受 load 以及任何其他操作的限制,同時不會影響查詢效率。是比較推薦的一種數(shù)據(jù)刪除方式。
該命令是同步命令,執(zhí)行成功即生效。而后臺數(shù)據(jù)真正刪除的時間可能會延遲 10 分鐘左右。文章來源地址http://www.zghlxwxcb.cn/news/detail-832131.html

到了這里,關(guān)于Doris-簡介、架構(gòu)、編譯、安裝和數(shù)據(jù)表的基本使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 2.數(shù)據(jù)表的基本操作

    2.數(shù)據(jù)表的基本操作

    SQL句子中語法格式提示: 1.中括號([])中的內(nèi)容為可選項(xiàng); 2.[,...]表示,前面的內(nèi)容可重復(fù); 3.大括號({})和豎線(|)表示選擇項(xiàng),在選擇項(xiàng)中僅需選擇其中一項(xiàng); 在MySQL中創(chuàng)建數(shù)據(jù)表的基本語法格式如下: 其中, CREATE TABLE 是用于創(chuàng)建數(shù)據(jù)表的。 table_name 是您要

    2024年02月09日
    瀏覽(24)
  • 【MySQL探索之旅】數(shù)據(jù)表的基本操作(附帶思維導(dǎo)圖)

    【MySQL探索之旅】數(shù)據(jù)表的基本操作(附帶思維導(dǎo)圖)

    ??博客主頁:愛敲代碼的小楊. ?專欄:《Java SE語法》 | 《數(shù)據(jù)結(jié)構(gòu)與算法》 | 《C生萬物》 |《MySQL探索之旅》 ??感謝大家點(diǎn)贊????收藏?評論???,您的三連就是我持續(xù)更新的動力?? ??小楊水平有限,歡迎各位大佬指點(diǎn),相互學(xué)習(xí)進(jìn)步! 學(xué)習(xí)數(shù)據(jù)表的基本操作之前

    2024年04月08日
    瀏覽(22)
  • 【postgresql 基礎(chǔ)入門】數(shù)據(jù)表的查詢基本知識,條件過濾、單列多列排序、按頁瀏覽數(shù)據(jù)、數(shù)據(jù)去重,得到你想要的數(shù)據(jù)

    ? 專欄內(nèi)容 : postgresql內(nèi)核源碼分析 手寫數(shù)據(jù)庫toadb 并發(fā)編程 ? 開源貢獻(xiàn) : toadb開源庫 個人主頁 :我的主頁 管理社區(qū) :開源數(shù)據(jù)庫 座右銘:天行健,君子以自強(qiáng)不息;地勢坤,君子以厚德載物. 入門準(zhǔn)備 postgrersql基礎(chǔ)架構(gòu) 快速使用 初始化集群 數(shù)據(jù)庫服務(wù)管理 psql客戶

    2024年02月07日
    瀏覽(118)
  • SQL Server基礎(chǔ) 第三章 數(shù)據(jù)表基本操作(增刪改查,不允許保存更改異常?。? decoding=

    SQL Server基礎(chǔ) 第三章 數(shù)據(jù)表基本操作(增刪改查,不允許保存更改異常!)

    往表里插數(shù)據(jù)我們現(xiàn)在有兩種方式 第一種是編輯直接修改,第二種是通過查詢來修改數(shù)據(jù) 兩種方法的區(qū)別 第一種更直接,如果數(shù)據(jù)量小那么直接改就好了,那如果數(shù)據(jù)量稍微龐大我們就需要用新建查詢來進(jìn)行表內(nèi)容的修改了?。。。。。?! 只需要新建查詢,然后新的查詢文

    2023年04月26日
    瀏覽(30)
  • MySql數(shù)據(jù)庫的初步安裝與數(shù)據(jù)表結(jié)構(gòu)數(shù)據(jù)管理

    MySql數(shù)據(jù)庫的初步安裝與數(shù)據(jù)表結(jié)構(gòu)數(shù)據(jù)管理

    目錄 一、數(shù)據(jù)庫的相關(guān)了解 1)數(shù)據(jù)庫的概念? 數(shù)據(jù)(Data) 表 數(shù)據(jù)庫系統(tǒng) 2)數(shù)據(jù)庫系統(tǒng)發(fā)展史 第一代數(shù)據(jù)庫 第二代數(shù)據(jù)庫 第三代數(shù)據(jù)庫 當(dāng)今主流數(shù)據(jù)庫介紹 2)數(shù)據(jù)庫的分類? 關(guān)系數(shù)據(jù)庫 非關(guān)系型數(shù)據(jù)庫 非關(guān)系型數(shù)據(jù)庫的優(yōu)點(diǎn) 二、mysql的yum安裝與源碼編譯安裝?? 1)源

    2024年02月08日
    瀏覽(2721)
  • 數(shù)據(jù)庫實(shí)驗(yàn)2 創(chuàng)建數(shù)據(jù)表修改數(shù)據(jù)表和刪除數(shù)據(jù)表

    數(shù)據(jù)庫實(shí)驗(yàn)2 創(chuàng)建數(shù)據(jù)表修改數(shù)據(jù)表和刪除數(shù)據(jù)表

    實(shí)驗(yàn)2 創(chuàng)建數(shù)據(jù)表修改數(shù)據(jù)表和刪除數(shù)據(jù)表 實(shí)驗(yàn)類型: ●驗(yàn)證性實(shí)驗(yàn) ?○綜合性實(shí)驗(yàn) ?○設(shè)計(jì)性實(shí)驗(yàn) 實(shí)驗(yàn)?zāi)康模????? (1)了解數(shù)據(jù)表的結(jié)構(gòu)特點(diǎn)。 ?????(2)掌握表中列定義時所用到的各種數(shù)據(jù)類型。 ?????(3)學(xué)會使用企業(yè)管理器(即MSSMS-----Microsoft SQL?Server Manag

    2024年02月07日
    瀏覽(106)
  • oracle數(shù)據(jù)表轉(zhuǎn)換為mysql數(shù)據(jù)表

    oracle數(shù)據(jù)表轉(zhuǎn)換為mysql數(shù)據(jù)表

    oracle數(shù)據(jù)表轉(zhuǎn)換為mysql數(shù)據(jù)表,或者反過來,我們可以借助navica的工具 1.打開navicat的工具-數(shù)據(jù)傳輸 2.選擇源數(shù)據(jù)庫以及目標(biāo)數(shù)據(jù)庫 目標(biāo)可以選擇數(shù)據(jù)庫也可以選擇文件,目標(biāo)數(shù)據(jù)庫需要提前建好表,這里是選擇文件,注意選擇一個文件,sql格式即為目標(biāo)數(shù)據(jù)庫類型,這里不

    2024年02月16日
    瀏覽(18)
  • MySql基礎(chǔ)教程(三):創(chuàng)建數(shù)據(jù)表、數(shù)據(jù)增刪改查、刪除數(shù)據(jù)表

    MySql基礎(chǔ)教程(三):創(chuàng)建數(shù)據(jù)表、數(shù)據(jù)增刪改查、刪除數(shù)據(jù)表

    創(chuàng)建MySQL數(shù)據(jù)表需要以下信息: 表名 表字段名 定義每個表字段 1.1 語法 下面是創(chuàng)建MySQL數(shù)據(jù)表的SQL通用語法: 以下例子在 nobug 數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)表 nobug_user : 實(shí)例解析: 如果你不想字段為 NULL 可以設(shè)置字段的屬性為 NOT NULL, 在操作數(shù)據(jù)庫時如果輸入該字段的數(shù)據(jù)為NULL ,

    2024年02月11日
    瀏覽(90)
  • 實(shí)現(xiàn)一個MYSQL工具類,包含判斷創(chuàng)建數(shù)據(jù)表是否存在,創(chuàng)建數(shù)據(jù)表

    可以使用Python的MySQLdb模塊來實(shí)現(xiàn)一個MYSQL工具類。下面是一個簡單的實(shí)現(xiàn)示例: 使用示例: 在上面的示例中,我們首先創(chuàng)建了一個MySQLTool類,并在初始化方法中傳入了數(shù)據(jù)庫的連接信息。然后使用connect方法連接到數(shù)據(jù)庫。 table_exists方法用于判斷給定的數(shù)據(jù)表是否存在,它執(zhí)

    2024年01月15日
    瀏覽(95)
  • 【MySQL】MySQL 數(shù)據(jù)類型,數(shù)值、日期和時間、字符串類型,創(chuàng)建數(shù)據(jù)表,刪除數(shù)據(jù)表

    【MySQL】MySQL 數(shù)據(jù)類型,數(shù)值、日期和時間、字符串類型,創(chuàng)建數(shù)據(jù)表,刪除數(shù)據(jù)表

    作者簡介: 辭七七,目前大一,正在學(xué)習(xí)C/C++,Java,Python等 作者主頁: 七七的個人主頁 文章收錄專欄: 七七的閑談 歡迎大家點(diǎn)贊 ?? 收藏 ? 加關(guān)注哦!???? MySQL 中定義數(shù)據(jù)字段的類型對你數(shù)據(jù)庫的優(yōu)化是非常重要的。 MySQL 支持多種類型,大致可以分為三類:數(shù)值、日

    2024年02月15日
    瀏覽(111)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包