建表的幾條原則
表數(shù)據(jù)量是隨著時(shí)間持續(xù)增加(像訂單類表),并且運(yùn)行一年后,表記錄數(shù)超過(guò)2000萬(wàn)條,則需要考慮表分區(qū)。如果表數(shù)據(jù)基本上是靜態(tài)的(像用戶信息表),一般不考慮分區(qū)。如果記錄數(shù)接近億條,則可以考慮用HASH分區(qū)。表名只能使用字母、數(shù)字和下劃線,字母都小寫(xiě)。數(shù)據(jù)庫(kù)里若存在多個(gè)用戶,則以用戶名簡(jiǎn)寫(xiě)開(kāi)頭,比如用戶庫(kù)的表以USR_開(kāi)頭,訂單庫(kù)的表以O(shè)RD_開(kāi)頭;若只有一個(gè)用戶,則以t(表)或v(視圖)開(kāi)頭。臨時(shí)表以tmp_開(kāi)頭;備份表以bak_開(kāi)頭。表的字段數(shù)量不超過(guò)30個(gè),在非必要的情況下不要使用clob等大字段。一張表里所有字段的總長(zhǎng)度盡量小,絕對(duì)不要超過(guò)8000(數(shù)據(jù)塊大小就是8K)。不同表里相同意義的字段,取名一樣。列如A表的更新時(shí)間字段取名update_time,那B表就不要再取名modify_time。選擇字段類型的時(shí)候,能用number就不要用varchar2。做查詢的時(shí)候,同等條件的number效率比varcha2高。值為枚舉型值的字段,用number(1)或者char(1);如果有超過(guò)10個(gè)以上的枚舉值,用char(2)。多個(gè)表里該類字段的值定義要一致。如a表status=0表示正常,則b表也應(yīng)一樣定義。這里可以約定一下:用char做類型時(shí),值為A、B、C這樣的字母類型;用number做類型時(shí),值為0-9,這樣方便區(qū)分。字段盡量設(shè)置為not null,或者設(shè)置默認(rèn)值。表和字段,都需要有comment,尤其是枚舉型值字段。在mysql中,每個(gè)表都會(huì)有一個(gè)id字段做主鍵,也就是聚簇索引,其它的輔助索引都要通過(guò)聚簇索引來(lái)查詢。在oracle中,所有的索引都是通過(guò)rowid直接查詢的,不存在“二次查詢”,所有如果該id字段不與其他表做管理,則在表設(shè)計(jì)時(shí)不需要該字段。將表數(shù)據(jù)和索引數(shù)據(jù)分開(kāi)存儲(chǔ)。建索引時(shí)明確指定表空間。索引數(shù)量不宜過(guò)多,一般情況下4個(gè)以內(nèi);索引太多會(huì)影響記錄的插入。個(gè)人認(rèn)為為了限制記錄的唯一性時(shí),可以建唯一索引;否則如果幾個(gè)字段均有可能作為查詢條件時(shí),可以分成多個(gè)索引。復(fù)合索引字段的先后順序很重要,第一個(gè)字段必須是查詢時(shí)使用最頻繁的,否則有可能用不到索引。舉個(gè)不恰當(dāng)?shù)睦樱河脩粜畔⒈砝镉凶C件類型(cert_type)和證件號(hào)碼(cert_no),建唯一索引的時(shí)候,索引字段順序肯定是需要cert_no,cert_type,而不是cert_type, cert_no。因?yàn)椴樵兊臅r(shí)候,很有可能只是用了cert_no,而沒(méi)用到cert_type。我說(shuō)“不恰當(dāng)”,是因?yàn)閛racle的CBO比較厲害,在使用cert_type,cert_no作為復(fù)合索引的時(shí)候,oracle會(huì)分析后以跳躍索引處理,仍然能用到索引。SQL基本規(guī)范
錯(cuò)誤用法:to_char(create_time)>’20220101’
正確用法:create_time>to_date(‘20220101’,’yyyymmdd’)+0.999
說(shuō)明:create_time為date類型,如果create_time字段有索引,加了函數(shù)就會(huì)用不到索引。
- 寫(xiě)查詢條件時(shí),字段類型必須一致
比如,status為char(1),就不要寫(xiě)成status=1,而是status=’1’。否則后續(xù)若status字典值擴(kuò)展了,用了字母,sql就會(huì)報(bào)錯(cuò)。
- 索引列字段不用函數(shù),查詢時(shí)要盡可能將函數(shù)操作移至等號(hào)右邊。
- 盡量避免使用order by和group by排序操作,大量的排序操作影響性能。如必須使用排序操作,盡量用在有索引的列上。
- 數(shù)據(jù)清理時(shí)的注意點(diǎn):
做delete或update數(shù)據(jù)時(shí),首先要select count(*)一下,計(jì)算一下受影響的記錄數(shù)。如果受影響記錄數(shù)是百萬(wàn)級(jí)的,或者查詢條件是全表掃描的,那務(wù)必在查詢條件增加個(gè)rownum<=10000,一次影響1萬(wàn)條。舉例1:(刪除500萬(wàn)行記錄)declare
i integer:=500;
begin
while i>0 loop
delete from oper_log t where t.create_time<to_date('20220228','yyyymmdd') and rownum<=10000;
commit;
i := i-1;
end loop;
end;
舉例2:(按天清理數(shù)據(jù)到備份表)declare
i integer:=200;
mindate varchar2(8) :=’20211001′;
maxdate varchar2(8) :=’20211231′;
currdate varchar2(8) := mindate;
begin
while currdate <= maxdate loop
insert into bak_oper_log
select * from oper_log t where t.create_time<to_date(currdate,'yyyymmdd');
delete from oper_log t where t.create_time<to_date(currdate,'yyyymmdd');
commit;
currdate := to_char(to_date(currdate,’yyyymmdd’)+1,’yyyymmdd’);
end loop;
end;
鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。