[完結11章]技術大牛成長課,從0到1帶你手寫一個數據庫系統(tǒng)
[完結11章]技術大牛成長課,從0到1帶你手寫一個數據庫系統(tǒng)
學習地址1:https://pan.baidu.com/s/1OWDu5fNq_BXRUbLGrxzpJw 提取碼:tjty?
學習地址2:https://share.weiyun.com/Tp6ewDIJ 密碼:6crcwd
今天跟大家交流一下關于開發(fā)一款數據庫系統(tǒng)的相關事宜,從零開始,手把手帶著大家一步步去實現這個功能,希望對大家有所幫助。
數據庫系統(tǒng)是為適應數據處理的需要而發(fā)展起來的一種較為理想的數據處理系統(tǒng),也是一個為實際可運行的存儲、維護和應用系統(tǒng)提供數據的軟件系統(tǒng),是存儲介質 、處理對象和管理系統(tǒng)的集合體。
數據庫系統(tǒng)DBS(Data Base System,簡稱DBS)通常由軟件、數據庫和數據管理員組成。其軟件主要包括操作系統(tǒng)、各種宿主語言、實用程序以及數據庫管理系統(tǒng)。數據庫由數據庫管理系統(tǒng)統(tǒng)一管理,數據的插入、修改和檢索均要通過數據庫管理系統(tǒng)進行。數據管理員負責創(chuàng)建、監(jiān)控和維護整個數據庫,使數據能被任何有權使用的人有效使用。數據庫管理員一般是由業(yè)務水平較高、資歷較深的人員擔任。
無論你是數據庫內核研發(fā)、DBA、還是后端研發(fā),能夠手寫一套自己的數據庫系統(tǒng),都是你突破技術發(fā)展瓶頸的有效途徑。本課程將帶你從架構設計 ,原理剖析,再到源碼的實現,手把手帶你構建一套完整的數據庫系統(tǒng),讓你深度掌握數據庫底層,及更多數據庫高端技術,具備解決大量生產級數據庫問題的能力,助力成為高端技術人才!
從數據庫架構設計到功能實現,吃透底層原理,解決大量生產級問題
具備從0到1數據庫系統(tǒng)的架構設計能力
從需求分析,系統(tǒng)分析,到系統(tǒng)架構設計,以及面向未知故障場景防御式編程,靈活運用設計模式,全面深入理解數據庫系統(tǒng)架構
深度掌握數據庫底層原理及系統(tǒng)性方法論
掌握SQL語法解析、語義解析原理,數據庫如何生成執(zhí)行計劃,數據庫底層存儲機制、事務管理機制,C/S架構網絡服務,綜合性提升數據庫運維、調優(yōu)能力
提升大量生產級數據庫問題高效解決能力
深入掌握數據庫索引調優(yōu)思路、瓶頸點,如何快速定位線上問題,深入挖掘針對數據庫的面試題,知其然更知其所以然,有效突破你的疑難雜癥問題解決能力。
1.5數據庫系統(tǒng)模式
開發(fā)人員角度(內部的系統(tǒng)結構):三級模式結構
用戶角度(外部的系統(tǒng)結構):單用戶結構、主從式結構、分布式結構
模式:數據庫中全體數據的邏輯結構和特征的描述,僅涉及型的描述,不涉及具體的值
實例:模式的一個具體的值
模式是相對穩(wěn)定的,實例是相對變動的
1.6數據庫系統(tǒng)的三級模式結構
數據庫由外模式、模式和內模式三級構成
模式(schema):也稱邏輯模式,是數據庫中全體數據的邏輯結構和特征的描述,是所有用戶的公共數據視圖。一個數據庫只有一個模式
外模式:也稱子模式或用戶模式,他是數據庫用戶能夠看到和使用的局部數據的邏輯結構和特征的描述,是數據庫用戶的數據視圖,是與某一應用有關的數據的邏輯表示。一個數據庫可以有多個外模式。一個應用只能用一個外模式,一個外模式可以共多個應用程序使用。
內模式:也稱存儲模式,描述數據物理結構和存儲方式。一個數據庫只有一個內模式
1.7數據庫的二級映像功能
為了能在系統(tǒng)內部實現三個抽象層次的聯系和轉換,數據庫管理系統(tǒng)在這三級模式之間提供了兩層映像:外模式/模式映像、模式/內模式映像
外模式/模式映像:模式描述的是數據的全局邏輯結構,外模式描述的是數據局部邏輯結構。一個模式可以有多個外模式。對每一個外模式有一個映像描述對應關系,這些映像定義包含在外模式的描述中
模式改變,管理員改變該映像,使外模式保持不變。應用程序不用改變,保證了數據與程序的邏輯獨立性
模式/內模式:該模式映像是唯一的。定義了數據全局邏輯結構和存儲結構之間的對應關系。
數據存儲結構改變時,改變該映像,可以使模式、應用程序保持不變。保證了數據與程序的物理獨立性。
因為添加角色和修改角色信息共用同一個彈窗頁面,彈窗頁面的代碼我們都已經寫完了,所以我們要回到角色管理頁面編寫JS代碼來顯示彈窗頁面,然后傳入要修改的角色ID,讓彈窗頁面去查詢該角色的信息。
<select id="searchCanDelete" resultType="boolean">
? ? SELECT IF( SUM( temp.users ) > 0, FALSE, TRUE ) AS result FROM (
? ? ? ? SELECT COUNT( u.id ) AS users
? ? ? ? FROM tb_role r
? ? ? ? JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
? ? ? ? WHERE r.id IN
? ? ? ? <foreach collection="array" open="(" separator="," close=")" item="one">
? ? ? ? ? ? #{one}
? ? ? ? </foreach>
? ? ? ? GROUP BY r.id
? ? ) temp
</select>
<delete id="deleteRoleByIds">
? ? DELETE FROM tb_role
? ? WHERE id IN
? ? <foreach collection="array" open="(" separator="," close=")" item="one">
? ? ? ? #{one}
? ? </foreach>
? ? AND systemic=FALSE
</delete>
如果我們把上面的SQL語句查詢的結果當做一張臨時表,統(tǒng)計求和是否大于零。如果大于零,說明你要刪除的這些角色中,有關聯用戶的角色。大家仔細想想,用戶在前端頁面勾選了若干角色,想要刪除這些角色。后端只要盤判定出這些角色,無論哪一個只要存在關聯的用戶,那么這些要刪除的角色一律不許刪除。除非我們統(tǒng)計求和的結果是零,說明這些要刪除的角色都沒有關聯用戶,這些角色允許刪除。
public class RoleController {
? ? ……
? ? @PostMapping("/deleteRoleByIds")
? ? @Operation(summary = "刪除角色記錄")
? ? @SaCheckPermission(value = {"ROOT", "ROLE:DELETE"}, mode = SaMode.OR)
? ? public R deleteRoleByIds(@Valid @RequestBody DeleteRoleByIdsForm form) {
? ? ? ? int rows = roleService.deleteRoleByIds(form.getIds());
? ? ? ? return R.ok().put("rows", rows);
? ? }
}
我們首先看一下模型層定義的變量,除了有查詢條件之外,還有與分頁相關的變量,以及保存勾選的部門記錄的變量,最后是表單驗證的規(guī)則??傮w上來看,跟用戶管理頁面的模型層差不多。
data: function() {
? ? return {
? ? ? ? dataForm: {
? ? ? ? ? ? deptName: null
? ? ? ? },
? ? ? ? dataList: [],
? ? ? ? pageIndex: 1,
? ? ? ? pageSize: 10,
? ? ? ? totalCount: 0,
? ? ? ? dataListLoading: false,
? ? ? ? dataListSelections: [],
? ? ? ? addOrUpdateVisible: false,
? ? ? ? dataRule: {
? ? ? ? ? ? deptName: [
? ? ? ? ? ? ? ? { required: false, pattern: '^[a-zA-Z0-9\u4e00-\u9fa5]{1,10}$', message: '部門名稱格式錯誤' }
? ? ? ? ? ? ]
? ? ? ? }
? ? };
},
我們聲明查詢按鈕點擊事件對應的回調函數,寫完這個函數大家就可以運行前后端項目,測試一下數據的查詢和分頁效果。
searchHandle: function() {
? ? this.$refs['dataForm'].validate(valid => {
? ? ? ? if (valid) {
? ? ? ? ? ? this.$refs['dataForm'].clearValidate();
? ? ? ? ? ? if (this.dataForm.deptName == '') {
? ? ? ? ? ? ? ? this.dataForm.deptName = null;
? ? ? ? ? ? }
? ? ? ? ? ? if (this.pageIndex != 1) {
? ? ? ? ? ? ? ? this.pageIndex = 1;
? ? ? ? ? ? }
? ? ? ? ? ? this.loadDataList();
? ? ? ? } else {
? ? ? ? ? ? return false;
? ? ? ? }
? ? });
},