<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么阿里巴巴禁止使用存儲過程?

          共 2983字,需瀏覽 6分鐘

           ·

          2021-06-16 11:49

          往期熱門文章:
          1、在外包干了三年,我廢了..… 不吹不黑!
          2、用鴻蒙跑了個 hello world
          3、還在寫大量 if 來判斷?試試用一個規(guī)則執(zhí)行器來替代它
          4、Spring Boot中的線程池,你真的會用么?
          5、重磅推薦幾個接私活的腳手架利器!
          來源:segmentfault.com/a/1190000011138993
          之所以有這個題目,我既不是故意吸引眼球,也不想在本文對存儲過程進行教科書般論述。最近項目中遇到的存儲過程問題,讓我想起了去年在武漢出差時一位同事的發(fā)問:
          我覺得存儲過程挺好用的,為什么你不建議用?
          當時我好似胸有萬言,但終究沒用一個實在的例子回答同事,只是從結論上大侃一通,代碼相對于SQL,復用、擴展、通用性都要更強。想必同事并不信服。
          現(xiàn)在想來,我最近正碰到的問題,算是一個可以回答同事的例子吧。
          最近項目中有個新需求,需要校驗一個用戶是否有Job,Certification,Disclosure這三個業(yè)務數(shù)據(jù)。
          翻看了代碼發(fā)現(xiàn),系統(tǒng)的用戶個人頁面的C#代碼調(diào)用了三個存儲過程,去抓取用戶的Job,Certification,Disclosure數(shù)據(jù)。
          我的新需求,自然需要復用這三個存儲過程,否則:
          若每一處都寫一次抓取數(shù)據(jù)的業(yè)務邏輯代碼,若業(yè)務邏輯發(fā)生變化,難以追查和維護所有讀取Job,Certification,Disclosure的SQL。
          如果我在C#代碼中調(diào)用這已有的三個存儲過程,事情本該非常快就能結束。我也是這么做的。
          但code reviewer認為,我的需求中,并不需要Job,Certification,Disclosure這三個業(yè)務對象的數(shù)據(jù)。我只是需要給定用戶_是否_有Job,Certification,Disclosure而已。所以我應將是否有無Job,Certification,Disclosure的判斷邏輯寫在數(shù)據(jù)庫,最終通過網(wǎng)絡從數(shù)據(jù)庫傳到web服務器的僅是true或false,節(jié)省網(wǎng)絡流量,這樣最好不過了。
          也對。除開網(wǎng)絡性能,從接口設計的角度講,接口的傳入和返回值,都應是你本身需要的數(shù)據(jù),不應帶有大量不需要或者需要caller去預處理的數(shù)據(jù)。從接口語義表達就可知調(diào)用的目的,這樣代碼可讀性也會有大大提高。
          那就動手改。但沒想到的是問題來了。
          為了講述問題,我簡化代碼,假設系統(tǒng)現(xiàn)有的存儲過程如下:
          CREATE PROCEDURE [dbo].[GetJobs]
          (
              @PersonId int,
              @OrganizaitionId int
           )
          AS
          BEGIN
            SELECT JobId,JobName,JobType FROM Job WHERE PersonId = @PersonId AND OrganizaitionId = @OrganizaitionId
          END
          我在新的存儲過程中調(diào)用它,我需要獲得該person的jobs的數(shù)量,即GetJobs返回結果集的count。
          為了實現(xiàn)這一目的,首先想到的是使用臨時表,將返回結果集存入臨時表,再對其進行count(*)的計數(shù)操作:
          CREATE PROCEDURE [dbo].[MyProc]
          (
              @PersonId int,
              @OrganizaitionId int,
           )
          AS
          BEGIN
            CREATE TABLE #Temp(
              PersonId int,
              OrganizaitionId int
            )

            INSERT INTO #Temp EXEC dbo.GetJobs
              @PersonId = @PersonId,
              @ParentOrgId = @ParentOrgId

            SELECT COUNT(*) FROM #Temp
          END
          這種辦法簡單有效,但它存在嚴重的維護問題。未來如果被調(diào)用的存儲過程的返回結果集字段有變動,那么MyProc中的臨時表結構也需要隨之變化。這是令人難以接受的。
          那么將MyProc中的INSERT INTO換為SELECT INTO呢?很遺憾,答案是不行。SQL本身并不支持這種用法。
          給現(xiàn)有存儲過程GetJobsoutput參數(shù)?本例中因為GetJobs已被其他多處代碼或SQL scripts調(diào)用,所以對現(xiàn)有現(xiàn)有存儲過程進行改動會有不小風險。
          我搜遍網(wǎng)絡,一位MS MVP的大神的文章幾乎總結了所有存儲過程之間傳遞數(shù)據(jù)的方法: How to Share Data between Stored Procedures。他在文章中也無可奈何地說道
          Keep in mind that compared to languages such as C# and Java, Transact-SQL is poorly equipped for code reuse, why solutions in T?SQL to reuse code are clumsier.
          最終我沒能找到一種滿意的辦法,無奈之下我在新寫的存儲過程中將查詢Jobs的語句寫一了次。
          存儲過程在很多場景時有其優(yōu)勢,比如性能。但對于業(yè)務邏輯的通用方法,非常不推薦將其寫在存儲過程中,代碼復用、擴展與客戶端語言比,相差甚遠。也許終究能實現(xiàn),但代價與風險比客戶端語言要高,得不償失。
          天知道還有沒有機會和那位前同事再討論這一話題呢。

          最近熱文閱讀:

          1、面試官:說一下JDK/Dubbo/Spring 三種 SPI 機制,誰更好?
          2、在外包干了三年,我廢了..… 不吹不黑!
          3、還在寫大量 if 來判斷?試試用一個規(guī)則執(zhí)行器來替代它
          4、重磅推薦幾個接私活的腳手架利器!
          5、MySQL究竟是怎么執(zhí)行的?看完終于不糾結了
          6、25種代碼壞味道總結+優(yōu)化示例
          7、如何優(yōu)雅處理重復請求/并發(fā)請求?
          8使用 Redis 實現(xiàn)一個輕量級的搜索引擎
          9、比MySQL快801倍,OLAP兩大新秀ClickHouse和Doris到底怎么選?
          10、從 0 到 1 手把手教你制作酷炫可視化大屏
          關注公眾號,你想要的Java都在這里

          瀏覽 31
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91在线视频成人 | 亚州视频免费不卡 | 77777777少妇亚洲 | 日本黄色电影视频 | 亚洲视频在线a |