Doris(二) -- 基本概念和數據表模型

来源:https://www.cnblogs.com/paopaoT/archive/2023/05/27/17437099.html
-Advertisement-
Play Games

# 欄位類型 | 數據類型 | 位元組 | 範圍 | | | | | |TINYINT|1 位元組|-2^7 + 1 ~ 2^7 - 1| |SMALLINT|2 位元組|-2^15 + 1 ~ 2^15 - 1| |INT|4 位元組|-2^31 + 1 ~ 2^31 - 1| |BIGINT|8 位元組| ...


欄位類型

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

表的基本概念

行和列

一張表包括行(Row)和列(Column);
Row 即用戶的一行數據。Column 用於描述一行數據中不同的欄位。
doris中的列分為兩類:key列和value列
key列在doris中有兩種作用:
聚合表模型中,key是聚合和排序的依據
其他表模型中,key是排序依據

數據表模型

Doris 的數據模型主要分為3類:
• Aggregate 聚合模型
• Unique 唯一模型
• Duplicate 明細模型

Aggregate 模型

相同key的數據進行自動聚合的表模型。表中的列按照是否設置了 AggregationType,分為 Key(維度列)和 Value(指標列),沒有設置AggregationType 的稱為 Key,設置了 AggregationType 的稱為 Value。當我們導入數據時,對於 Key 列相同的行會聚合成一行,而 Value 列會按照設置的AggregationType 進行聚合。AggregationType 目前有以下五種聚合方式:

  1. SUM:求和,多行的 Value 進行累加。
  2. REPLACE:替代,下一批數據中的 Value 會替換之前導入過的行中的 Value。
  3. REPLACE_IF_NOT_NULL :當遇到 null 值則不更新。
  4. MAX:保留最大值。
  5. MIN:保留最小值。

有如下場景:需要創建一個表,來記錄公司每個用戶的每一次消費行為信息,有如下欄位:
image
而且,公司對這份數據,特別關心一個報表
每一個用戶最後一次訪問我們頁面的時間,用戶消費的總金額,用戶停留在我們頁面上的最大最小時長
image
每次要看這個報表,都需要在“明細表”上運行一個統計sql

Select
    user_id,data,city,age,gender,
    max(visit_data) as last_visit_data,
    sum(cost) as cost,
    max(dwell_time) as max_dwell_time,
    min(dwell_time) as min_dwell_time
From  t
Group by  user_id,data,city,age,gender  -- 對應的是聚合模型型key

聚合模型
image

-- 這是一個用戶消費和行為記錄的數據表
CREATE TABLE IF NOT EXISTS test.ex_user
(
 `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 "用戶最小停留時間" 
 )
ENGINE=olap
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
-- 分桶 創建表時必須指定分桶 分桶的概念下麵說
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1;

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

查看數據的時候發現,數據只剩下6條了,就是因為再key相同的時候,將後面的結果聚合了

image

UNIQUE 模型

相同key的數據進行自動去重的表模型。在某些多維分析場景下,用戶更關註的是如何保證 Key 的唯一性,即如何獲得 Primary Key 唯一性約束。因此,引入了 Uniq 的數據模型。該模型本質上是聚合模型的一個特例,也是一種簡化的表結構表示方式。

-- 創建表
drop table if exists test.user;
CREATE TABLE IF NOT EXISTS test.user
(
-- key列
 `user_id` LARGEINT NOT NULL COMMENT "用戶 id",
 `username` VARCHAR(50) NOT NULL COMMENT "用戶昵稱",
 -- value列
 `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 1;

-- 插入數據
insert into test.user values\
(10000,'zss','北京',18,0,12345678910,'北京朝陽區 ','2017-10-01 07:00:00'),\
(10000,'zss','北京',19,0,12345678910,'北京順義區 ','2018-10-01 07:00:00'),\
(10000,'lss','北京',20,0,12345678910,'北京海澱區','2017-11-15 06:10:20');


insert into test.user1 values\
(10000,'zss','北京',18,0,12345678910,'北京朝陽區 ','2017-10-01 07:00:00'),\
(10000,'zss','北京',19,0,12345678910,'北京順義區 ','2018-10-01 07:00:00'),\
(10000,'lss','北京',20,0,12345678910,'北京海澱區','2017-11-15 06:10:20');

查詢結果後發現,相同的數據就會被替換掉
image

Duplicate 模型

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

-- 創建表
CREATE TABLE IF NOT EXISTS test.log_detail
(
 `timestamp` DATETIME NOT NULL COMMENT "日誌時間",
 `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(`timestamp`, `type`) -- key用作排序使用
DISTRIBUTED BY HASH(`timestamp`) BUCKETS 1;

-- 插入數據
insert into test.log_detail 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');

數據模型的選擇

數據模型在建表時就已經確定,且無法修改;所以,選擇一個合適的數據模型非常重要。

  • Aggregate 模型可以通過預聚合,極大地降低聚合查詢時所需掃描的數據量和查詢的計算量,非常適合有固定模式的報表類查詢場景。

  • Uniq 模型針對需要唯一主鍵約束的場景,可以保證主鍵唯一性約束。但是無法利用 ROLLUP 等預聚合帶來的查詢優勢(因為本質是 REPLACE,沒有 SUM 這種聚合方式)。

  • Duplicate 適合任意維度的查詢。雖然同樣無法利用預聚合的特性,但是不受聚合模型的約束,可以發揮列存模型的優勢(只讀取相關列,而不需要讀取所有 Key 列)

分區與分桶

  • partition(分區):是在邏輯上將一張表按行(橫向)劃分
  • tablet(又叫bucket,分桶):在物理上對一個分區再按行(橫向)劃分

image

分區(Partition)

• Partition 列可以指定一列或多列,在聚合模型中,分區列必須為 KEY 列。
• 不論分區列是什麼類型,在寫分區值時,都需要加雙引號。
• 分區數量理論上沒有上限。
• 當不使用 Partition 建表時,系統會自動生成一個和表名同名的,全值範圍的 Partition。該 Partition 對用戶不可見,並且不可刪改。
• 創建分區時不可添加範圍重疊的分區。

Range 分區

單列分區

drop table if exists test.expamle_range_tbl;
CREATE TABLE IF NOT EXISTS test.expamle_range_tbl
(
    `user_id` LARGEINT NOT NULL COMMENT "用戶id",
    `date` DATE NOT NULL COMMENT "數據灌入日期時間",
    `timestamp` DATETIME NOT NULL COMMENT "數據灌入的時間戳",
    `city` VARCHAR(20) COMMENT "用戶所在城市",
    `age` SMALLINT COMMENT "用戶年齡",
    `sex` TINYINT COMMENT "用戶性別"
)
ENGINE=OLAP
DUPLICATE KEY(`user_id`, `date`) -- 表模型
-- 分區的語法
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 1;

image

• 分區列通常為時間列,以方便的管理新舊數據。
• Partition 支持通過 VALUES LESS THAN (...) 僅指定上界,系統會將前一個分區的上界作為該分區的下界,生成一個左閉右開的區間。同時,也支持通過 VALUES[...) 指定上下界,生成一個左閉右開的區間。
• 通過 VALUES ...) 同時指定上下界比較容易理解。這裡舉例說明,當使用 VALUES LESS THAN (...) 語句進行分區的增刪操作時,分區範圍的變化情況:
如上 expamle_range_tbl 得建表語句中可以看到,當建表完成後,會自動生成如下3個分區:

-- 查看表中分區得情況
SHOW PARTITIONS FROM test.expamle_range_tbl \G;

-- 增加一個分區
ALTER TABLE test.expamle_range_tbl ADD PARTITION p201705 VALUES LESS THAN ("2017-06-01");

--刪除分區
ALTER TABLE test.expamle_range_tbl DROP PARTITION p201703;

-- 此時的分區狀態如下:
-- p201701: [MIN_VALUE,  2017-02-01)
-- p201702: [2017-02-01, 2017-03-01)
-- p201705: [2017-04-01, 2017-06-01)
-- 出現了一個空洞:[2017-03-01, 2017-04-01)
-- 如果導入的數據範圍在這個空洞範圍內,是無法導入的

多列分區

PARTITION BY RANGE(`date`, `id`)     前閉後開
(
    PARTITION `p201701_1000` VALUES LESS THAN ("2017-02-01", "1000"),
    PARTITION `p201702_2000` VALUES LESS THAN ("2017-03-01", "2000"),
    PARTITION `p201703_all`  VALUES LESS THAN ("2017-04-01")-- 預設採用id類型的最小值
)
-- 當用戶插入數據時,分區列值會按照順序依次比較,最終得到對應的分區

image

List分區

• 分區列支持 BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE, DATETIME, CHAR, VARCHAR 數據類型,分區值為枚舉值。只有當數據為目標分區枚舉值其中之一時,才可以命中分區。

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

-- 單列
CREATE TABLE IF NOT EXISTS test.expamle_list_tbl
(
    `user_id` LARGEINT NOT NULL COMMENT "用戶id",
    `date` DATE NOT NULL COMMENT "數據灌入日期時間",
    `timestamp` DATETIME NOT NULL COMMENT "數據灌入的時間戳",
    `city` VARCHAR(20) NOT NULL COMMENT "用戶所在城市",
    `age` SMALLINT NOT NULL COMMENT "用戶年齡",
    `sex` TINYINT NOT NULL 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 "用戶最小停留時間"
)
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 1
PROPERTIES
(
    "replication_num" = "3"
);



-- 多列
PARTITION BY LIST(`id`, `city`)
(
    PARTITION `p1_city` VALUES IN (("1", "Beijing",), ("2", "Shanghai")),
    PARTITION `p2_city` VALUES IN (("2", "Beijing"), ("1", "Shanghai")),
    PARTITION `p3_city` VALUES IN (("3", "Beijing"), ("4", "Shanghai"))

)

分桶(Bucket)

  • 如果使用了 Partition,則 DISTRIBUTED ... 語句描述的是數據在各個分區內的劃分規則。如果不使用 Partition,則描述的是對整個表的數據的劃分規則。
  • 分桶列可以是多列,但必須為 Key 列。分桶列可以和 Partition 列相同或不同。
  • 分桶列的選擇,是在 查詢吞吐 和 查詢併發 之間的一種權衡:
    • 如果選擇多個分桶列,則數據分佈更均勻。如果一個查詢條件不包含所有分桶列的等值條件,那麼該查詢會觸發所有分桶同時掃描,這樣查詢的吞吐會增加,單個查詢的延遲隨之降低。這個方式適合大吞吐低併發的查詢場景。
    • 如果僅選擇一個或少數分桶列,則對應的點查詢可以僅觸發一個分桶掃描。此時,當多個點查詢併發時,這些查詢有較大的概率分別觸發不同的分桶掃描,各個查詢之間的IO影響較小(尤其當不同桶分佈在不同磁碟上時),所以這種方式適合高併發的點查詢場景。
  • 分桶的數量理論上沒有上限

image
關於 Partition 和 Bucket的數量和數據量的建議。

  1. 一個表的 Tablet 總數量等於 (Partition num * Bucket num)。
  2. 一個表的 Tablet 數量,在不考慮擴容的情況下,推薦略多於整個集群的磁碟數量。
  3. 單個 Tablet 的數據量理論上沒有上下界,但建議在 1G - 10G 的範圍內。如果單個 Tablet 數據量過小,則數據的聚合效果不佳,且元數據管理壓力大。如果數據量過大,則不利於副本的遷移、補齊,且會增加 Schema Change 或者 Rollup 操作失敗重試的代價(這些操作失敗重試的粒度是 Tablet)。分桶應該控制桶內數據量 ,不易過大或者過小
  4. 當 Tablet 的數據量原則和數量原則衝突時,建議優先考慮數據量原則。
  5. 在建表時,每個分區的 Bucket 數量統一指定。但是在動態增加分區時(ADD PARTITION),可以單獨指定新分區的 Bucket 數量。可以利用這個功能方便的應對數據縮小或膨脹。
  6. 一個 Partition 的 Bucket 數量一旦指定,不可更改。所以在確定 Bucket 數量時,需要預先考慮集群擴容的情況。比如當前只有 3 台 host,每台 host 有 1 塊盤。如果 Bucket 的數量只設置為 3 或更小,那麼後期即使再增加機器,也不能提高併發度。

註:表的數據量可以通過 SHOW DATA命令查看,結果除以副本數,即表的數據量。

複合分區與單分區的選擇

複合分區
• 第一級稱為 Partition,即分區。用戶可以指定某一維度列作為分區列(當前只支持整型和時間類型的列),並指定每個分區的取值範圍。
• 第二級稱為 Distribution,即分桶。用戶可以指定一個或多個維度列以及桶數對數據進行 HASH 分佈。

以下場景推薦使用複合分區
• 有時間維度或類似帶有有序值的維度,可以以這類維度列作為分區列。分區粒度可以根據導入頻次、分區數據量等進行評估。地域、時間
• 歷史數據刪除需求:如有刪除歷史數據的需求(比如僅保留最近N 天的數據)。使用複合分區,可以通過刪除歷史分區來達到目的。也可以通過在指定分區內發送 DELETE 語句進行數據刪除。
• 改善數據傾斜問題:每個分區可以單獨指定分桶數量。如按天分區,當每天的數據量差異很大時,可以通過指定分區的分桶數,合理劃分不同分區的數據,分桶列建議選擇區分度大的列。
用戶也可以不使用複合分區,即使用單分區。則數據只做 HASH 分佈。

PROPERTIES

在建表語句的最後,可以用 PROPERTIES 關鍵字來設置一些表的屬性參數(參數有很多)

PROPERTIES(
  "參數名" = "參數值"
)

分片副本數(replication_num)

每個 Tablet 的副本數量。預設為 3,建議保持預設即可。在建表語句中,所有 Partition中的 Tablet 副本數量統一指定。而在增加新分區時,可以單獨指定新分區中 Tablet 的副本數量。

副本數量可以在運行時修改。強烈建議保持奇數。

最大副本數量取決於集群中獨立 IP 的數量(註意不是 BE 數量)。Doris 中副本分佈的原則是,不允許同一個 Tablet 的副本分佈在同一臺物理機上,而識別物理機即通過 IP。所以,即使在同一臺物理機上部署了 3 個或更多 BE 實例,如果這些 BE 的 IP 相同,則依然只能設置副本數為 1。對於一些小,並且更新不頻繁的維度表,可以考慮設置更多的副本數。這樣在 Join 查詢時,可以有更大的概率進行本地數據 Join。

存儲介質 和 熱數據冷卻時間

• storage_medium
• storage_cooldown_time
建表時,可以統一指定所有 Partition 初始存儲的介質及熱數據的冷卻時間,如:

"storage_medium" = "SSD"

-- 要在當前時間之後,並且是一個datetime類型 
"storage_cooldown_time" = "2023-04-20 00:00:00"

-- 預設初始存儲介質可通過 fe 的配置文件 fe.conf 中指定 default_storage_medium=xxx,如果沒有指定,則預設為 HDD。如果指定為 SSD,則數據初始存放在 SSD 上。沒設storage_cooldown_time,則預設 30 天後,數據會從 SSD 自動遷移到 HDD上。如果指定了 storage_cooldown_time,則在到達 storage_cooldown_time 時間後,數據才會遷移。

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡訊在實現的邏輯上,也遵循消息中心的基礎設計,即消息生產之後,通過消息中心進行投遞和消費,屬於典型的生產消費模型; ...
  • # 1.新建python項目 1. 在編寫程式之前,我們需要新建一個項目(Project),在桌面雙擊PyCharm的快捷方式![image](https://img2023.cnblogs.com/blog/3179433/202305/3179433-20230526074257088-7431 ...
  • # WPF佈局基礎 ## WPF的佈局原則 + 一個視窗中只能包含一個元素 + 不應顯示設置元素尺寸 + 不應使用坐標設置元素的位置 + 可以嵌套佈局容器 ## WPF有哪些佈局容器? + Grid:網格。可以自定義行和列並通過行列的數量、行高和列寬來調整控制項的佈局。近似於HTML中的Table。 ...
  • 1. 什麼是MAF和MEF? MEF和MEF微軟官方介紹:https://learn.microsoft.com/zh-cn/dotnet/framework/mef/ MEF是輕量化的插件框架,MAF是複雜的插件框架。 因為MAF有進程隔離和程式域隔離可選。我需要插件進程隔離同時快速傳遞數據,最後 ...
  • 有個.NET面試官反饋面試了一個小白,問他用過哪些.NET庫,結果只回答上了幾個。作為一個.NET開發者,瞭解一些常用的.NET庫是非常重要的。本文將介紹.NET開發人員應該瞭解的10個常用.NET庫,這些庫可以幫助開發人員提高開發效率、簡化開發流程,開發出優秀的.NET應用程式。 **1、Auto ...
  • 《機器人SLAM導航核心技術與實戰》第1季:第5章_機器人主機 視頻講解 【第1季】5.第5章_機器人主機-視頻講解 【第1季】5.1.第5章_機器人主機_X86與ARM主機對比-視頻講解 【第1季】5.2.第5章_機器人主機_ARM主機樹莓派3B+-視頻講解 【第1季】5.3.第5章_機器人主機_ ...
  • # shell 常用命令3 ## 1 sed 用來自動編輯文件,可以用來實現替換配置文件的配置 ```shell 語法: sed [-hnV][-e][-f][文本文件] ``` > **參數說明**: > > - -e\或--expression=\ 以選項中指定的script來處理輸入的文本文件 ...
  • 要使用 `systemctl` 啟動單個服務,其中包含多個進程,你可以使用 Systemd 的 `template` 機制。以下是使用 Systemd 'template' 以創建一個可同時啟動多個進程的服務單元文件的過程: 1. 為你的服務創建一個 template 服務單元文件。服務單元文件通常 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...