{eval=Array;=+count(Array);}
先表明立場(chǎng),任何時(shí)候都不要在后臺(tái)代碼里拼接sql。(除了中小公司內(nèi)部報(bào)表類需求外)
首先,提主遇到的大公司拼接sql,“都”明顯是偽命題。在互聯(lián)網(wǎng)公司的應(yīng)用領(lǐng)域內(nèi),是嚴(yán)禁嵌套,拼接sql的。一個(gè)大流量超高并發(fā)的系統(tǒng),數(shù)據(jù)庫(kù)鏈接池資源,是非常寶貴的。基本決定了系統(tǒng)的性能上限。不然為什么加分布式緩存,數(shù)據(jù)庫(kù)分庫(kù)分表呢?對(duì)于高頻低熵的系統(tǒng),明顯高頻次低耗時(shí)的數(shù)據(jù)庫(kù)鏈接是最可靠的方式。
其次,對(duì)于各種大型的傳統(tǒng)IT服務(wù)業(yè)和政府,銀行類系統(tǒng),由于系統(tǒng)本身相對(duì)于一線互聯(lián)網(wǎng)公司,并發(fā)非常低。所以線程對(duì)數(shù)據(jù)庫(kù)鏈接的持有時(shí)間可以稍微耗時(shí)長(zhǎng)一些,以得到比較快的系統(tǒng)響應(yīng)。其實(shí)這么做,也并非是明智之舉。明顯,互聯(lián)網(wǎng)類的技術(shù)拆分和技術(shù)架構(gòu),對(duì)于大公司的各種場(chǎng)景更為合適。傳統(tǒng)的IT那種所有難題扔sql,扔給存儲(chǔ)過(guò)程的方式已經(jīng)過(guò)時(shí)多年。
最后,對(duì)于高并發(fā)的大型在線系統(tǒng),有復(fù)雜查詢類的需求,絕不推薦在后臺(tái)sql中用復(fù)雜的查詢?nèi)?shí)現(xiàn)。這個(gè)對(duì)于系統(tǒng)的成本消耗明顯太高。對(duì)于復(fù)雜的查詢,自然有其他的技術(shù)架構(gòu)去實(shí)現(xiàn)。
可以多多關(guān)注一線互聯(lián)網(wǎng)公司的架構(gòu)技術(shù),也可以看下我之前的回答。
發(fā)現(xiàn)持續(xù)還有人關(guān)注本問(wèn)題,看到大家來(lái)自各個(gè)不同業(yè)務(wù)領(lǐng)域,再聊一些吧。
本身這個(gè)問(wèn)題是高并發(fā)類系統(tǒng)的常識(shí)性問(wèn)題。不管是低頻高熵的傳統(tǒng)業(yè)務(wù),還是高頻低熵的互聯(lián)網(wǎng)業(yè)務(wù)公司,技術(shù)架構(gòu)往往是業(yè)務(wù)特性來(lái)決定的。
傳統(tǒng)IT公司,IT服務(wù)類公司確實(shí)仍然存在拼接這樣粗暴的實(shí)現(xiàn)方式。因?yàn)椴l(fā)低,迭代快。當(dāng)然如果能滿足低頻低熵的業(yè)務(wù)需求,也無(wú)可厚非。但單單從技術(shù)角度看,這么做可能并不是最優(yōu)。事實(shí)上,傳統(tǒng)公司的新項(xiàng)目也很少有人會(huì)這么玩了。(節(jié)省幾臺(tái)服務(wù)器,也是錢啊)。
很多同學(xué)領(lǐng)域不同,對(duì)業(yè)務(wù)需要的技術(shù)理解自然會(huì)有區(qū)別。技術(shù)同學(xué)可以適當(dāng)多看機(jī)會(huì),多接觸不同業(yè)務(wù)領(lǐng)域的技術(shù)實(shí)現(xiàn)方案。多思考技術(shù)架構(gòu)這樣設(shè)計(jì)背后的業(yè)務(wù)原因。
另外,如果有任何問(wèn)題或質(zhì)疑,歡迎去看我之前的回答,或留言與我討論。不喜勿噴。
題主說(shuō)的確實(shí)存在,但是要區(qū)分不同業(yè)務(wù)類型和領(lǐng)域的“大”公司,軟件行業(yè)里面,有bat這樣的互聯(lián)網(wǎng)公司,也有神州這樣的看起來(lái)大的公司,也有藍(lán)凌這樣的專做OA的大公司,還有思迅這樣在收銀軟件獨(dú)霸一方的。他們?cè)诟髯灶I(lǐng)域,都是大公司。
如果是傳統(tǒng)管理軟件的公司,這種情況確實(shí)大量存在。這和歷史原因,業(yè)務(wù)現(xiàn)狀有關(guān)。他們的主要問(wèn)題是每天面臨大量不同項(xiàng)目的不同功能需求要完成,當(dāng)合理的使用拼接sql方式,能夠加快開發(fā)交付速度,也能靈活面對(duì)業(yè)務(wù)需求的變化。這類軟件的業(yè)務(wù)復(fù)雜度遠(yuǎn)大于并發(fā)需求,所以這樣也能抗住性能壓力,也能完成各種復(fù)雜功能(業(yè)務(wù)復(fù)雜{{BANNED}}程度遠(yuǎn)超一般長(zhǎng)期接觸互聯(lián)網(wǎng)行業(yè)的工程師的想象)的快速開發(fā)。
而如果是一個(gè)互聯(lián)網(wǎng)公司,業(yè)務(wù)又是2C的,那么就不會(huì)拼接sql了。往往采用基礎(chǔ)表的數(shù)據(jù)整條讀寫訪問(wèn)(數(shù)據(jù)庫(kù)淪為持久化工具之一),數(shù)據(jù)內(nèi)存做緩存,數(shù)據(jù)邏輯關(guān)系由代碼而不是sql完成,以提高效能,降低延遲,提高并發(fā)(按每秒單節(jié)點(diǎn)10w次記)。所以,這種大公司是絕不可能大量有sql拼接的,有也是少數(shù)sql,也或許是緩存穿透后的操作。
還有一種情況,就是大公司里面某些團(tuán)隊(duì),接了開發(fā)任務(wù),項(xiàng)目又是項(xiàng)目產(chǎn)品型的,項(xiàng)目負(fù)責(zé)人開始為了加快進(jìn)度,搭建的基礎(chǔ)架構(gòu)就偏簡(jiǎn)單,加之業(yè)務(wù)還沒(méi)成熟,技術(shù)選擇上也會(huì)采用拼接sql來(lái)實(shí)現(xiàn),這樣對(duì)開發(fā)人員要求低,開發(fā)速度快。
綜上所屬,就會(huì)出現(xiàn),題主說(shuō)的情況,那些說(shuō)沒(méi)有的人,也沒(méi)錯(cuò),他們只是單一行業(yè)接觸的多,跨行業(yè)領(lǐng)域接觸的少而已。
這跟大小公司無(wú)關(guān),一方面跟業(yè)務(wù)有關(guān),一方面跟程序員個(gè)人有關(guān),比如復(fù)雜的多條件查詢,不拼接怎么辦?
不拼接你想怎么寫,那些框架組件不也是幫你實(shí)現(xiàn)拼接的。只不過(guò)不要直接把參數(shù)拼接進(jìn)去,用參數(shù)綁定處理。
看了回答。任何問(wèn)題都不只是單純的技術(shù)問(wèn)題。討論任何問(wèn)題都應(yīng)該有一個(gè)業(yè)務(wù)場(chǎng)景,所以造成了大家的爭(zhēng)論。
高并發(fā)場(chǎng)景下確實(shí)不建議復(fù)雜sql,查詢緩慢造成數(shù)據(jù)庫(kù)服務(wù)器的巨大壓力。
如果你的系統(tǒng)數(shù)據(jù)量沒(méi)那么大,并發(fā)也沒(méi)多少。寫個(gè)復(fù)雜sql有有什么問(wèn)題呢?
有些公司采取的措施是一刀切,復(fù)雜sql不能有,嚴(yán)禁sql嵌套循環(huán)等。一刀切帶來(lái)的問(wèn)題是可能不是一個(gè)問(wèn)題,而為了解決所謂的問(wèn)題浪費(fèi)時(shí)間。我想說(shuō)的是復(fù)雜sql效率不一定低,循環(huán)極少數(shù)次又有什么問(wèn)題呢?最終的目的不還是為了保證查詢效率嗎?他們之間沒(méi)有必然的關(guān)系。這種問(wèn)題可以采用開發(fā)規(guī)范或者代碼審核來(lái)避免。開發(fā)規(guī)范可以警示開發(fā)人員:聯(lián)合查詢n張表的時(shí)候需考慮性能問(wèn)題,并考慮是否拆分sql。
還是那句話,脫離了業(yè)務(wù)場(chǎng)景討論技術(shù)就是耍流氓。
看了一下評(píng)論,有的偏題有的不準(zhǔn)確,為什么拼接sql,一句話就是:為了效率。如果使用orm框架各種封裝,效率顯然沒(méi)有直接sql來(lái)的更直接。這也是mybatis比hibernate現(xiàn)在更流行的一個(gè)原因。
最終不都是拼接成sql字符串的么? 防止注入就自己把參數(shù)檢查做到位就好了。各種框架表面好用,等查問(wèn)題的時(shí)候會(huì)惡心死你。
1.數(shù)據(jù)庫(kù)更換時(shí),部分?jǐn)?shù)據(jù)庫(kù)拼接的語(yǔ)法有區(qū)別,而orm框架基本做了兼容可以很方便的切換數(shù)據(jù)庫(kù)。
2.互聯(lián)網(wǎng)系統(tǒng)流量?jī)?nèi)容查詢不能過(guò)于復(fù)雜,所以使用orm已經(jīng)可以滿足大部分需求。但是內(nèi)部業(yè)務(wù)復(fù)雜的系統(tǒng)時(shí),orm因?yàn)闉榱藵M足1,大量的共通拼接查詢寫法效率相對(duì)較低,很難做查詢優(yōu)化。所以所有的orm框架在提供對(duì)象關(guān)系管理的同時(shí),也都提供了sql語(yǔ)法的支持為了滿足特殊業(yè)務(wù)需求。java的mybatis比hibernate更有效率的原因就在這。python的django中的orm框架因?yàn)檎Z(yǔ)言性能的原因,orm寫法和sql寫法對(duì)比效果更明顯。orm在簡(jiǎn)單的curd上是很方便的,但是碰到復(fù)雜邏輯時(shí),如果設(shè)計(jì)未考慮到復(fù)雜的鏈接,單純使用orm就是災(zāi)難。
曾帶過(guò)一個(gè)項(xiàng)目,其中一個(gè)數(shù)據(jù)接口處理,orm需要14個(gè)小時(shí),動(dòng)不動(dòng)over heap. 10多年沒(méi)碰代碼的我,被迫上線現(xiàn)場(chǎng)改用純sql,放數(shù)據(jù)庫(kù)處理,處理時(shí)間2分鐘以內(nèi)。
0
回答0
回答0
回答1
回答0
回答0
回答0
回答0
回答0
回答0
回答