操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    數據庫中,除了數據表外,還有一個重要對象叫視圖。視圖是由SQL語句將不同字段從不同表中抽取或者構造后形成的新表,跟數據庫表不同在于,它不存儲在磁盤上,而是在使用時臨時構建出來。

    跟數據庫表一樣,視圖同樣需要進行元數據管理。跟上節相同我們定義一個來創建視圖,同時創建一個數據庫表來存儲視圖的元數據,這個表有兩個字段分別是,他是字符串類型,還有一個叫,他是一個二進制數據類型,具體細節在后面的實現中會清楚說明。

    我們看看代碼實現,首先在目錄下創建文件.go文件,然后輸入代碼如下:

    package metadata_manager

    import (
    rm "record_manager"
    "tx"
    )

    const (
    /*
    視圖元數據對應數據結構大小,通常視圖元數據的定義需要幾千個字節,我們這里出于學習和實驗目的,只把使用
    100字節來表示
    */

    MAX_VIEWDEF = 100
    )

    type ViewManager struct {
    tblMgr *TableManager
    }

    func NewViewManager(isNew bool, tblMgr *TableManager, tx *rm.Transation) *ViewManager {
    viewMgr := &ViewManager{
    tblMgr: tblMgr,
    }

    if isNew {
    //使用表管理器創建元數據表viewcat
    sch := rm.NewSchema()
    sch.AddStringField("viewname", MAX_NAME)
    sch.AddStringField("viewdef", MAX_VIEWDEF)
    tblMgr.CreateTable("viewcat", sch, tx)
    }

    return viewMgr
    }

    func (v *ViewManager) CreateView(vname string, vdef string, tx *rm.Transation) {
    //每創建一個視圖對象,就在viewcat表中插入一條對該視圖對象元數據的記錄
    layout := v.tblMgr.getLayout("viewcat", tx)
    ts := rm.NewTableScan(tx, "viewcat", layout)
    ts.Insert()
    ts.SetString("viewname", vname)
    ts.SetString("viewdef", vdef)
    ts.Close()
    }

    func (v *ViewManager) GetViewDef(vname string, tx *tx.Transation) string {
    result := ""
    layout := v.tblMgr.GetLayout("viewcat", tx)
    //獲取視圖的表結構
    ts := rm.NewTableScan(tx, "viewcat", layout)
    for ts.Next() {
    if ts.GetString("viewcat") == vname {
    result = ts.GetString("viewdef")
    break
    }
    }

    ts.Close()
    return result
    }

    另外還需要考慮的元數據是統計信息。統計信息一般包含當前有多少條記錄,字段在磁盤中的分布信息等,這些數據在引擎執行查詢時用于估計成本,統計信息處理的好能大大加快查詢速度。如果是商用數據庫,這些信息將會多如牛毛,我們這里簡單起見就保持三種數據即可,他們分別是每個表使用了多少區塊,每個表包含了多少條記錄,對于某個表中的某個字段數據庫中創建視圖的語句是,它有多少個不重復的值。

    不難看到維護這些統計信息需要付出一定的性能代價,因為當數據庫表有插入,刪除,更新等操作時,我們都得對統計信息進行更新,為了處理這個問題我們不再像前面那樣使用元數據表來存放統計數據,而是把統計信息全部保留在內存里,當數據庫系統啟動時,它掃描一次所有數據庫表,構造出統計信息寄存在內存中。同時每過一段時間系統就掃描數據庫表然后更新統計數據。這種做法的問題在于在某個時刻統計信息跟實際情況有所不符數據庫中創建視圖的語句是,但問題不大,因為這些信息主要用來估算查詢成本,它不是很準確問題也不大。我們看看統計元數據的實現,在當前目錄增加一個文件名為.go,實現代碼如下:

    package metadata_manager

    import (
    rm "record_manager"
    "sync"
    "tx"
    )

    const (
    //數據庫表發生變化100次后更新統計數據
    REFRESH_STAT_INFO_COUNT = 100
    )

    type StatInfo struct {
    numBlocks int //數據庫表的區塊數
    numRecs int //數據庫表包含的記錄數
    }

    func newStatInfo(numBlocks int, numRecs int) *StateInfo {
    return &StatInfo{
    numBlocks: numBlocks,
    numRecs: numRecs,
    }
    }

    func (s *StatInfo) BlocksAccessed() int {
    return s.numBlocks
    }

    func (s *StatInfo) RecordsOutput() int {
    return s.numRecs
    }

    func (s *StatInfo) DistincValues(fldName string) int {
    //字段包含多少不同的值
    return 1 + (s.numRecs / 3) //初步認為三分之一,后面再修改
    }

    type StatManager struct {
    tblMgr *TableManager
    tableStats map[string]*StateInfo
    numCalls int
    lock sync.Mutex
    }

    func NewStatManager(tblMgr *TableManager, tx *tx.Transation) *StatManager {
    statMgr := &StatManager{
    tblMgr: tblMgr,
    numCalls: 0,
    }
    //更新統計數據
    statMgr.refreshStatistics(tx)
    return statMgr
    }

    func (s *StatManager) GetStatInfo(tblName string, layout *rm.Layout, tx *tx.Transation) *StatInfo {
    s.lock.Lock()
    defer s.lock.Unlock()
    s.numCalls += 1
    if s.numCalls > REFRESH_STAT_INFO_COUNT {
    s.refreshStatistic(tx)
    }

    si := s.tableStats[talName]
    if si == nil {
    //為新數據庫表創建統計對象
    si = s.calcTableStats(tblName, layout, tx)
    s.tableStats[tblName] = si
    }

    return si
    }

    func (s *StatManager) refreshStatistics(tx *tx.Transation) {
    s.tableStats = make(map[string]*StatInfo)
    s.numCalls = 0
    tcatLayout := s.tblMgr.GetLayout("tblcat", tx)
    tcat := rm.NewTableScan(tx, "tblcat", tcatLayout)
    for tcat.Next() {
    tblName := tcat.GetString("tblname")
    layout := s.tblMgr.GetLayout(tblName, tx)
    si := s.calcTableStats(tblName, layout, tx)
    s.tableStats[tblName] = si
    }

    tcat.Close()
    }

    func (s *StatManager) calcTableStats(tblName string, layout *rm.Layout, tx *tx.Transation) *StatInfo {
    numRecs := 0
    numBlocks := 0
    ts := rm.NewTableScan(tx, tblName, layout)
    for ts.Next() {
    numRecs += 1
    numBlocks = ts.GetRid().BlockNumber() + 1
    }
    ts.Close()
    return newStatInfo(numRecs, numBlocks)
    }

    sql 查詢視圖創建語句_sql創建視圖語句_數據庫中創建視圖的語句是

    在上面代碼中,我們使用對象來包含表的統計信息,其中包括表的記錄數,區塊數還有給定字段擁有的不同值的數量。用于獲取統計元數據,它只在系統啟動時創建,在創建時它調用自己的接口創建統計數據并存儲在內存中,這個接口會繼續調用來獲取每個表的相關數據,后者會從通過獲取所有數據庫表,然后獲得每個表的相關數據,然后創建對象,并把表的統計數據存儲在其中。

    最后我們使用一個名為的對象將前面實現的所有統一管理起來,在目錄中創建.go實現代碼如下:

    package metadata_manager

    import (
    rm "record_manager"
    "tx"
    )

    type MetaDataManager struct {
    tblMgr *TableManager
    viewMgr *ViewManager
    statMgr *StatManager
    //索引管理器以后再處理
    //idxMgr *IndexManager
    }

    func NewMetaDataManager(isNew bool, tx *tx.Transation) *MetaDataManager {
    metaDataMgr := &MetaDataManager{
    tblMgr: NewTableManager(isNew, tx),
    }

    metaDataMgr.viewMgr = NewViewManager(isNew, metaDataMgr.tblMgr, tx)
    metaDataMgr.statMgr = NewStatManager(metaDataMgr.tblMgr, tx)

    return metaDataMgr
    }

    func (m *MetaDataManager) CreateTable(tblName string, sch *rm.Schema, tx *tx.Transation) {
    m.tblMgr.CreateTable(tblName, sch, tx)
    }

    func (m *MetaDataManager) CreateView(viewName string, viewDef string, tx *tx.Transation) {
    m.viewMgr.CreateView(viewName, viewDef, tx)
    }

    func (m *MetaDataManager) GetLayout(tblName string, tx *tx.Transation) *rm.Layout {
    return m.tblMgr.GetLayout(tblName, tx)
    }

    func (m *MetaDataManager) GetViewDef(viewName string, tx *tx.Transation) string {
    return m.viewMgr.GetViewDef(viewName, tx)
    }

    func (m *MetaDataManager) GetStatInfo(tblName string, layout *rm.Layout, tx *tx.Transation) *StatInfo {
    return m.statMgr.GetStatInfo(tblName, layout, tx)
    }

    最后我們在main函數中調用看看效果:

    package main

    import (
    bmg "buffer_manager"
    fm "file_manager"
    "fmt"
    lm "log_manager"
    "math/rand"
    mm "metadata_management"
    record_mgr "record_manager"
    "tx"
    )

    func main() {
    file_manager, _ := fm.NewFileManager("recordtest", 400)
    log_manager, _ := lm.NewLogManager(file_manager, "logfile.log")
    buffer_manager := bmg.NewBufferManager(file_manager, log_manager, 3)

    tx := tx.NewTransation(file_manager, log_manager, buffer_manager)
    sch := record_mgr.NewSchema()
    sch.AddIntField("A")
    sch.AddStringField("B", 9)

    mdm := mm.NewMetaDataManager(true, tx)
    mdm.CreateTable("MyTable", sch, tx)
    layout := mdm.GetLayout("MyTable", tx)
    size := layout.SlotSize()
    fmt.Printf("MyTable has slot size: %d\n", size)
    sch2 := layout.Schema()
    fmt.Println("Its fields are: ")
    for _, fldName := range sch2.Fields() {
    fldType := ""
    if sch2.Type(fldName) == record_mgr.INTEGER {
    fldType = "int"
    } else {
    strlen := sch2.Length(fldName)
    fldType = fmt.Sprintf("varchar ( %d )", strlen)
    }

    fmt.Printf("%s : %s\n", fldName, fldType)
    }

    ts := record_mgr.NewTableScan(tx, "MyTable", layout)
    //測試統計元數據
    for i := 0; i < 50; i++ {
    ts.Insert()
    n := rand.Intn(50)
    ts.SetInt("A", n)
    strField := fmt.Sprintf("rec%d", n)
    ts.SetString("B", strField)
    }
    si := mdm.GetStatInfo("MyTable", layout, tx)
    fmt.Printf("blocks for MyTable is %d\n", si.BlocksAccessed())
    fmt.Printf("records for MyTable is :%d\n", si.RecordsOutput())
    fmt.Printf("Distinc values for field A is %d\n", si.DistinctValues("A"))
    fmt.Printf("Distinc values for field B is %d\n", si.DistinctValues("B"))

    //統計視圖信息
    viewDef := "select B from MyTable where A = 1"
    mdm.CreateView("viewA", viewDef, tx)
    v := mdm.GetViewDef("viewA", tx)
    fmt.Printf("View def = %s\n", v)
    tx.Commit()
    }

    上面代碼運行后輸出結果如下:

    MyTable has slot size: 33
    Its fields are:
    A : int
    B : varchar ( 9 )
    blocks for MyTable is 5
    records for MyTable is :50
    Distinc values for field A is 17
    Distinc values for field B is 17
    View def = select B from MyTable where A = 1
    transation 1 committed

    具體的邏輯請在B站搜索迪斯尼查看調試演示和邏輯講解。代碼下載路徑:

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有