日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

第三步:學習數據庫表設計要點

良好的表結構設計不僅能支持豐富的功能需求,還能大幅提升數據庫系統的性能、可維護性和可擴展性等,因此數據庫的表結構設計至關重要。本文為您介紹在云數據庫 SelectDB 版中,設計表結構時需要重點關注的表屬性,并幫助您快速掌握如何根據業務場景選擇合適的表設計,從而更好的滿足業務需求。

重要表屬性概覽

在業務接入SelectDB時,根據業務場景做好重要表屬性的設計,對于構建出能滿足業務需求且高性能、易維護的表結構至關重要。以下是SelectDB重要表屬性的快速概覽。

表屬性

是否必選

屬性關鍵作用

詳情鏈接

數據模型

不同的數據模型適用于不同的業務場景:Unique模型支持主鍵唯一性約束,可滿足靈活高效的數據更新需求。

Duplicate模型采用追加寫模式,適用于明細數據的高性能分析場景。

Aggregate模型支持數據預聚合,專注于數據聚合統計場景。

數據模型

分桶

分桶用于將數據分散到集群中的不同節點,以充分利用分布式系統的分而治之的能力來管理和查詢海量數據。

分區

分區能夠根據指定字段(如時間、地域等)將原始表劃分為多個子表,以便于對數據進行分區管理和查詢,同時利用分區裁剪來提升查詢速度。

索引

索引能夠快速地過濾或定位數據,從而大幅提升查詢性能。

索引

數據模型

數據模型的合理選擇,對于能否滿足數據分析場景的功能需求和性能要求具有決定性影響。不同的模型適用于不同的業務場景。此處僅對各個模型進行簡要介紹,旨在幫助您快速了解數據模型,以便于您進行模型選擇。更多詳情,請參見專題介紹文章數據模型。

基礎概念

SelectDB中,數據通過表(Table)的形式在邏輯層面進行組織和管理。每張表由行(Row)和列(Column)組成。行表示數據表中的一行數據,而列用于描述該行數據中的不同字段。

列可以分為以下兩大類:

  • Key列:Key列是指建表語句中被關鍵字UNIQUE KEYAGGREGATE KEYDUPLICATE KEY修飾的列。

  • Value列:除Key列外,其余列均為Value列。

模型選擇指導

SelectDB中,表的數據模型分為三種,分別為Unique模型、Duplicate模型和Aggregate模型。

重要
  • 數據模型在建表時已確定且不可修改。

  • 如果在建表時未指定數據模型,將默認采用Duplicate模型,并自動選擇前三列作為Key列。

  • Unique模型、Duplicate模型和Aggregate模型中,數據均按照Key列進行排序存儲。

模型類型

模型特點

適用場景

模型不足

Unique

每一行的Key值唯一。

Key列值相同時,多行數據的Value列會按寫入的先后順序進行覆蓋。

適用于對數據有唯一主鍵要求或高效更新要求的場景。例如電商訂單、用戶屬性信息等數據分析場景。

  • 無法通過建立同步物化視圖進行預聚合來加速查詢。

Duplicate

允許多行的Key值相同。

Key列值相同時,多行數據同時存儲在系統中。

數據的寫入和查詢效率極高,適用于保留所有原始數據記錄的場景。例如日志、賬單等明細數據分析場景。

  • 無法通過建立同步物化視圖進行預聚合來加速查詢。

Aggregate

每一行的Key值唯一。

Key列值相同時,多行數據的Value列會按照建表時指定的聚合方式進行預聚合。

類似于傳統數據倉庫的Cube模型,適用于通過預聚合提升查詢性能的聚合統計場景。例如網站流量分析、定制化報表等數據分析場景。

  • count(*)查詢的支持不友好。

  • Value列的聚合方式是固定的。

快速使用模型

Unique模型

在Unique模型中,Key列值相同時,多行數據的Value列會按寫入的先后順序進行覆蓋。Unique模型提供了兩種實現方式:讀時合并(MOR,merge-on-read)和寫時合并(MOW,merge-on-write)。

由于寫時合并技術已非常成熟且穩定,并且能夠提供優異的查詢性能,因此建議您優先采用寫時合并的實現方式。此處僅簡要介紹Unique模型的寫時合并。有關讀時合并的詳細信息,請參見讀時合并(MOR)。

注意事項

創建Unique模型且為寫時合并實現方式的表時,須在建表時注意以下事項。

  • 通過UNIQUE KEY指定主鍵唯一的字段。

  • 在PROPERTIES中添加開啟寫時合并的屬性。

    "enable_unique_key_merge_on_write" = "true"
示例

創建orders表語句如下。其表示將orders表指定為Unique模型,同時將orders表主鍵設定為由order_id和order_time組成的聯合主鍵,并啟用寫時合并模式。

CREATE TABLE IF NOT EXISTS orders
(
    `order_id` LARGEINT NOT NULL COMMENT "訂單id",
    `order_time` DATETIME NOT NULL COMMENT "訂單時間",
    `customer_id` LARGEINT NOT NULL COMMENT "用戶id",
    `total_amount` DOUBLE COMMENT "訂單總金額",
    `status` VARCHAR(20) COMMENT "訂單狀態",
    `payment_method` VARCHAR(20) COMMENT "支付方式",
    `shipping_method` VARCHAR(20) COMMENT "運輸方式",
    `customer_city` VARCHAR(20) COMMENT "用戶所在城市",
    `customer_address` VARCHAR(500) COMMENT "用戶地址"
)
UNIQUE KEY(`order_id`, `order_time`)
PARTITION BY RANGE(`order_time`) ()
DISTRIBUTED BY HASH(`order_id`)
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);

Duplicate模型

在Duplicate模型中,Key列值相同時,多行數據同時存儲在系統中,沒有預聚合、主鍵唯一性約束等特點。

例如,您希望記錄并分析業務系統產生的日志數據,且期望數據按照日志時間、日志類型、錯誤碼進行排序存儲,您可以選擇此模型。具體創建log表的語句如下,其表示log表模型為Duplicate模型,且數據會按照log_time、log_type和error_code進行排序。

CREATE TABLE IF NOT EXISTS log
(
    `log_time` DATETIME NOT NULL COMMENT "日志時間",
    `log_type` INT NOT NULL COMMENT "日志類型",
    `error_code` INT COMMENT "錯誤碼",
    `error_msg` VARCHAR(1024) COMMENT "錯誤詳細信息",
    `op_id` BIGINT COMMENT "負責人id",
    `op_time` DATETIME COMMENT "處理時間"
)
DUPLICATE KEY(`log_time`, `log_type`, `error_code`)
PARTITION BY RANGE(`log_time`) ()
DISTRIBUTED BY HASH(`log_type`)
PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);

Aggregate模型

注意事項

在Aggregate模型中,Key列值相同時,多行數據的Value列會按照建表時指定的聚合方式進行預聚合。因此,在創建Aggregate模型的表時,需特別關注以下事項。

  • 通過AGGREGATE KEY指定Key列,相同Key列的數據行將進行聚合。

  • 指定Value的聚合方式。目前支持的聚合方式如下:

    聚合方式參數

    參數說明

    SUM

    求和。適用數值類型。

    MIN

    求最小值。適合數值類型。

    MAX

    求最大值。適合數值類型。

    REPLACE

    替換。對于維度列相同的行,指標列會按照導入的先后順序,后導入的替換先導入的。

    REPLACE_IF_NOT_NULL

    非空值替換。和REPLACE的區別在于對于null值,不做替換。這里要注意的是字段默認值要給NULL,而不能是空字符串,如果是空字符串,會給你替換成空字符串。

    HLL_UNION

    HLL類型的列的聚合方式,通過HyperLogLog算法聚合。

    BITMAP_UNION

    BITMAP類型的列的聚合方式,進行位圖的并集聚合。

示例

例如,您需要對用戶行為進行統計分析,記錄其最后訪問時間、總消費額、最大停留時間和最短停留時間,您可以選擇此模型。具體創建user_behavior表的語句如下。其表示當多條數據的Key列(用戶ID、數據寫入日期、用戶所在城市、用戶年齡和用戶性別)相同時,用戶的Value列進行預聚合。聚合規則如下:

  • 用戶最后一次訪問時間:取多條用戶行為數據中last_visit_date字段的最大值。

  • 用戶總消費:多條數據中用戶消費的總和。

  • 用戶最大停留時間:取多條用戶行為數據中max_dwell_time字段的最大值

  • 用戶最小停留時間:取多條用戶行為數據中min_dwell_time字段的最小值。

CREATE TABLE IF NOT EXISTS user_behavior
(
    `user_id` LARGEINT NOT NULL COMMENT "用戶id",
    `date` DATE NOT NULL COMMENT "數據寫入日期時間",
    `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 "用戶總消費",
    `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用戶最大停留時間",
    `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用戶最小停留時間"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
PARTITION BY RANGE(`date`) ()
DISTRIBUTED BY HASH(`user_id`)
PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);

數據劃分概述

SelectDB支持兩層數據劃分,如下圖所示。第一層是分區(Partition),用于對數據進行邏輯劃分,分區是用戶進行數據管理的最小單元。第二層是分桶(Tablet),用于對數據進行物理劃分,分桶是系統進行數據打散、移動等操作的最小單元。

image

分區與分桶的關聯
  • 一個分桶僅屬于一個分區,而一個分區則包含多個分桶。

  • 在建表過程中,如果采用了分區(Partition),則表先按分區規則進行劃分,分區內再按指定的分桶規則進行劃分;如果未使用分區,則表直接按指定的分桶規則進行劃分。

  • 在數據寫入過程中,數據首先被劃分至相應的分區,隨后在分區內依據分桶規則進一步寫入至不同的分桶中。分桶是對分區數據的進一步細分,其目的是為了更加均勻地分布數據,從而提升查詢效率。

分區(Partition)

SelectDB的存儲引擎中,分區是一種數據組織方式,用于將表中的數據按照用戶定義的規則劃分為多個獨立的部分,從而實現數據的邏輯劃分。這有助于提升查詢效率,同時也使得數據管理更加靈活和便捷。此處僅對分區進行簡要介紹,旨在幫助您快速了解分區,以便于您進行分區選型。更多詳情,請參見分區動態分區。

分區選擇指導

SelectDB支持兩種分區方式:Range分區和List分區。同時,也提供了簡單易用的動態分區功能,以實現對分區的自動化管理。不同的分區方式,適用于不同的業務場景。

分區方式

支持的列類型

指定分區信息方式

適用場景

Range

列類型:DATE、DATETIME、TINYINT、SMALLINT、INT、BIGINT、LARGEINT

支持四種寫法:

  1. VALUES [...):定義分區的左閉右開區間。

  2. VALUES LESS THAN (...):僅定義分區上界。下界由上一個分區的上界決定。

  3. BATCH RANGE:批量創建數字類型和時間類型的Range分區,定義分區的左閉右開區間,設定步長。

  4. MULTI RANGE:批量創建Range分區,定義分區的左閉右開區間。

適用于對數據劃分區間進行管理,典型的場景是按時間進行分區。

List

列類型:BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、LARGEINT、DATE、DATETIME、CHAR、VARCHAR

支持通過VALUES IN (...)來指定每個分區包含的枚舉值。

適用于依據數據的既有類別或固定特性進行數據管理,分區列通常為枚舉值,例如根據用戶所屬地域進行數據劃分管理。

注意事項

  • SelectDB的表可分為分區表和無分區表。該屬性可選,在建表時確定是否進行分區,之后不可更改。具體而言,對于分區表,您可以在后續使用過程中對分區進行增刪操作;而對于無分區表,則無法再進行增加分區等操作。

  • 分區列必須為Key列,可指定一列或多列。

  • 不論分區列是什么類型,在寫分區值時,都需要加雙引號。

  • 分區的數量在理論上并沒有上限。

  • 在創建分區時,必須確保每個分區的取值范圍不重疊。

快速使用分區

Range分區

Range分區是指按照分區字段范圍,對數據進行劃分管理,是最常用的分區方式。典型的使用場景是按照時間進行數據分區,方便對海量的時間序數據進行管理、查詢優化等。

分區分桶的最終目的是合理地劃分數據,分區規則設置合理性的主要標準是:

  • 在分區及分桶規則下,每個分桶(Tablet)的數據量在1~10 GB的范圍內;

  • 根據您管理數據的粒度確定分區粒度(例如,在日志場景下,您通常需要按天淘汰歷史數據,此時選擇以天為分區粒度比較合適)。

在日志場景下,經常按照時間范圍過濾查詢數據,且需要按照時間淘汰歷史分區,您可以將log_time字段指定為分區列,并采取按天分區的方式,示例如下。

CREATE TABLE IF NOT EXISTS log
(
 `log_time` DATETIME NOT NULL COMMENT "日志時間",
 `log_type` INT NOT NULL COMMENT "日志類型",
 `error_code` INT COMMENT "錯誤碼",
 `error_msg` VARCHAR(1024) COMMENT "錯誤詳細信息",
 `op_id` BIGINT COMMENT "負責人id",
 `op_time` DATETIME COMMENT "處理時間"
)
DUPLICATE KEY(`log_time`, `log_type`, `error_code`)
PARTITION BY RANGE(`log_time`)
(
 PARTITION `p20240201` VALUES [("2024-02-01"), ("2024-02-02")),
 PARTITION `p20240202` VALUES [("2024-02-02"), ("2024-02-03")),
 PARTITION `p20240203` VALUES [("2024-02-03"), ("2024-02-04"))
)
DISTRIBUTED BY HASH(`log_type`)
PROPERTIES ();

建表完成后,您可以通過如下SQL查看表的分區信息。

SHOW partitions FROM log;
p20240201: [("2024-02-01"), ("2024-02-02"))
p20240202: [("2024-02-02"), ("2024-02-03"))
p20240203: [("2024-02-03"), ("2024-02-04"))

當您使用以下語句查詢數據時,就會命中分區p20240202: [("2024-02-02"), ("2024-02-03")),系統不會掃描剩余兩個分區的數據,從而提高了查詢數據的速度。

SELECT * FROM orders WHERE order_time = '2024-02-02';

List分區

List分區是按照分區字段的枚舉值,對數據進行劃分管理。當對采用List分區的表進行查詢時,可結合過濾條件快速進行分區裁剪,提升查詢性能。

您可以根據操作業務數據時常用的字段來選擇List分區列。需要注意的是,各個分區之間的數據量要均勻,避免嚴重的數據傾斜。

例如,在電商場景中,訂單數據量通常非常龐大,且某些場景經常需要根據訂單用戶所屬城市來查詢分析此類數據。因此,為了更方便地管理和查詢數據,可以將customer_city字段指定為分區列。假如數據量按地域的分布如下:

  • 北京、上海和中國香港預計有6GB。

  • 紐約、舊金山預計有5GB。

  • 東京預計有5GB。

此時您可以按照以下示例進行分區。

CREATE TABLE IF NOT EXISTS orders
(
    `order_id` LARGEINT NOT NULL COMMENT "訂單id",
    `order_time` DATETIME NOT NULL COMMENT "訂單時間",
    `customer_city` VARCHAR(20) COMMENT "用戶所在城市",
    `customer_id` LARGEINT NOT NULL COMMENT "用戶id",
    `total_amount` DOUBLE COMMENT "訂單總金額",
    `status` VARCHAR(20) COMMENT "訂單狀態",
    `payment_method` VARCHAR(20) COMMENT "支付方式",
    `shipping_method` VARCHAR(20) COMMENT "運輸方式",
    `customer_address` VARCHAR(500) COMMENT "用戶地址"
)
UNIQUE KEY(`order_id`, `order_time`, `customer_city`)
PARTITION BY LIST(`customer_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(`order_id`) BUCKETS 16
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true"
);

建表完成后,您可以通過如下SQL查看表的分區信息,該表會自動生成以下3個分區。

SHOW partitions FROM orders;
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "San Francisco")
p_jp: ("Tokyo")

當您使用以下語句查詢數據時,就會命中分區p_jp: ("Tokyo"),系統不會掃描剩余兩個分區的數據,從而提高了查詢數據的速度。

SELECT * FROM orders WHERE customer_city = 'Tokyo';

使用動態分區

實際生產環境中,數據表的分區數量可能比較多,此時手動管理分區的工作將變得十分繁瑣,這為數據庫管理人員帶來了額外的維護成本。SelectDB允許在建表時設定動態分區規則以進行自動化分區管理。

例如,在電商中,針對訂單信息表,經常按照時間范圍過濾查詢數據,且需要對歷史訂單進行轉儲歸檔的場景。您可以將order_time字段指定為分區列,并在PROPERTIES中設置動態分區屬性。比如在PROPERTIES中設置該分區采取按天分區(dynamic_partition.time_unit)的方式,只保留最近180天(dynamic_partition.start)的分區,并且預先創建未來3天(dynamic_partition.end)的分區,示例如下。

重要

下述語句中PARTITION BY RANGE(`order_time`) ()末尾的()并非語法錯誤,如果您要使用動態分區,此括號為固定語法,必不可少。

CREATE TABLE IF NOT EXISTS orders
(
    `order_id` LARGEINT NOT NULL COMMENT "訂單id",
    `order_time` DATETIME NOT NULL COMMENT "訂單時間",
    `customer_id` LARGEINT NOT NULL COMMENT "用戶id",
    `total_amount` DOUBLE COMMENT "訂單總金額",
    `status` VARCHAR(20) COMMENT "訂單狀態",
    `payment_method` VARCHAR(20) COMMENT "支付方式",
    `shipping_method` VARCHAR(20) COMMENT "運輸方式",
    `customer_city` VARCHAR(20) COMMENT "用戶所在城市",
    `customer_address` VARCHAR(500) COMMENT "用戶地址"
)
UNIQUE KEY(`order_id`, `order_time`)
PARTITION BY RANGE(`order_time`) ()
DISTRIBUTED BY HASH(`order_id`)
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-180",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);

當您預計表的分區數量較多時,強烈建議您學習動態分區的相關內容,詳情請參見動態分區

分桶(Tablet

SelectDB的存儲引擎中,數據根據指定列的Hash值劃分到不同的分桶(Tablet),分桶則由集群中的不同節點進行管理,從而利用分布式系統的能力來進行管理、查詢海量數據。在建表時,通過DISTRIBUTED BY HASH(`<分桶列>`) BUCKETS <分桶數量>進行分桶的設置。有關分桶的詳細信息,請參見分桶。

注意事項

  • 如果建表時使用了分區(Partition),則DISTRIBUTED...語句所描述的是數據在各個分區內的劃分規則;如果未使用分區,則所描述的是對整個表的數據劃分規則。

  • 分桶列可以包含多個。

    對于Aggregate和Unique模型,分桶列必須為Key列;而對于Duplicate模型,分桶列則沒有限制。

    分桶列建議選擇唯一值多的高基數列,以便打散數據,避免數據傾斜。

  • 分桶(Tablet)的數量理論上沒有上限。

    單個分桶(Tablet)的數據量理論上沒有上下界,但建議在1~10 GB的范圍內。

    如果單個分桶(Tablet)數據量過小,容易導致分桶過多,元數據管理壓力增大。

    如果單個分桶(Tablet)數據量過大,不利于副本的遷移、分布式集群的充分利用,增加Schema變更或者索引創建等操作失敗重試的代價(這些操作失敗重試的粒度是Tablet)。

分桶列選擇指導

在表設計過程中,分桶列的選擇對查詢的性能和并發量有著重要影響,分桶列選擇的原則如下所示。當業務中存在多種查詢需求時,會產生多種分桶列的期望,此時應優先根據最主要查詢的需求進行選擇。

選擇原則

作用

優先保障數據均勻打散,選擇高基數列或多列組合。

數據在集群節點上分布更均衡。對于過濾效果不佳、進行大量數據掃描的查詢,可充分利用分布式系統的資源提升查詢性能。

選擇經常用于查詢過濾條件的列,兼顧數據裁剪加速查詢。

相同分桶列的數據聚集在一起。對于指定分桶列作為過濾條件的點查詢,可快速進行數據裁剪提高查詢并發。

說明

點查詢通常用于從數據庫中檢索特定條件下的少量數據。這種查詢通過指定特定的條件(例如通過主鍵、高基數列進行過濾),來精確確定位并獲取數據庫中符合條件的少量數據。

使用示例

在電商場景中,大量查詢按照訂單維度進行過濾查詢,也有部分查詢對全量訂單數據進行統計分析。此時,您可以選擇訂單信息表Key列中的高基數列order_id作為分桶列,可保障數據能夠均勻地分配到每個桶,且單個order_id的數據聚集在一起,可同時滿足前述兩種類型查詢的性能需求。具體建表語句如下。

CREATE TABLE IF NOT EXISTS orders
(
    `order_id` LARGEINT NOT NULL COMMENT "訂單id",
    `order_time` DATETIME NOT NULL COMMENT "訂單時間",
    `customer_id` LARGEINT NOT NULL COMMENT "用戶id",
    `total_amount` DOUBLE COMMENT "訂單總金額",
    `status` VARCHAR(20) COMMENT "訂單狀態",
    `payment_method` VARCHAR(20) COMMENT "支付方式",
    `shipping_method` VARCHAR(20) COMMENT "運輸方式",
    `customer_city` VARCHAR(20) COMMENT "用戶所在城市",
    `customer_address` VARCHAR(500) COMMENT "用戶地址"
)
UNIQUE KEY(`order_id`, `order_time`)
PARTITION BY RANGE(`order_time`) ()
DISTRIBUTED BY HASH(`order_id`)
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);

索引

索引在數據庫設計中至關重要,合適的索引可大幅提高查詢性能。創建索引存在一定的成本,可能導致額外的存儲空間占用以及寫入性能的下降。此處僅對常用索引進行簡要介紹,以幫助您快速了解索引,以便于您進行索引選型。更多詳情,請參見索引加速

設計指南

  • 最常使用的過濾條件應指定為Key自動建立前綴索引,因為其過濾效果最佳。然而,一個表只能擁有一個前綴索引,因此建議將其應用于最頻繁的過濾條件上。

  • 對于其他過濾加速需求,首選創建倒排索引,因其適用范圍廣泛,支持多條件組合。對于字符串的等值、LIKE匹配查詢場景,可考慮輕量級的BloomFilter、NGram BloomFilter索引。

索引選擇指導

SelectDB中,表的索引的構建方式有內建和自定義兩種。對于內建索引,系統會自動創建。而對于自定義索引,需要您在建表時或者建表后,根據需要自行創建。

構建方式

索引類型

支持的查詢類型

不支持的查詢類型

優勢

劣勢

內建

前綴索引

  • 等于、不等于查詢

  • 范圍查詢

  • LIKE查詢

  • MATCH(關鍵詞、短語)

前綴索引占用的空間相對較小,能夠在內存中進行全量緩存,從而實現快速定位數據塊,顯著提升查詢效率。

一個表只能有一個前綴索引。

自定義

倒排索引(推薦)

  • 字符串、數值、日期時間類型的等于、不等于查詢、范圍查詢

  • 字符串類型MATCH(關鍵詞、短語)

  • 文本類型的全文檢索

支持的查詢類型豐富。支持在建表時、建表后按需創建索引,并支持索引刪除。

索引存儲空間相對較大。

BloomFilter索引

等于查詢

  • 不等于查詢

  • 范圍查詢

  • LIKE查詢

  • MATCH(關鍵詞、短語)

索引構建占用的計算和存儲資源少。

支持的查詢類型少,只支持等于查詢。

NGram BloomFilter索引

LIKE查詢

  • 等于、不等于查詢

  • 范圍查詢

  • MATCH(關鍵詞、短語)

提高LIKE查詢速度,索引構建占用的計算和存儲資源少。

只支持LIKE加速。

快速使用索引

倒排索引

SelectDB支持倒排索引,可用于滿足文本字段的全文檢索、以及普通字段的等值或范圍查詢,能夠快速從大量數據中篩選出滿足條件的數據。此處僅簡紹如何創建倒排索引,更多信息,請參見倒排索引。

建表時創建索引

在電商場景中,根據用戶ID、用戶地址關鍵詞查詢訂單信息是高頻操作,此時可以在customer_idcustomer_address字段上建立倒排索引來提高查詢速度。具體建表語句如下。

CREATE TABLE IF NOT EXISTS orders
(
    `order_id` LARGEINT NOT NULL COMMENT "訂單id",
    `order_time` DATETIME NOT NULL COMMENT "訂單時間",
    `customer_id` LARGEINT NOT NULL COMMENT "用戶id",
    `total_amount` DOUBLE COMMENT "訂單總金額",
    `status` VARCHAR(20) COMMENT "訂單狀態",
    `payment_method` VARCHAR(20) COMMENT "支付方式",
    `shipping_method` VARCHAR(20) COMMENT "運輸方式",
    `customer_city` VARCHAR(20) COMMENT "用戶所在城市",
    `customer_address` VARCHAR(500) COMMENT "用戶地址",
    INDEX idx_customer_id (`customer_id`) USING INVERTED,
    INDEX idx_customer_address (`customer_address`) USING INVERTED PROPERTIES("parser" = "chinese")
)
UNIQUE KEY(`order_id`, `order_time`)
PARTITION BY RANGE(`order_time`) ()
DISTRIBUTED BY HASH(`order_id`)
PROPERTIES (
    "enable_unique_key_merge_on_write" = "true",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.create_history_partition" = "true",
    "dynamic_partition.buckets" = "16"
);
已有表創建索引

在電商場景中,根據用戶ID查詢訂單信息數據是一個高頻操作,但如果建表時沒有為customer_id字段創建倒排索引,可以使用以下語句為其增加索引。

ALTER TABLE orders ADD INDEX idx_customer_id (`customer_id`) USING INVERTED;

前綴索引

前綴索引是在底層數據按照Key列排序的基礎上,選擇前綴的一個或多個Key列構建的索引,其本質是基于數據排序特性進行二分查找。前綴索引屬于內建索引,建表后SelectDB自動創建。

前綴索引沒有專門的語法去定義,系統會根據建表的Key列字段定義順序,選取前36個字節所能覆蓋的字段作為前綴索引,但當遇到VARCHAR類型時,前綴索引會直接截斷,后面的Key列不再加入前綴索引。

建表時字段定義的順序尤為重要,它決定了哪些字段會被用作前綴索引,強烈建議您參考如下原則確定Key列順序:

  • 高頻用于過濾條件的、高基數的Key列放在其他字段之前。如Duplicate模型章節的日志場景中,日志時間log_time放在錯誤碼error_code之前。

  • 等值過濾條件的Key列放在區間過濾條件的Key列之前。如倒排索引章節的電商場景中,時間order_time通常按照區間過濾,放在訂單號order_id之后。

  • 普通類型字段放在VARCHAR類型字段之前。如INT類型的Key列放在VARCHAR類的KEY列之前。

使用示例

倒排索引章節的電商場景,訂單信息表的前綴索引為order_id+order_time,當查詢條件是前綴索引的前綴時(即查詢條件包含order_id或同時包含order_id和order_time),可以極大的加快查詢速度。如以下兩個示例,示例一的查詢速度會遠高于示例二的查詢速度。

示例一

SELECT * FROM orders WHERE order_id = 1829239 and order_time = '2024-02-01';

示例二

SELECT * FROM orders WHERE order_time = '2024-02-01';

下一步

完成本教程的前三個步驟后,您已初步了解SelectDB,并具備設計符合業務需求的數據庫表的基本能力。下一步,您可以根據后續指引,了解您業務涉及的具體功能,例如數據遷移、查詢外部數據源、版本升級等。更多功能,請參見后續指引。