Hive學習筆記

hive簡介

解釋一:Hive是一個數(shù)據(jù)倉庫基礎工具在Hadoop中用來處理結構化數(shù)據(jù)。它架構在Hadoop之上,總歸為大數(shù)據(jù),并使得查詢和分析方便。并提供簡單的sql查詢功能,可以將sql語句轉換為MapReduce任務進行運行

解釋二:Hive 是建立在 Hadoop 上的數(shù)據(jù)倉庫基礎構架。它提供了一系列的工具,可以用來進行數(shù)據(jù)提取轉化加載(ETL),這是一種可以存儲、查詢和分析存儲在 Hadoop 中的大規(guī)模數(shù)據(jù)的機制。Hive 定義了簡單的類 SQL 查詢語言,稱為 QL,它允許熟悉 SQL 的用戶查詢數(shù)據(jù)。同時,這個語言也允許熟悉 MapReduce 開發(fā)者的開發(fā)自定義的 mapper 和 reducer 來處理內建的 mapper 和 reducer 無法完成的復雜的分析工作。

  • Hive是SQL解析引擎,它將SQL語句轉譯為M/R Job然后再Hadoop執(zhí)行
  • QL語句在底層被轉化為相應的MapReduce操作
  • Hive的表其實就是HDFS的目錄,按表名把文件夾分開。如果是分區(qū)表,分區(qū)值是子文件夾,可以直接在M/R Job里使用這些數(shù)

通俗來講就是傳統(tǒng)mysql無法處理大數(shù)據(jù),而大數(shù)據(jù)文件系統(tǒng)HDFS不能使用SQL,Hive就是一種可以用類SQL語句對大數(shù)據(jù)文件系統(tǒng)中的結構化數(shù)據(jù)進行操作的工具

Hive的系統(tǒng)架構

Hive系統(tǒng)架構圖

(JobTracker是Hadoop1.x中的ResouceManager + AppMaster
TaskTracker相當于NodeManager + YarnChild)

  • 用戶接口,包括CLI,JDBC/ODBC,WebUI
  • metastore,Hive將元數(shù)據(jù)存儲在數(shù)據(jù)庫中(metastore),目前只支持 mysql、derby(Derby引擎的缺點:一次只能打開一個會話。使用Mysql作為外置存儲引擎,多用戶同時訪問)。Hive 中的元數(shù)據(jù)包括表名、列、分區(qū)及其屬性、表的屬性(是否為外部表等)、表數(shù)據(jù)所在目錄等
  • Driver 解釋器、編譯器、優(yōu)化器完成 HQL 查詢語句從詞法分析、語法分析、編譯、優(yōu)化以及查詢計劃(plan)的生成。生成的查詢計劃存儲在HDFS 中,并在隨后有 MapReduce 調用執(zhí)行
  • Hive的數(shù)據(jù)存儲在HDFS中,大部分的查詢由MapReduce完成(包含 * 的查詢,比如select * from tb不會生成MapReduce任務)

Hive和普通關系數(shù)據(jù)庫的異同

  1. 查詢語言。由于SQL被廣泛的應用在數(shù)據(jù)倉庫中,因此,專門針對Hive的特性設計了類SQL的查詢語言HQL。熟悉SQL開發(fā)就很容易入手Hive開發(fā)。
  2. 數(shù)據(jù)倉庫位置。Hive是建立在Hadoop之上的,所有Hive的數(shù)據(jù)都是存儲在HDFS中的。而數(shù)據(jù)庫則可以將數(shù)據(jù)保存在塊設備或者本地文件系統(tǒng)中。
  3. 數(shù)據(jù)格式。 Hive中沒有定義專門的數(shù)據(jù)格式,數(shù)據(jù)格式可以由用戶指定,用戶定義數(shù)據(jù)格式需要指定三個屬性,列分隔符(通常為空格)、行分隔符(“\n”)以及讀取文件數(shù)據(jù)的方法(Hive中默認有三個文件格式TextFile,SequenceFile以及RCFile)。由于在加載數(shù)據(jù)的過程中,不需要從用戶數(shù)據(jù)格式到Hive定義的數(shù)據(jù)格式的轉換,因此,Hive在加載的過程中不會對數(shù)據(jù)本身進行任何修改,而只是將數(shù)據(jù)內容復制或者移動到相應的HDFS目錄中。
  4. 數(shù)據(jù)更新。由于Hive是針對數(shù)據(jù)倉庫應用設計的,而數(shù)據(jù)倉庫的內容是讀多寫少的。因此,Hive中不支持對數(shù)據(jù)的改寫和添加,所有的數(shù)據(jù)都是在加載的時候中確定好的。而數(shù)據(jù)庫中的數(shù)據(jù)通常是需要經(jīng)常進行修改的,因此可以使用 INSERT INTO … VALUES 添加數(shù)據(jù),使用 UPDATE … SET修改數(shù)據(jù)。
  5. 索引。Hive在加載數(shù)據(jù)的過程中不會對數(shù)據(jù)進行任何處理,甚至不會對數(shù)據(jù)進行掃描,因此也沒有對數(shù)據(jù)中的某些Key建立索引。Hive要訪問數(shù)據(jù)中滿足條件的特定值時,需要暴力掃描整個數(shù)據(jù),因此訪問延遲較高。由于 MapReduce 的引入, Hive 可以并行訪問數(shù)據(jù),因此即使沒有索引,對于大數(shù)據(jù)量的訪問,Hive 仍然可以體現(xiàn)出優(yōu)勢。數(shù)據(jù)庫中,通常會針對一個或者幾個列建立索引,因此對于少量的特定條件的數(shù)據(jù)的訪問,數(shù)據(jù)庫可以有很高的效率,較低的延遲。由于數(shù)據(jù)的訪問延遲較高,決定了 Hive 不適合在線數(shù)據(jù)查詢。
  6. 執(zhí)行。Hive中大多數(shù)查詢的執(zhí)行是通過 Hadoop 提供的 MapReduce 來實現(xiàn)的(類似 select * from tbl的查詢不需要MapReduce)。而數(shù)據(jù)庫通常有自己的執(zhí)行引擎。
  7. 執(zhí)行延遲。Hive 在查詢數(shù)據(jù)的時候,由于沒有索引,需要掃描整個表,因此延遲較高。另外一個導致 Hive 執(zhí)行延遲高的因素是 MapReduce框架。由于MapReduce 本身具有較高的延遲,因此在利用MapReduce 執(zhí)行Hive查詢時,也會有較高的延遲。相對的,數(shù)據(jù)庫的執(zhí)行延遲較低。當然,這個低是有條件的,即數(shù)據(jù)規(guī)模較小,當數(shù)據(jù)規(guī)模大到超過數(shù)據(jù)庫的處理能力的時 候,Hive的并行計算顯然能體現(xiàn)出優(yōu)勢。
  8. 可擴展性。由于Hive是建立在Hadoop之上的,因此Hive的可擴展性是和Hadoop的可擴展性是一致的。而數(shù)據(jù)庫由于 ACID 語義的嚴格限制,擴展行非常有限。目前最先進的并行數(shù)據(jù)庫 Oracle 在理論上的擴展能力也只有100臺左右。
  9. 規(guī)模。由于Hive建立在集群上并可以利用MapReduce進行并行計算,因此可以支持很大規(guī)模的數(shù)據(jù);對應的,數(shù)據(jù)庫可以支持的數(shù)據(jù)規(guī)模較小。

Hive數(shù)據(jù)類型

在對Hive進行操作之前,首先要明白Hive數(shù)據(jù)類型有哪些。

  • tinyint/smallint/int/bigint
  • float/double
  • boolean
  • DECIMAL -用戶可以指定范圍和小數(shù)點位數(shù)
  • STRING -在特定的字符集中的一個字符串序列
  • VARCHAR -在特定的字符集中的一個有最大長度限制的字符串序列
  • CHAR -在特定的字符集中的一個指定長度的字符串序列
  • BINARY -一個二進制位序列
  • 結構體類型(Stuct): 使用點(.)來訪問類型內部的元素。例如,有一列c,它是一個結構體類型{a INT; b INT},字段a可以使用表達式c.a來訪問。
  • Map(key-value鍵值對):使用['元素名']來訪問元素。例如,有一個MapM,包含'group'->gid的映射,則gid的值可以使用M['group']來訪問。
  • 數(shù)組:數(shù)組中的元素是相同的類型??梢允褂肹n]來訪問數(shù)組元素,n是數(shù)組下標,以0開始。例如有一個數(shù)組A,有元素['a','b','c'],則A[1]返回'b'。

Hive實踐操作

配置Hive

上一階段配置CDH的時候就一起配置了Hive,也可以使用Apache Hadoop單獨配置
這里出現(xiàn)一個問題,hive啟動不起來,一直等待在界面沒反應,去master:10002查看了一下hive服務,發(fā)現(xiàn)無響應,說明hive沒有啟動起來,所以去管理界面查看情況,運行狀態(tài)不良

想了一下,這個問題可能是有幾次強制關機造成的,只有重新安裝CDH。所以千萬不能強制關掉CDH集群,因為這樣會導致各種各樣的玄學問題。。。

建立內表、外表

  1. 在導入數(shù)據(jù)到外部表,數(shù)據(jù)并沒有移動到自己的數(shù)據(jù)倉庫目錄下(如果指定了location的話),也就是說外部表中的數(shù)據(jù)并不是由它自己來管理的!而內部表則不一樣;
  2. 在刪除內部表的時候,Hive將會把屬于表的元數(shù)據(jù)和數(shù)據(jù)全部刪掉;而刪除外部表的時候,Hive僅僅刪除外部表的元數(shù)據(jù),數(shù)據(jù)是不會刪除的!
  3. 在創(chuàng)建內部表或外部表時加上location 的效果是一樣的,只不過表目錄的位置不同而已,加上partition用法也一樣,只不過表目錄下會有分區(qū)目錄而已,load data local inpath直接把本地文件系統(tǒng)的數(shù)據(jù)上傳到hdfs上,有l(wèi)ocation上傳到location指定的位置上,沒有的話上傳到hive默認配置的數(shù)據(jù)倉庫中。

數(shù)據(jù)選擇Sogou用戶查詢語料信息,下載之后由于編碼有問題,還需要進行編碼轉為為utf8。
iconv -f gbk -t utf8 -c SogouQ.sample > SogouQ.sample2
因為外表建立需要明確行列分隔符,而數(shù)據(jù)當中存在列分隔符不一致的情況,需要利用sed命令進行轉換。

替換前
使用命令cat SogouQ.sample2 | sed -e 's/ /\t/g' >>Sogou可以將空格替換為\t,替換規(guī)則為sed 's/要被取代的字串/新的字串/g'再配合管道和追加到Sogou文件中就完成了替換。
替換后

  • 首先和mysql一樣需要創(chuàng)建數(shù)據(jù)庫


  • 建立對應的外表



  • 同時建立內表



這里指定了外部表的具體存儲位置為/tmp/sogou文件夾,方便以后查看。由于原始數(shù)據(jù)里行分隔符為\t,所以創(chuàng)建時要匹配為\t。

  • 導入數(shù)據(jù)到表
    load data local inpath '/usr/tmp/Sogou' into table sogou;這里的路徑指的是本機上的文件路徑。
  • 查看導入數(shù)據(jù)情況


    外表

    內表

外表和內表都導入成功了,那么來看一下兩個表在hdfs中存儲位置有什么區(qū)別。

  • 刪除表



    可以看到內表的表信息和數(shù)據(jù)全部都被刪除了。



    然而外部表的數(shù)據(jù)全部都還在。

hive sql

hive的大多數(shù)查詢都會轉化為MapReduce程序,可以導master:8088查看相應的MapReduce程序。


  • group by
    group by和sql里面的使用方法相似,都是用于對某個或多個列的值進行分組查詢。
    select rank,count(url) from sogou group by rank having rank < 10;用于查詢排名前10的url個數(shù)
  1. select后面的非聚合列必須出現(xiàn)在group by中(比如上面的rank)
  2. 除了普通列就是一些聚合操作(比如上面的count(rank))
  • Order by
    Order by會對輸入做全局排序,因此只有一個Reducer(多個Reducer無法保證全局有序),然而只有一個Reducer,會導致當輸入規(guī)模較大時,消耗較長的計算時間。
    Order by語法如下:
select col,col2...  
from tableName  
where condition  
order by col1,col2 [asc|desc] 
  1. order by后面可以有多列進行排序,默認按字典排序。
  2. order by為全局排序。
  3. order by需要reduce操作,且只有一個reduce,無法配置(因為多個reduce無法完成全局排序)。
    select * from sogou order by rank desc limit 5;獲取排名前5的所有信息
  • sort by
    hive使用order by會默認設置reduce的個數(shù)=1,既然reducer的個數(shù)都是1了,結果自然全排序!但是reducer個數(shù)為1會導致效率非常的低,所以提供了一個新的排序方式sort by。
    它會保證每個reducer的輸出文件是有序的,要想實現(xiàn)全排序,還得加一個order by的過程,就是對sort by的reduce輸出結果再進行一次排序。要想用hive實現(xiàn)全排序:要么用order by,但這樣默認了reducer個數(shù)為1,效率低下。要么用sort by+order by,sort by過程可以設置reducer個數(shù)(n),order by過程用n個reducer的輸出文件進行一次全排序,得到最終的結果。
    select * from sogou sort by rank desc limit 5;這里是對rank進行排序,但是不是全局排序,而是對每一個reducer內部進行排序,那么怎樣hive如何將所有數(shù)據(jù)劃分給若干個reducer呢?這就要用到下面的distribute了。
  • distribute by
    distribute by是控制map的輸出在reducer是如何劃分的。hive會根據(jù)distribute by后面列,對應reduce的個數(shù)進行分發(fā),默認是采用hash算法。舉個例子
    select * from sogou distribute by rank sort by rank,time desc limit 5;

表示將rank哈希后(這里并不是簡單的把rank相同的數(shù)據(jù)劃分為一個cluster,而是對rank值哈希后再對cluster個數(shù)進行求余)相同的數(shù)據(jù)全部送到一個reducer進行處理,這就是因為指定了distribute by rank,再配合sort by這樣的話就可以統(tǒng)計出每個rank排名中所有數(shù)據(jù)的時間順序了。這里需要注意的是distribute by必須要寫在sort by之前。

  • cluster by
    cluster by的功能就是distribute by和sort by相結合,如下2組語句是等價的:
    select * from sogou cluster by rank
    select * from sogou cluster by distribute by rank sort by rank

注意被cluster by指定的列只能是升序,不能指定asc和desc。

Java、Python調用Hive

和下面Python調用一樣,只需要下載相應的jar,跟著官方文檔即可。

pyhive

首先安裝連接hive需要的依賴

pip install sasl
pip install thrift
pip install thrift-sasl
pip install PyHive

然后就可以按照固定的格式開啟連接了

from pyhive import hive

conn = hive.Connection(host='192.168.233.100',port=10000,username='root',database='mytest')
cursor = conn.cursor()
cursor.execute('select * from sogou limit 10')
for result in cursor.fetchall():
    print(result)

但是報錯了
thrift.transport.TTransport.TTransportException: Could not start SASL: b'Error in sasl_client_start (-4) SASL(-4): no mechanism available: Unable to find a callback: 2'
查看hive的日志
java.lang.RuntimeException: org.apache.thrift.transport.TSaslTransportException: No data or no sasl data in the stream
網(wǎng)上找了一下也沒什么好的解決方案,看這個報錯信息應該是windows系統(tǒng)底層的問題,所以換到centos里執(zhí)行剛剛的python程序。
成功連接hive并得到查詢結果。

Java Hive

UDF、UDAF、UDTF

Hive中,除了提供豐富的內置函數(shù)之外,還允許用戶使用Java開發(fā)自定義的UDF函數(shù)。UDF有幾種:

  • (普通)UDF:操作作用于單個數(shù)據(jù)行,且產(chǎn)生一個數(shù)據(jù)行作為輸出。
  • 用戶自定義聚合函數(shù)(UDAF):接受多個輸入數(shù)據(jù)行,并產(chǎn)生一個輸出數(shù)據(jù)行。
  • 用戶自定義生表函數(shù)(UDTF):接受一個數(shù)據(jù)行,然后返回產(chǎn)生多個數(shù)據(jù)行

開發(fā)自定義UDF函數(shù)有兩種方式
繼承org.apache.hadoop.hive.ql.exec.UDF
繼承org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
如果是針對簡單的數(shù)據(jù)類型(比如String、Integer等)可以使用UDF,如果是針對復雜的數(shù)據(jù)類型(比如Array、Map、Struct等),可以使用GenericUDF,另外,GenericUDF還可以在函數(shù)開始之前和結束之后做一些初始化和關閉的處理操作。

UDF

使用自定義UDF時,只需要繼承org.apache.hadoop.hive.ql.exec.UDF,并定義public Object evaluate(Object args) {} 方法即可。例如:

package li;


import org.apache.hadoop.hive.ql.exec.UDF;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashMd5 {
    public String evaluate(String password) {
        try {
            // 得到一個信息摘要器
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[] result = digest.digest(password.getBytes());
            StringBuffer buffer = new StringBuffer();
            // 把每一個byte 做一個與運算 0xff;
            for (byte b : result) {
                // 與運算
                int number = b & 0xff;// 加鹽
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }

            // 標準的md5加密后的結果
            return buffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }

    }
}

evaluate方法就是要進行處理的函數(shù)內容。這個函數(shù)的意思是將輸入的內容轉為它的MD5值。
用IDEA把剛剛寫好的Java文件打成jar包(這里特別需要注意編譯成jar包的環(huán)境JDK要和hive平臺的JDK一致,所以我把JDK變?yōu)榱?.6)


然后就可以在hive交互界面使用命令add jar /usr/tmp/myudf.jar
這里的路徑是把jar包存放在linux文件下的路徑。
接著生成函數(shù)方法
create temporary function md5 as 'li.HashMd5';
因為我只是為了測試,所以用的temporary,表示該方法的作用時間只是這次session,as后面跟著的是你寫入自定義函數(shù)的類的完整類名
隨后就可以寫測試hive sql來看看是否成功了。
select rank,md5(rank) from sogou limit 10;
這里第一次報錯了
Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:dr
錯誤顯示想要訪問/user下的內容,但是權限不夠,因為我是在root用戶下進入的hive交互界面,所以有些文件不能執(zhí)行操作,所以切換至hdfs用戶就可以了。

這里可以看到同樣的值得到了同樣的MD5值,所以驗證成功。

UDAF

UDAF 接受多個輸入數(shù)據(jù)行,并產(chǎn)生一個輸出數(shù)據(jù)行。
一個計算函數(shù)必須實現(xiàn)以下5個方法:

  • init(): 該方法負責初始化計算函數(shù)并重設它的內部狀態(tài) 。
  • iterate(): 每次對一個新值進行聚合計算時會調用該方法。
  • terminatePartial(): Hive需要部分聚合結果時會調用該方法。
  • merge(): Hive需要將部分聚合結果和另外部分聚合結果合并時會調用該方法。
  • terminate(): 需要最終結果時會調用該方法



    和上面自定義UDF的方法類似,也是編寫代碼后臺添加功能。

package li;


import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.FloatWritable;

@SuppressWarnings("deprecation")
public class Mean extends UDAF {
    public static class MeanFloatUDAFEvaluator implements UDAFEvaluator {
        public static class PartialResult {
            float sum;
            long count;
        }

        private PartialResult partialresult;

        @Override
        public void init() {
            // TODO Auto-generated method stub
            partialresult = null;
        }

        public boolean iterate(FloatWritable value) {
            if (value == null) {
                return true;
            }
            if (partialresult == null) {
                partialresult = new PartialResult();
            }

            partialresult.sum += value.get();
            ++partialresult.count;
            return true;
        }

        public PartialResult terminatePartial() {
            return partialresult;
        }

        public boolean merge(PartialResult other) {
            if (other == null) {
                return true;
            }
            if (partialresult == null) {
                partialresult = new PartialResult();
            }

            partialresult.sum += other.sum;
            partialresult.count += other.count;

            return true;
        }

        public FloatWritable terminate() {
            if (partialresult == null) {
                return null;
            }
            return new FloatWritable(partialresult.sum / partialresult.count);
        }
    }
}

然后添加jar和臨時方法
add jar /usr/tmp/myudf.jar
create temporary function my_mean as 'li.Mean';
可以再show functions里面看到自己的方法了。

分區(qū)、分桶

Hive使用select語句進行查詢的時候一般會掃描整個表內容,會消耗很多時間做沒必要的工作。Hive可以在創(chuàng)建表的時候指定分區(qū)空間,這樣在做查詢的時候就可以很好的提高查詢的效率。
Hive中的每個分區(qū)對應數(shù)據(jù)庫中相應分區(qū)列的一個索引,每個分區(qū)對應著表下的一個目錄,在HDFS上的表現(xiàn)形式與表在HDFS上的表現(xiàn)形式相同,都是以子目錄的形式存在。

  • 創(chuàng)建分區(qū)表
 create table t1(
    > id int,
    > name string
    > )
    > partitioned by (pt varchar(8))
    > ;

這里表示將字段pt作為分區(qū)的目標字段

  • 裝載數(shù)據(jù)進分區(qū)表
    首先創(chuàng)建測試數(shù)據(jù)data
1,a
2,b
3,c

load data local inpath '/usr/tmp/data' overwrite into table t1 partition (pt='001');
所有數(shù)據(jù)都被裝載到分區(qū)001中去了;再次將數(shù)據(jù)裝載進分區(qū)002中去。
load data local inpath '/usr/tmp/data' overwrite into table t1 partition (pt='002');


通過這里可以看出成功將數(shù)據(jù)裝載進了不同的分區(qū),下面再看一下在HDFS中分區(qū)是如何實現(xiàn)的。
進入到hive默認存儲地址/user/hive/warehouse

在這里我們可以清晰的看到hive首先為這個數(shù)據(jù)庫創(chuàng)建了一個文件夾,然后為每一個分區(qū)創(chuàng)建一個子目錄,將屬于各自分區(qū)的數(shù)據(jù)就存放在各自分區(qū)的目錄下。

也可以查看有哪些分區(qū)和刪除指定分區(qū)(會同時刪除分區(qū)中數(shù)據(jù))

hive>partitions t1;
OK
pt=001
pt=002
hive> alter table t1 drop partition(pt=001);
Dropped the partition pt=001
OK

對于每一個表或者是分區(qū),Hive可以進一步組織成,也就是說桶是更為細粒度的數(shù)據(jù)范圍劃分。Hive是針對某一列進行分桶。Hive采用對列值哈希,然后除以桶的個數(shù)求余的方式?jīng)Q定該條記錄存放在哪個桶中。分桶的好處是可以獲得更高的查詢處理效率。使取樣更高效。分桶比分區(qū),更高的查詢效率。

  • 建立桶表
create table bucket_test(
     id int,
     name string
     )
     clustered by(id) into 4 buckets
     row format delimited fields terminated by '\t'
     sorted as textfile;

裝入數(shù)據(jù)
load data local inpath '/usr/tmp/data' overwrite into table bucket_test;


數(shù)據(jù)成功裝入后,就去目錄中看一看桶的結構。發(fā)現(xiàn)分桶沒有成功。查了一下資料,說是設置hive分桶為true
set hive.enforce.bucketing = true;
但是還是不行。仔細思考了一下,應該是導入數(shù)據(jù)的方式有問題,我這里用load導入數(shù)據(jù)使得hive可能不會逐一檢索數(shù)據(jù)并根據(jù)哈希值存入桶,應該用insert方式導入數(shù)據(jù),hive才會逐一根據(jù)數(shù)據(jù)指定列的哈希值存入不同的桶。

insert overwrite table bucketed_user
    > select id,name from t1;

這樣就將數(shù)據(jù)庫分為了4個桶。仔細觀察會發(fā)現(xiàn)每個桶不是文件夾,而是文件,這點和分區(qū)不一樣。當從桶表中進行查詢時,hive會根據(jù)分桶的字段進行計算分析出數(shù)據(jù)存放的桶中,然后直接到對應的桶中去取數(shù)據(jù),這樣做就很好的提高了效率。

  • 索引和分區(qū)最大的區(qū)別就是索引不分割數(shù)據(jù)庫,分區(qū)分割數(shù)據(jù)庫。
  • 分區(qū)和分桶最大的區(qū)別就是分桶隨機分割數(shù)據(jù)庫,分區(qū)是非隨機分割數(shù)據(jù)庫。
  • 其次兩者的另一個區(qū)別就是分桶是對應不同的文件(細粒度),分區(qū)是對應不同的文件夾(粗粒度)。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容