SQL應(yīng)該負(fù)責(zé)怎么樣的CURD,分組、排序、可能根據(jù)業(yè)務(wù)邏輯只是選擇性查個(gè)別字段、使用SQL函數(shù)等等讓不讓數(shù)據(jù)庫做?還是自己用編程語言(比如java、c++)寫的應(yīng)用程序里處理數(shù)據(jù)?實(shí)例:統(tǒng)計(jì)2015-03-22~2015-03-24期間全國每個(gè)城市/省份每天的訪問ip量。假設(shè)查詢涉及的表的數(shù)據(jù)量為S??紤]以下三種方式。做法一:在一個(gè)以天為步進(jìn)單位長(zhǎng)度來遍歷2015-03-22~2015-03-24日期范圍以及全國每個(gè)城市的循環(huán)里,執(zhí)行countIp(visitDay,cityCode)統(tǒng)計(jì)某個(gè)城市或省份某天的ip量。核心SQL:SELECTCOUNT(DISTINCTuser_ip)FROMpv_accessWHEREvisit_date_timeBETWEEN{某天最早時(shí)間點(diǎn)}AND{某天最晚時(shí)間點(diǎn)}ANDcity_code={某個(gè)城市的編碼}SELECTCOUNT(DISTINCTuser_ip)FROMpv_accessWHEREvisit_date_timeBETWEEN{某天最早時(shí)間點(diǎn)}AND{某天最晚時(shí)間點(diǎn)}ANDcity_codeLIKE{模糊匹配某個(gè)省的所有城市}做法二:通過以下SQL獲取數(shù)據(jù),然后在應(yīng)用程序中做分組統(tǒng)計(jì)。SELECTvisit_date_time,city_code,user_ipFROMpv_accessWHEREvisit_date_timeBETWEEN'2015-03-2200:00:00'AND'2015-03-2423:59:59'ANDcity_codein({所有城市的編碼})如果沒有統(tǒng)計(jì)省份的需求,有第三種做法,直接執(zhí)行SQL按【天+城市】分組統(tǒng)計(jì):SELECTDATE_FORMAT(visit_date_time,"%Y-%m-%d")asday,city_code,ipCountFROMpv_accessWHEREvisit_date_timeBETWEEN'2015-03-2200:00:00'AND'2015-03-2423:59:59'ANDcity_codein({所有城市的編碼})GROUPBYDATE_FORMAT(visit_date_time,"%Y-%m-%d"),city_code;我自己的分析:涉及循環(huán)n次訪問數(shù)據(jù)庫,每次取一個(gè)分組的統(tǒng)計(jì)結(jié)果,時(shí)間復(fù)雜度為(nS)。優(yōu)點(diǎn)應(yīng)該是易于維護(hù)。數(shù)據(jù)庫負(fù)責(zé)簡(jiǎn)單的查出記錄集,不負(fù)責(zé)統(tǒng)計(jì),一次性取出統(tǒng)計(jì)所需的所有數(shù)據(jù),然后讓應(yīng)用程序做分組統(tǒng)計(jì)等處理。但是這樣不就增加了傳輸量嗎?因?yàn)榭赡芪覀冃枰淖罱K結(jié)果只是一個(gè)統(tǒng)計(jì)值(比如這個(gè)例子),但為了將統(tǒng)計(jì)工作轉(zhuǎn)移到應(yīng)用程序,就必須傳輸更多的數(shù)據(jù)。傳輸量為(S)。一條SQL語句獲取最終結(jié)果則只需一次請(qǐng)求,時(shí)間復(fù)雜度為(S)。但壓力大部分會(huì)轉(zhuǎn)移到數(shù)據(jù)庫?如果涉及分組統(tǒng)計(jì),而分組不是互斥的(上面的例子【天+地區(qū)】分組不是互斥,既有城市又有省份),那么應(yīng)該無法使用直接用SQL實(shí)現(xiàn)分組統(tǒng)計(jì)得到最終結(jié)果,是吧?這個(gè)時(shí)候只能通過自身應(yīng)用程序?qū)崿F(xiàn)分組統(tǒng)計(jì)?我想我上面的問題的本質(zhì)問題是:兩個(gè)可互相通訊并對(duì)外提供服務(wù)的程序各自應(yīng)該負(fù)擔(dān)什么工作,業(yè)務(wù)邏輯放在哪,放多少?希望各位有經(jīng)驗(yàn)有見解的童鞋給我指點(diǎn)迷津。
業(yè)務(wù)邏輯寫在數(shù)據(jù)庫還是自身應(yīng)用程序?
森林海
2019-04-16 17:05:35