Oracle之数据库设计概述
生活随笔
收集整理的這篇文章主要介紹了
Oracle之数据库设计概述
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
其實講了索引的這塊了,接下來可能要講的內容是物化視圖,然后講分區,然后數據庫表結構的設計,你們總問我SQL優化,那在講整個物化視圖之前,咱們之前講索引了,對于數據庫的設計,咱們從頭到尾的去過一遍,然后我們工作中怎么去設計表結構的,當然這個沒有實例,只是憑我說一下,然后就是個人的一些工作中的總結,跟你說一下,大體上有幾種,其實我還是要畫圖,然后去說明,當然我只是拿ORACLE為例,MYSQL其實我也不是很熟,什么分區,分片,分表啊,這種都是很easy的東西,但是只是說概念是很easy的,但是場景還是很麻煩的,你業務得懂,你還得考慮數據庫的可擴展性,包括一些很多的問題,說一說數據庫的設計,我就畫一張圖吧,我這邊畫一幅畫,可能列出來這么多種,當然我就用文字描述,在你們的心中,對于數據庫的好與壞,SQL語句優化怎樣啊,這個其實相當于怎么說呢,或者你買一個產品,會有一個售前售后服務,我覺得這個東西就相當于售后服務一樣,SQL優化這個東西是屬于售后,售后出現的事情,才叫做SQL優化,事前出現的問題不叫SQL優化,這個SQL優化肯定是我們最后要做的一件事情,在你這個立項開始,在做分析開始,然后再加上表結構設計開始,等等這一系列東西,咱們要關心的其實還是售前,這個才是解決的最根本方案,售后這個事其實我并不太看重,那我就從咱們最開始,我分兩大點,第一大點我用,數據庫設計,無論是建模還是從整體所有的,分兩大方面,第一方面是對于數據庫表的設計,第二大方面其實是對于索引,對于索引的設計,你不能這么說,對于結構優化的設計,這是兩大方面
1. 數據庫表的設計(1)業務需要學會區分 先從表開始,咱們的一個數據庫表,可能最初規劃的時候,你有一點需要做的事情是,這個東西都是太簡單的事情了,咱們就不提數據庫范式了,那個是規范,你一定要遵守是最好,數據庫表的設計,第一點是要干什么事呢,在我看來你最重要的是業務你得會切分,就是業務你得學會切分,然后這個業務你怎么去切分呢,業務切分就是相當于你某個產品吧,我們就舉電商為例,電商那個產品為例,其實電商這個東西之前也沒提,他到底是怎么回事呢,因為它平臺很大,涉及到很多系統的結合,可能傳統行業走流程,電商走一個訂單的一個量,是一個很大的需求量,從供應商開始,一直到結束,涉及的東西其實是很復雜的,你比如說我打個最簡單的比方,我在電商網站上,現在給我一個平臺,比如淘寶的平臺,然后我有一個供應商,相當于賣東西的賣家,他想去賣一個產品,比如是蘋果,IPHONE手機,或者賣其他的東西,總之是賣一個產品,那最初肯定是做什么事啊,我這里面肯定是有一個供應商系統,肯定有一個供應商的系統,我就這么寫了,這個系統主要是做什么事呢,我這邊來了一個供應商以后,他們要和網站要簽一個合同的東西,就是供應商的資質啊,審批啊,等等就是一系列的東西,這個東西其實是很復雜的,包括他的供應商的編號啊,還有許可啊,一堆,然后就往系統里去錄入,然后他們兩個完成合同以后,這個供應商系統第一個步驟就走完了,填完這個東西以后,下一步怎么辦,下一步可能就涉及到商品的系統了,管理商品的,那這個商品可能不只是一個數據庫,可能是多個數據庫,比如你賣鞋,賣衣服,賣產品,賣吃的,還有賣其他東西的,供應商還是要操作商品這個東西的,然后就往里添加商品,接下來還有一個庫存的系統,進銷存系統,庫存,那這個庫存的系統,比如說,你賣手機,賣蘋果,我這里就有添加蘋果的商品了,然后你就得告訴蘋果有多少條嗎,比如他錄入了500件商品,就是庫存,接下來往下走,這個東西還是很復雜的,還有一些其他的環節我就略了,因為太細節的環節我就略了,然后緊接著這個東西還有一個,其實所有電商都有一個非常核心的模塊,這個模塊就是ERP,不管是天貓還是淘寶,還是其他的這個,都有這個ERP,不管是哪一個角色吧,你做了這些操作以后,都得回到這個ERP系統里,然后由ERP交給前端的一個系統里,前端什么系統呢,就是咱們的網站系統,就是這個網站,網站系統就是用戶打開網站購物的網站,看到這個商品,訪問商品這個模塊,就是這個系統,接下來以后,其實整個這一塊的過程,一般在電商叫SCM,它是一套,是好幾個系統組成的一個綜合的系統,然后EPR里面的分類又更多了,然后接下來就是這個用戶client端,可能要去下訂單買產品,買產品的過程中肯定會涉及到很復雜的邏輯,我舉個最簡單的例子,我們去提交訂單的時候,提交完了之后,每個電商都不一樣,一般都會有一個分單的系統,什么意思呢,你這個網站是第三方的,還是自營的,會有淘寶,天貓,自營的產品,京東自營的或者是其他自營的產品,把用戶所下的單根據類型進行一個分流,根據類型進行一個分流,如果是要走一個系統的話壓力太大,這邊可能就是處理訂單的系統,這是一個分單的系統,然后這里有一個處理訂單的系統,自營的處理訂單的系統,然后這是第三方處理訂單的系統,三方處理訂單的系統,然后接下來還有一些細粒度的系統,然后還有什么發票啊,發票怎么管理,有一個發票的系統,然后還有一些更細節的系統了,你比如說我這邊要做促銷,還有好多的小系統,價格管理的系統,這商品多少錢,還有一些促銷的系統啊,這些都是加進來的業務,這些分散的點都非常的多,總之你要走一個流程走完了之后,其實電商這東西怎么說呢,它是很復雜的,它是根據每一個人的角色不同,提供了一個職務,但是其實最終最核心的還是ERP,無論什么樣的系統,最總都會匯總到EPR系統里,這是內部人員去使用的,或者財務去使用的,財務肯定是會涉及到錢啊,財務系統就涉及到結算了,一般是在咱們用戶去付錢,交給的都是網站,然后和供應商定期簽合同,每個月的1號,2號,就是一個月一結算,這個月我賣了500件產品,然后你給我finace財務系統,然后財務系統對應的還有一個結算系統,然后把對應的錢對應的供應商,是這樣的,一般的都是這樣的,包括你看到的一些淘寶啊,用戶轉賬都是轉到類似支付寶,余額寶,自己的公司里,再過多少天以后,一個月以后,然后把這個錢轉給供應商,都是這么去做的,其實針對于不同的操作,供應商其實也有一個系統,這個只是供應商的合同系統,那你要是再往下分的話,供應商的管理系統,比如我用戶去下一個訂單,下一個訂單之后,比如要賣Iphone手機,其實供應商管理這個系統,比如用戶下了一個手機Iphone,然后這邊直接通知給供應商了,供應商肯定是自己利用這套系統,做一些包裹啊,快遞啊,這個系統是供應商自己操作的,是供應商自己具體去操作的,你比如用戶買完了,又申請取消訂單,那供應商首先得知道,其實說白了吧,每一個角色,在咱們電商里邊,你自己的這個人,每一個供應商都是和用戶直接打交道的,總之這個東西是很復雜的,就比如京東不是很大的網站,跟淘寶是沒法比的,他那個系統里面就涉及到100多個小系統,100多個子系統,就是覆蓋的非常多吧,這個系統和系統之間,會有一些交叉,其實他們最終都是涉及到ERP,往這里面去裝數據,ERP它是不對外網公開的,它是內部去做的,大體上都是很亂,不說這事了,所以第一件事是很重要的,要學會數據庫設計,第一點就是學會業務切分,比如你做O2O電商,你自己有很豐富的經驗,規劃出來這個東西,業務切分是非常重要的一件事,然后再往下看可能就是涉及到細節問題了,咱們去做數據庫表結構設計,他這個東西就是分層,物理分層
(2)邏輯分層,這個什么意思呢,你自己得規劃好,有一些就是基礎信息,你這個平臺搭建之初,肯定有一些基礎信息,你上層的業務其實是根據基礎信息去操作的,剛才我只是根據供應商這一個角色,那你根據用戶的角色就更麻煩了,用戶可能會涉及到我的空間,還有我買到的產品,涉及到網站就更多了,涉及到購物車,這個就很復雜了,這個就不說了,剛才我就說看到了分層,你要把基礎表要設計的非常好,你只有基礎表設計得非常好以后,你再往上層去擴展業務的時候,你才好擴展,才很靈活,基礎信息這個設計是非常重要的,分層一般就是基礎信息加上你的業務層,每一個業務層可能有一套數據庫,你的一堆表,就是邏輯分層,就是數據庫分層,就這么說吧,你做好了這兩件事以后,這個是整體最大的框架,然后再往下,數據庫分層很重要,再往下才開始要設計一些數據庫表結構
(3)數據庫表結構,就是在你了解業務的前提,數據建模,哪些業務和哪些業務分到一個數據庫里,就比如供應商涉及到幾張表里,那他單獨放在一個庫里面,然后用戶涉及到好幾張表,單獨放在一個庫里面,這個東西相當于什么啊,就是一直拆分嗎,有垂直,垂直去拆分,那其實也是根據不同的業務去拆分,這個有點像第一塊,還不一樣,這是根據數據表層次的去拆分,然后呢,這個數據庫表結構的設計與拆分,大方向的垂直拆分以后,比如有一張訂單表啊,或者是用戶表啊,這個信息量都很大,然后你就會才去一定的策略了,這個訂單表很大的,這個時候才會涉及到水平拆分(3.1)mysql水平拆分(分片) 比如說訂單這個表,然后奇偶數,訂單的ID,取余2等于0,比如取余3等于0,取余5等于0,取余5等于0,可能不是4,2和4是一樣的,取余3等于0,取余5等于0,可能是會把一張表水平的拆成多張表,這里面放取余等于2的一些數據這里面放取余等于3的一些數據,這里面取余等于5的一些數據,可能還有其他的算法,不一定只是按照ID去拆分,我只是說訂單,我只是說用戶,用戶可能還有一些級別,VIP用戶,普通用戶啊,就好像騰訊里面的QQ,都有些級別嗎,有黃鉆,紅鉆,里面都有不同的業務功能,他那些業務功能都是繼承的,你可能有一個黃鉆,基礎功能有三個,1,2,3,黃鉆在這兩個基礎上再加兩個功能,然后紅鉆再在這個基礎上再加幾個功能,然后紫鉆再加幾個功能,VIP,超級VIP,權限都有不同的,所以可能我猜想,我沒看過騰訊,最大方法肯定是不會通過ID去分的,最大方面可能是經過用戶的Type類型,去進行一次水平的拆分,然后Type類型之后呢,要想QQ的用戶量有多大啊,通過類型拆分了以后,還得通過一次取模,再次產生,只能通過幾級的拆分,第一級是通過Type,拆分3個表,然后一個Type里面再通過取模,再拆分,如果還復雜就繼續再拆分,這個架構就造成一個什么問題呢,我查數據的時候,這個就很難查,我要查一些數據在這個庫里有,在這個庫里有,還是在這個庫里有,那就可能是兩個庫進行join了,join查詢了,或者是三個庫里進行join查詢了,多個庫進行join,垂直拆分是按照業務去拆分,一會會講到,拆分是吧,剛才是按照業務拆分,3個庫join這塊,不是有人要我講mycat,mysql,mysql的代理是mycat,mysql的最佳代理,就好像咖啡加牛奶,這個最佳代理,其實我也去看了一天,這個東西其實非常不成熟,因為它現在只支持兩個表的join,多個表的join就是不支持的,而且其實你仔細想一想,這個性能真的有他說的這么高嗎,我覺得不見得,雖然我沒有做過測試,但是mycat肯定比你自己寫業務要快,其實在一個開源產品上做一個封裝了,如果你有能力的話,你也可以自己公司開發一套,其實你看京東,就包括淘寶,他肯定不是用開源的mycat,淘寶是用comba,他肯定是類似于mycat這種東西,但是他是自己實現的,他自己實現可能是通過NIO異步的通信,去解決了這個問題,比如像數據庫中間件,他為什么開源啊,因為做不了那么強大的東西,所以開源,然后一般是根據你實際的業務去設計數據庫中間件,說我這個東西到底要返回哪幾個庫,然后我怎么去做訪問,采用什么技術,然后數據來了之后我要怎么合并,然后我怎么去排序,怎么去做統計分析計算,一系列的東西,根據你公司實際的業務去做實際優化的,不可能有一種通用的產品能實現這個事,這是我自己感覺的,MYCAT是我暫時pass掉的一個東西,因為它現在才出到1.5版本很不穩定,兩個表join,而且兩個表join的時候還有各種各樣的問題,然后分片就是把一個表里的數據分成多個數據庫,分片的這個概念,他們之間做匯總的時候,他也有一些問題,說是挺清晰的,但是其實還是挺嘔心的事,就是MYSQL的一些原生的問題也沒有解決,之前咱們說MYSQL,MYSQL的主從怎么做啊,比如這是MSYQL的主服務器,這是MYSQL的從服務器,其實那天也說了,MYSQL主服務器有一個binlog日志,就好像ORACLE的日志歸檔一樣,就是咱們兩個都是空庫前提下,沒有數據的情況下,如果有數據,就要先備份一下,把這里的數據導到這里面,好多年前我一直用MYSQL,MYSQL有兩個線程,跟主數據庫,從庫有兩個線程,一個是跟主數據庫通信的線程,一個是解析日志的線程,他把里面的日志轉化成SQL,去執行,其實還是一條SQL一條SQL的去執行,所以說MYSQL的這種主從同步,它是邏輯上的同步,不是物理上的同步,物理上的同步是把數據直接COPY到這上面了,這種同步其實性能還是很不好的,你想想啊,就好像我們把一個dump文件,去導入mysql,去批量的去執行SQL,往里面加數據,他其實就是這種邏輯,然后利用主從還有問題,比如我配置了一主多從的機制,可能兩個從,3個從,4個從,主掛了,他的切換一個從服務器,這個時間段如果有數據進來,他掛了的時候如果我進來,那我肯定有丟數據的問題,所以說即使是主修復好了,然后主服務器再上來的時候,那肯定數據就不一致了,就會有這個問題,其實碰到過很多的這種案例,開始做MYSQL主從,各種各樣的問題,數據不一致,就比如MYSQL的硬件壞了,磁盤壞了,然后切到一臺從服務器上,然后就會產生這個問題,如果你要做多主呢,多態主服務器系統,其實他還能保證高可靠,數據不丟失,但是會有一個問題,從服務器掛,這也是MYSQL的一些問題,然后現在不是基于這個問題有一個MYSQL,我記得看文檔它是用這個hproxy,去做這個高可用這個事,兩臺這個hproxy,訪問我們的中間件mycat,后面再通過心跳的機制,去監控MYSQL的集群,其實他這個東西也做的不穩定,反正也不太好,你還不如采用這個官方提供的方案,去做主從,做主從分離,我剛才說到的這個事情,是數據庫的拆分問題,然后這個拆分其實分的很細,主要說其實是水平拆分,水平拆分,那這可能是MYSQL的解決方案,因為你在數據大的時候怎么辦,那就水平拆分,其實要是到ORACLE里面那就easy了,ORACLE他肯定要保證數據不丟失,性能也能保證,分庫是已經實現分庫了,把一些固定的業務邏輯的表放在一個庫中,垂直拆分是第一步,相當在ORACLE里面呢,可能產生分區的方案,一些各種各樣的分區(3.2)分區:只有你想不到的,沒有不提供的,各種各樣的分區,咱們以后要講,我們講的range分區啊,區間分區啊,list分區啊,間隔分區啊,包括hash分區啊,很多很多,七八種分區吧,這個東西還可以轉成自定義,然后MYSQL他要求的是單個分區,MYSQL他就不叫分區了,MYSQL的叫分片,就把它放在不同的數據源上,單個分片是不大于1000萬條數據,我覺的這個頻率還是很大的,就算你一個片上只能放1000萬條數據,當然是單表1000萬條數據,一個片上,其實咱們的這個ORACLE分區已經很明了,你可以做無數個分區,ORACLE當是記得是OCP的時候,他要求是500萬條數據一個分區,那其實一個大表可以是無限個分區,然后每個分區可以存個500萬條數據,然后他這個分區的查詢的性能還是很大的,還是很好的,其實早期就是因為MYSQL的分區性能不好,5.0之前可能還沒有分區的特性呢,5.0之前是沒有分區這個特性的,5.0之后有分區這個特性,但是性能還是和ORACLE沒法比,它會產生一個分布式事務的問題,分片MYSQL,就是相當于ORACLE里面的分區,最終我要兩張表的數據進行join的時候,當時我們的ORACLE是能做的,ORACLE叫做跨分區查詢嗎,我這500萬條數據和這500萬條數據今夕跨分區查詢,如果是多表join的話,MYSQL就得用多表join來完成這個事,那還有一件事情,是什么呢,就是咱們要講的物化視圖(3.2)物化視圖:其實物化視圖這個概念,就解決了多表join的這個問題,多表join會有很多問題,分布式事務的問題,兩個數據庫要做寫操作的話,有分布式事務的問題,ORACLE里面的解決方案就是物化視圖,那你想一想一件事,比如我們做多表join,一張表里數據量很大,這一張表里數據量也很大,然后這一張表里數據量也很大,很多張表進行join,他join他,他join他,可能還有一些子查詢,一系列這個復雜的東西,MYSQL就解決不了這個問題,但是咱們ORACLE里邊呢,MYSQL里也有視圖,在ORACLE里面有一個物化視圖的概念,就是把你自己寫好的一個視圖變成一個實體,就是變成一個存到數據庫的一個位置,它是物理級的存儲,物化視圖的概念,那咱們平常的視圖呢,是一個虛表,其實走視圖還是要走幾張表聯合起來找到一個結果,那在咱們的ORACLE里邊,物化視圖就是相當于把這幾張表的查詢結果,放到一個表里,這個表就保存著一些數據,那我client在進行查詢的時候,確實是查這張表里的數據,查物化視圖表里的數據,如果是正常視圖呢,其實還是相當于你走這個,1,2,3,4,5,這幾張表join,那這個區分就很大了,join和不join的區別就很大了,所以物化視圖是能提高咱們查詢的效率,也是非常高的查詢,能明白我說的意思吧,然后繼續再看,其實還有,如果你系統夠好的話,就相當于把數據存在一個中間表里,如果真涉及到一種業務的話,其實解決方案還有很多很多
(4)中間表:中間表的方案,中間表的方案是什么意思呢,其實就是物化視圖的另一種了,比如你這個表的數據量很大,然后很多條數據,然后我可以把這個東西匯總成一張小表,比如你這里一天要存放10條數據,某一條記錄吧,比如我這個表里有一個type字段,一天要存放10條數據,然后還有好多條type類型,那我可以把他利用一些存儲過程,有一些其他的手段,把他這個進行統計分析,存到另外一張中間表里,那就是每一條數據就存一個type,一天的數據是10條,然后type2這個數據是15條,type3是多少條,然后我做月,年統計分析的時候,可能就查這一張表,再來一個,可能這個是天表,這邊可能就是月,然后再來一張表就是季度,或者是年份,有很多張表,或者你也可以把月季年,劃分成一張表,然后自己經歷的一個周期,根據周期的類型去指定月份,季度,年,這個就相當于一個中間表的方案,這個時候也叫緩沖表,我最后用戶client端去做查詢的時候,只要查天的表,月,季,年的就行了,不會走這個數量很大的基表,去做查詢了,其實還有很多種,還有其他的方案,設計的方案(5)設計的方案:你有沒有想過你這個數據量很大的時候,我能不能靠一些優雅的數據表的設計,去完成一個很好地事,比如你這個表要和其他的表進行join,做其他的事情,這里可能是一個樹形,可能是其他的結構,第一張表和第二張表要關聯的字段,已經關聯好了,已經存儲好的一個節奏,我可能利用一個存儲過程,很簡潔的,然后再和這張表進行join,這個效果性能可能就會更好了,針對于不同的場景,具體去做業務邏輯的設計,然后抽象出一張比較簡單的表,然后他們兩個進行join,咱們數據庫瓶頸的一些方案吧,這個是我們單獨從數據庫表去走,你就會有這么多的方案
2. 對于結構優化的設計由于咱們昨天講了索引了,第一方面咱們先放在這里不講,先講第二方面,咱們先講第二方面,然后從結構上來,從結構上去優化的話,還有很多,最簡單的就是建立咱們的索引,最簡單的一種方案就是建立咱們的索引(1)建立索引:我想問一下你們平時工作的時候,都是怎么去建立索引的,比如設計這個表啊,數據量可能是比較大的,可能有幾百萬,幾千萬,可能更大的條數,你們都是怎么去建立索引的,有沒有可能經常去建立一些規則索引,就是經常關聯字段去建立索引,就是規則索引吧,在建立規則索引之后,怎么去查詢呢,就是根據解釋索引吧,其實規則索引還是挺難建的一個,你是怎么去建立規則索引的,這個規則索引不好建,難道你說,你在設計表之初就得想好這個事,比如這個表,這個ID先不考慮,他就是咱們要建立的一個規則索引,可能有一個name,這里面可能有一個其他的字段,可能有一個其他的區域,AREA,AREA區域,還有一個什么啊,比如一個日期date,然后可能還有一些字段,我現在就跟你說一個問題,就是這張表數據量很大很大,幾億,上億,或者幾十億,那你除了要分區以外,分區是肯定的,這么大的表,那么你現在這個規則怎么去建立呢,規則索引什么意思,就是你主鍵不是來一個uuid就完事了,就是有一定規則的去生成的,比如前幾位你要規劃成什么樣,后幾位你要規劃成什么樣,然后再往后幾位你又要怎么去規劃,然后最后去查詢的時候,正常來講如果你不建這個規則索引的時候,我舉個例子,某一天我這個type字段挺頻繁查詢的,那怎么辦啊,后期我們在type上建一個索引吧,在type上加一個索引,那現在這張表就兩個索引了,到最后你發現日期也是非常頻繁的去查詢,怎么辦啊,咱們再去在日期上建一個索引,就三個索引了,然后隨著字段的多,你的需求不斷地去擴張,那你就會發現,完了,還得建一個索引,本身一個數據庫表的數據就很大,再建10個索引,你以后再做持久化操作insert的時候,或者update的時候,你總得維護索引,你總得去做,IO性能,就是包括你讀的時候,找的時候都很麻煩,會根據幾個索引規則去找,這個性能肯定是不高的,那我想問一下,你是怎么去建立規則索引的,最常用使用的查詢條件,后期也補過索引,where條件多例的話,算出不重復的總數,然后創建符合索引,由多到少排序,肯定也會涉及到一些,就得建復合索引,你得考慮這張表有多少個字段,你得有預留字段,后期需求擴展可能要添加,或者從考慮之初,這張表可能是不穩定的,以后可能會加業務,要把這個業務口流出來,來一個額外的一個外鍵,然后把業務這張表直接給建出來,可能直接關聯出來,以后什么時候用到這個業務了,這張表直接當外鍵了,直接和我擴張業務的這張表,直接掛鉤了,預留字段是干什么事,預留字段其實預留的都是外鍵,因為咱們工作都好幾年了就肯定會看到一些公司,不管有的沒的會的不會的,一張表里總會有幾個預留字段,那這個預留字段你知道他是真正干什么用的嗎,你別告訴我預留字段以后的目的就是為了我有一個條件,我加一個字段,然后去做一個預留字段的,不是這個事的,預留字段其實不是干這個事的,預留字段是干什么事的,是我以后,剛才我們說了,我這張表不可預期,我這張表寫完了之后,我要預留幾個字段,盡可能的預留多幾個字段,比如預留4,5個字段,我可能后期有一個業務,這個業務可能有涉及到一張表,根這張表產生關聯,那我就會預留一個字段,那這個字段就相當于這張表的外鍵,就是他這個外鍵跟他關聯嗎,這個預留字段是干這個事的,以后我就要往預留字段上加一個新表,然后用這連個join起來,我覺得預留字段最主要的目的是干這個事,他不是說隨便一個字段加一個需求,然后你就改了,我寧愿加個需求加個字段我可以做其他的事,不去做這個事情,能明白我的意思吧,然后這個建立索引其實還有規則的,剛才我說到了這塊,就是做擴展字段,這個規則是什么啊,咱們索引是不能做任何函數操作的,能理解我的意思吧,比如你where條件,where id,比如id是一個索引字段,你要把id做一些函數的操作,substring啊,或者其他的那你這個索引值就失效了,就是你這個索引不能做任何函數的操作,主要是做函數的操作索引的值就失效了,這個應該能理解吧,應該知道吧,這個應該能理解吧,只要隨便加一個函數,就失效了是不是,那你現在這個索引你要怎么加呢,是不是挺不好加的,我們的規則是,正常我們的規則是怎么加呢,就是這個東西是這樣的,比如說我有一個業務,首先看哪個是最大的一塊,比如說咱們要統計人吧,全國各地的人,區域就是北京,天津,上海,這個范圍是最大的一塊,北京這塊有多少人,天津的這塊有多少人,然后上海這塊有多少人,咱們就舉個例子吧,因為我也沒看過騰訊的user表里面,怎么去設計的,我就是猜測,隨便猜啊,他肯定首先是按區域去劃分的,你比如說北京,他這個字段就是1100,我就隨便寫一個,北京可能是1000,前四位,那索引的前四位就是1000,然后呢再往下走,北京下面還有一些區域吧,大興,昌平啊,什么房山啊,區域是不是有一些區域編號,就是10001100,延慶,隨便舉一個例子,然后大興是10001200,我就按照這個數字當做一個type類型了,然后再往下走,它是屬于什么會員級別的,當然會員級別不是固定死的,主鍵的,剛才我們只是隨便一說,因為QQ有一個會員升級的功能,開始可能是一個普通用戶,那以后可能就變成一個會員了,不可能去改主鍵去,思路是錯的,他不可能這么去建,但是咱們假設吧,他有些其他的字段,那就繼續往下劃分,比如第一種人員的類型,你有一個外鍵表,第一種人員類型,然后type是1的話,我就寫一個1,然后第二種,type是2的話,在這個基礎之上再去擴展,那這個時候就變成100011001什么,這邊就變成100011002什么什么,反正就是按照這個規則吧,去往里加數字,然后會剩下不夠的位數,我們可能生成一個UUID,比如我用了多少位,用了10位,UUID一般是32位,或者你再長一點,可能還有20位是我自己隨機生成的一個UUID,那這個整體去拼成一個ID,就是根據業務規則去拼成ID,這樣的話你做查詢就簡單了,你要查北京的怎么查,北京不是1000開頭的嗎,那我就查北京的區域,1000后面一堆數小于等于id,大于2000后面一堆,最后肯定會轉成0123這種形式的,按照這種形式去查詢,那這個索引肯定是會加主鍵的,加index,一下子就過濾了一部分數據了,你要查北京延慶的,那就這樣,10001100后面一堆數字,然后去小于等于id,然后大于100012000后面一堆的數字,中間一小部分數據就是屬于北京,再往后就是延慶的數據,直接給我過濾出來了,就是具有業務規則的索引,都是這么去建立的,1000后面加一個斜杠,加一個type就是abcd,就是這種東西肯定不行,或者是加一些其他的東西,總之你不能讓這個索引最終失效,因為你不能在這個索引上加任何的函數,所以就固定了咱們業務組件的規則,就是一個數值,加上一個隨機的UUID,UUID不都是這樣的嗎,不是AF207CKO13就是這種嗎,這戲字母啊,都會轉成0123這種形式的,就是一個32位的大數字,然后通過這種東西去查,說的挺多的,明白我的意思吧,這種就是建立索引的規則(1.1)建立普通索引(1.2)建立規則索引(1.3)建立復合索引
DataBase 是ORCL,這個Schema,沒關系,就是隨便看一眼,就是有一個DAT_CHECK_DATA表,表里就是我們的檢測,以后數量肯定會很大的,我沒模擬的這么大,我就放了一點點數據,就放了10150條數據,就是一萬多條嗎,就是以這種規則,看見了吧
其實我這個主鍵是有業務規則的,其實我這個業務規則就是相當簡單了,就是前幾位可能都是北京下面的了,北京下面的某一個區域,你會發現前面都是一樣的,前面都是1129,然后這個是1112,然后沒有了,就是1129和1112,這都是有業務規則的,然后后面就是根據你生成的日期,我copy一下,我直接粘到這兒,1129就是一個規則,可能是北京的一個區域,然后再空格,2015年06月份19號,是這么劃分的,我們在這里找一個1129的,這個就是這樣的,那這個業務劃分就是這樣的,2015年11月21號,其實都是有這種業務規則去劃分的,那我現在想問你,1129是什么東西呢,有一個叫dist這張表
我先query一下,其實你會發現,這個它是有規則的,1129其實就是把112900后面的兩個0省略了,1129其實是屬于北京市的一個延慶縣,1112是屬于北京市的一個通州,通州區的一個數據,那我現在就可以去做一個過濾了,那我查詢的時候怎么去查詢啊
比如我這張表里有這么多數據,只想查延慶或者通州的數據,我查的時候就是SELECT * FROM 表,然后這個表叫DCD,where條件就是什么啊,就是CHECK_NO肯定是一個主鍵,他應該是滿足什么條件呢,大于等于這個值嗎,這后面應該怎么去補全呢,2015年這一塊,你要是想查所有的數據,那我2015年,可能還有2014年的,也可以去劃分,現在我就想查所有的數據,比如我現在就想查2015年6月份的數據,那怎么查,就是前面都是不變的,不是1506開頭的嗎,6月份的數據這里就歸零,20150600,后面的就全用0去替換一下,這個你確實得這樣去做你要去查6月份的數據,然后把這個復制一下,然后再小于,這樣就查詢到延慶所有6月份的數據了,直接七月份吧,你就一個SELECT,就是他大于等于,然后加上AND條件,然后這邊是小于,應該是這種語法,這樣您看一共有多少條數據,一共649條數據,他一定是2015年6月份到7月份的,并且是某一個延慶,延慶縣的所有的數據,這樣的話查詢起來就很快了,相當于我直接分區域,直接去查詢了,直接走索引了,剛才的操作理解了嗎,這樣是不是很輕松就查出來了,明白我說的意思吧,正常情況下,咱們不建立規則索引的情況下,你得怎么查,咱們如果不建立規則索引的話你怎么查啊,想想你要查區域的話,就是這個DAT表,你得join這個DIST,你這個表里得建一個區域的外鍵,然后還得join這張表,兩張表進行join,join完了之后你再取出來,那個數據,這樣的話你不覺得性能就這樣下去了嗎,就是我們要把規則加上去的時候我們就要把規則放在里面,然后查詢的時候去做,意思就是這個規則本身就一個索引,大體我就要給你演示這個事,就是有很多規則它是很正常的規則,無論是時間維度,還是空間維度,這些都是咱們建立規則索引的時候需要考慮的一個事情,就是你必須做一個設計,你最簡單最基礎的入門,你要考慮這個索引,你去看看哪個維度比較好,你比如你要按區域劃分的話,這就是一個空間維度,北京,延慶,天津,上海,根據你這個數據量,到底是以空間維度開頭,還是以時間維度開頭,明白我的意思吧,我這個是空間維度加上時間維度能夠過濾出來的量比較大,所以說我就按空間,如果你時間過濾出來的維度比較大,就時間放在前面,而空間往后走,還有其他的特殊的結構,明白我說的意思吧,差不多就是這個意思,就是按照不同的維度去建立這個索引,當然這個是一種方案啦,我覺得還是很好用的
(3)復合索引:還有一種就是復合索引了,就比如說你這個維度啊,你現在不確定,你要有兩個索引,要有預留的方案,比如這個表以后建索引可能要很多很多,那你就得復合索引,聯合主鍵,這么去查,這個維度都不夠用了,因為咱們的索引字段一般都是32位的,可能以后我加完了之后,還不夠了,肯定還要預留一個字段,他們兩個可能要拼成一個聯合主鍵,那如果你確定有這個事的話,那你最好做什么事啊,你最好建表之初,把這個字段加上一個聯合主鍵,你寧可這邊插入1,2,3,4這種排序,你都可以去做這個事情,那如果其它方案呢,那就算了,一般我去建立數據庫表的規則,接下來還是這個規則啦,接下來還是規則啦,這是索引的建立,沒一張表我還要去建立規則,這個數據規則
(4)數據規則:這個數據規則是什么啊,就是無論說我什么表啊,我永遠都不會少了4個字段的,這4個字段永遠都是放在表的最后的,你可以看一下,無論哪張表都是有這個東西的,咱們去Edit,去做這個事,這張表里,無論什么情況,后頭有4個字段,CREATE_BY,CREATE_TIME,UPDATE_BY,UPDATE_TIME,就是插入數據的人是誰,創建人是誰,一條數據是誰創建的,創建時間是什么,有時間戳的,更新人,更新時間,我所有的表基本上都會有這4條字段,為什么啊,這個是咱們以后做數據交換的時候,做數據分析的時候一個非常有用的,樂觀鎖version,這個怎么說呢,你是并發的時候需要考慮的,我是很少去做這個事的,其實這個問題用時間戳就可以解決,在ORACLE來講其實用時間戳就可以解決,當然時間戳可能就是小數點后面的幾位吧,當然我不可能保證這個時間太細,太細就產生什么了,什么意思呢,這一塊比如我有一張表,插入了一堆數據,然后這個數據,有一個人,又把這條數據區更新了,那么會有一個什么情況,做統計分析的時候,就不對了,原先這個條記錄可能是100,這個值,咱們要做統計分析的這個字段,這條數據是100,然后第一天上傳了之后,咱們去做一個統計分析的一個匯總,一個東西給匯總出來了,比如這條記錄的匯總值,當天的值可能是5000,這一列的數據是5000,然后是第二天,或者是過幾天,或一個月,甚至是過好久,然后當時那個人錄入數據的時候是錄錯了,這塊不是100了,然后把這個改了,那你想想這個統計分析的結果是多少了,應該是5020了,是5010,是5100,之前這個值是100,100的時候是5000,把他改成200的時候再加100,就是5100,所以說呢,這個時候你就的用UPDATE_TIME去做一個數據的重新統計了,你就查詢一下這個UPDATE_TIME有變更嗎,哪張表UPDATE_TIME變更了,然后把UPDATE_TIME變更的抓出來,抓出來之后,看看這條記錄統計的到底是哪一天的,然后再把這條數據重新統計一遍,把之前的這條記錄刪了,然后再重新統計一遍,統計完了之后再放到這個位置,可能還會設計到后端的存儲過程的事情,這個是在統計分析的時候一個很常見的業務吧,就是UPDATE_TIME可以做這個事情,包括兩個庫做數據交換的時候,都是通過時間戳去判斷,這個東西是不是最近的,或者像你說的,用VERSION去判斷,開始改了,就有一張級聯的一張表,VERSION是1.0版本,然后這邊并發的來了,那我就2.0,3.0,VERSION變更了,這個數據就不能弄了,還有一些其他的方案,除了數據規則,添加你認為必要的擴展資料,可能就是這個事
(5)預留字段:就是我剛才說的預留字段,就是關聯其他業務的,就是在我去做數據庫表結構設計的時候,就是我單純從數據庫表結構設計的時候,那我就可能會考慮這些問題,然后看我的業務對應哪幾種方案,當然可能還會有很多的方案,這個還是具體的業務具體的分析,你看看怎么去做比較合適,包括還可以有一些數據的冗余,這一塊也加上吧,這些可能都是一些解決方案(6)做一些合理的冗余:這是做什么事呢,ORACLE其實很早就提出冗余這個事,然后MSYQL近幾年才出來這個事,我覺得其實這個很正常,就比如說有一個應用場景,就是你現在做一個水平切割,就是做水平分表分庫,無論說你是把一張表的幾個字段,拆分成幾張小表,把這個表的數據水平的去切分,成兩張表,不管怎么樣也好,分表分庫也好,或者是垂直拆分也好,你都要應該理想化的去看待這個事情,你可以合理的去做一些冗余,那比如說我舉個例子,比如說我有一個業務,這個業務能夠單獨的去獨立開來,一張庫,這張庫可能有四五張表,然后對著四五張表簡單的join,完成了我們所說的一個事,然后呢,這是一塊業務,說的是一個什么業務呢,剛才我們說的電商系統,又回到了那個電商了,這是一個購物車或者商品的業務,電商里面其實還有一塊,支付業務,有的人支付是自己做的,有的是調第三方接口什么的,這就不說了,這一塊總之是一個獨立的業務,分一塊獨立的業務,比如剛才的供應商吧,那我問你供應商和這個商品,他既然是兩個系統,整體一個大系統有一個名字,一個小系統獨立的起個名字,然后這個系統里面有幾張表,那你一定會發現這個供應商里面,肯定會涉及到數據,其中有一張表我可以做什么事呢,我這張供應商這張表里面,我可以有自己的字段,而且我可以把商品里要查詢的字段呢,比如商品表我要加3字段,這張表需要加2個字段,這張表我需要加2個字段,那么我這7個字段就可以合理的去冗余到這張表里,能理解我說的意思吧,這是避免一個什么問題,避免兩個數據庫之間要進行一個join,要進行分布式事務的問題,那以后我們可以做什么事啊,我單純一個數據源連一個數據庫,我通過一張表就可以返回數據,我沒必要把這一張表的數據再抽出來,再查詢給我,那這個就看你怎么去做了,這幾個字段在不同的表中,你這樣做就很麻煩,很累,就是相對于這種合理的冗余,也是我們采取數據庫設計的一種手段,能理解我說的意思吧,反正就是說,設計這個事情,是很不好把控的,沒有說固定來講設計就好,還是根據不同的需求去設計表結構,當然,大方向的原原則,我在這里可能就總結了幾點了,這可能是我工作常用的幾招,大體上就是這樣
?
總結
以上是生活随笔為你收集整理的Oracle之数据库设计概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle之索引和索引碎片问题解决
- 下一篇: Oracle之同义词,DBLINK,表空