Java學習總結

Java學習總結(三)

關於JDBC與數據庫知識

在數據庫進行海量數據處理過程中,通常由以下方法:

分區處理

在一些數據庫的官方文檔中,可以講數據庫分爲以下常用三個分區:
一、範圍分區
最常見的例子就是根據時間字段進行範圍劃分。
二、哈希分區
利用hash函數運算,從而使數據均勻分佈在各個分區並方便於並行處理。適用於各個分區中數據要求均勻的情況下使用。但要求數據應當重複率較低。
三、列表分區
適用於有高重複率的字段值表。進行列值於分區的映射。

索引

一、B樹索引
在數據量不大時。B樹累哦非常好地完成工作,幾乎成了索引的代名詞。鍵值重複率低的字段比較適合B樹索引。
這裏重點介紹B樹,B樹是由二叉搜索樹擴展而來。二叉搜索樹是由L,k,R三部分構成。其中L,R又分別代表一顆二叉搜索樹,滿足以下條件:
key(L)<=k<=key(R)
將這一定義進行推廣,如果樹中包含多個鍵值以及分支,那麼它就是一顆B樹。排列方式如下:
c1,k1,c2,k2.c3,k3,c4,k4
B樹節點滿足以下限制:
一、所有的鍵值按照單調遞增的順序進行保存,即k1<=k2<=k3<=k4 ;
二、對於任意ki ,子樹ci 中的所有元素都不大於ki ,且ki 不大於子樹ci+1 中任意元素。
三、所有的葉子結點具有相同的深度。
四、爲了保證平衡性,定義整數t,稱爲B樹的最小度數
——每個節點最多含有2t1 個鍵值。
——除根節點以外,每個節點至少含有t1 個鍵值。
t值往往展現的是中心節點,這對於樹的拆分很有幫助。

class BTree:
    def __init__(self, t=TREE_2_3_4):
        self.t = t
        self.keys = [] #self.data = ...
        self.children = []
    def is_leaf(t):
        return t.children == []
    def is_full(node):
        return len(node.keys) >= 2 * node.t - 1
##have not debug yet,please correct me if it has any problems##
def B_tree_search(tr, key):
    for i in range(len(tr.keys)):
        if key==tr.keys[i]:
            return(tr,i)
        elif key<tr.keys[i]:
            tr=tr.children[i]
            if tr.is_lead:
                return "沒有找到"
            else:
                B_tree_search(tr, key)
        elif key>tr.keys[-1]:
            i=i+1
            tr=tr.children[i]
            if tr.is_lead:
                return "沒有找到"
            else:
                B_tree_search(tr, key)

二、位圖索引
實際情況下,存放海量數據的表中幾乎很少使用主鍵,因爲這些表都是一存放事實數據爲目的,而不是作爲參照表被引用。位圖索引適用於重複字段多的數據。
定義:位圖索引的鍵值是重複率較高的字段,存儲的是每行該關鍵字的標誌位,有則置1,無則置0。
二、適用於特定的SQL操作。位圖索引非常適合在索引字段見進行諸如計數(count)、或(or)、與(and)這樣的操作。
三、系統適應性問題。位圖的引入,主要是解決海量數據下查詢性能的問題,適用範圍爲OLAP和數據倉庫型數據庫。而不是OLTP。

三、全文索引
全文索引屬於語言文學的範疇,它的屬性和語言文字的屬性直接相關聯起來。

架構

RAC、負載均衡、冗餘備份。

關於數據庫的一些相關概念

主鍵或者唯一性約束:主鍵更強調錶的關係性,他可以被其他表的外鍵所引用;而唯一性約束則強調字段值的唯一性。

關於delete/truncate、drop的相關操作:
1、delete消耗大量的系統資源且無法釋放空間。屬於DML事件機制中,可以回滾復原。
2、truncate屬於一種DDL,一旦操作,便立即釋放空間。一旦執行便不能回滾,且操作速度比delete塊。

OLTP與OLAP的介紹
數據處理大致可以分成兩大類:聯機事務處理OLTP(on-line transaction processing)、聯機分析處理OLAP(On-Line Analytical Processing)。OLTP是傳統的關係型數據庫的主要應用,主要是基本的、日常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持複雜的分析操作,側重決策支持,並且提供直觀易懂的查詢結果。
OLTP 系統強調數據庫內存效率,強調內存各種指標的命令率,強調綁定變量,強調併發操作;
OLTP比較常用的設計與優化方式爲Cache技術與B-tree索引技術。瓶頸在於CPU與磁盤子系統。
OLAP 系統則強調數據分析,強調SQL執行市場,強調磁盤I/O,強調分區等
數據庫對比

實際編程中數據庫實用知識

上述介紹了許多關於數據庫的概念,但是在實際編程中,其實用到最廣泛的是兩類知識:

一、遊標
二、事物處理(ADIC):取消數據庫自動提交過程,執行多條SQL語句,如果沒有異常則提交,如果發生異常則回滾。(重點強調原子性和一致性)

以下爲了方便分析,貼上最近導師要我寫的一段 python 代碼對數據庫進行操作:

import psycopg2
import dicom
import os
import tqdm
import re

def insert_db(pathname):
    info=loadFileInformation(pathname)
    try:
        conn=psycopg2.connect(host="192.168.4.128",user="postgres",password="lmi456",dbname="axesdb")
    except:
        print('數據庫連接信息有誤,請覈對後進行修改')
    ##該部分進行實例化,並顯示連接到數據庫的信息##
    cur=conn.cursor()
    print('請覈實數據庫信息,數據庫名字爲:%s\n數據庫的IP地址爲:%s\n端口號爲:%s\n用戶名是:%s\n'%(conn.get_dsn_parameters()['dbname']\
,conn.get_dsn_parameters()['host'],conn.get_dsn_parameters()['port'],conn.get_dsn_parameters()['user']))
    ###初始化查詢信息####
    pat_id=info["PatientID"]
    s_iuid=info['SOPInstanceUID']
    i_iuid=info['SeriesInstanceUID']
    try:
        cur.execute("ROLLBACK;")
        SQL1="INSERT INTO public.ta_nodule (nodule_name) VALUES (%s);"
        data1=(pat_id,)
        cur.execute(SQL1, data1)
    #         conn.commit()
        ##傳輸完成後依據pat_id找到主鍵nodule_no###
        SQL2="select nodule_no from public.ta_nodule where nodule_name=(%s);"
        cur.execute(SQL2, data1)
        nodule_no=cur.fetchone()[0]
        print(nodule_no)##
        ##接下來將以上信息插入兩張關聯表###
        ###################################
        ##1、依照SOPInstanceUID查詢圖片主鍵##
        SQL3="select id from public.t_image where sop_iuid=(%s);"
        data3=(s_iuid,)
        cur.execute(SQL3, data3)
        fk_image_no=cur.fetchone()[0]
        print(fk_image_no)
        ##插入操作##
        SQL4="INSERT INTO public.ta_image_nodule (fk_nodule_no,fk_image_no) VALUES (%s,%s);"
        data4=(nodule_no,fk_image_no,)
        cur.execute(SQL4, data4)

        ##2、依照SeriesInstanceUID查詢圖片主鍵##
        SQL5="select id from publicwhere .t_series series_iuid=(%s);"
        data5=(i_iuid,)
        cur.execute(SQL5,data5)
        fk_series_no=cur.fetchall()[0][0]
        print(fk_series_no)
        ##插入操作##
        SQL6="INSERT INTO public.ta_series_nodule (fk_series_no,fk_nodule_no) VALUES (%s,%s);"
        data6=(fk_series_no,nodule_no,)
        cur.execute(SQL6, data6) 
        conn.commit()
    except:
        ....

數據庫爲postgresql,前面導入了部分庫是處理醫療影像dicom數據的。從圖像中提取信息插入到數據庫中。上述代碼片很重要的兩段即連接數據庫部分,當數據庫成功簡歷連接以後,隨後就是靠遊標來提交數據庫的操作命令了。遊標最重要的兩個方法分別是execute*()和fetch*()方法,所有針對數據庫的請求操作都是依靠他們完成。
事件處理用到的是數據庫中commit()方法如果不成功可調用rollback()方法,也可以提交rollback語句。此外,注意操作完畢之後執行關閉連接操作。實際代碼強調交互性,需要大量的異常處理模塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章