<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>

          為什么我們不用數(shù)據(jù)庫生成 ID?

          共 1946字,需瀏覽 4分鐘

           ·

          2021-01-30 11:04

          先介紹一下背景???


          團(tuán)隊(duì)正在一個(gè)為 SQL Server 構(gòu)建數(shù)據(jù)目錄項(xiàng)目的歷程中,我們優(yōu)化系統(tǒng)以實(shí)現(xiàn)解耦。這對(duì)我們來說非常重要,從根本上來說,我歸結(jié)為兩個(gè)核心原則,希望每個(gè)軟件專業(yè)人員都能認(rèn)同:


          • 我們不希望系統(tǒng)復(fù)雜度隨功能的增加而線性增長,這樣會(huì)大大拖慢我們?cè)跇I(yè)務(wù)發(fā)展速度以及對(duì)于價(jià)值的信心。

          • 我們希望能夠優(yōu)先從客戶需求、訪問性能、查詢模式、業(yè)務(wù)變化等方面考慮,能夠適應(yīng)不斷發(fā)展的需求和需要。換句話說,我們希望能夠?qū)⑾到y(tǒng)內(nèi)的任何組件換成更合適的組件,以滿足當(dāng)前而不是過去的需求。


          下面是 protoactor-go 開源項(xiàng)目里的一句話 “software should be composed, not built”,與我要在本文陳述的觀點(diǎn)非常相似:



          對(duì)持久化有何影響???


          考慮到前面總體原則,我們不想把自己的狀態(tài)持久化耦合到一個(gè)特定的數(shù)據(jù)庫引擎上。從實(shí)際情況來看,就是說不將持久化的具體關(guān)注點(diǎn)傳遞到領(lǐng)域?qū)印V砸獙?shí)現(xiàn)這一點(diǎn),因?yàn)槲覀兘裉鞂?duì)規(guī)則的認(rèn)知可能會(huì)讓我們依賴某種具體數(shù)據(jù)庫技術(shù),比如 SQL Server,但并不能確保它能滿足未來的能力需求。


          有了這個(gè)具體的要求,持久化就需要出現(xiàn)在域事件而不是存儲(chǔ)系統(tǒng)中,這也導(dǎo)致不同的存儲(chǔ)需求。


          幸運(yùn)的是,有一些廣為人知的、經(jīng)過實(shí)戰(zhàn)檢驗(yàn)的模式可以解決這個(gè)問題,如結(jié)合 CQRS 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中的聚合設(shè)計(jì)等。因此這里的假設(shè)是,實(shí)現(xiàn)理想狀態(tài)對(duì)我們來說是低成本的。


          代碼生成 ID 還是數(shù)據(jù)庫生成 ID ??


          許多數(shù)據(jù)存儲(chǔ)系統(tǒng)(如 SQL Server)都具備為每條記錄(如行、文檔等)生成唯一標(biāo)識(shí)符的方法。當(dāng)將新記錄插入表中時(shí),使用自動(dòng)增量鍵可以生成唯一編號(hào)。當(dāng)我們要插入一條新記錄時(shí),數(shù)據(jù)庫引擎就自動(dòng)完成自增主鍵,并且可以確保該鍵對(duì)于表是唯一的。


          但是如果依賴數(shù)據(jù)庫來為我們業(yè)務(wù)域生成唯一標(biāo)識(shí)符,這將讓業(yè)務(wù)層與數(shù)據(jù)存儲(chǔ)系統(tǒng)耦合在一起。如果我們想切換一個(gè)不支持生成自動(dòng)增量主鍵的數(shù)據(jù)存儲(chǔ)系統(tǒng),那就不能簡單更換。而且,每個(gè)數(shù)據(jù)存儲(chǔ)系統(tǒng)生成標(biāo)識(shí)符的方式都不一樣,這可能會(huì)導(dǎo)致我們最終使用不同的主鍵類型。除此之外,這些類型的生成方式可能不適合分布式系統(tǒng)。例如,當(dāng)我們?cè)?SQL Server 數(shù)據(jù)庫中擁有一個(gè)生成主鍵的表時(shí),我們沒有一個(gè)簡單的方法在分布式環(huán)境中水平擴(kuò)展這個(gè)表。


          通過讓業(yè)務(wù)域的消費(fèi)者(即通過命令和查詢與域通信的傳輸層)負(fù)責(zé)唯一鍵的標(biāo)識(shí)符生成,就可以克服這些問題。它減少對(duì)環(huán)境的依賴性,又反過來讓我們不用依賴數(shù)據(jù)庫來生成 Id。這種方法還有一個(gè)好處:它可以支持分布式。例如,我們可以將一個(gè)表分區(qū)到兩個(gè)物理 SQL Server上,并分擔(dān)查詢的請(qǐng)求。如果我們有一個(gè)自動(dòng)增量的字段,這在 SQL Server 上就不行了。


          我們決定做什么???


          基于這些事實(shí),我們決定讓業(yè)務(wù)域?qū)觼砩捎蚣系臉?biāo)識(shí)符。我們?cè)谟驅(qū)觾?nèi)將這些標(biāo)識(shí)符表示為 64 位無符號(hào)整數(shù)。域消費(fèi)者可以根據(jù)自己的上下文自由決定應(yīng)該用什么表示方式(例如ASP.NET Core MVC 可以將標(biāo)識(shí)符序列化為字符串,以便于其客戶端消費(fèi)資源對(duì)象等)。


          為什么要 64 位整型,而不是 UUID?


          最后,您可能想知道為什么使用64位整數(shù)。此處的主要目的是使我們能夠甚至跨聚合根生成唯一的標(biāo)識(shí)符。考慮到幾乎每個(gè)平臺(tái)都有對(duì)應(yīng)的 API,UUID 是非常方便的調(diào)用方式(例如 .NET 中 Guid.NewGuid() 等)。UUID 最大的問題是存儲(chǔ)和索引方面的成本與開銷,雖然對(duì)我們來說不是大問題。不過,在分布式系統(tǒng)中,已經(jīng)有一些成熟的方法來生成唯一標(biāo)識(shí)符作為更高效的主鍵類型,比如使用 64 位整數(shù)。Twitter Snowflake (1) 算法就是其中之一,這讓我們選擇了 64 位整數(shù)而不是 UUID。我們使用的是 Rob Janssen 的開源 IdGen (2) 庫,它是一個(gè)適用于 .NET 的 Twitter Snowflake 類型的 ID 生成器。


          (1)?https://developer.twitter.com/en/docs/basics/twitter-ids.html

          (2) https://github.com/RobThree/IdGen


          英文原文:

          https://medium.com/ingeniouslysimple/why-did-we-shift-away-from-database-generated-ids-7e0e54a49bb3

          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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精品久久久久久 | 老妇裸体乱婬A片 | 日日干日日 | 欧美一级日韩 |