<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                PG 9.4版本里面,增強了對json數據的支持,受到了很大關注。9.4之前,PG已經原生支持json數據類型了,但只是用字符串的形式存儲和處理。這樣做天然有性能上的缺點:每次對json字符串里面的數據進行查詢,一般需要全表掃描加字符串匹配,效率很低。當然也可以在存儲json的字符串字段上創建GIN索引,但需要對查詢中用到的json的key或value創建單獨索引,造成要被動維護很多索引。所以,這種json類型,只適用于把PG單純作為數據存儲,只讀入讀出數據,不對數據進行限定key或value查詢的場景。 PG 9.4中引入了jsonb類型。其特點是,將json數據中的key和value進行解析,轉換為PG的基本數據類型,包括數字,字符串和布爾類型等;同時,增加了對應的GIN處理函數,可以將json中的所有key和value轉換為GIN索引的key。這樣,只用一個GIN索引,即可實現對所有key或value的條件查詢。下面我們分析一下jsonb的使用方法和內核實現。 **使用** 創建含jsonb類型的表方法如下所示: ~~~ => create table test_jsonb(col_jsonb jsonb); CREATE TABLE => insert into test_jsonb values('{"product": "PostgreSQL", "version": 9.4, "platform":["win", "linux", "unix"]}'::jsonb); INSERT 0 1 ~~~ 創建GIN索引的方法如下: ~~~ --創建jsonb_ops索引: => create index idx_jsonb on test_jsonb using gin (col_jsonb); CREATE INDEX --創建jsonb_ops_path索引: => create index idx_jsonb_path on test_jsonb using gin (col_jsonb jsonb_path_ops); CREATE INDEX ~~~ 可以使用下面的查詢得到含有鍵值對的行: ~~~ =>select * from test_jsonb where col_jsonb @> '{"product"?: "PostgreSQL"}'; col_jsonb --------------------------------------------------------------------------------- {"product": "PostgreSQL", "version": 9.4, "platform": ["win", "linux", "unix"]} ~~~ **內核實現** 先分析一下jsonb是如何從字符串,變成特殊的二進制形式存入磁盤的。追蹤一下jsonb插入的過程,可以看到PG所調用的函數流程如下。 ~~~ jsonb_in->jsonb_from_cstring->pg_parse_json->JsonbValueToJsonb ~~~ 其中,pg_parse_json先把用戶輸入的字符串,通過編譯器轉換為一個樹形結構(每個節點的類型為JsonbValue)。然后JsonbValueToJsonb在這個結構基礎上,轉換為存入磁盤的格式。從convertJsonbObject函數可以看出,轉換為磁盤格式的策略為:從樹形結構的根部開始遍歷,遞歸進行廣度優先遍歷。對于同一父親下面的子鍵值,將所有鍵名(字符串)長度寫入buffer中預留的頭部,隨后將鍵名依次寫入buffer中。最后再以相似的方式寫入鍵所對應的所有值(值如果是json對象,則遞歸調用)。這樣,讀入buffer的頭部,就可以遍歷出所有鍵名的位置,得到鍵名。再從讀第一個鍵值開始,讀入對應的值或子鍵,最終得到整個樹(見JsonbIteratorNext)。 采用這種存儲方式,jsonb所占用的存儲空間比原來支持的json類型要多一些。其實,jsonb的核心優勢在于快速和靈活的索引。從前面創建index的語句可以看到,jsonb支持兩種特有的GIN索引jsonb_ops和jsonb_path_ops。我們知道,GIN索引建立時,會先通過內建函數從表中每行數據的索引字段的值中,抽取鍵(key),一個字段值一般可抽取多個key。然后,將每個key與含有此key的所有行的ID組成鍵值對,再將它們插入b樹索引供查詢。那么這兩種GIN索引有什么區別呢? 它們的區別在于,生成GIN key的方式不同。jsonb_ops調用gin_extract_jsonb函數生成key,這樣每個字段的json數據中的所有鍵和值都被轉成GIN的key;而jsonb_path_ops使用函數gin_extract_jsonb_path抽取:如果將一個jsonb類型的字段值看做一顆樹,葉子節點為具體的值,中間節點為鍵,則抽取的每個鍵值實際上時每個從根節點到葉子節點的路徑對應的hash值。 不難推測,jsonb_path_ops索引的key的數目和jsonb的葉子節點數有關,用葉子節點的路徑做查詢條件時會比較快(這也是這種索引唯一支持的查詢方式);而jsonb_ops索引的key的數目與jsonb包含的鍵和值(即樹形結構的所有節點)的總數有關,可以用于路徑查詢之外的其他查詢。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看