天天看點

【原創】C#搭建足球賽事資料庫與預測平台(2) 資料庫與XCode元件1.資料庫選型2.XCode元件分庫技術3.現有資料庫的資料統計情況

  本篇文章開始将逐漸介紹使用C#搭建足球賽事資料庫與預測平台的相關細節。還是先從資料庫開始,從本文開始将逐漸對每個核心實體類和資料庫設計相關的内容進行講解,并公布源代碼,至于能不能跑起來,看的看個人努力。資料庫很龐大,且采用了XCode非常牛逼的分庫技術,秒殺千萬級乃至上億的資料需求。而隻需要最基本的C#技術,對我這種資料庫文盲來說,真的幫助非常大。

  考慮到足球賽事資料庫的複雜性,以及考慮到項目的前瞻性(要考慮到很多還沒有發生的事情,便于以後擴充),以及大量資料,查詢和計算的速度,本項目經曆了3次重構,到目前為止其實也不是很成型,但基本趨于穩定。現在總結起來肯定是很流暢,但這中間的過程非常痛苦,也希望把這些經驗寫出來,有自己做的朋友可以一起探讨,避免踩坑。

  上學的時候,自己折騰資料庫,現在看來其實是走了很多彎路,動不動就搞一個龐大的Ms Sql ,哪怕一個再簡單的東東,也搞一個mssql,安裝不僅占用系統資源,還慢,部署也挺麻煩。。雖然用的是盜版,但其實作在看來,由于自己的無知和大學書本知識的匮乏,盲目的指導,我們失去了很多美好的東西。在近幾年的工作中,我已經逐漸抛棄了MSSQL,MySQL這些龐然大物,并不是說他們不能用,或者不好用。隻是問題太小,殺雞焉用牛刀。。。小題大作不僅自己累,還影響總體的效果,還會浪費很多寶貴的時間。在一些小的場景下,我會使用一些C#檔案資料庫,如NDataBase,XML Database等等,在一些實際資料量在億及級别的情況下,會選擇Sqlite資料庫等等。隻要能滿足我的使用要求即可,沒必要搞的那麼花哨。

  是以說說本項目使用的資料庫:Sqlite,使用它的原因有:

1.輕量級、跨平台。它是程序内的資料庫引擎,是以不存在資料庫的用戶端和伺服器。使用SQLite一般隻需要帶上它的一個動态庫,就可以享受它的全部功能。而且那個動态庫的尺寸也非常小,幾百K而已。相比幾個G的 MSSQL,情何以堪; 2.綠色、單一檔案。它的核心引擎本身不依賴第三方的軟體,使用不需要“安裝”,可以省去部署時不少麻煩。是不是有人安裝 MSSQL 經常報錯。。沒安裝之前的校驗就通不過。。是不是很坑爹;這個也是處于個人開發成本的考慮,想一想買一個幾個G的資料庫空間啥價格,而買幾個G的硬碟空間簡直就是白菜。。在不影響功能的情況下,何樂而不為; 3.XCode元件的特殊支援。本人12年起開始使用XCode元件,非常感謝它減輕了我很多關于資料庫的東西,讓我隻需要關注業務。XCode對Sqlte的支援可以說更加人性化,對很多Sqlite的缺點進行了優化,而且有大量的使用案例。同時XCode在計劃的V9版本開始支援網絡和分布式資料庫,這樣Sqlite的功能将更加強大,沒有理由不使用。而且XCode靈活的分庫技術也是解決我查詢問題的重要手段,雖然我不懂MSSQL上億資料的優化,但我可以用分庫,更加低的技術含量和有限的資源來解決問題;

  說完Sqlite的優點,有人可能說,這些誰不知道,但怎麼面對它的缺點呢?其實這都不是事。。。

1.不理想的在并發性能。這是Sqlite被認為的最大問題之一,由于是單一檔案資料庫,可能會被寫操作獨占,進而導緻其它讀寫操作阻塞或出錯。這個問題不能否認,我認為應該單獨放在具體情況中來看。本文的項目資料庫要求在正常時期寫操作和讀操作基本不會同步,因為寫操作是資料采集更新的時候,這個時候是基本不會進行查詢分析的;其次即使查詢分析,由于大量的使用了分庫技術,獨占的情況也會少得多。 2.網絡通路。有時候需要通路其它機器上的SQLite資料庫檔案,就會把資料庫檔案放置到網絡共享目錄上。據說這樣會在并發讀寫的時候會出現資料損壞的問題。這個問題其實以前也困擾我,因為如果以後做大了,考慮做分布式的時候,這樣是非常不便利的,利用網絡共享目錄肯定是諸多不友善和不安全,但考慮到XCode V9會進行重大更新,會支援網絡和分布式資料庫,到時候Sqlite也可以進行分布式操作,這些也都不是問題。至于億級資料,也暫時不需要網絡分布式,是以這個暫時不用擔心。

  這是個人認為本項目非算法的最大的亮點之一。這和選用Sqlite作為資料庫也有很大關系,一方面本人對資料庫了解較少,無法用MSSQL輕松解決幾千萬資料的問題,資料遷移,伺服器管理,大量資料查詢的效率問題,這些對個人來說真的很難辦到,不是辦不到,是在有限的時間和精力下,不能做的更好,這也是選用XCode元件和Sqlite資料庫的主要原因。說一說XCode分庫技術的在本項目中的用法和作用,讓大家也提前開開葷。

  本項目中大量進行分庫的目的很明顯,減少查詢的複雜程度,同時也便于資料庫遷移和分離,特别考慮開源情況下,可以直接擷取各個聯賽資料庫以及各種附加資料,而不需要單獨進行導出。本項目的由于累積的曆史資料會越來越多,而且經過前2個版本的測試,大量的附加資料查詢非常頻繁,是以必須通過這種方法來減少的查詢複雜度。例如從單表500萬的資料表中,多次查詢資料 和 從單表3萬的資料庫中查,差别會有多少?當然我沒測試過,簡單情況下,時間總歸是有差别的,應該也不小,而且500萬資料是要增長的,而單表3萬是基本不會增長(因為一場比賽結束了,相關資料就終止了,不會再增加)。

  本項目的分庫場景非常多,這裡舉幾個例子說明,其他的在具體的資料庫表設計和業務分析的時候再進行說明。

1.比賽場次表。比賽場次表按照聯賽進行分庫,每一個聯賽或者杯賽,的資料都儲存在一起。按照最多球隊的西甲20支隊伍來說,一年也就380場比賽,10年也就3800條記錄,是以怎麼查,技術再差,也不會慢到哪裡去,何苦還有XCode的緩存支援;在前2個版本的設計中,還考慮過設計一個總庫,但由于實際的使用情況場景還有待考察,是以新版本的資料庫還暫時沒有添加總庫。總庫和分庫的作用是協調互補的,根據實際情況進行。

2.歐賠指數表。勝平負的玩法是足球比賽中最常見的,是以歐賠的資料也是最多的,歐賠指數的複雜性不在于每一場比賽會動态調整,而在于每一場比賽,每一個家賠率公司開出的賠率都不一樣,賠率公司多大幾百家,考慮到實際情況,本系統隻采集了權威的20家左右,分庫方式也很特别,為了獲得查詢的效率,按照 賠率公司 + 聯賽 的方式進行分庫。

3.其他指數表。大小盤指數表和其他指數表與歐賠類型,都采用了 最符合時間的 分庫方式。 

   在XCode中,分庫是非常簡單的事情,隻需要修改對應的連接配接字元串,就可以了,查詢之前也設定對應的連結字元串就可以了,下面就是核心的設定連接配接字元串的方法,注意方法的核心是修改Meat.ConnName,至于值取決你分庫的标準,如下面的比賽場次表的分庫:

【原創】C#搭建足球賽事資料庫與預測平台(2) 資料庫與XCode元件1.資料庫選型2.XCode元件分庫技術3.現有資料庫的資料統計情況

下面這個是賠率資料的一個分庫情況:

【原創】C#搭建足球賽事資料庫與預測平台(2) 資料庫與XCode元件1.資料庫選型2.XCode元件分庫技術3.現有資料庫的資料統計情況

   隻需要在插入資料或者查詢資料前,執行上述方法就可以了。其他操作和你的業務是一模一樣的。

  由于賠率資料的時效性,本系統也隻采集了2013年以後的賠率資料,至于場次資料,可以追溯到10年前。是以暫時來說資料量不是很大,随着累計的時間越來越長,資料的增長會越來越快。寫了一個簡單的程式對現在項目的資料庫的數量和資料記錄做了一下統計:

 看看核心代碼:

看看統計的結果:

【原創】C#搭建足球賽事資料庫與預測平台(2) 資料庫與XCode元件1.資料庫選型2.XCode元件分庫技術3.現有資料庫的資料統計情況

截至2015年5月8日,總的資料量是:743萬。主要原因是一方面曆史資料過了太長時間采集不到(國外可以,但是麻煩)。是以考慮到實際情況,隻采集了2013年以後的主要賠率資料。以前的資料隻采集基本的比賽結果資訊。