鄒同浩 許學(xué)添
(廣東司法警官職業(yè)學(xué)院 廣東省廣州市 510520)
在數(shù)據(jù)庫(kù)設(shè)計(jì)的過(guò)程中,經(jīng)常遇到對(duì)于同類事物需要的信息不一樣,為解決這一問(wèn)題,需要針對(duì)不同的事物設(shè)計(jì)不同的數(shù)據(jù)表,數(shù)據(jù)表之間通過(guò)關(guān)鍵字段確定多種內(nèi)聯(lián)關(guān)系。如果把不同的事物放在同一張數(shù)據(jù)表中,不同的事物有不同的屬性,這樣創(chuàng)建一張表就很難進(jìn)行輸入和管理。例如,把人和物存在同一張表格內(nèi),人的屬性有“性別”,而物沒(méi)有這樣的屬性,存在同一張表中,很多字段對(duì)于彼此都是無(wú)效字段,增加了計(jì)算機(jī)處理負(fù)荷,從而暴露出數(shù)據(jù)庫(kù)設(shè)計(jì)的龐大和復(fù)雜性。本文指出用split()函數(shù)減少數(shù)據(jù)庫(kù)設(shè)計(jì)中的多表性和內(nèi)聯(lián)性,降低數(shù)據(jù)庫(kù)設(shè)計(jì)的復(fù)雜性 ,盡最大可能的把不同的信息存儲(chǔ)設(shè)計(jì)在同一張數(shù)據(jù)表中,減少表的數(shù)據(jù)表的數(shù)量和降低數(shù)據(jù)之間關(guān)聯(lián)性,提高數(shù)據(jù)的設(shè)計(jì)效率,降低數(shù)據(jù)庫(kù)的管理復(fù)雜度。
Split 函數(shù)是編程語(yǔ)言中使用于分割字符串一種函數(shù),它返回一個(gè)下標(biāo)從零開始的一維數(shù)組。它是在邏輯上對(duì)輸入數(shù)據(jù)進(jìn)行的分割,并不會(huì)在磁盤上將其切割成片存儲(chǔ)[1]。
Split 函數(shù)格式:Split(expression[,delimiter [,count[, ompare]]])。如果用“.”作為分隔的話,必須寫法,String.split("\."),這樣才能正確的分隔開,不能用String.split(".");如果用“|”作為分隔的話,寫法,String.split("\|"),這樣才能正確的分隔開;“.”和“|”都是轉(zhuǎn)義字符,必須得加"\";如果在一個(gè)字符串中有多個(gè)分隔符,可以用“|”作為連字符,比如,“acount=? and uu =? or n=?”,把三個(gè)都分隔出來(lái),可以用String.split("and|or");
使用String.split 方法分隔字符串時(shí),分隔符如果用到一些特殊字符,可能會(huì)得不到我們預(yù)期的結(jié)果。
在數(shù)據(jù)庫(kù)設(shè)計(jì)的過(guò)程中,程序開發(fā)人員結(jié)合數(shù)據(jù)庫(kù)的設(shè)計(jì)和程序設(shè)計(jì)中Split()函數(shù)特點(diǎn),取長(zhǎng)補(bǔ)短,優(yōu)化數(shù)據(jù)庫(kù)的設(shè)計(jì),目標(biāo)是降低數(shù)據(jù)庫(kù)設(shè)計(jì)的復(fù)雜性和內(nèi)聯(lián)性。
程序員在數(shù)據(jù)庫(kù)設(shè)計(jì)過(guò)程中,遇到同一個(gè)物品,數(shù)據(jù)表需要的字段不一樣,給數(shù)據(jù)表的建立增加非常多的統(tǒng)計(jì)表格?;蛘呶锲份^多,但統(tǒng)計(jì)量有很少,增加數(shù)據(jù)表的設(shè)計(jì)數(shù)量,又顯得多余。還要通過(guò)設(shè)置主鍵和外鍵進(jìn)行關(guān)聯(lián),這樣會(huì)增加數(shù)據(jù)庫(kù)的復(fù)雜度。我們?cè)囅?,能否把?shù)據(jù)放在一張數(shù)據(jù)表中,一張數(shù)據(jù)表能把所有物品的數(shù)據(jù)信息存儲(chǔ)下來(lái),共查詢和統(tǒng)計(jì)。數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)能否利用split()函數(shù)的字符分割功能解決這些問(wèn)題。
在開發(fā)固定資產(chǎn)管理系統(tǒng)時(shí),物品種類幾千種,屬性參數(shù)各不相同,在建立數(shù)據(jù)庫(kù)時(shí)可能要幾千個(gè)數(shù)據(jù)表。例如,臺(tái)式計(jì)算機(jī)的參數(shù)有系統(tǒng)、CPU 型號(hào)、內(nèi)存、主板等;辦公椅的參數(shù)有類別、扶手類型、五星腳材質(zhì)等,如果把這樣的物品放在同一張數(shù)據(jù)表中,會(huì)出這樣的情況,如表1 所示。
表1:匯總表
表2:拆分表1
表3:拆分表2
表4:改造后的匯總表
表5:成績(jī)表
這樣設(shè)計(jì)出來(lái)的數(shù)據(jù)表,冗余量太大,對(duì)于同一物品無(wú)效字段太多、數(shù)據(jù)表字段太多等一系列問(wèn)題。查詢物品的信息相互關(guān)聯(lián)時(shí),是否能夠合并作為一個(gè)字段,需要統(tǒng)計(jì)的公用信息可以單列字段,這樣就減少數(shù)據(jù)表的設(shè)計(jì)復(fù)雜性。假設(shè)對(duì)不同類物品單列一張數(shù)據(jù)表如表2、表3 所示。
這樣精煉了數(shù)據(jù)表中的字段項(xiàng),但增加了數(shù)據(jù)表的數(shù)量。后期會(huì)增加程序設(shè)計(jì)的復(fù)雜性。因此,我們考慮,根據(jù)用戶的需求,比如一鍵查詢出某個(gè)物品的所有信息,而不是單個(gè)信息?;蛘哒f(shuō),查詢某個(gè)物品的單個(gè)信息和整個(gè)信息時(shí)等價(jià)的,或者沒(méi)有實(shí)在意義,是否能通過(guò)程序設(shè)計(jì),可以使數(shù)據(jù)庫(kù)的表的數(shù)量最少,還能滿足系統(tǒng)需求。
例如,在固定資產(chǎn)管理系統(tǒng)中,注重的是產(chǎn)品的存在及價(jià)值,對(duì)于具體參數(shù)不是統(tǒng)計(jì)重點(diǎn),我們是否考慮不同的物品的參數(shù)僅僅用一個(gè)字段表示,如“參數(shù)說(shuō)明”。數(shù)據(jù)表可以設(shè)計(jì)如表4 所示。
這樣的數(shù)據(jù)庫(kù)設(shè)計(jì)方法應(yīng)用必須滿足兩個(gè)條件。第一該物品字段統(tǒng)計(jì)字段次不齊或無(wú)統(tǒng)計(jì)價(jià)值;第二可以大大降低數(shù)據(jù)庫(kù)中數(shù)據(jù)表的數(shù)量。數(shù)據(jù)表這樣的設(shè)計(jì),會(huì)出現(xiàn)統(tǒng)計(jì)量統(tǒng)計(jì)的問(wèn)題,我們通過(guò)程序設(shè)計(jì)中Split()函數(shù)可以解覺(jué)數(shù)據(jù)表數(shù)量與程序設(shè)計(jì)的問(wèn)題[2]。例如通過(guò)split()函數(shù)可以吧表4 中的“參數(shù)說(shuō)明”的字段信息通過(guò)split()函數(shù)進(jìn)行拆分提取,分別以“:”和“;”進(jìn)行拆分。當(dāng)然我們可以根據(jù)統(tǒng)計(jì)需要以不同的符號(hào)代表進(jìn)行多次拆分。利用String 類中的split 函數(shù)進(jìn)行分割,同時(shí)將結(jié)果存放在一個(gè)二維數(shù)組中。問(wèn)題在于怎么利用兩次split 分割后放在數(shù)組的兩個(gè)維度中,過(guò)程不再撰述。數(shù)組為引用型,需要申請(qǐng)內(nèi)存。
通過(guò)程序設(shè)計(jì)中split()函數(shù)字符串的分割功能,可以吧數(shù)據(jù)表的存儲(chǔ)有固定格式的字段內(nèi)容提取后根據(jù)需要進(jìn)行拆分,提取需要的內(nèi)容。完成統(tǒng)計(jì)功能。對(duì)于學(xué)生成績(jī)管理系統(tǒng),這種功能更能體現(xiàn)出來(lái)。一張數(shù)據(jù)表就可以解決。例如表5 如下,統(tǒng)計(jì)一下“張三”的總成績(jī)。
以上兩種通過(guò)程序設(shè)計(jì)中Split()的函數(shù)來(lái)解決數(shù)據(jù)庫(kù)的設(shè)計(jì)問(wèn)題及統(tǒng)計(jì)量的問(wèn)題,從而大大的降低了數(shù)據(jù)庫(kù)設(shè)計(jì)的復(fù)雜度,尤其在數(shù)據(jù)表的數(shù)量上會(huì)大大的減少,減少了數(shù)據(jù)庫(kù)的維護(hù)性[3]。僅僅在錄入數(shù)據(jù)庫(kù)時(shí),程序上一定要做格式上的驗(yàn)證,防止輸入不能被split()函數(shù)識(shí)別的問(wèn)題,這點(diǎn)在程序設(shè)計(jì)之初,必須要考慮的。
Split()函數(shù)在數(shù)據(jù)庫(kù)設(shè)計(jì)查詢過(guò)程中,顯示其優(yōu)越性。例如,全校不同專業(yè)的學(xué)生可以放在同一張表格內(nèi),三個(gè)字段:學(xué)號(hào)、姓名、成績(jī),在成績(jī)這個(gè)字段中,可以把學(xué)生各科成績(jī)放在同一個(gè)字段中,比如:語(yǔ)文:90;數(shù)學(xué):96;英語(yǔ):98;通過(guò)冒號(hào)和分號(hào)區(qū)別門課和成績(jī)。如果學(xué)生查詢總的成績(jī)時(shí),直接查詢,如果學(xué)生查詢“語(yǔ)文”成績(jī)時(shí),調(diào)用Split()函數(shù)直接單獨(dú)顯示語(yǔ)文成績(jī)。如統(tǒng)計(jì)總成績(jī)、平均成績(jī)等都可以通過(guò)Split()函數(shù)進(jìn)行實(shí)現(xiàn)。雖然用Split()函數(shù)可以提高數(shù)據(jù)的設(shè)計(jì)效率,但其的開銷比較大,因此Split()函數(shù)比較適合較小規(guī)模的數(shù)據(jù)庫(kù)設(shè)計(jì),而且對(duì)服務(wù)器的要求比較高。
Split()函數(shù)的在數(shù)據(jù)庫(kù)設(shè)計(jì)的應(yīng)用必然會(huì)增加程序的計(jì)算效率。程序中用到for 循環(huán)嵌套,時(shí)間復(fù)雜度達(dá)到O(n2)。文中提到split()函數(shù)在計(jì)算機(jī)上僅僅是邏輯分割,并不會(huì)在磁盤上將其切割成片存儲(chǔ)這樣對(duì)服務(wù)器的性能要求就會(huì)提高,增加了服務(wù)器的符合。如果通過(guò)增加數(shù)據(jù)表的方法來(lái)開發(fā),程序的復(fù)雜度可以達(dá)到O(n),但數(shù)據(jù)庫(kù)的維護(hù)復(fù)雜度就會(huì)增加[4]。
在字符串截取字符串應(yīng)用方面,Split()函數(shù)沒(méi)有其優(yōu)越性,StringTokenizer 在截取字符串中效率最高,不論數(shù)據(jù)量大小,幾乎持平。SubString 則要次之,數(shù)據(jù)量增加耗時(shí)也要隨之增加。Split()函數(shù)則是表現(xiàn)一般,究其原因,split 的實(shí)現(xiàn)方式是采用正則表達(dá)式實(shí)現(xiàn),所以其性能會(huì)比較低。
在字符串拆分應(yīng)用方面,以看出Split()方法比StringTokenizer類的拆分方法更加簡(jiǎn)潔和方便后續(xù)處理。Split()方法可以匹配正則表達(dá)式,而StringTokenizer 則不行。且大多數(shù)時(shí)候拆分得到的子字符串是要進(jìn)行操作的,而StringTokenizer 類操作子字符串是靠遍歷進(jìn)行的,比較繁瑣,相比之下運(yùn)用數(shù)組進(jìn)行下標(biāo)操作就方便多了,事實(shí)上官方也不推薦用StringTokenizer 類生成對(duì)象的方法來(lái)進(jìn)行字符串的拆分操作了。
根據(jù)用戶規(guī)模和實(shí)際需求,尋求數(shù)據(jù)庫(kù)設(shè)計(jì)方法,重效率還是重管理,數(shù)據(jù)庫(kù)有不同的設(shè)計(jì)方法。同一張數(shù)據(jù)表中,關(guān)聯(lián)性強(qiáng)的屬性可以合并后存入同一字段中,需要統(tǒng)計(jì)字段可以單列出來(lái)建立字段,這樣只要折中找出一個(gè)最優(yōu)點(diǎn),就可以減少數(shù)據(jù)表內(nèi)冗余,減少數(shù)據(jù)庫(kù)中數(shù)據(jù)表的數(shù)量和數(shù)據(jù)表間的關(guān)聯(lián)程度。對(duì)于合并項(xiàng),可以利用Split()函數(shù)進(jìn)行分割提取,因Split()函數(shù)開銷較大,但目前隨著服務(wù)器性能的提高及云服務(wù)能力的急速提升,開銷已不是主要考慮的問(wèn)題,降低數(shù)據(jù)庫(kù)設(shè)計(jì)的復(fù)雜度和內(nèi)聯(lián)性是我們考慮的重點(diǎn)問(wèn)題。