oracle 物化檢視、中間表的方案
阿新 • • 發佈:2019-01-14
物化檢視
有個專案因為有比較多的查詢彙總,考慮到速度,所以使用了物化檢視。簡單的把用到的給整理了下。 先看簡單建立語句: create materialized view mv_materialized_test refresh force on demand start with sysdate next to_date(concat(to_char( sysdate+1,'dd-mm-yyyy'),'10:25:00'),'dd-mm-yyyy hh24:mi:ss') as select * from user_info; --這個物化檢視在每天10:25進行重新整理 物化檢視也是種檢視。Oracle的物化檢視是包括一個查詢結果的資料庫對像,它是遠端資料的的本地副本,或者用來生成基於資料表求和的彙總表。物化檢視儲存基於遠端表的資料,也可以稱為快照。 物化檢視可以查詢表,檢視和其它的物化檢視。 特點: (1) 物化檢視在某種意義上說就是一個物理表(而且不僅僅是一個物理表),這通過其可以被user_tables查詢出來,而得到確認; (2) 物化檢視也是一種段(segment),所以其有自己的物理儲存屬性; (3) 物化檢視會佔用資料庫磁碟空間,這點從user_segment的查詢結果,可以得到佐證; 建立語句:create materialized view mv_name as select * from table_name 因為物化檢視由於是物理真實存在的,故可以建立索引。 建立時生成資料: 分為兩種:build immediate 和 build deferred, build immediate是在建立物化檢視的時候就生成資料。 build deferred則在建立時不生成資料,以後根據需要在生成資料。 如果不指定,則預設為build immediate。 重新整理模式: 物化檢視有二種重新整理模式: 在建立時refresh mode是 on demand 還是 on commit。 on demand 顧名思義,僅在該物化檢視“需要”被重新整理了,才進行重新整理(REFRESH),即更新物化檢視,以保證和基表資料的一致性; on commit 提交觸發,一旦基表有了commit,即事務提交,則立刻重新整理,立刻更新物化檢視,使得資料和基表一致。一般用這種方法在操作基表時速度會比較慢。 建立物化檢視時未作指定,則Oracle按 on demand 模式來建立。 上面說的是重新整理的模式,針對於如何重新整理,則有三種重新整理方法: 完全重新整理(COMPLETE): 會刪除表中所有的記錄(如果是單表重新整理,可能會採用TRUNCATE的方式),然後根據物化檢視中查詢語句的定義重新生成物化檢視。 快速重新整理(FAST): 採用增量重新整理的機制,只將自上次重新整理以後對基表進行的所有操作重新整理到物化檢視中去。FAST必須建立基於主表的檢視日誌。對於增量重新整理選項,如果在子查詢中存在分析函式,則物化檢視不起作用。 FORCE方式:這是預設的資料重新整理方式。Oracle會自動判斷是否滿足快速重新整理的條件,如果滿足則進行快速重新整理,否則進行完全重新整理。 關於快速重新整理:Oracle物化檢視的快速重新整理機制是通過物化檢視日誌完成的。Oracle通過一個物化檢視日誌還可以支援多個物化檢視的快速重新整理。物化檢視日誌根據不同物化檢視的快速重新整理的需要,可以建立為ROWID或PRIMARY KEY型別的。還可以選擇是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。 查詢重寫(QueryRewrite): 包括 enable query rewrite 和 disable query rewrite 兩種。 分別指出建立的物化檢視是否支援查詢重寫。查詢重寫是指當對物化檢視的基表進行查詢時,oracle會自動判斷能否通過查詢物化檢視來得到結果,如果可以,則避免了聚集或連線操作,而直接從已經計算好的物化檢視中讀取資料。 預設為disable query rewrite。 語法: create materialized view view_name refresh [fast|complete|force] [ on [commit|demand] | start with (start_time) next (next_time) ] AS subquery; 具體操作 建立物化檢視需要的許可權: grant create materialized view to user_name; 在源表建立物化檢視日誌: create materialized view log on test_table tablespace test_space -- 日誌空間 with primary key; -- 指定為主鍵型別 在目標資料庫上建立MATERIALIZED VIEW: create materialized view mv_materialized_test refresh force on demand start with sysdate next to_date(concat(to_char(sysdate+1,'dd-mm-yyyy'),'10:25:00'),'dd-mm-yyyy hh24:mi:ss') as select * from user_info; --這個物化檢視在每天10:25進行重新整理 修改重新整理時間: alter materialized view mv_materialized_test refresh force on demand start with sysdate next to_date(concat(to_char(sysdate+1,'dd-mm-yyyy'),' 23:00:00'),'dd-mm-yyyy hh24:mi:ss'); 或 alter materialized view mv_materialized_test refresh force on demand start with sysdate next trunc(sysdate,'dd')+1+1/24; -- 每天1點重新整理 建立索引: create index IDX_MMT_IU_TEST on mv_materialized_test(ID,UNAME) tablespace test_space; 刪除物化檢視及日誌: drop materialized view log on test_table; --刪除物化檢視日誌: drop materialized view mv_materialized_test; --刪除物化檢視 --------------------------------------------------------------------- 物化檢視的重新整理有二類,分別是:on commit ;on demand。重新整理方法有三種分別是:快速(FAST),完全(COMPLETE),強制(FORCE); ON COMMIT 與DEMAND 在應用中的問題 ON COMMIT 如果選擇on commit ,則在對主表應用上會造成速度,這是因為ORACLE在對主表操作提交後馬上會進行重新整理物化檢視操作,這部分時間是也包括在提交時間中。 a) refresh force on commit:中對刪,新增記錄,物理檢視都能真實反映主表的變化。同時這種情況下不用建物化檢視日誌表。缺點是提交時間長。 b) refresh fast on commit:中對新增或修改能真實反映主表的變化,但對刪除則不能反映,必須進行一次完全重新整理。 ON DEMAND DEMAND必須用DBMS_MVIEW.REFRESH儲存過程建立的JOB去定時重新整理物化檢視。 a) refresh fast on DEMAND:必須通過呼叫DBMS_MVIEW.REFRESH儲存過程來進行快速重新整理反映主表新增情況;但當對主表中的資料刪除或修改時,快速重新整理則會報錯,因此必須調DBMS_MVIEW.REFRESH的完全重新整理才能反映。可以通過建立JOB解決。 表1:快速重新整理 declare v_mvname varchar2(50); begin v_mvname:='MOCHA_FE_DOC_CONTENT_MV'; dbms_mview.refresh(v_mvname,'f'); end; / 表2:完全重新整理 declare v_mvname varchar2(50); begin v_mvname:='MOCHA_FE_DOC_CONTENT_MV'; dbms_mview.refresh(v_mvname,'C'); end; / 注意:用FAST 重新整理物化檢視,前提要新建物化檢視日誌表。 b) refresh force/complate on DEMAND: 在這種方式下物化檢視也是無法自動重新整理,必須通過JOB或手工。 FAST、FORCE、COMPLETE區別 FAST:增量式重新整理,使用此方法必須有前提,就是建立物化檢視日誌表。 FORCE::如果可以以fast 方式重新整理則用,否則完全重新整理。 COMPLETE:先將物化視圖表內容刪除,然後再重新整理。此方式缺少就是在重新整理時間內用法在頁面無法查到的所需要內容。 ---------------------------------------------------------------------------------- 官方文件: https://docs.oracle.com/cd/E11882_01/server.112/e10706/repmview.htm#REPLN335 1.1 概念 物化檢視 [1] (Materialized View)在9i以前的版本叫做快照(SNAPSHOT),從9i開始改名叫做物化檢視。它是用於預先計算並儲存表連線或聚集等耗時較多的操作的結果,這樣,在執行查詢時,就可以避免進行這些耗時的操作,從而快速的得到結果。物化檢視有很多方面和索引很相似:使用物化檢視的目的是為了提高查詢效能;物化檢視對應用透明,增加和刪除物化檢視不會影響應用程式中SQL 語句的正確性和有效性;物化檢視需要佔用儲存空間;當基表發生變化時,物化檢視也應當重新整理。 簡單說,物化檢視不僅儲存了sql的定義,還儲存了資料;它是遠端資料的的本地副本,或者用來生成基於資料表求和的彙總表。物化檢視儲存基於遠端表的資料,也可以稱為快照。 物化檢視可以查詢表,檢視和其它的物化檢視。 特點: (1) 物化檢視在某種意義上說就是一個物理表(而且不僅僅是一個物理表),這通過其可以被user_tables查詢出來,而得到確認; (2) 物化檢視也是一種段(segment),所以其有自己的物理儲存屬性; (3) 物化檢視會佔用資料庫磁碟空間,這點從user_segment的查詢結果,可以得到佐證; 建立語句:create materialized view mv_name asselect * from table_name 因為物化檢視由於是物理真實存在的,故可以建立索引。 字典: --物化檢視日誌字典,可檢視具體的日誌表 select* from dba_MVIEW_LOGS; --檢視物化檢視,可以查到定義的各種條件以及更新時間,以及查詢語句等 select* from DBA_MVIEWS; --物化檢視跟源物件的對應關係 select * from all_mview_refresh_times aa whereaa.MASTER='EMP' and aa.NAME='MY_EMP_VIEW'; 1.1.1 語法 create materialized view view_name build immediate|deferred refresh [fast|complete|force] [on [commit|demand] | enable queryrewrite |disable query rewrite start with (start_time) next (next_time) ] AS 查詢語句; 預設: build immediate,refresh force,on demand,disablequery rewrite 含義: 1建立時生成資料: 分為兩種:build immediate 和 build deferred, build immediate是在建立物化檢視的時候就生成資料。 build deferred則在建立時不生成資料,以後根據需要在生成資料。 如果不指定,則預設為buildimmediate。 2重新整理模式: 物化檢視有二種重新整理模式: 在建立時refresh mode是 ondemand 還是 on commit。 on commit 提交觸發,一旦基表有了commit,即事務提交,則立刻重新整理; 如果選擇on commit ,則在對主表應用上會造成速度,這是因為ORACLE在對主表操作提交後馬上會進行重新整理物化檢視操作,這部分時間是也包括在提交時間中。 a) refresh complete on commit:完全更新,不用建日誌表,缺點是提交時間長。 b) refreshfast on commit:必須先建立日誌表,增刪改都能同步 ,oracle11g經過測試得出; c) refresh force oncommit:先走fast,不行走complete on demand:手動重新整理同步,呼叫過程DBMS_MVIEW.REFRESH,也可以建立job呼叫過程更新; 相對於commit,只不過手動呼叫而已; a) refresh completeon DEMAND:全量重新整理 b) refresh fast on DEMAND: 同commit必須先建立日誌表 通過呼叫DBMS_MVIEW.REFRESH儲存過程來進行資料的重新整理同步; c) refresh force on DEMAND: 先走fast,不行走complete 3細節如下: 完全重新整理(COMPLETE): 會刪除表中所有的記錄(如果是單表重新整理,可能會採用TRUNCATE的方式),然後根據物化檢視中查詢語句的定義重新生成物化檢視。 快速重新整理(FAST): 採用增量重新整理的機制,只將自上次重新整理以後對基表進行的所有操作重新整理到物化檢視中去。FAST必須建立基於主表的檢視日誌。對於增量重新整理選項,如果在子查詢中存在分析函式,則物化檢視不起作用。 FORCE方式:這是預設的資料重新整理方式。Oracle會自動判斷是否滿足快速重新整理的條件,如果滿足則進行快速重新整理,否則進行完全重新整理。 關於快速重新整理fast:Oracle物化檢視的快速重新整理機制是通過物化檢視日誌完成的。 Oracle通過一個物化檢視日誌還可以支援多個物化檢視的快速重新整理。 快速更新必須要有物化檢視日誌表,不論是commit還是demand; 4查詢重寫(QueryRewrite): 包括 enablequery rewrite 和 disable query rewrite 兩種。 分別指出建立的物化檢視是否支援查詢重寫。查詢重寫是指當對物化檢視的基表進行查詢時,oracle會自動判斷能否通過查詢物化檢視來得到結果,如果可以,則避免了聚集或連線操作,而直接從已經計算好的物化檢視中讀取資料。 預設為disable queryrewrite。 5fast重新整理的限制: 所有型別的快速重新整理物化檢視都必須滿足的條件: 1.物化檢視不能包含對不重複表示式的引用,如SYSDATE和ROWNUM; 2.物化檢視不能包含對LONG和LONG RAW資料型別的引用。 只包含連線的物化檢視: 1.必須滿足所有快速重新整理物化檢視都滿足的條件; 2.不能包括GROUP BY語句或聚集操作; 3.如果在WHERE語句中包含外連線,那麼唯一約束必須存在於連線中內表的連線列上; 4.如果不包含外連線,那麼WHERE語句沒有限制,如果包含外連線,那麼WHERE語句中只能使用AND連線,並且只能使用“=”操作。 5.FROM語句列表中所有表的ROWID必須出現在SELECT語句的列表中。 1.2 物化檢視日誌 Following are the types of materializedview logs: Primary Key: The materialized view records changes to the master table or master materialized view based on the primary key of the affected rows. Row ID: The materialized view records changes to the master table or master materialized view based on the rowid of the affected rows. Object ID: The materialized view records changes to the master object table or master object materialized view based on the object identifier of the affected row objects. Combination: The materialized view records changes to the master table or master materialized view based any combination of the three options. It is possible to record changes based on the primary key, the ROWID, and the object identifier of the affected rows. Such a materialized view log supports primary key, ROWID, and object materialized views, which is helpful for environments that have all three types of materialized views based on a master. 翻譯: 主鍵:物化檢視根據受影響行的主鍵記錄對主表或主物化檢視的更改。 行ID:物化檢視根據受影響行的rowid記錄對主表或主物化檢視的更改。 Object ID:物化檢視根據受影響行物件的物件識別符號記錄對主物件表或主物件物化檢視的更改。 組合:物化檢視記錄基於這三個選項的任意組合對主表或主物化檢視的更改。可以根據主鍵、ROWID和受影響行的物件識別符號記錄更改。這樣的物化檢視日誌支援主鍵、ROWID和物件物化檢視,這對於基於主目錄擁有所有三種類型物化檢視的環境很有幫助。 物化檢視日誌根據不同物化檢視的快速重新整理的需要,可以建立為ROWID或PRIMARY KEY型別的。還可以選擇是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。 底層應該還是用到了類似的行級觸發器; 如: create materialized view log on emp --可以指定表空間tablespacetest_space -- 日誌空間 with primary key; --檢視物化檢視的重新整理情況 select *from USER_MVIEW_LOGS; 物化檢視日誌的名稱為MLOG$_後面跟基表的名稱,如果表名的長度超過20位,則只取前20位, 當截短後出現名稱重複時,Oracle會自動在物化檢視日誌名稱後面加上數字作為序號。 通過這個字典可以查詢到具體的日誌表; 通過日誌表就可以知道更新情況; --檢視日誌表 select *from MLOG$_EMP ; SNAPTIME$$:用於表示重新整理時間。 DMLTYPE$$:用於表示DML操作型別,I表示INSERT,D表示DELETE,U表示UPDATE。 OLD_NEW$$:用於表示這個值是新值還是舊值。N(EW)表示新值,O(LD)表示舊值,U表示UPDATE操作。 CHANGE_VECTOR$$:表示修改向量,用來表示被修改的是哪個或哪幾個欄位。 當重新整理完成後MLOG$_EMP相應的日誌記錄,會被清空; 在重新整理(同步)物化檢視之前你可以做各種DML操作; 在你提交之前就會記錄到日誌表; ------------------------------------------------------------------------------- 1. 用法 物化檢視是包括一個查詢結果的資料庫物件,它是遠端資料的的本地副本,或者用來生成基於資料表求和的彙總表。 物化檢視儲存基於遠端表的資料,也可以稱為快照。對於複製,物化檢視允許你在本地維護遠端資料的副本,這些副本是隻讀的。 如果你想修改本地副本,必須用高階複製的功能。當你想從一個表或檢視中抽取資料時,你可以用從物化檢視中抽取。 對於資料倉庫,建立的物化檢視通常情況下是聚合檢視,單一表聚合檢視和連線檢視。 實現兩個資料庫之間的資料同步,可以存在時間差。 1. 重新整理的方式 Fast Complete Fource 2. 重新整理的方法 DBMS_REFRESH.Refresh DBMS_MVIEW.Refresh 2. 具體應用 (1).在源資料庫建立mview log日誌檔案 create materialized view log on w_1 ; ----注:(TEST為表名或者檢視名,關於檢視上建立物化檢視,見基於檢視的物化檢視 ----建立物化檢視語句: (2).在統計資料建立materializad view 語法 Create materialized view MV_TEST ----MVTEST為物化檢視名 Build immediate ----建立時生成資料對應的是build deferred Refresh fast ----增量重新整理 On commit ----在基表有更新時提交,這裡該句對檢視無效 With rowid ----這裡建立基於rowid的物化檢視,對應的是 primary key As Select * from TEST; ----生成物化檢視資料語句 (3).呼叫時進行重新整理 dbms_refresh.refresh('W_1') --------------------------------------------------------------- oracle物化檢視 物化檢視是一種特殊的物理表,“物化”(Materialized)檢視是相對普通檢視而言的。普通檢視是虛擬表,應用的侷限性大,任何對檢視的查詢,Oracle都實際上轉換為檢視SQL語句的查詢。這樣對整體查詢效能的提高,並沒有實質上的好處。 建立物化檢視需要的許可權: grant create materialized view to user_name; 建立語句: create materialized view mv_name [選項n] as select * from table_name; [選項1]:BUILD [immediate,deferred] 是否在建立檢視時生成資料,預設生成、deferred為不生成資料,需要的時候生成 [選項2]:refresh [fast|complete|force|never] fast是增量重新整理,或者叫快速重新整理;complete為全表重新整理;force為如果增量重新整理可以使用則使用增量重新整理,否則全表重新整理;never則是不進行重新整理(不使用) [選項3]:on [demand,commit] 即手工重新整理和提交時重新整理 [選項4]:start with 通知資料庫完成從主表到本地表第一次複製的時間 [選項5]:next 說明了重新整理的時間間隔,下次重新整理的時間=上次執行完成的時間+時間間隔 例子1: create materialized view V_AB refresh force on commit as select * from a,b where a.id=b.id 分析:建立一個物化檢視來儲存a,b兩個表的資料,force表示儘量使用增量重新整理,但是這種寫法只會進行全表重新整理。commit表示自動重新整理,也就是說,當我們增刪改a,b表後進行commit操作後,我們的物化檢視也會同時進行資料的重新整理。如果想要使用增量重新整理來提高效率,請看下面的例子 例子2: 首先要建立與原表rowid相關的物化檢視: create materialized view log on A with rowid; create materialized view log on B with rowid; 再建立真正的物化檢視 create materialized view V_AB refresh fast on demand start with sysdate next sysdate+1/1440 as select a.rowid as arowid,b.rowid as browid, (其餘欄位) from a,b where a.id=b.id; 這裡使用demand代表手動重新整理,start with代表開始複製的時間,next說明間隔一分鐘後重新整理,也就是說,當我們增刪改a,b表後進行commit操作後,我們的物化檢視再經過1分鐘後會進行資料的重新整理。 查詢已經建立的物化檢視語句: SELECT * FROM user_mviews WHERE mview_name = '物化檢視名稱'; -------------------------------------------------------------------------
中間表的方案
中間表的由來 中間表是資料庫中專門存放中間計算結果的資料表。報表系統中的中間表是普遍存在的。那麼,這些中間表是如何出現的?為什麼中間表會越來越多?中間表會給專案組帶來什麼樣的困擾,如何解決這些困擾?這裡我們就嘗試探討一下這個問題。 中間表出現的典型場景主要有三個: 一步算不出來。資料庫中的原始資料表要經過複雜計算,才能在報表上展現出來。一個SQL很難實現這樣的複雜計算。要連續多個SQL實現,前面的生成中間表給後邊的SQL使用。 實時計算等待時間過長。因為資料量大或者計算複雜,報表使用者等待時間太長。所以要每天晚上跑批量任務,把資料計算好之後存入中間表。報表使用者基於中間表查詢就會快很多。 多樣性資料來源參加計算。來自於檔案、NOSQL、Webservice等的外部資料,需要與資料庫內資料進行混合計算時,傳統辦法只能匯入資料庫形成中間表。 中間錶帶來的問題 在一個運營商的報表系統中,我們發現了一個讓人吃驚的現象。在DB2資料倉庫中,有兩萬多個數據庫表!經過深入瞭解發現,真正的原始資料表只有幾百張,剩下的大量的資料庫表都是為查詢和報表服務的中間表。 經過幾年乃至十幾年的執行,資料庫中的中間表越來越多,甚至出現這個專案中上萬個的情況。大量中間錶帶來的直接困擾是資料庫儲存空間不夠用,面臨頻繁的擴容需求。中間表對應的儲存過程、觸發器等等需要佔用資料庫的計算資源,也會造成資料庫的擴容壓力。 那麼,是不是可以清理掉一些不用的中間表?一般的結論都是:搞不動。資料庫中的中間表是不同程式設計師製作的,有的是綜合查詢系統使用,有的是報表系統使用。中間表之間還存在交叉引用,有些程式設計師看到有別人生成的中間表就直接使用了。有時候一些查詢報表已經廢棄不用了,但是對應的中間表沒人敢刪,因為不知道刪掉之後會影響其他什麼查詢或者報表。 很多情況下,專案組只好為了越來越多的中間表去擴容資料庫。但是資料庫的擴容成本太昂貴了:不管是換更強的伺服器(縱向擴容),還是增加資料庫伺服器的節點(橫向擴容),都不便宜。過於頻繁的擴容讓專案組非常頭疼。 那麼,能不能把中間表匯出到檔案中,從而減輕資料庫的壓力呢?這個辦法初看挺好,但是有個問題始終無法解決。例如:每天晚上把經營分析表資料生成好之後放到檔案中,第二天上班的時候發現,業務人員還要對經營分析表按照各種條件過濾,或者按照各種維度分組。因為檔案本身是沒有計算能力的,一旦把中間表從資料庫中匯出成檔案就很難進一步計算了。不得已,只能把中間表繼續留在資料庫中。 解決問題的辦法 採用潤乾集算器實現檔案計算,就可以把中間表從庫中遷移到檔案系統中了。採用集算器的前後對比圖如下: 在集算器結構中,資料庫的大量中間表都移到了庫外,資料庫僅僅儲存少量原始資料表,壓力就小了很多。針對這些中間表實現的多個ETL儲存過程、觸發器、複雜SQL也都由集算器來實現,資料庫的計算壓力也變小了很多。雖然計算和儲存壓力由應用伺服器來承擔,但是成本還是要比資料庫伺服器低很多。專案組不用再每隔一段時間就申請資料庫伺服器擴容了。 同時,集算器可以讀取多樣性資料來源,直接參與混合計算。無需再匯入資料庫,成為中間表。 集算器程式設計很容易 移到庫外的資料檔案不能再使用SQL計算了,換成集算器會不會增加編寫的難度呢?實際上,集算器編寫簡單計算指令碼的時候和SQL差不多,複雜多步驟計算還要比SQL容易。例如: 從上述例子來看,採用集算器實現資料檔案庫外計算,學習成本很低,很容易掌握。 新方案的價值 新方案的價值還不僅僅是降低資料庫的壓力。 對於報表應用而言,中間資料的存在是有價值的:有些中間表是報表業務決定的,有些是為了彌補現有技術的不足。也就是說,中間資料和報表模板一樣,都是報表系統的一部分。所以,集算器的方案並沒有讓中間資料消失,只是移到了庫外,儲存在報表應用的檔案目錄中,使得中間表在物理上也成為了報表應用系統的一部分。這樣既能發揮中間資料的價值,還可以讓中間資料和報表系統的其他部分一起管理。顯然,檔案系統的樹形目錄結構比資料庫混在一起的幾萬個表要更容易維護。 在實際專案中,可以給中間資料檔案建立多層資料夾儲存。例如:第一層目錄是財務管理、人力資源、ERP等等。人力資源又有子目錄:工資管理,基本資訊,黨員資訊等等。目錄可以細化到某個報表,如果該報表發生了變化,只需要調整這個目錄中的報表模板或者資料檔案即可。如果該報表廢棄不用,那麼刪掉或者移走報表所在目錄,就可以快速的釋放硬碟空間。 從計算速度來說,由於檔案更底層,更接近於磁碟,IO效能要好於資料庫。所以集算器的方案可以為報表系統帶來更快的效能。 報表資料來自於多樣性資料來源時,還可以有更好的實時性,不像傳統手段時只能定期入庫。 ---------------------------------------------------------------------------------- 中間表起一種如關聯的作用。 比如課件和課件包,他們之間的關係是,一個課件包有多個課件。 如果建了一箇中間表,專門用來關聯課件和課件包的。 這樣,當要刪除一個課件的時候,只用先把這個中間表中關於這個這個課件的資料給刪除, 然後再在課件的表中將該課件給刪除。 這樣整個課件就刪除了。 如果我是在課件包這端建立關聯關係,@OneToMany。 這樣如果要用分頁獲取課件。(該課件包的課件) 這個時候如果一個課件包有好多的課件,要進行分頁。@OneToMany就會不合適。 如果在課件端建立關聯關係,@ManyToOne 這樣分頁的問題是解決了,但是如果要刪除掉該課件,但是由於,課件與課件包關聯著,刪除課件會報錯。 如果用課件與課件包中間表來解決此問題就會方便的多。 刪除上面說了。 分頁,只用將課件包的id得到就行。 --------------------------------------------------------------------------------- 資料庫設計中,經常遇到一個決策:究竟是使用檢視,還是中間表? 考慮庫存管理的一個場景:最普通的單據是入庫和出庫單,庫管員需要看到當前的庫存。對庫存的處理,我們有兩個方案:一是使用檢視,所有的入庫減去所有的出庫,就是當前庫存;另外就是使用中間表,建立一個庫存表,記錄當前的庫存。 1、使用檢視的方案 入庫時,系統記錄入庫單據; 出庫時,系統查詢庫存檢視,判斷是否有充足的庫存可以出庫,然後記錄出庫單據; 可見,系統只需要記錄入庫和出庫單據,庫存的計算是由DBMS在查詢檢視時進行的; 2、使用庫存表的方案 入庫時,系統記錄入庫單據,同時增加相應的庫存; 出庫時,系統查詢庫存表,判斷是否有充足的庫存可以出庫,然後記錄出庫單據,減少相應的庫存; 可見,系統除了記錄入庫和出庫單據外,還需要更新庫存表的當前庫存數量; 3、方案的比較 對系統本身的設計和編碼來說,檢視方案易於實現,測試方便;庫存表方案則稍微複雜。從這點上看,檢視方案可以在原型階段大展身手。 使用者體驗到的效能方面,檢視方案的效能壓力在查詢庫存上,庫存表方案的效能壓力在業務處理上: 檢視方案:由於每次查詢庫存,DBMS都需要掃描入庫和出庫單據,查詢時間長;還可能會對入庫和出庫單據加鎖,導致入庫和出庫處理延長,甚至失敗(尤其是查詢庫存檢視在一個事務中時);庫存檢視如果和其它表或者檢視連線,構成複雜的SQL時,由於索引不能有效(或無法)使用,查詢速度會更慢; 庫存表方案:庫存表上可以建索引,查詢速度比檢視會快很多;在入庫和出庫時,更新庫存表的SQL會對出入庫處理的速度有一些影響,但是由於更新隻影響出入庫的SKU,與查詢庫存表併發時,加鎖時間非常短,影響會比較小。 4、結論 檢視方案適用情形:原型,資料量比較小; 庫存表方案適用情形:資料量比較大,針對庫存的分析較多; -------------------------------------------------------------------------------------- 為了提高效能,對於中間表,的同步,採用初臺全量同步,每天,增量同步的方案。 我介紹一下我們增量方案吧! 要增量,增量日誌表是必需的,增量日誌表的設計。 KEY(原業務表關鍵字),CREATE_DATE(變更時間),FLAG(資料修改與刪除標誌),USE_FLAG(增量表是否被使用的記錄,(一個儲存過濾使用一位)) 每天增量同步時,做如下操作 --如果增量日誌表,所有標誌位都已經使用,把增量日誌表移到增量日誌備份表裡 INSERT LOG_MANUAL_INC_BAK SELECT * FROM LOG_MANUAL_INC WHERE LEFT(USING_FLAG,4)='1111' DELETE LOG_MANUAL_INC WHERE LEFT(USING_FLAG,4)='1111' --建臨時中間表,方便同步(欄位內容與真實表一樣) CREATE TABLE #TG_ENTRY ( [TE_ENTRY_ID] [char] (18) NOT NULL .. ) GO ---------------------將未整合記錄從中間表中刪除 --SUBSTRING(USING_FLAG,2,1)為這次整合使用的標記位 DELETE FROM TG_ENTRY WHERE TG_ENTRY_ID IN (SELECT TG_ENTRY_ID FROM LOG_MANUAL_INC WHERE SUBSTRING(USING_FLAG,2,1)<>1) 。。下面就可以做同步資料了, 。。。同步資料是從原業務表裡取,不過,資料範圍限定在,增量表裡的沒有做增量操作(並且操作型別為新加與修改的)的資料 也就同步多加一個WHERE條件, WHERE LOG_MANUAL_INC.ARJ_MARK='M' and SUBSTRING(USING_FLAG,2,1)<>1 取好的資料是放在新建的臨時中間表,#TG_ENTRY 做好了同步操作,不要忘了更新增量表的標誌。 ---------------------