新聞中心
數(shù)據(jù)庫布局是數(shù)據(jù)庫設(shè)計(jì)與管理的重要一環(huán),好的數(shù)據(jù)庫布局可以極大地提高數(shù)據(jù)庫的性能與可維護(hù)性。因此,在數(shù)據(jù)庫設(shè)計(jì)的過程中,優(yōu)化數(shù)據(jù)庫布局是一個(gè)至關(guān)重要的步驟。

下面將從以下三個(gè)方面探討如何優(yōu)化數(shù)據(jù)庫布局:表設(shè)計(jì)、數(shù)據(jù)類型選擇與索引設(shè)計(jì)。
一、表設(shè)計(jì)
在數(shù)據(jù)庫設(shè)計(jì)中,表設(shè)計(jì)是最為基礎(chǔ)性的設(shè)計(jì)。因此,對(duì)表的設(shè)計(jì)需要特別重視。
1. 規(guī)范化設(shè)計(jì)
規(guī)范化是指將相對(duì)松散的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為規(guī)范的關(guān)系型數(shù)據(jù)庫模式。規(guī)范化設(shè)計(jì)是數(shù)據(jù)庫設(shè)計(jì)的重要策略之一,可以避免數(shù)據(jù)冗余,提高數(shù)據(jù)的一致性和完整性。在表設(shè)計(jì)時(shí),要根據(jù)實(shí)際需求對(duì)數(shù)據(jù)進(jìn)行規(guī)范化設(shè)計(jì)。規(guī)范化設(shè)計(jì)是一個(gè)以數(shù)據(jù)為中心的過程,它注重?cái)?shù)據(jù)之間的關(guān)系,而非表間關(guān)系。正確的規(guī)范化設(shè)計(jì)可以避免數(shù)據(jù)冗余,實(shí)現(xiàn)數(shù)據(jù)的一致性和完整性。
2. 主鍵設(shè)計(jì)
表設(shè)計(jì)還需要使用正確的主鍵,主鍵不僅是該表的唯一標(biāo)識(shí)符,還是該表與其他表的關(guān)系的建立基礎(chǔ)。在設(shè)計(jì)主鍵時(shí),要遵循以下原則:簡(jiǎn)潔性、穩(wěn)定性、唯一性、簡(jiǎn)單性。
二、數(shù)據(jù)類型選擇
在數(shù)據(jù)庫設(shè)計(jì)中,選擇合適的數(shù)據(jù)類型可以極大地影響系統(tǒng)的性能。
1. 數(shù)字類型選擇
數(shù)據(jù)庫中使用的數(shù)字類型主要包括int、bigint、float、double、decimal等。在選擇數(shù)字類型時(shí),要根據(jù)實(shí)際需要選擇正確的數(shù)據(jù)類型。一般來說,越小的數(shù)據(jù)類型速度越快,但存儲(chǔ)的大小也越小。如果需要處理很大的數(shù)字,可以使用bigint等大號(hào)整型。如果需要進(jìn)行小數(shù)計(jì)算,可以使用float和double。如果需要精確計(jì)算可以使用decimal類型。
2. 字符串類型選擇
在數(shù)據(jù)庫中使用的字符串類型主要包括char、varchar、text等。在設(shè)計(jì)字符串類型時(shí),要根據(jù)實(shí)際需要選擇正確的數(shù)據(jù)類型。一般來說,如果字符的長(zhǎng)度是在30個(gè)字符以內(nèi),可以使用char類型;如果字符的長(zhǎng)度不固定,可以使用varchar類型; 如果存儲(chǔ)的內(nèi)容比較大,可以使用text類型。
三、索引設(shè)計(jì)
索引是數(shù)據(jù)庫中的一種重要資源,對(duì)于提高數(shù)據(jù)庫性能有著至關(guān)重要的貢獻(xiàn)。
1. 建立主鍵索引
主鍵索引是一種特殊的索引,它是根據(jù)主鍵列建立的。主鍵是唯一的,所以主鍵索引非???,對(duì)于查詢單個(gè)行和排序非常有用。
2. 建立唯一索引
唯一索引是一種特殊的索引,它能夠保證索引列的唯一性。它通常用于約束模式中的某些字段,如賬戶名、手機(jī)號(hào)碼等。如果需要對(duì)表進(jìn)行大量的查找和統(tǒng)計(jì)操作,可以建立唯一索引。
3. 建立復(fù)合索引
復(fù)合索引是指將多個(gè)列的索引組合在一起,用于提高聯(lián)合查找的效率。通過合理地建立復(fù)合索引,可以提高查詢的效率,減少對(duì)物理存儲(chǔ)的訪問次數(shù),從而提高查詢性能。
優(yōu)化數(shù)據(jù)庫布局是數(shù)據(jù)庫設(shè)計(jì)中的一項(xiàng)關(guān)鍵步驟。正確的數(shù)據(jù)庫布局可以提高數(shù)據(jù)庫的查詢效率,降低系統(tǒng)崩潰和數(shù)據(jù)丟失的風(fēng)險(xiǎn),從而提高數(shù)據(jù)庫的可靠性和可擴(kuò)展性。因此,數(shù)據(jù)庫設(shè)計(jì)人員在進(jìn)行數(shù)據(jù)庫設(shè)計(jì)時(shí),需要遵循規(guī)范化設(shè)計(jì)原則,選擇正確的數(shù)據(jù)類型,并合理地建立索引,從而優(yōu)化數(shù)據(jù)庫布局。
相關(guān)問題拓展閱讀:
- 如何自己實(shí)現(xiàn)一個(gè)關(guān)系型數(shù)據(jù)庫
- 如何自己實(shí)現(xiàn)一個(gè)關(guān)系型數(shù)據(jù)庫
如何自己實(shí)現(xiàn)一個(gè)關(guān)系型數(shù)據(jù)庫
先寫一個(gè)并發(fā)控制子系統(tǒng)。里面要提供各種各樣的閂鎖。包括具有不同相容性矩陣的,有優(yōu)先隊(duì)列或者沒有的,能指數(shù)后退或者不能的,全局可追蹤的或者不可追蹤的,等等等等。
然
后寫一個(gè)存儲(chǔ)管理子系統(tǒng)。在這里你可以決定你的數(shù)據(jù)庫的外存布局。比如一個(gè)表可不可以分開幾個(gè)文件存,有沒有區(qū)的概念,有沒有段的概念,有沒有表空間的概
念,它們之中誰是定長(zhǎng)的,誰是可變長(zhǎng)的,誰是空間申請(qǐng)單位,誰是空間調(diào)度單位。決定好了開始設(shè)計(jì)頁區(qū)段表空間格式,它們的描述符格式,然后用頁頭,頁記
錄,頁尾有的沒的串一起。設(shè)計(jì)好了開始決定這個(gè)子系統(tǒng)有哪些內(nèi)存對(duì)象,至少要有一個(gè)存儲(chǔ)管理器用來初始化,分配或者調(diào)度存儲(chǔ)單元,至少還要提供一堆方法來
決定怎么把二進(jìn)制數(shù)據(jù)變成有意義的數(shù)據(jù),比如讀一個(gè)ushort, 寫一個(gè)uint64等等。
之后就要開始寫一個(gè)緩沖區(qū)管理子系統(tǒng)(假設(shè)
你做的不是一個(gè)內(nèi)存數(shù)據(jù)庫)。先弄明白什么是一個(gè)談激block,一個(gè)page,
一個(gè)frame。這些都是你的類。然后寫一個(gè)緩沖池,再寫一個(gè)緩沖區(qū)管理器。緩沖池規(guī)定數(shù)據(jù)在內(nèi)存上的布局,緩沖區(qū)管理器就是這個(gè)系統(tǒng)的接口了,可以回應(yīng)
一個(gè)頁的申請(qǐng),并實(shí)現(xiàn)你最心儀的頁替換策略。
再之后要寫一個(gè)日志系統(tǒng)。先想好你是要用shadow
page日志啊,還是ARIES算法日志啊。假設(shè)用后者,于是你就失去了強(qiáng)制寫,并采用偷幀的技術(shù)。這樣你要設(shè)計(jì)redo日志的格式,并使你的日志記錄種
類可擴(kuò)展,因?yàn)椴灰欢ㄊ裁磿r(shí)候你就會(huì)需要一種新的日志記錄。如果想讓你的系統(tǒng)更穩(wěn)健含哪襪,看看需不需要組日志(一組日志記錄要么都重做要么都不重做)。如果想
讓你的系統(tǒng)更高效,看看需不需要mvcc。要的話還得再加入undo日志,并設(shè)計(jì)格式。下面你要設(shè)計(jì)日志記錄粒度。全物理日志?全邏輯日志?物理邏輯日
志??傊?,邏輯的成分越多,系統(tǒng)設(shè)計(jì)越復(fù)雜(比如糟糕的部分寫怎么處理)。最后跟存儲(chǔ)管理系統(tǒng)要個(gè)地方物化日緩好志,再管緩沖區(qū)管理系統(tǒng)要個(gè)地方用來調(diào)度日志
頁。
接下來要寫一個(gè)鎖系統(tǒng)。先想好你的系統(tǒng)是表級(jí)鎖還是頁級(jí)鎖還是行級(jí)鎖。前兩個(gè)最自然,直接用fix
number什么的就搞定,最后一個(gè)你要有用來表示行鎖的額外數(shù)據(jù)結(jié)構(gòu)。每個(gè)行一個(gè)鎖實(shí)例?每個(gè)頁共用一坨鎖實(shí)例?之后去這個(gè)鎖表,用來統(tǒng)一申請(qǐng)釋放鎖。
最后再?zèng)Q定如何解決死鎖,超時(shí)拋出異常?依賴圖分析?
再接下來要寫一個(gè)事務(wù)子系統(tǒng)。它無非就是提供了一些方法確保各種操作正確地使用了二
階段鎖,正確地寫了日志,正確地回滾。但是這個(gè)系統(tǒng)的架構(gòu)由”各種操作”的多樣性決定。相比堆文件,對(duì)b+樹組織的記錄文件中記錄的增刪改查就要極大復(fù)雜
化日志寫入過程。相比定長(zhǎng)記錄文件,對(duì)可變長(zhǎng)記錄的增刪改查又是another story。
還有元數(shù)據(jù)管理子系統(tǒng),記錄(索引)子系
統(tǒng)。以上這些組成了一個(gè)存儲(chǔ)引擎。題主還想要的額外的東西分別是: SQL lexer, SQL parser, SQL planner, SQL
optimizer。以上又構(gòu)成了一個(gè)SQL compiler。 最后再來個(gè)Server/Client Module
用來控制權(quán)限,提供API,估計(jì)就差不多了。
對(duì)外數(shù)據(jù)模型為關(guān)系型數(shù)據(jù)庫,內(nèi)部的實(shí)現(xiàn)主要分成兩大類,一類是disk-based,比如mysql,postgres,一類是memory based,后者包括MemSQL,SAP HAHA,OceanBase??搭}目的意思指的是前者。判世這里說一個(gè)disk-based的關(guān)系型數(shù)據(jù)庫涉及多少東西。
上世紀(jì)70/80年代內(nèi)存不大,數(shù)據(jù)不能都放在內(nèi)存里,大部分?jǐn)?shù)據(jù)都存在磁盤上,讀數(shù)據(jù)也需要從磁盤讀,然而讀寫磁盤太慢了,所以就在內(nèi)存里做了一個(gè)buffer pool,將已經(jīng)讀過的數(shù)據(jù)緩存到buffer pool中,寫的時(shí)候也是寫到buffer pool中就返回,buffer pool的功能就是管理數(shù)據(jù)在磁盤和內(nèi)存的移動(dòng)。在buffer pool中數(shù)據(jù)的管理單位是page。page大小一般幾十KB。一般都可以配置。如果buffer pool中掘賀肢沒有空閑的page,就需要將某一個(gè)page提出buffer pool,如果它是dirty page,就需要flush到磁盤,這里又需要一個(gè)LRU算法。一個(gè)page包含多條記錄,page的格式需要設(shè)計(jì)用來支持變長(zhǎng)字段。如果這時(shí)宕機(jī)了,buffer pool中的數(shù)據(jù)就丟了。這就需要REDO log,將對(duì)數(shù)據(jù)的修改先寫到redo log中,然后寫buffer pool,然后返回給客戶端,隨后,buffer pool中的dirty page會(huì)被刷到數(shù)據(jù)文件中(NO FORCE)。那么重啟的時(shí)候,數(shù)據(jù)就能從redo log中恢復(fù)。REDO log還沒刷完就刷數(shù)據(jù)到磁盤可以加快寫入速度,缺點(diǎn)就是恢復(fù)的時(shí)候需要回放UNDO log,回滾一些還沒有提交的事務(wù)的修改。寫log又分為邏輯log和物理log,還有物理邏輯log。簡(jiǎn)單說邏輯log就是記錄操作,比如將某個(gè)值從1改成2.而物理log記錄具體到record的位置,例如某個(gè)page的某個(gè)record的某個(gè)field,原來的值是多少,新值是多少等。邏輯log的問題是并況下不太好恢復(fù)成一致。物理log對(duì)于某些操作比如create table又過于瑣碎,所以一般數(shù)據(jù)庫都采用混合的方式。為了跟蹤系統(tǒng)中各種操作的順序,這就需要為log分配id,記做LSN(log sequence number)。系統(tǒng)中記錄各種LSN,比如pageLSN, flushedLSN等等。為了加快宕機(jī)恢復(fù)速度,需要定期寫checkpoint,checkpoint就是一個(gè)LSN。
以上ACID里的C和D有關(guān)。下面說A和I,即原子性和隔離性。
這兩個(gè)性質(zhì)通過concurrency control來保證。隔離級(jí)別有很多種,最開始有4種,從低到高read uncommitted, read committed, repeatable read, serializable。serializable就是多個(gè)事務(wù)并發(fā)執(zhí)行的結(jié)果和某種順序執(zhí)行事務(wù)的結(jié)果相同。除了serializable,其他都有各種問題。比如repeatable read有幻讀問題(phantom),避免幻讀需要gap lock。read committed有幻讀和不可重復(fù)讀問題。后來又多了一些隔離級(jí)別,比如snapshot isolation,snapshot isolation也有write skew問題。早期,并發(fā)控制協(xié)議大多是基于兩階段鎖來做的(2PL),所以早拍吵期只有前面提到的四種隔離級(jí)別,后來,又出現(xiàn)一類并發(fā)控制協(xié)議,統(tǒng)稱為Timestamp Ordering,所以又多了snapshot isolation等隔離級(jí)別。關(guān)于隔離級(jí)別,可以看看這篇論文
。2PL需要處理deadlock的問題。
Timestamp Ordering大體的思想就是認(rèn)為事務(wù)之間沖突不大,不需要加鎖,只在commit的時(shí)候check是否有沖突。屬于一種樂觀鎖。
Timestamp Ordering具體來說包括多種,最常見的MVCC就是這類,還有一類叫做OCC(optimistic concurrency control)。MVCC就是對(duì)于事務(wù)的每次更新都產(chǎn)生新的版本,使用時(shí)間戳做版本號(hào)。讀的時(shí)候可以讀指定版本或者讀最新的版本。幾乎主流數(shù)據(jù)庫都支持MVCC,因?yàn)镸VCC讀寫互相不阻塞,讀性能高。MySQL的回滾段就是用來保存老的版本。MVCC需要有后臺(tái)線程來做不再需要的版本的回收工作。Postgres的vacuum就是做這事的。OCC和MVCC的區(qū)別是,OCC協(xié)議中,事務(wù)的修改保存在私有空間(比如客戶端),commit的時(shí)候再去檢測(cè)沖突,通常的做法是事務(wù)開始時(shí)看一下自己要修改的數(shù)據(jù)的最后一次修改的時(shí)間戳,提交的時(shí)候去check是否這個(gè)時(shí)間戳變大了,如果是,說明被別人改過了,沖突。沖突后可以回滾或者重試。
上面這些搞定了就實(shí)現(xiàn)了數(shù)據(jù)庫的核心,然后為了性能,需要index,通常有兩種,一種支持順序掃描B+Tree,還有一種是Hash Index。單條讀適合用Hash Index,O(1)時(shí)間復(fù)雜度,順序掃描只適合用B+Tree,O(logN)復(fù)雜度。然后,有些查詢只需要掃描索引就能得到結(jié)果,有些查詢直接掃描數(shù)據(jù)表就能得到結(jié)果,有些查詢可以走二級(jí)索引,通過二級(jí)索引找到數(shù)據(jù)表然后得到結(jié)果。。具體用哪種方式就是優(yōu)化器的事了。
再外圍一些,關(guān)系型數(shù)據(jù)庫自然需要支持SQL了,由SQL變成最后可以執(zhí)行的物理執(zhí)行計(jì)劃中間又有很多步,首先SQL通過詞法語法分析生成抽象語法樹,然后planner基于這棵樹生成邏輯執(zhí)行計(jì)劃,邏輯執(zhí)行計(jì)劃的生成通常涉及到等價(jià)謂詞重寫,子查詢消除等邏輯層面的優(yōu)化技術(shù),優(yōu)化的目的當(dāng)然是性能。比如等價(jià)謂詞重寫,用大于小于謂詞消除like,between .. and..等不能利用索引的謂詞。下一步是邏輯執(zhí)行計(jì)劃生成物理執(zhí)行計(jì)劃,物理執(zhí)行計(jì)劃樹每個(gè)節(jié)點(diǎn)是一個(gè)operator,operator的執(zhí)行就是實(shí)實(shí)在在的操作,比如掃表的operator,filter opertor。一個(gè)邏輯執(zhí)行計(jì)劃通??梢杂卸鄠€(gè)物理執(zhí)行對(duì)應(yīng),選擇哪個(gè)就涉及到物理執(zhí)行計(jì)劃優(yōu)化,這里涉及到經(jīng)典的cost model,綜合考慮內(nèi)存,CPU, I/O,網(wǎng)絡(luò)等。最典型的,三表join,從左到右還是右到左,使用hash join,還是sort merge join等。
如何自己實(shí)現(xiàn)一個(gè)關(guān)系型數(shù)據(jù)庫
先寫一個(gè)并發(fā)控制子系統(tǒng)。里面要提供各種各樣的閂鎖。包括具有不同相容性矩陣的,有優(yōu)先隊(duì)列或者沒有的,能指數(shù)后退或者不能的,全局可追蹤的或者不可追蹤的,等等等等。
然
后寫一個(gè)存儲(chǔ)管理子系統(tǒng)。在這里你可以決定你的數(shù)據(jù)庫的外存布局。比如一個(gè)表可不可以分開幾個(gè)文件存,有沒有區(qū)的概念,有沒有段的概念,有沒有表空間的概
念,它們之中誰是定長(zhǎng)的,誰是可變長(zhǎng)的,誰是空間申請(qǐng)單位,誰是空間調(diào)度單位。決定好了開始設(shè)計(jì)頁區(qū)段表空間格式,它們的描述符格式,然后用頁頭,頁記
錄,頁尾有的沒的串一起。設(shè)計(jì)好了開始決定這個(gè)子系統(tǒng)有哪些內(nèi)存對(duì)象,至少要有一個(gè)存儲(chǔ)管理器用來初始化,分配或者調(diào)度存儲(chǔ)單元,至少還要提供一堆方法來
決定怎么把二進(jìn)制數(shù)據(jù)變成有意義的數(shù)據(jù),比如讀一個(gè)ushort, 寫一個(gè)uint64等等。
之后就要開始寫一個(gè)緩沖區(qū)管理子系統(tǒng)(假設(shè)
你做的不是一個(gè)內(nèi)存數(shù)據(jù)庫)。先弄明白什么是一個(gè)談激block,一個(gè)page,
一個(gè)frame。這些都是你的類。然后寫一個(gè)緩沖池,再寫一個(gè)緩沖區(qū)管理器。緩沖池規(guī)定數(shù)據(jù)在內(nèi)存上的布局,緩沖區(qū)管理器就是這個(gè)系統(tǒng)的接口了,可以回應(yīng)
一個(gè)頁的申請(qǐng),并實(shí)現(xiàn)你最心儀的頁替換策略。
再之后要寫一個(gè)日志系統(tǒng)。先想好你是要用shadow
page日志啊,還是ARIES算法日志啊。假設(shè)用后者,于是你就失去了強(qiáng)制寫,并采用偷幀的技術(shù)。這樣你要設(shè)計(jì)redo日志的格式,并使你的日志記錄種
類可擴(kuò)展,因?yàn)椴灰欢ㄊ裁磿r(shí)候你就會(huì)需要一種新的日志記錄。如果想讓你的系統(tǒng)更穩(wěn)健含哪襪,看看需不需要組日志(一組日志記錄要么都重做要么都不重做)。如果想
讓你的系統(tǒng)更高效,看看需不需要mvcc。要的話還得再加入undo日志,并設(shè)計(jì)格式。下面你要設(shè)計(jì)日志記錄粒度。全物理日志?全邏輯日志?物理邏輯日
志??傊壿嫷某煞衷蕉?,系統(tǒng)設(shè)計(jì)越復(fù)雜(比如糟糕的部分寫怎么處理)。最后跟存儲(chǔ)管理系統(tǒng)要個(gè)地方物化日緩好志,再管緩沖區(qū)管理系統(tǒng)要個(gè)地方用來調(diào)度日志
頁。
接下來要寫一個(gè)鎖系統(tǒng)。先想好你的系統(tǒng)是表級(jí)鎖還是頁級(jí)鎖還是行級(jí)鎖。前兩個(gè)最自然,直接用fix
number什么的就搞定,最后一個(gè)你要有用來表示行鎖的額外數(shù)據(jù)結(jié)構(gòu)。每個(gè)行一個(gè)鎖實(shí)例?每個(gè)頁共用一坨鎖實(shí)例?之后去這個(gè)鎖表,用來統(tǒng)一申請(qǐng)釋放鎖。
最后再?zèng)Q定如何解決死鎖,超時(shí)拋出異常?依賴圖分析?
再接下來要寫一個(gè)事務(wù)子系統(tǒng)。它無非就是提供了一些方法確保各種操作正確地使用了二
階段鎖,正確地寫了日志,正確地回滾。但是這個(gè)系統(tǒng)的架構(gòu)由”各種操作”的多樣性決定。相比堆文件,對(duì)b+樹組織的記錄文件中記錄的增刪改查就要極大復(fù)雜
化日志寫入過程。相比定長(zhǎng)記錄文件,對(duì)可變長(zhǎng)記錄的增刪改查又是another story。
還有元數(shù)據(jù)管理子系統(tǒng),記錄(索引)子系
統(tǒng)。以上這些組成了一個(gè)存儲(chǔ)引擎。題主還想要的額外的東西分別是: SQL lexer, SQL parser, SQL planner, SQL
optimizer。以上又構(gòu)成了一個(gè)SQL compiler。 最后再來個(gè)Server/Client Module
用來控制權(quán)限,提供API,估計(jì)就差不多了。
關(guān)于數(shù)據(jù)庫布局的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡(jiǎn)單好用,價(jià)格厚道的香港/美國(guó)云服務(wù)器和獨(dú)立服務(wù)器。創(chuàng)新互聯(lián)——四川成都IDC機(jī)房服務(wù)器托管/機(jī)柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機(jī)房租用、服務(wù)器托管、機(jī)柜租賃、大帶寬租用,高電服務(wù)器托管,算力服務(wù)器租用,可選線路電信、移動(dòng)、聯(lián)通機(jī)房等。
網(wǎng)頁題目:如何優(yōu)化數(shù)據(jù)庫布局?(數(shù)據(jù)庫布局)
網(wǎng)站地址:http://www.dlmjj.cn/article/dpsepij.html


咨詢
建站咨詢
