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

為什么要給數(shù)據(jù)庫加索引?轉(zhuǎn)自 https: //blog.tankery.me/development/why-we-need-indexes-for-database

這篇具有很好參考價(jià)值的文章主要介紹了為什么要給數(shù)據(jù)庫加索引?轉(zhuǎn)自 https: //blog.tankery.me/development/why-we-need-indexes-for-database。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

這篇文章不是數(shù)據(jù)庫索引的使用文檔,不會給每個功能的使用都做介紹,而是通過我自己的案例,對案例中遇到的幾個點(diǎn)做詳細(xì)的說明。如果想查看具體的使用幫助,可以參考官網(wǎng)的文檔:Query Planning

“老譚,測試發(fā)現(xiàn)睡眠歷史記錄頁面的打開速度太慢了,你給快速解決一下唄,明天發(fā)版?!?/p>

嗯,所以我還可以換一個標(biāo)題:“如何在1天之內(nèi)將頁面加載性能提升10倍以上”。。行了不廢話,給大家講講這個故事。

太長不看版

  1. 數(shù)據(jù)庫存儲順序隨機(jī),如果沒有索引,每次查詢都需要一行行遍歷,查找出符合條件的點(diǎn),復(fù)雜度 O(N)
  2. 數(shù)據(jù)庫會按照 rowid 排序,并給主鍵建立索引,所以如果以 rowid 或者主鍵為搜索條件,復(fù)雜度可以近似看做二分查找的復(fù)雜度,即 O(logN)
  3. 如果沒有主鍵,或搜索條件不是主鍵,可以給搜索目標(biāo)增加索引,將該字段的搜索復(fù)雜度,提升到 O(logN)
  4. 如果搜索條件有多個,可以建立組合索引 (multi-column index),將搜索復(fù)雜度,降低到 O(k * logN)
  5. 注意,如果搜索條件中帶有范圍的搜索,可能導(dǎo)致索引失效,退化到 O(N) 復(fù)雜度,可以通過合理排列聯(lián)合索引的字段順序來避免。

好了,如果這個精簡版看得不過癮,那就請繼續(xù)閱讀,我會用一個案例,也就是本次性能優(yōu)化的故事,來解釋上面的幾點(diǎn)。

問題背景

首先,我們需要先來了解一下我們睡眠應(yīng)用的數(shù)據(jù)設(shè)計(jì),讓大家對問題域有個基本的了解。

睡眠采用了類似?Google Fit API?的設(shè)計(jì),將睡眠分為?DataSession?和?DataPoint?兩部分。session 主要用于記錄一次睡眠的開始和結(jié)束時間,而 point 則是所有數(shù)據(jù)的存儲結(jié)構(gòu)。睡眠深度、心率等數(shù)據(jù),都是以 point 的形式存儲在一張大表中。如果需要展現(xiàn)一次睡眠的記錄,需要首先查找出 session,之后根據(jù) session 的起止時間,找出這個區(qū)間的所有 point。

下面我們簡化一下這個問題,假設(shè) DataPoint 有下面的結(jié)構(gòu):

class DataPoint {
    int type;
    long time;
    String values;
    String account;
}

它確定了數(shù)據(jù)的類型、數(shù)據(jù)發(fā)送的時間,數(shù)據(jù)的值,以及所屬賬號。

每個 point 都是獨(dú)立的,可能被任何 session 包含,所以也有著獨(dú)立的數(shù)據(jù)同步邏輯。如需加載一段睡眠,那么需要將這段睡眠時間內(nèi)所有的 point 都加載出來。在用戶打開歷史記錄頁面時,這個加載過程大致分為這么幾步:

  1. 從數(shù)據(jù)庫查找當(dāng)前頁面時間范圍內(nèi)的 point,更新到UI。
  2. 向服務(wù)器請求這段時間的數(shù)據(jù),用于更新本地的數(shù)據(jù)。
  3. 從服務(wù)器拉下一串 point 后,更新數(shù)據(jù)庫。如果 point 不存在,則插入該點(diǎn),如果已經(jīng)存在,則跳過。
  4. 再次更新UI。

睡眠歷史每次展現(xiàn)一個月,加上預(yù)加載的一個月,需要一次加載兩個月的數(shù)據(jù)。假設(shè)每天有一段8小時的睡眠,每10分鐘有一個睡眠深度數(shù)據(jù),那么就需要一次加載近3000個數(shù)據(jù)點(diǎn)。

感官上認(rèn)為,這個速度肯定會很慢,但是具體慢在哪里,心里還沒底。于是利用 Android Studio 的?Android Profiler?工具,對加載過程做了分析。最終發(fā)現(xiàn)占用絕大部分時間的,就是數(shù)據(jù)庫的查詢操作。

這是因?yàn)椋趶姆?wù)器拉下更新的 points 后,需要更新數(shù)據(jù)庫。由于需要避免重復(fù)數(shù)據(jù)的插入,所以在每個點(diǎn)的插入前,都需要查找是否有重復(fù)的點(diǎn)。如果與數(shù)據(jù)庫現(xiàn)有點(diǎn)重復(fù),則需跳過。這就需要大量的查詢的操作,如果說數(shù)據(jù)庫有 M 個點(diǎn),從服務(wù)器拉下 N 個點(diǎn),最壞情況,使用遍歷查詢的話,需要做 M x N 次比對,復(fù)雜度是 O(MN)。

那么數(shù)據(jù)庫查詢的復(fù)雜度到底是多少呢?

數(shù)據(jù)庫查詢原理

首先我們需要知道,雖然數(shù)據(jù)庫利用 SQL 語句來構(gòu)建查詢條件,查詢的過程是個黑盒,但它也不是什么魔法,我們可以通過理性分析來估計(jì)其復(fù)雜度。

假設(shè)我們有如下的數(shù)據(jù)表(有一個默認(rèn)的自增長的 rowid):

rowid type time values account
1 1 10 ”” “tankery”
2 2 10 ”” “tankery”
3 1 50 ”” “l(fā)ilya”
4 1 20 ”” “tankery”
5 2 20 ”” “l(fā)ilya”

可以看到,由于點(diǎn)的插入順序是隨機(jī)的,數(shù)據(jù)點(diǎn)是亂序排列的。那如果我們需要知道一個新的點(diǎn)是否與現(xiàn)有點(diǎn)重復(fù),需要怎么做呢?由于存儲結(jié)構(gòu)是亂序的,我們只能一個個遍歷。比如我們想知道 {type: 1, time: 20, account: “tankery”} 的點(diǎn)是否與現(xiàn)有數(shù)據(jù)重復(fù),我們可以構(gòu)建下面的查詢:

SELECT count(*) FROM `data_point`
  WHERE `type` = 1
  AND `time` = 20
  AND `account` = "tankery";

這樣的一個查詢,需要給每一行數(shù)據(jù)都做比較,確定 type, time, account 是否符合條件。其復(fù)雜度是 O(N)。這個性能有多差呢?看看下面這個圖來直觀的感受下:

為什么要給數(shù)據(jù)庫加索引?轉(zhuǎn)自 https: //blog.tankery.me/development/why-we-need-indexes-for-database,數(shù)據(jù)庫,oracle

來源:Jason Feinstein 的博客

也就是說,隨著數(shù)據(jù)量的增大,對排序過的數(shù)據(jù)做二分查找,其時間增長相對 O(N) 來說,幾乎可以忽略不計(jì)了。

那么如何確定數(shù)據(jù)庫的查詢,采用的是什么方法?復(fù)雜度是什么?下面祭出神器,EXPLAIN QUERY PLAN。在查詢語句前加上這句話,讓數(shù)據(jù)庫給你解釋清楚它的查詢計(jì)劃。讓你清清楚楚建索引,明明白白做查詢。那么我們就用這個神器來看看,沒加索引的數(shù)據(jù)庫,采用的是什么方案(我這里使用的是 SQLite 數(shù)據(jù)庫,我猜其他數(shù)據(jù)庫應(yīng)該也會有類似功能):

EXPLAIN QUERY PLAN
SELECT count(*) FROM `data_point`
  WHERE `type` = 1
  AND `time` = 20
  AND `account` = "tankery";

查詢的結(jié)果是:

selectid order from detail
0 0 0 SCAN TABLE data_point

可以看到,沒有增加索引的數(shù)據(jù)庫,確實(shí)是只能使用遍歷 (SCAN) 的方式來一行一行比對了。那么,是時候談?wù)勊饕恕?/p>

數(shù)據(jù)庫索引

索引,就是給某個字段建立了一個排序表,就像是圖書館按照圖書的編號進(jìn)行排序,查找某個編號的圖書時,只需要使用類似二分查找的方式,就可以迅速找到對應(yīng)的圖書了。

數(shù)據(jù)庫會分配一個額外的空間,用來存儲索引表,每次對數(shù)據(jù)庫的修改(插入、修改、刪除),也都會對應(yīng)的修改索引表,所以增加索引以后,會一定程度的增加數(shù)據(jù)庫大小,和數(shù)據(jù)庫修改的時間。因此,如果你的數(shù)據(jù)庫是修改多,查詢少,那么就需要三思一下,增加索引是否有必要了。

對于上面的數(shù)據(jù)表,我們可以用下面的語句對 type 建索引:

CREATE INDEX IF NOT EXISTS "point_type" ON `data_point`(type);

這行SQL語句為 data_point 數(shù)據(jù)表的 type 字段建立了一個名為 point_type 的索引。建立以后,索引表將會以類似下面這樣的形式組織:

type rowid
1 1
1 3
1 4
2 2
2 5

可以看到,索引表按照 type 進(jìn)行了排序,這樣,當(dāng)我們應(yīng)用查詢語句時,數(shù)據(jù)庫能夠非常迅速的在索引表中找到符合條件的 type,并通過對應(yīng)的 rowid,找到原數(shù)據(jù)表中所有值。使用?EXPLAIN QUERY PLAN?來驗(yàn)證一下我們的想法:

selectid order from detail
0 0 0 SEARCH TABLE data_point USING INDEX point_type (type=?)

數(shù)據(jù)庫誠不欺我,真的使用了 INDEX 來 SEARCH,而不是 SCAN 了。但是,聰明的你是否發(fā)現(xiàn),這個索引對于我們的查詢并沒有什么用,迅速查到 type = 1 的數(shù)據(jù),然后呢?除 type 之外的內(nèi)容沒有排序,還是有一大半的數(shù)據(jù)需要一個個查詢。

這時我們會想,既然索引能加快目標(biāo)字段的查詢速度,那既然我們的查詢需要依賴多個字段,那給每個字段都給建立個索引不就行了?不錯,來試試:

CREATE INDEX IF NOT EXISTS "point_type" ON `data_point`(type);
CREATE INDEX IF NOT EXISTS "point_time" ON `data_point`(time);
CREATE INDEX IF NOT EXISTS "point_account" ON `data_point`(account);

然后再次使用?EXPLAIN QUERY PLAN?來驗(yàn)證我們的想法:

selectid order from detail
0 0 0 SEARCH TABLE data_point USING INDEX point_type (type=?)

瘋了瘋了,已經(jīng)為每個字段都加上了索引,這個數(shù)據(jù)庫怎么不聽話,還是只用 type??“這屆數(shù)據(jù)庫不行”。

但冷靜下來想想,為每個字段單獨(dú)建立索引,就會建立三個依照不同字段進(jìn)行排序的獨(dú)立的索引表,當(dāng)我們使用 type 來索引,這些行對應(yīng)到其他兩個表,就是亂序的,無法二分查找。

這時我們會想,不是還有個組合索引么,可以用它么?

組合索引 (multi-column index)

我們先丟掉之前創(chuàng)建的那些沒用的東西:

DROP INDEX IF EXISTS `point_type`;
DROP INDEX IF EXISTS `point_time`;
DROP INDEX IF EXISTS `point_account`;

然后可以用下面的語句來創(chuàng)建一個組合索引:

CREATE INDEX IF NOT EXISTS "point_query" ON `data_point`(type, time, account);

這是什么意思呢?其實(shí),組合索引,會將指定的字段,都放入同一張索引表,并且會按照創(chuàng)建時的順序,對各個字段依次進(jìn)行排序。也就是說,對于上面的索引,數(shù)據(jù)庫會先按照 type 排序,再按照 time,然后是 account。這張索引表建立起來,是類似下面這個樣子的:

type time account rowid
1 10 “tankery” 1
1 20 “tankery” 4
1 50 “l(fā)ilya” 3
2 10 “tankery” 2
2 20 “l(fā)ilya” 5

可以看到,首先是按照 type 排序,如果 type 相等,就按照 time 排序,如果 time 也相等,才會按照 account 排序。看起來不錯,我們再用?EXPLAIN QUERY PLAN?驗(yàn)證一下:

selectid order from detail
0 0 0 SEARCH TABLE data_point USING COVERING INDEX point_query (type=? AND time=? AND account=?)

非常棒!將三個查詢條件全都囊括了,而且,原來的 “USING INDEX” 變成了 “USING COVERING INDEX”,什么意思呢?好事壞事?

其實(shí) COVERING INDEX 指的是,索引表已經(jīng)包含了所有查詢所需的信息,無需再通過 rowid 到原始數(shù)據(jù)表中去查找原始數(shù)據(jù)行了。上面這個例子,由于索引表已經(jīng)包含了所有查詢條件,而且我們僅需要 count,不需要具體信息,因此僅僅查詢索引表就已經(jīng)可以獲取到我們所需的查詢結(jié)果。這使得查詢速度又提升了一倍(不需要通過rowid進(jìn)行二次查找)。

看起來非常完美了,打完收工?

范圍查詢 (RANGE SCAN)

范圍查詢實(shí)際上是個比較復(fù)雜的用法了,大部分講數(shù)據(jù)庫索引的文章都不會做介紹,但沒辦法,很多時候我們就是需要做范圍查詢。比如回到我們的問題域。有一個需求是需要加載一個月中所有的數(shù)據(jù)點(diǎn),也就是數(shù)據(jù)點(diǎn)的 time 字段在某個時間范圍內(nèi)的所有數(shù)據(jù)點(diǎn),這時,還能不能優(yōu)雅的使用索引來查詢呢?

如果我們?nèi)匀皇褂们拔牡慕M合索引,那么還是使用?EXPLAIN QUERY PLAN?來查看數(shù)據(jù)庫的查詢策略:

EXPLAIN QUERY PLAN
SELECT * FROM `data_point`
  WHERE `type` = 1
  AND `time` >= 20
  AND `time` < 100
  AND `account` = "tankery";

結(jié)果如下:

selectid order from detail
0 0 0 SEARCH TABLE data_point USING INDEX point_query (type=? AND time>? AND time<?)

為何 account 的索引沒有用上?

回到組合索引的實(shí)現(xiàn),我們發(fā)現(xiàn),當(dāng)我們的查詢中包含了一個范圍查詢以后,由于 time 的值是在一個范圍內(nèi),而不是特定的值時,account 字段就是亂序的了,因?yàn)?account 只有在 time 一致時,才會排序。也就是說,如果需要用上某個字段的索引,那么就必須確保這個字段的前序字段,都是確定的值。

這就引出了建立索引時一個非常重要的原則:“相等查詢的字段,盡量放在組合索引的前面”。

對于我們的業(yè)務(wù)需求,你會發(fā)現(xiàn),我們還是有機(jī)會用上所有字段的索引,因?yàn)?account 字段,實(shí)際上也是相等查詢。我們按照這個原則,重新創(chuàng)建索引:

DROP INDEX IF EXISTS `point_query`;
CREATE INDEX IF NOT EXISTS "point_query" ON `data_point`(type, account, time);

這個索引建立以后,索引表大概是這個樣子:

type account time rowid
1 “l(fā)ilya” 50 3
1 “tankery” 10 1
1 “tankery” 20 4
2 “l(fā)ilya” 20 5
2 “tankery” 10 2

也就是按照 type -> account -> time 的順序進(jìn)行排序了。我們分析一下查詢策略,結(jié)果如下:

selectid order from detail
0 0 0 SEARCH TABLE data_point USING INDEX point_query (type=? AND account=? AND time>? AND time<?)

終于,我們再次用上了所有的索引字段。

實(shí)測發(fā)現(xiàn),所有的數(shù)據(jù)庫操作,時間都降到了1s以下,對于一個異步加載,我已經(jīng)心滿意足了。

參考資料

如果你覺得我的故事不好聽,或者想了解更多,可以看看下面幾篇為你精選的文章,祝好。

  • Jason Feinstein:?Squeezing Performance from SQLite: Indexes? Indexes!
  • SQLite Org:?Query Planning
  • Range Query:?Using the Index, Luke

written by: Tankery Chen文章來源地址http://www.zghlxwxcb.cn/news/detail-774428.html

到了這里,關(guān)于為什么要給數(shù)據(jù)庫加索引?轉(zhuǎn)自 https: //blog.tankery.me/development/why-we-need-indexes-for-database的文章就介紹完了。如果您還想了解更多內(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)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

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

相關(guān)文章

  • 公司為什么選擇云數(shù)據(jù)庫?它的魅力到底是什么!

    亞馬遜云科技提供了100余種產(chǎn)品免費(fèi)套餐。其中,計(jì)算資源Amazon EC2首年12個月免費(fèi),750小時/月;存儲資源 Amazon S3 首年12個月免費(fèi),5GB標(biāo)準(zhǔn)存儲容量;數(shù)據(jù)庫資源 Amazon RDS 首年12個月免費(fèi),750小時;Amazon Dynamo DB 25GB存儲容量 永久免費(fèi)。) 談到數(shù)據(jù)庫想必我們都不陌生,其中主流

    2024年02月04日
    瀏覽(24)
  • 什么是 Java 中的數(shù)據(jù)庫連接池?為什么使用連接池來管理數(shù)據(jù)庫連接?

    什么是 Java 中的數(shù)據(jù)庫連接池?為什么使用連接池來管理數(shù)據(jù)庫連接?

    數(shù)據(jù)庫連接池(database connection pool)是在 Java 中用于管理數(shù)據(jù)庫連接的一種技術(shù)。它的主要目的是提高數(shù)據(jù)庫連接的重用性和性能。在傳統(tǒng)的數(shù)據(jù)庫連接方式中,每次與數(shù)據(jù)庫建立連接時都需要進(jìn)行一系列的網(wǎng)絡(luò)通信和身份驗(yàn)證操作,這樣的開銷較大并且會影響應(yīng)用程序的性

    2024年02月06日
    瀏覽(33)
  • Elasticsearch:什么是向量和向量存儲數(shù)據(jù)庫,我們?yōu)槭裁搓P(guān)心?

    Elasticsearch:什么是向量和向量存儲數(shù)據(jù)庫,我們?yōu)槭裁搓P(guān)心?

    Elasticsearch 從 7.3 版本開始支持向量搜索。從 8.0 開始支持帶有 HNSW 的 ANN 向量搜索。目前 Elasticsearch 已經(jīng)是全球下載量最多的向量數(shù)據(jù)庫。它允許使用密集向量和向量比較來搜索文檔。 向量搜索在人工智能和機(jī)器學(xué)習(xí)領(lǐng)域有許多重要的應(yīng)用。 有效存儲和檢索向量的數(shù)據(jù)庫對于

    2024年02月08日
    瀏覽(31)
  • 為什么說PostgreSQL是面向?qū)ο蟮臄?shù)據(jù)庫?

    PostgreSQL 官方宣稱它是世界上最先進(jìn)的開源對象-關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(ORDBMS)。相信大家對于關(guān)系型數(shù)據(jù)庫并不陌生,它基于關(guān)系模型(由行和列組成的二維表),定義了完整性約束并且使用 SQL 作為操作語言。 不過今天我們的主題不是關(guān)系模型,而是 PostgreSQL 提供的面向

    2024年03月25日
    瀏覽(26)
  • 為什么數(shù)據(jù)庫要允許沒有主鍵的表存在

    在數(shù)據(jù)庫設(shè)計(jì)中,主鍵是一個關(guān)鍵概念,用于唯一標(biāo)識數(shù)據(jù)庫表中的每一行數(shù)據(jù)。然而,有時候數(shù)據(jù)庫允許沒有主鍵的表存在的情況,這可能會引起一些爭議和疑問。本文將探討為什么數(shù)據(jù)庫允許沒有主鍵的表以及相關(guān)的考慮因素。 主鍵在數(shù)據(jù)庫中具有以下作用: 唯一標(biāo)識

    2024年02月08日
    瀏覽(32)
  • mysql面試題30:什么是數(shù)據(jù)庫連接池、應(yīng)用程序和數(shù)據(jù)庫建立連接的過程、為什么需要數(shù)據(jù)庫連接池、你知道哪些數(shù)據(jù)庫連接池

    mysql面試題30:什么是數(shù)據(jù)庫連接池、應(yīng)用程序和數(shù)據(jù)庫建立連接的過程、為什么需要數(shù)據(jù)庫連接池、你知道哪些數(shù)據(jù)庫連接池

    該文章專注于面試,面試只要回答關(guān)鍵點(diǎn)即可,不需要對框架有非常深入的回答,如果你想應(yīng)付面試,是足夠了,抓住關(guān)鍵點(diǎn) 數(shù)據(jù)庫連接池是一種用于管理和復(fù)用數(shù)據(jù)庫連接的技術(shù)。它是在應(yīng)用程序和數(shù)據(jù)庫之間建立一組數(shù)據(jù)庫連接,并以池的形式存儲起來,每當(dāng)應(yīng)用程序需

    2024年02月07日
    瀏覽(31)
  • 數(shù)據(jù)庫——Redis 沒有使用多線程?為什么不使用多線程?

    數(shù)據(jù)庫——Redis 沒有使用多線程?為什么不使用多線程?

    雖然說 Redis 是單線程模型,但是, 實(shí)際上, Redis 在 4.0 之后的版本中就已經(jīng)加入了對多線程的支持。 不過,Redis 4.0 增加的多線程主要是針對一些大鍵值對的刪除操作的命令,使用這些命令就會使用主處理之外的其他線程來“異步處理”。 大體上來說, Redis 6.0 之前主要還是

    2024年02月11日
    瀏覽(31)
  • AIGC基礎(chǔ):大型語言模型 (LLM) 為什么使用向量數(shù)據(jù)庫,嵌入(Embeddings)又是什么?

    嵌入: 它是指什么?嵌入是將數(shù)據(jù)(例如文本、圖像或代碼)轉(zhuǎn)換為高維向量的數(shù)值表示。這些向量捕捉了數(shù)據(jù)點(diǎn)之間的語義含義和關(guān)系??梢詫⑵淅斫鉃閷?fù)雜數(shù)據(jù)翻譯成 LLM 可以理解的語言。 為什么有用?原始數(shù)據(jù)之間的相似性反映在高維空間中對應(yīng)向量之間的距離上。

    2024年02月21日
    瀏覽(101)
  • Facebook 用戶量十分龐大,為什么還使用 MySQL 數(shù)據(jù)庫?

    Facebook 用戶量十分龐大,為什么還使用 MySQL 數(shù)據(jù)庫?

    當(dāng)談到社交媒體巨頭Facebook時,我們立刻想到的是其龐大的用戶基礎(chǔ)和每日海量的數(shù)據(jù)流。然而,您可能會驚訝地發(fā)現(xiàn),盡管面對如此巨大的規(guī)模,F(xiàn)acebook 仍然選擇使用 MySQL 數(shù)據(jù)庫作為其核心的數(shù)據(jù)存儲和管理系統(tǒng)。 為什么Facebook沒有選擇其他更強(qiáng)大或更高級的數(shù)據(jù)庫系統(tǒng)?

    2024年02月04日
    瀏覽(26)
  • 數(shù)據(jù)庫為什么使用B+樹而不是B樹做索引

    數(shù)據(jù)庫為什么使用B+樹而不是B樹做索引

    ??作者簡介,黑夜開發(fā)者,CSDN領(lǐng)軍人物,全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者?,CSDN博客專家,阿里云社區(qū)專家博主,2023年6月CSDN上海賽道top4。 ??數(shù)年電商行業(yè)從業(yè)經(jīng)驗(yàn),歷任核心研發(fā)工程師,項(xiàng)目技術(shù)負(fù)責(zé)人。 ??本文已收錄于PHP專欄:MySQL的100個知識點(diǎn)。 ??歡迎 ??點(diǎn)贊?評論?收

    2024年02月10日
    瀏覽(23)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包