<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>醉后不知天在水</title>
        <link>https://kunni.top//</link>
        <description>满船星梦压星河</description>
        <lastBuildDate>Tue, 27 Oct 2026 11:33:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2026, 困溺</copyright>
        <item>
            <title><![CDATA[（不）锐评云谷食堂]]></title>
            <link>https://kunni.top//article/3f40e356-2fd6-8006-aedc-eb7d20864eac</link>
            <guid>https://kunni.top//article/3f40e356-2fd6-8006-aedc-eb7d20864eac</guid>
            <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3f40e3562fd68006aedceb7d20864eac"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-3f40e3562fd680f9b9e4d409c1b22c90">一起去码头上吃点薯条。</div><div class="notion-text notion-block-3f50e3562fd680178207e18eea6d30ac">从夯到拉评价分成 5 个等级，从天花板到地板砖，依次是：夯 → 顶级 → 人上人 → <a class="notion-link" href="https://zhida.zhihu.com/search?content_id=273543652&amp;content_type=Article&amp;match_order=1&amp;q=NPC&amp;zhida_source=entity" target="_blank" rel="noopener noreferrer">NPC</a> → 拉完了。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd680bb856bd0b21e1fef63" data-id="3f40e3562fd680bb856bd0b21e1fef63"><span><div id="3f40e3562fd680bb856bd0b21e1fef63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680bb856bd0b21e1fef63" title="天权餐厅"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">天权餐厅</span></span></h3><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-3f40e3562fd680ee9a7efdc5022b31d5" data-id="3f40e3562fd680ee9a7efdc5022b31d5"><span><div id="3f40e3562fd680ee9a7efdc5022b31d5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680ee9a7efdc5022b31d5" title="蘸水菜"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">蘸水菜</span></span></h5><div class="notion-text notion-block-3f50e3562fd680d88401fd4ba833d30b">从夯到拉：人上人</div><div class="notion-text notion-block-3f50e3562fd680c18653e106298857a0">简简单单，清清淡淡，清清脆脆，因为油盐比较少，比较健康。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f40e3562fd680a2a53ed9b38e4252c3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F85d5580e-22e6-4557-982f-960e0b737f51%2F1791541832515.jpg%3Ftable%3Dblock%26id%3D3f40e356-2fd6-80a2-a53e-d9b38e4252c3%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3DZ5Ul0xKo0Mpb9yT02NbZPlEjAuOmjVSKCQJ06seyVRU&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-3f50e3562fd680b7b82bd10d52d4d455" data-id="3f50e3562fd680b7b82bd10d52d4d455"><span><div id="3f50e3562fd680b7b82bd10d52d4d455" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f50e3562fd680b7b82bd10d52d4d455" title="神龙炒饭"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">神龙炒饭</span></span></h5><div class="notion-text notion-block-3f50e3562fd680bfaf37cbdcfad3dbeb">从夯到拉：夯</div><div class="notion-text notion-block-3f50e3562fd68014b988e8de933f3ae8">跟麻辣香锅一样难排但好吃的店，有锅气。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f50e3562fd680bb9f17f376c4c104f7"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F1d7f83dc-3ef1-4887-9e72-cd3c4e387492%2F1791628146643.jpg%3Ftable%3Dblock%26id%3D3f50e356-2fd6-80bb-9f17-f376c4c104f7%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3D-XKyGzpxYAS8NLMpQINbtzOWID86XFbmZvASzBZmMow&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4030e3562fd68070ab16ea5f4ab8f47b"> </div><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-4030e3562fd680c3bb2bcec390c5f7ee" data-id="4030e3562fd680c3bb2bcec390c5f7ee"><span><div id="4030e3562fd680c3bb2bcec390c5f7ee" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4030e3562fd680c3bb2bcec390c5f7ee" title="牛关关"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">牛关关</span></span></h5><div class="notion-text notion-block-4030e3562fd680a595e0ec58d907ec1f">各种口味（番茄、红烧、麻辣）的牛腩、牛骨，凑合。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4030e3562fd68066984afd1c86e82cb5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:366px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F4f3958d0-cf34-45d8-a270-44fff5ba56f6%2F0B336314-A88B-44A2-83D0-B409D1B8DEA6.jpeg%3Ftable%3Dblock%26id%3D4030e356-2fd6-8066-984a-fd1c86e82cb5%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3DnL6vlHQe9ECZcww4aGDDeFYYkCFz6FXzkx86O0MBozY&amp;w=366&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4030e3562fd680b199f3e3d432b15d0c"> </div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd6801fbae4d45359e9e516" data-id="3f40e3562fd6801fbae4d45359e9e516"><span><div id="3f40e3562fd6801fbae4d45359e9e516" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6801fbae4d45359e9e516" title="天枢餐厅"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">天枢餐厅</span></span></h3><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-3f40e3562fd680bc9347fd4c906cbd07" data-id="3f40e3562fd680bc9347fd4c906cbd07"><span><div id="3f40e3562fd680bc9347fd4c906cbd07" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680bc9347fd4c906cbd07" title="街头美式汉堡"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">街头美式汉堡</span></span></h5><div class="notion-text notion-block-3f50e3562fd6802789e8ecb7a7fd0fd9">从夯到拉：NPC</div><div class="notion-text notion-block-3f50e3562fd680f0b351e15aba499f6f">一般，只适合周四晚上吃吃。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f40e3562fd6806f9d68cc0eaadbe820"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2Fe8430ed4-55b9-4846-9fbb-2750ef6066f5%2F1791541142114.jpg%3Ftable%3Dblock%26id%3D3f40e356-2fd6-806f-9d68-cc0eaadbe820%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3DwXBdRZNc1niTyaIa-Y48PADrJaDTxf62U_OPRGbJ95M&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd680da80d8c87e7fae2aeb" data-id="3f40e3562fd680da80d8c87e7fae2aeb"><span><div id="3f40e3562fd680da80d8c87e7fae2aeb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680da80d8c87e7fae2aeb" title="天璇餐厅"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">天璇餐厅</span></span></h3><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-3f40e3562fd680119de4ecb751c99dab" data-id="3f40e3562fd680119de4ecb751c99dab"><span><div id="3f40e3562fd680119de4ecb751c99dab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680119de4ecb751c99dab" title="山东炒鸡"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">山东炒鸡</span></span></h5><div class="notion-text notion-block-3f50e3562fd6805db76aefccf822f2e6">从夯到拉：顶级</div><div class="notion-text notion-block-3f50e3562fd680ff8510e96910cce7ba">好吃👍。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f40e3562fd680148b1bc74e02c884fa"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F4c0566db-5f77-4cf5-b98f-92d5ac019dc2%2F1791541215993.jpg%3Ftable%3Dblock%26id%3D3f40e356-2fd6-8014-8b1b-c74e02c884fa%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3DDLmEH58IPEwv7UTP8M6TOjqM9S26zQuG8xfBmIXVVMU&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f50e3562fd680548400da7682d8da4c" data-id="3f50e3562fd680548400da7682d8da4c"><span><div id="3f50e3562fd680548400da7682d8da4c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f50e3562fd680548400da7682d8da4c" title="开阳餐厅"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开阳餐厅</span></span></h3><h5 class="notion-h notion-h4 notion-h-indent-1 notion-block-3f40e3562fd6808499d6cdcb00765b63" data-id="3f40e3562fd6808499d6cdcb00765b63"><span><div id="3f40e3562fd6808499d6cdcb00765b63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6808499d6cdcb00765b63" title="缙云烧饼"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">缙云烧饼</span></span></h5><div class="notion-text notion-block-3f50e3562fd68039a7a8dd8746ac4f45">从夯到拉：人上人</div><div class="notion-text notion-block-3f50e3562fd680d7aaaff571a852e8ed">4号楼没啥好吃的，这个还行。</div><div class="notion-text notion-block-3f70e3562fd680dfa37cf679db2041bd">有薄饼和胖饼两种。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f50e3562fd680d88171dd266c51fdfa"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F941c9b68-fc60-4f08-9f3e-fe4b852967a3%2F1791606254982.jpg%3Ftable%3Dblock%26id%3D3f50e356-2fd6-80d8-8171-dd266c51fdfa%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3DWEmw9krsDGqZnhNsIdJy_1JkNJWutJ29IcB5O9NTQSY&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-3f70e3562fd680a9a271ec7106045ef5">瘦肉丸里加满辣椒。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3f50e3562fd680ffa91aff6ebf00b85b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:364px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://kunni.top/api/notion-image?url=https%3A%2F%2Ffile.notion.com%2Ff%2Ff%2Fa95da7e0-8420-4210-8902-0cd7a8e5935b%2F9dd79c2c-abb3-4cc5-a676-9c8d1077f5a3%2F1791606128870.jpg%3Ftable%3Dblock%26id%3D3f50e356-2fd6-80ff-a91a-ff6ebf00b85b%26spaceId%3Da95da7e0-8420-4210-8902-0cd7a8e5935b%26expirationTimestamp%3D1793124000000%26signature%3D0cUJ-AuH5HzJcDHGvy0qCWw5wwkgJg655vg8W-nA5Dk&amp;w=364&amp;q=88" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-3f70e3562fd68078bfc0cd23cf36b8bc"> </div><div class="notion-blank notion-block-3f50e3562fd68013b53edafb8246ad1d"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DuckDB 与 DuckLake：从嵌入式分析，到湖存储的新选择]]></title>
            <link>https://kunni.top//article/4020e356-2fd6-805d-8daf-ee42dd9ad3e4</link>
            <guid>https://kunni.top//article/4020e356-2fd6-805d-8daf-ee42dd9ad3e4</guid>
            <pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-4020e3562fd6805d8dafee42dd9ad3e4"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-4020e3562fd680e294b7dc3b8b984380">对于长期使用 Flink、Iceberg、Paimon 的开发者来说，第一次接触 DuckDB 和 DuckLake，很容易产生两个疑问：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680aca585f7e1a8e9bdc0"><li>已经有这么多数据库和计算引擎，为什么还需要 DuckDB？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680d3a3accee713a1c354"><li>DuckLake 与 DuckDB 是什么关系，它又与 Iceberg、Paimon 有什么不同？</li></ul><div class="notion-text notion-block-4020e3562fd680818ddcea4e839422f9">理解它们的关键，不是先比较功能数量或性能数字，而是先弄清楚：<b>它们分别承担哪一层的职责，又想减少哪一部分复杂度。</b></div><hr class="notion-hr notion-block-4020e3562fd680b3ae23f2af6f5eeee2"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680eaa588ccfa0301f9f4" data-id="4020e3562fd680eaa588ccfa0301f9f4"><span><div id="4020e3562fd680eaa588ccfa0301f9f4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680eaa588ccfa0301f9f4" title="一、先分清层次：DuckDB 是数据库，DuckLake 是湖表格式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一、先分清层次：DuckDB 是数据库，DuckLake 是湖表格式</span></span></h3><div class="notion-text notion-block-4020e3562fd680e49c23e6ebd1aa2c7d">DuckDB 是一个支持 SQL 的关系型分析数据库。它拥有自己的查询执行能力、事务管理和原生存储，默认可以直接嵌入应用进程运行。因此，按产品类别划分，它更接近 MySQL、PostgreSQL，而不是 Iceberg。</div><div class="notion-text notion-block-4020e3562fd6808994b1e69850d3999b">不过，“同属数据库”不意味着定位相同。DuckDB 的设计重心是分析型负载，尤其是扫描、聚合和 JOIN；它又借鉴了 SQLite 简单、嵌入式的使用方式。因此，一个更直观的类比是：<b>面向分析的 SQLite。</b></div><div class="notion-text notion-block-4020e3562fd680f2a727d4d6faf18c1e">DuckLake 则处于另一个层次：它定义湖上的表、快照、文件与元数据组织方式，并通过 SQL 数据库管理 Catalog。它的比较对象更接近 Iceberg、Paimon。</div><div class="notion-text notion-block-4020e3562fd6806abe1ecde2cc6a3172">从工程职责上，可以做如下划分：</div><table class="notion-simple-table notion-block-4020e3562fd680f0937fd7a362d706ee"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-4020e3562fd68010a965d7ad5b9132e3"><td class="" style="width:120px"><div class="notion-simple-table-cell">组件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要承担的职责</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd6806f9975f86cd3589159"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Flink</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">分布式、有状态的有界／无界数据处理</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd680b8a91cec5501cbaa14"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>DuckDB</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">SQL 分析计算，也能管理自身的原生数据库</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd6807496bac82c129c3a60"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Iceberg</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开放表格式，定义快照、Schema、数据文件与删除语义</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd68004a0ffebc650868f76"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Paimon</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">面向流批场景的湖存储，包括主键更新、合并与文件组织</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd68064b1b4c4f6e2cae038"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>DuckLake</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">使用 SQL 数据库管理元数据的开放湖表与 Catalog 格式</div></td></tr></tbody></table><div class="notion-text notion-block-4020e3562fd6803eb134e0e8de36b362">这里的划分只是为了突出设计重心：Flink 的核心是分布式有状态计算；Iceberg 通过规范描述表状态；Paimon 的主键表还包含 LSM、版本合并和 compaction 等存储机制，不能简单理解成一个文件格式。</div><hr class="notion-hr notion-block-4020e3562fd680589100d1fd24959984"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680739376d10d484c35a4" data-id="4020e3562fd680739376d10d484c35a4"><span><div id="4020e3562fd680739376d10d484c35a4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680739376d10d484c35a4" title="二、为什么已经有 Flink、Spark，还需要 DuckDB？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二、为什么已经有 Flink、Spark，还需要 DuckDB？</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680a4a61fe444cdf6a69b" data-id="4020e3562fd680a4a61fe444cdf6a69b"><span><div id="4020e3562fd680a4a61fe444cdf6a69b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680a4a61fe444cdf6a69b" title="1. 并不是每个分析任务都值得启动一套分布式执行流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 并不是每个分析任务都值得启动一套分布式执行流程</span></span></h4><div class="notion-text notion-block-4020e3562fd680fbb2fff8186d09164d">数据工程里，有很多需求看起来很小，却经常需要经过完整的平台链路：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680608823f6c615a46c23"><li>检查一批文件有没有重复数据；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd68099bf2fd1051d161e44"><li>对某个月的数据做一次聚合；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd68095a22dcd242ac5e56d"><li>将 CSV 清洗后转换为 Parquet；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680a38837fdb5a82fbd91"><li>把日志与维表 JOIN，生成一份报告；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680db897ee89a000b19b0"><li>排查一次连接器提交前后的数据差异。</li></ul><div class="notion-text notion-block-4020e3562fd680129e33d3b48ae0cc4b">对这些任务而言，实际计算可能并不是主要成本。环境准备、作业提交、数据搬运和结果获取，反而可能占据更多时间。</div><div class="notion-text notion-block-4020e3562fd68088b626c56034a52edc">DuckDB 提供了另一种选择：<b>把分析数据库当作程序库使用，而不是先建设一个数据库服务或计算平台。</b>它默认运行在应用进程内，可以由 Python、Java、C++ 等语言调用。</div><div class="notion-text notion-block-4020e3562fd680969ce2e4bd1a8bfc9f">因此，它首先降低的是“使用分析能力的门槛”，而不只是某个算子的执行时间。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680169527fa138eb4babd" data-id="4020e3562fd680169527fa138eb4babd"><span><div id="4020e3562fd680169527fa138eb4babd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680169527fa138eb4babd" title="2. 文件可以直接成为查询输入"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 文件可以直接成为查询输入</span></span></h4><div class="notion-text notion-block-4020e3562fd680869351de93de11da17">使用 DuckDB，并不一定要先把数据导入它的原生数据库。</div><div class="notion-text notion-block-4020e3562fd68094bc37c782635f484c">CSV、JSON、Parquet 等文件可以直接出现在查询中。应用可以对文件进行过滤、JOIN 和聚合，也可以把查询结果转换成另一种格式。</div><div class="notion-text notion-block-4020e3562fd68058b9abff1ba67f9711">这让它很适合处于数据库之外的数据：</div><div class="notion-text notion-block-4020e3562fd680ca9b45ef2da933e71e"><b>文件不再只是等待导入数据库的中间产物，也可以直接成为分析的数据源。</b></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd6809e8944f105f27f8202" data-id="4020e3562fd6809e8944f105f27f8202"><span><div id="4020e3562fd6809e8944f105f27f8202" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd6809e8944f105f27f8202" title="3. 轻量，不等于只能处理小数据"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 轻量，不等于只能处理小数据</span></span></h4><div class="notion-text notion-block-4020e3562fd680a78b93f41875fd64c6">DuckDB 的核心是单节点数据库，但可以利用多核、内存和本地磁盘资源。它的扩展方向主要是单节点资源扩展，而不是自动把一个查询分发到多个计算节点。</div><div class="notion-text notion-block-4020e3562fd68075b3d1d9985302b279">同时，单节点不等于所有数据都必须装进内存。DuckDB 支持通过 spill-to-disk 处理超过内存容量的工作集，不过部分复杂聚合和算子组合仍可能遇到内存限制。</div><div class="notion-text notion-block-4020e3562fd680118fbffbc40ca285d5">所以，选型时更值得问的是：</div><blockquote class="notion-quote notion-block-4020e3562fd680a8ba29f996ecff6c08"><div>经过过滤、分区和列裁剪后，这个任务真正需要处理多少数据？其中间结果是否适合单节点？</div></blockquote><div class="notion-text notion-block-4020e3562fd680b8a45ad33f49e202fe">而不是仅凭数据湖的总容量，决定所有查询都必须走分布式系统。</div><hr class="notion-hr notion-block-4020e3562fd6800fb39be5ab6b6964ca"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd6804b98e5c2e25701e4a9" data-id="4020e3562fd6804b98e5c2e25701e4a9"><span><div id="4020e3562fd6804b98e5c2e25701e4a9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd6804b98e5c2e25701e4a9" title="三、一个具体场景：给商家生成销售分析报表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三、一个具体场景：给商家生成销售分析报表</span></span></h3><div class="notion-text notion-block-4020e3562fd680758808f085d691ccac">假设一个电商平台已经通过上游处理，得到了一批整理好的支付记录：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd6807188bef9ddc258d6ee"><li>每笔支付只有一条记录；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680c886fbf374f07d75ff"><li>数据已经去重；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680a0bed7eebb4c3bee34"><li>某个月的数据以 Parquet 保存；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680cca524e0c4e7a455fb"><li>查询期间，这批已发布文件保持不变。</li></ul><div class="notion-text notion-block-4020e3562fd680a3b478ecef355c891b">运营提出一个需求：</div><blockquote class="notion-quote notion-block-4020e3562fd68072b397c199699f0e10"><div>查询某个商家，各商品品类的支付笔数、销售额和平均支付金额。</div></blockquote><div class="notion-text notion-block-4020e3562fd680dcbf74cb094a46ad45">一种实现方式是将数据导入分析数据库，再执行查询；另一种方式是提交批处理作业。</div><div class="notion-text notion-block-4020e3562fd680259ab8ed25f20f2fc8">如果这个任务适合单节点资源，也可以把 DuckDB 嵌入报表后端：</div><div class="notion-text notion-block-4020e3562fd68091833ae621eab6573c">这套方案的价值在于：<b>不必为了一个局部分析需求，额外维护一份导入后的数据副本和一套独立服务。</b></div><div class="notion-text notion-block-4020e3562fd680e7ad6cc451ce0ab736">DuckDB 的向量化执行以批次处理数据；对于远程 Parquet，减少不必要的列和数据读取，也有助于降低 I/O 成本。但具体性能仍取决于文件布局、网络、硬件和查询形态，不能脱离条件承诺“多少 GB 一定几秒完成”。</div><div class="notion-text notion-block-4020e3562fd680ea92d9c5f744b090ef">这不只是临时脚本的用法。Hex 在公开工程文章中介绍过：其分析工作台采用基于 DuckDB 的架构，查询保存在 S3 中的 Arrow 数据，避免每一步都把完整数据物化为 Pandas DataFrame，只在需要时才将数据送入 Python。</div><div class="notion-text notion-block-4020e3562fd6809885cac99758d73b72">这个案例说明，DuckDB 也可以成为产品内部的分析计算内核，而不必始终以“一个供用户直接登录的数据库”的形态出现。</div><hr class="notion-hr notion-block-4020e3562fd680fa9e25cfacf6c77714"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680b29cccebe165eb0404" data-id="4020e3562fd680b29cccebe165eb0404"><span><div id="4020e3562fd680b29cccebe165eb0404" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680b29cccebe165eb0404" title="四、既然 DuckDB 能直接读文件，为什么还需要 DuckLake？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四、既然 DuckDB 能直接读文件，为什么还需要 DuckLake？</span></span></h3><div class="notion-text notion-block-4020e3562fd68037ba90c6d29563a702">因为，<b>“能查询文件”与“能正确管理一张持续变化的表”，是两个不同的问题。</b></div><div class="notion-text notion-block-4020e3562fd680b1a809f506addea828">如果数据只是一批不再变化的文件，直接扫描通常容易理解。但当数据持续追加、更新和删除时，就必须回答：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd6806baad2ce34d98ffe43"><li>当前这张表包含哪些文件？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd68077939fc974b91ece95"><li>哪些记录已经被删除？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680818808c5c0ea3c28a6"><li>一次写入是否完整提交？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680978c6ce6b7f8bd685a"><li>读者应该看到哪个版本？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd6804aa9f3eb9bd0bd0b19"><li>字段重命名后，旧文件应该如何解释？</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680539d58d2fc58a33b56"><li>多个 writer 同时提交时，如何避免覆盖彼此的结果？</li></ul><div class="notion-text notion-block-4020e3562fd6803e9fcff1563e674b5b">Iceberg 用表元数据、快照、Manifest List、Manifest 以及数据／删除文件等结构解决这些问题。表的逻辑内容不能简单等同于目录中的全部文件。</div><div class="notion-text notion-block-4020e3562fd68032a7caf58d7e050276">DuckLake 面对的是同一类需求，但它选择了不同的元数据架构：</div><blockquote class="notion-quote notion-block-4020e3562fd680319bc4fc81c77a0508"><div><b>主要数据继续保存在 Parquet 文件中，表元数据则交给关系数据库管理。</b></div></blockquote><hr class="notion-hr notion-block-4020e3562fd680598768dae7d0ebe337"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680339db8dc6935aa70a7" data-id="4020e3562fd680339db8dc6935aa70a7"><span><div id="4020e3562fd680339db8dc6935aa70a7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680339db8dc6935aa70a7" title="五、DuckLake 的核心设计：让数据库管理湖表元数据"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">五、DuckLake 的核心设计：让数据库管理湖表元数据</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680ab9281e1b840701386" data-id="4020e3562fd680ab9281e1b840701386"><span><div id="4020e3562fd680ab9281e1b840701386" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680ab9281e1b840701386" title="1. 数据与元数据分别放在哪里？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 数据与元数据分别放在哪里？</span></span></h4><div class="notion-text notion-block-4020e3562fd68080a23af5b0d1d81301">一个典型的 DuckLake 部署可以简化为：</div><div class="notion-text notion-block-4020e3562fd68021bcbfc7c2dbce8036">DuckLake 的规范定义了 Catalog 中的 SQL 表结构、查询和更新语义。DuckDB 通过 <code class="notion-inline-code">ducklake</code> 扩展实现这些操作，但规范本身与查询执行器是两个概念。</div><div class="notion-text notion-block-4020e3562fd680b087c8d226da8771f4">在参考实现中，Catalog 可以根据部署需求选择不同数据库：本地使用可以选择 DuckDB 或 SQLite，多用户、远程协作场景则可以使用 PostgreSQL。</div><div class="notion-text notion-block-4020e3562fd68091a985c5521354afc8">因此，使用 PostgreSQL 做 DuckLake Catalog，并不意味着要把整座数据湖的明细全部导入 PostgreSQL。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680378d31efbc55b51346" data-id="4020e3562fd680378d31efbc55b51346"><span><div id="4020e3562fd680378d31efbc55b51346" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680378d31efbc55b51346" title="2. 一次写入如何变成可见数据？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 一次写入如何变成可见数据？</span></span></h4><div class="notion-text notion-block-4020e3562fd680ce9b78efa344f32fb3">先忽略小数据的特殊优化，普通文件写入可以理解为：</div><ol start="1" class="notion-list notion-list-numbered notion-block-4020e3562fd6803288d8fbb029314e68" style="list-style-type:decimal"><li>准备新的数据文件；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-4020e3562fd680f09a3eca7ed3318ef6" style="list-style-type:decimal"><li>在 Catalog 事务中登记文件和相关元数据；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-4020e3562fd680aea6c9ee6fe0515a2a" style="list-style-type:decimal"><li>提交新的快照；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-4020e3562fd68042b8fbe17f9ab59937" style="list-style-type:decimal"><li>读者根据目标快照，确定应该读取的文件集合。</li></ol><div class="notion-text notion-block-4020e3562fd6806b8396d0b8ff086778">这里最重要的区别是：</div><blockquote class="notion-quote notion-block-4020e3562fd680789a5fdb327bc3233e"><div><b>文件上传成功，不等于数据已经成为表中可见的一部分。</b></div></blockquote><div class="notion-text notion-block-4020e3562fd68072af4ef2ced0e0bcde">可见性由表的提交协议决定，而不是由对象存储目录是否出现新文件决定。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd6803c8560e94233750956" data-id="4020e3562fd6803c8560e94233750956"><span><div id="4020e3562fd6803c8560e94233750956" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd6803c8560e94233750956" title="3. 为什么要把元数据放进数据库？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 为什么要把元数据放进数据库？</span></span></h4><div class="notion-text notion-block-4020e3562fd6806a9ccedc8e2619e248">DuckLake 的设计思路是：既然数据库已经擅长事务、索引、并发控制和结构化查询，就可以让它更完整地管理湖表元数据，而不是把这部分状态全部编码到元数据文件中。</div><div class="notion-text notion-block-4020e3562fd680e0819be80b107da98b">由此可以获得几个值得关注的设计空间：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680f58a5bdf02879f51d0"><li><b>关系化的元数据查询</b>：文件、字段、快照和统计信息具有明确的 SQL 表示。</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd68092a02ad0b8c6d5dd4c"><li><b>同一 Catalog 内的多表事务</b>：相关表的变更可以放进同一个事务边界。</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680288d47c7d5bd3cfc6f"><li><b>事务化的数据与 DDL 变更</b>：数据修改和建表、改表等操作具有事务支持。</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680eab023def9fe0abbd1"><li><b>小变更内联</b>：小批数据可以先写入 Catalog 内部的数据表，而不是每次都生成一个小 Parquet 文件。</li></ul><div class="notion-text notion-block-4020e3562fd68032a3bcfcb12427c755">最后一点也意味着：严格来说，DuckLake 的实际数据并非永远全部位于 Parquet 中。它允许针对小变更使用不同的物理存储路径。</div><hr class="notion-hr notion-block-4020e3562fd680f79f4bf55c28815d20"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd6807a9470dfe1aedc1b5b" data-id="4020e3562fd6807a9470dfe1aedc1b5b"><span><div id="4020e3562fd6807a9470dfe1aedc1b5b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd6807a9470dfe1aedc1b5b" title="六、DuckLake 与 Iceberg、Paimon：不同的复杂度分配方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">六、DuckLake 与 Iceberg、Paimon：不同的复杂度分配方式</span></span></h3><div class="notion-text notion-block-4020e3562fd680509c19c8a2e23c8a80">从设计重心来看，可以这样比较：</div><table class="notion-simple-table notion-block-4020e3562fd680d4a274d2f83536956d"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-4020e3562fd680ef8cb8f3695664b1ca"><td class="" style="width:120px"><div class="notion-simple-table-cell">项目</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">值得关注的核心思路</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd6806b9120d5876940219c"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Iceberg</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用开放规范和文件化元数据描述表状态，实现跨引擎的表访问</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd680048973d4ecd55c8ec5"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Paimon</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">将流式更新、主键合并和 LSM 等存储机制结合起来</div></td></tr><tr class="notion-simple-table-row notion-block-4020e3562fd6808cbcc9ef032cf4a53f"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>DuckLake</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用关系数据库管理湖表元数据，以数据库事务协调表变更</div></td></tr></tbody></table><div class="notion-text notion-block-4020e3562fd68008897acafb1bf8c306">这些区别来自各自的表状态与存储组织方式，不应被简化成“谁支持更新、谁不支持更新”。</div><div class="notion-text notion-block-4020e3562fd6807f8c8eea836bab95ff">更合理的工程判断是：<b>它们在不同位置承担复杂度。</b></div><div class="notion-text notion-block-4020e3562fd680b7a521f38e8bd36271">文件化元数据需要考虑文件组织、遍历、缓存和提交协议；数据库化元数据则需要评估：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680ad8ac5c97052303ac0"><li>Catalog 数据库的容量和热点；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680868f3bc41375a3c34e"><li>高频提交下的事务竞争；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680cd8881d6334891ccbe"><li>高可用、备份和恢复；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680ad99edd7fb48d238f8"><li>元数据恢复点与对象存储数据的一致性；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd6808bae1be041d346bef6"><li>内联数据增长后的运维成本。</li></ul><div class="notion-text notion-block-4020e3562fd6808d870fe6428cd82fb1">所以，DuckLake 并不是“没有元数据管理成本”，而是把一部分问题交给了成熟的数据库基础设施。</div><div class="notion-text notion-block-4020e3562fd680f6ad89c2822735ebeb">同样，开放规范也不能自动证明所有引擎都已完整支持。选型时仍需要检查目标实现对类型、删除、演进和事务语义的覆盖程度。</div><hr class="notion-hr notion-block-4020e3562fd6802a95a0ee08a8938ea9"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680bbbbe5e5b112a9a894" data-id="4020e3562fd680bbbbe5e5b112a9a894"><span><div id="4020e3562fd680bbbbe5e5b112a9a894" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680bbbbe5e5b112a9a894" title="七、对 Flink 湖存储连接器开发的启发"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">七、对 Flink 湖存储连接器开发的启发</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680b5aeb5e45dc09affd3" data-id="4020e3562fd680b5aeb5e45dc09affd3"><span><div id="4020e3562fd680b5aeb5e45dc09affd3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680b5aeb5e45dc09affd3" title="1. 将 DuckDB 当作独立消费者，而不是只当作另一个 Sink"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 将 DuckDB 当作独立消费者，而不是只当作另一个 Sink</span></span></h4><div class="notion-text notion-block-4020e3562fd680b39091e42c27bfe709">连接器能成功写出文件，只能证明写入链路完成了一部分工作。</div><div class="notion-text notion-block-4020e3562fd680788f59e56ad72f67b1">更有价值的验证是：</div><div class="notion-text notion-block-4020e3562fd6802ca9d2c4402a5459ea">从这个角度，DuckDB 可以成为跨引擎互操作验证的参与者。</div><div class="notion-text notion-block-4020e3562fd680e39dede276df9e8726">建议重点覆盖：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680349f33fc95b02f32cd"><li>更新、删除之后的最终结果；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680d8a7a3f73091b6573b"><li>字段重命名后的身份匹配；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd6802a9bcdee33fb3fa838"><li>时间戳精度与时区语义；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd6801b9ef2ec8805de53a0"><li>DECIMAL 的精度和舍入；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680eea6f2d60f5e1d7550"><li>嵌套类型和空值；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd6809ab0ebcf9f7585f834"><li>同一快照在不同引擎中的一致性。</li></ul><div class="notion-text notion-block-4020e3562fd680dfb6d5e755e676480e">这里强调的是<b>逻辑表读取</b>。例如，Iceberg 删除文件需要按适用规则作用于数据文件，不能直接扫描所有 Parquet 来代替表查询。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd6808ea5c9fcdad3997638" data-id="4020e3562fd6808ea5c9fcdad3997638"><span><div id="4020e3562fd6808ea5c9fcdad3997638" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd6808ea5c9fcdad3997638" title="2. “存储有 ACID”不等于“Flink 自动 exactly-once”"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. “存储有 ACID”不等于“Flink 自动 exactly-once”</span></span></h4><div class="notion-text notion-block-4020e3562fd680448f15ef388f29d25b">这是连接器设计中最容易被产品能力列表掩盖的问题。</div><div class="notion-text notion-block-4020e3562fd680d7a1aee2c52887fdc0">即使外部存储支持事务，仍然需要明确：</div><div class="notion-text notion-block-4020e3562fd6801aa684c31261f12059">这些是需要额外建立的连接器协议。数据库事务可以提供原子提交能力，但不会自动替 Flink 管理 checkpoint 状态、重试幂等和恢复决策。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4020e3562fd680b1b424eb62bb3f2bcf" data-id="4020e3562fd680b1b424eb62bb3f2bcf"><span><div id="4020e3562fd680b1b424eb62bb3f2bcf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680b1b424eb62bb3f2bcf" title="3. 不要只优化写入吞吐，也要评估下游读取成本"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 不要只优化写入吞吐，也要评估下游读取成本</span></span></h4><div class="notion-text notion-block-4020e3562fd680d19b6dc5b5e6d0cd48">文件大小、排序方式、版本数量和 compaction 策略，会影响后续读取需要做多少工作。Paimon 主键表就是一个直观例子：不同 sorted run 中可以保留同一主键的多个物理版本，读取或 compaction 需要按规则合并它们。</div><div class="notion-text notion-block-4020e3562fd680fba707c2ab19960e51">因此，连接器性能评估不应只记录“每秒写入多少条”，还应该记录：</div><ul class="notion-list notion-list-disc notion-block-4020e3562fd680f4aaf0c3e3d65ee668"><li>写出了多少文件；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680d0a6dbd2968d522371"><li>一次查询需要读取多少字节；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680fc9d29ce508f4896e6"><li>需要合并多少版本；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd680428ddad6b04ab758b8"><li>删除处理占多少开销；</li></ul><ul class="notion-list notion-list-disc notion-block-4020e3562fd68000b6abeefa915305d9"><li>compaction 后是否显著改变消费成本。</li></ul><div class="notion-text notion-block-4020e3562fd680929dfccef15da13484"><b>好的写入路径，应当同时考虑数据未来如何被读取。</b></div><hr class="notion-hr notion-block-4020e3562fd6806ba3e3e99131403d4d"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-4020e3562fd680b888eeea7cace7555c" data-id="4020e3562fd680b888eeea7cace7555c"><span><div id="4020e3562fd680b888eeea7cace7555c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4020e3562fd680b888eeea7cace7555c" title="结语：不是替代所有系统，而是重新选择边界"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结语：不是替代所有系统，而是重新选择边界</span></span></h3><div class="notion-text notion-block-4020e3562fd680e087d3f05f7ff317eb">理解 DuckDB 和 DuckLake，可以抓住两句话：</div><blockquote class="notion-quote notion-block-4020e3562fd6803d8953f27d3efa6cad"><div><b>DuckDB 尝试让分析计算像调用一个库一样方便。</b></div><div class="notion-text notion-block-4020e3562fd6802c8d3beb5304431baf"><b>DuckLake 尝试让湖表元数据更多地回归数据库管理。</b></div></blockquote><div class="notion-text notion-block-4020e3562fd680a5bd02ee806da67298">前者让我们重新审视：哪些分析任务真的需要分布式执行，哪些可以在单节点内更直接地完成。</div><div class="notion-text notion-block-4020e3562fd68092a1ceed72323897c7">后者让我们重新审视：湖存储中的哪些状态应该文件化，哪些能力可以交给数据库事务。</div><div class="notion-text notion-block-4020e3562fd68078ba86c27842d4d0ad">对于 Flink、Iceberg、Paimon 开发者而言，它们最有价值的启发，不是“现有系统应该被替换”，而是：</div><div class="notion-text notion-block-4020e3562fd680fcb507c10263536d88"><b>先明确问题的边界，再选择复杂度应该由谁承担。</b></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[大数据项目周报(十月下)]]></title>
            <link>https://kunni.top//article/3e10e356-2fd6-8004-9641-e11d662a3e4b</link>
            <guid>https://kunni.top//article/3e10e356-2fd6-8004-9641-e11d662a3e4b</guid>
            <pubDate>Sun, 20 Sep 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3e10e3562fd680049641e11d662a3e4b"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-4010e3562fd6809e8010ee30611c650b" data-id="4010e3562fd6809e8010ee30611c650b"><span><div id="4010e3562fd6809e8010ee30611c650b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6809e8010ee30611c650b" title="2026/10/16～2026/10/22"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2026/10/16～2026/10/22</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-4010e3562fd6806d9fa5e0dd00a5a738" data-id="4010e3562fd6806d9fa5e0dd00a5a738"><span><div id="4010e3562fd6806d9fa5e0dd00a5a738" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6806d9fa5e0dd00a5a738" title="本周十大热点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">本周十大热点</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd68088a659eaff32731df9" data-id="4010e3562fd68088a659eaff32731df9"><span><div id="4010e3562fd68088a659eaff32731df9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68088a659eaff32731df9" title="1. Apache Kafka 4.3.2 修复分层存储数据丢失风险"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. Apache Kafka 4.3.2 修复分层存储数据丢失风险</span></span></h4><div class="notion-text notion-block-4010e3562fd68016b7e1df937114fe15">Kafka 4.3.2 不能只当作一次普通补丁更新。其中最需要排查的是 <code class="notion-inline-code">KAFKA-20732</code>：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd68010985bca364e322630"><li>分层存储在 Leader 切换后，远端最高 Offset 的内存状态可能尚未初始化；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68076b917e760d37db8f3"><li>按容量执行保留策略时，同一批本地、远端数据可能被重复计入大小；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68090af18e69a3a60f582"><li>系统因而误判超过 <code class="notion-inline-code">retention.bytes</code>，删除实际上仍应保留的远端数据；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680d8a3d4c499123c6463"><li>随着日志起始 Offset 推进，本地副本也会删除对应数据。</li></ul><div class="notion-text notion-block-4010e3562fd680ec9c1ce923f7350057">本版还修复了 Kafka Streams 状态目录过早清理，以及任务损坏、任务复用和状态更新超时后线程退出等问题。</div><div class="notion-text notion-block-4010e3562fd680d5b2a2c4d8a492c67b">这不是所有 Kafka 集群都会触发的通用故障。启用了分层存储和容量保留策略的团队，应优先核对受影响版本、配置与修复分支；其他版本线不能仅凭本条消息直接决定跨大版本升级。</div><div class="notion-text notion-block-4010e3562fd680f5a965e56585494dcf"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680c68e9cfebf05ed2506"><li><a class="notion-link" href="https://github.com/apache/kafka/releases/tag/4.3.2" target="_blank" rel="noopener noreferrer">Kafka 4.3.2 Release</a></li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68029b866f05d793a1a1a"><li><a class="notion-link" href="https://downloads.apache.org/kafka/4.3.2/RELEASE_NOTES.html" target="_blank" rel="noopener noreferrer">4.3.2 官方 Release Notes</a></li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6803c9d09ea4403a2b58a"><li><a class="notion-link" href="https://issues.apache.org/jira/browse/KAFKA-20732" target="_blank" rel="noopener noreferrer">KAFKA-20732：触发条件及修复版本</a></li></ul><div class="notion-text notion-block-4010e3562fd680428902cbf784b887a2"><b>编辑评价：本周数据正确性方向的最高优先级事项。</b> 补丁版本是否重要，应看修复的故障后果，而不是版本号变化大小。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680118e2ce7e0e12e4612" data-id="4010e3562fd680118e2ce7e0e12e4612"><span><div id="4010e3562fd680118e2ce7e0e12e4612" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680118e2ce7e0e12e4612" title="2. DuckDB 2.0.0 LTS 正式发布"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. DuckDB 2.0.0 LTS 正式发布</span></span></h4><div class="notion-text notion-block-4010e3562fd680939751f6529a4437c5">DuckDB 发布代号为 Cinnamon Teal 的 2.0.0 LTS，支持期至少持续到 2027 年 10 月。</div><div class="notion-text notion-block-4010e3562fd680b38292e52cb7f93b05">主要变化包括：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6800a80faf058d6ebbd0b"><li>完善 Quack 远程协议，并增加 <code class="notion-inline-code">CONNECT</code> 语句；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680b1856eceeff3b2c494"><li>引入异步 I/O，提升远程文件读取的并行能力；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680529874e81f865c6392"><li>将 <code class="notion-inline-code">VARIANT</code> 更完整地接入列式存储、执行与 Parquet 读写；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6809ea605e1f7e88549d8"><li>CLI 为 Agent 提供紧凑输出、截断提示和结构化错误；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680b5b04dfae1859c7f84"><li>默认使用可扩展的 PEG SQL Parser；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68084bc86d0be4082b7f0"><li>增加 Trigger 等 SQL 能力，部分 Trigger 组合仍有限制。</li></ul><div class="notion-text notion-block-4010e3562fd68078a1eaeb037d987260">升级时尤其需要注意：<b>2.0 之前的版本不能读取由 2.0 新建的数据库文件</b>；2.0 仍可读写既有格式文件。关键业务应先验证文件兼容性、客户端与扩展，而不是只替换可执行文件。</div><div class="notion-text notion-block-4010e3562fd680e2ae93c23a7e3cd5fb"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd68005a609c7d3219a9127"><li><a class="notion-link" href="https://duckdb.org/2026/10/21/announcing-duckdb-200" target="_blank" rel="noopener noreferrer">DuckDB 2.0.0 发布公告</a></li></ul><div class="notion-text notion-block-4010e3562fd680fb977cfea4f072109c"><b>编辑评价：本周最重要的分析数据库版本之一。</b> 远程连接、异步 I/O、半结构化数据和客户端体验同时演进，但不能把它简单理解为放弃嵌入式定位。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680f095eeeb55cbb3ab32" data-id="4010e3562fd680f095eeeb55cbb3ab32"><span><div id="4010e3562fd680f095eeeb55cbb3ab32" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680f095eeeb55cbb3ab32" title="3. DuckLake 1.1 发布：加强元数据、删除向量与文件裁剪"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. DuckLake 1.1 发布：加强元数据、删除向量与文件裁剪</span></span></h4><div class="notion-text notion-block-4010e3562fd6800dafb6c630b5b78a45">DuckLake 同步发布 1.1 规范与 DuckDB 参考实现。需要区分“升级扩展”和“迁移 Catalog 规范”两件事。</div><div class="notion-text notion-block-4010e3562fd6804692a5d3553bb6dbdc">依赖 1.1 规范的新能力包括：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680cb8207fe61ce6257e7"><li>嵌套 Schema；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680db9b89fe5fc3be97e8"><li>PostgreSQL、SQLite Catalog 中的 <code class="notion-inline-code">VARIANT</code> 小批量数据内联；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680e0bdbcff0ba9f44924"><li>与 Iceberg 计数约定一致的 Epoch 分区变换；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68055b551caabf6b6de6f"><li>一个 Puffin 文件保存同一数据文件多个快照的删除向量；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68087903ee8d4dfd51dd0"><li>记录字符串统计边界是否精确，以及文件的 Row Group 数量。</li></ul><div class="notion-text notion-block-4010e3562fd680399384e6f2ded9da89">新扩展还改善文件裁剪、Compaction 控制和外部 Parquet 导入，这些改进中的多数无需迁移既有 1.0 Catalog。</div><div class="notion-text notion-block-4010e3562fd68021b21ac8635e51d750">迁移是显式选择，不会因为升级扩展就自动发生；操作前应备份 Catalog，并验证工作流兼容性。</div><div class="notion-text notion-block-4010e3562fd68056be72f25277e1f86a"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680578c97f8b030c6a96e"><li><a class="notion-link" href="https://ducklake.select/2026/10/21/ducklake-11/" target="_blank" rel="noopener noreferrer">DuckLake 1.1 发布说明</a></li></ul><div class="notion-text notion-block-4010e3562fd6800d9d23eaddd0bd33d3"><b>编辑评价：开放湖存储的优化继续下沉到元数据层。</b> 提前知道文件统计、删除历史和并行扫描粒度，可以减少不必要的对象存储读取。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680e9b68bcffef5fd8403" data-id="4010e3562fd680e9b68bcffef5fd8403"><span><div id="4010e3562fd680e9b68bcffef5fd8403" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680e9b68bcffef5fd8403" title="4. pgBackRest 2.60.0 收紧恢复与备份过期的校验行为"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. pgBackRest 2.60.0 收紧恢复与备份过期的校验行为</span></span></h4><div class="notion-text notion-block-4010e3562fd6800dbbbbc2991e5fbae2">pgBackRest 2.60.0 最值得关注的不是功能数量，而是发现页面校验错误后的默认行为变化：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6809dbee2da688d64e078"><li><code class="notion-inline-code">restore</code> 遇到无效页面校验和时，默认报错并停止，恢复出的集群可能不完整、无法启动，需要重新恢复；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680af9052e9c5cf2f46d4"><li><code class="notion-inline-code">expire</code> 在最旧保留备份包含校验错误时，默认拒绝执行过期清理，并阻止该仓库相应归档过期；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6803395f5ee77d52665c7"><li><code class="notion-inline-code">backup</code> 对这类错误仍默认告警，而不是与恢复命令一样默认失败；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6804fab60d98103195f47"><li><code class="notion-inline-code">checksum-page-error=n</code> 可以改为告警，但这不等于修复损坏。</li></ul><div class="notion-text notion-block-4010e3562fd6808d93e5d3390dc32b1e">其他更新包括对象存储多文件／Range 读取预取，以及 GCS Workload Identity Federation。</div><div class="notion-text notion-block-4010e3562fd68027a2adf9af86ef483b"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680e29f46c9fa7fe11fd2"><li><a class="notion-link" href="https://www.postgresql.org/about/news/pgbackrest-2600-released-3416/" target="_blank" rel="noopener noreferrer">PostgreSQL 社区发布消息</a></li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68043959eca543cf9d7cb"><li><a class="notion-link" href="https://pgbackrest.org/release.html" target="_blank" rel="noopener noreferrer">pgBackRest 2.60.0 详细变更与重要说明</a></li></ul><div class="notion-text notion-block-4010e3562fd68001a4a1d00818f360c7"><b>编辑评价：升级前应先检查恢复与清理自动化。</b> 更严格的正确性检查有价值，但原本“继续执行”的流程现在可能明确停止，不能把这种行为差异当作偶发失败。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd68009a9c5c2ade4f99fab" data-id="4010e3562fd68009a9c5c2ade4f99fab"><span><div id="4010e3562fd68009a9c5c2ade4f99fab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68009a9c5c2ade4f99fab" title="5. LinkedIn 公布每日数千亿事件的埋点管道重建实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. LinkedIn 公布每日数千亿事件的埋点管道重建实践</span></span></h4><div class="notion-text notion-block-4010e3562fd6807db7a6f3990ba4e934">LinkedIn 介绍了高吞吐 Tracking Infrastructure 的并行重建与迁移，覆盖每日数千亿事件、峰值每秒数百万事件。</div><div class="notion-text notion-block-4010e3562fd680fa91bde461d0ba1d77">可复用的经验包括：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6804b9e48f51107a93737"><li>按工作负载成本和故障影响拆分容量与部署单元；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680ebaa64ed6428b4572b"><li>批次内复用公共上下文，减少重复序列化和网络传输；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680a0a248f40903ff4194"><li>新旧链路并行比对，分批迁移，利用路由保持快速回滚；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6807f8daef8f79502692f"><li>将 Kafka Producer 异步回调中的过载信号接入后续请求准入。</li></ul><div class="notion-text notion-block-4010e3562fd68072af47eb6ae25a852b">作者报告：迁移到全部流量口径后，入站网络用量约下降 89%。这是上下文复用、Protocol Buffers 与相关序列化改造的共同效果，不是单纯更换传输协议的收益。</div><div class="notion-text notion-block-4010e3562fd680e28664d3a87e154517">一个重要边界是：API 在记录进入 Producer 本地缓冲后就可返回成功，<b>并不等待 Kafka Broker 确认</b>。API 成功、Broker 确认和下游内容正确必须分别验证。</div><div class="notion-text notion-block-4010e3562fd6808f9b1ff1f95886816b"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6803fa5b8f6d1f373bb29"><li><a class="notion-link" href="https://www.linkedin.com/blog/engineering/infrastructure/rebuilding-linkedins-tracking-infrastructure-scaling-migrating-and-hardening-a-high-volume-event-pipeline" target="_blank" rel="noopener noreferrer">LinkedIn Tracking Infrastructure 工程复盘</a></li></ul><div class="notion-text notion-block-4010e3562fd680be8af0de8427088721"><b>编辑评价：比“迁移到 gRPC”更值得读的是异步管道的成功边界、隔离与准入设计。</b> 性能数据来自作者的生产观测，不应直接迁移成其他系统的预期收益。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd6802ebc1be496296f830b" data-id="4010e3562fd6802ebc1be496296f830b"><span><div id="4010e3562fd6802ebc1be496296f830b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6802ebc1be496296f830b" title="6. Apache Fluss 展示带外部副作用 Worker 的崩溃恢复方法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. Apache Fluss 展示带外部副作用 Worker 的崩溃恢复方法</span></span></h4><div class="notion-text notion-block-4010e3562fd680999ac9ef72c1b6b1c5">Fluss 官方博客通过一个可复现实验，讨论 Worker 调用外部服务后崩溃时，如何判断是否应该重试。</div><div class="notion-text notion-block-4010e3562fd6807d80bfc1b3ebee3784">核心方法是：</div><ol start="1" class="notion-list notion-list-numbered notion-block-4010e3562fd6801c8977c84d174b9c40" style="list-style-type:decimal"><li>调用服务前，先将稳定的 <code class="notion-inline-code">action_id</code>、完整请求与摘要写入日志；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-4010e3562fd68041aa5ddd355577c936" style="list-style-type:decimal"><li>重启后重放已提交历史，识别未确认的动作；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-4010e3562fd680f28cd6ef48de2868b9" style="list-style-type:decimal"><li>向下游查询已提交回执，区分“尚未执行”和“已执行但确认未写回”；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-4010e3562fd680c1b984f3a5e397e99a" style="list-style-type:decimal"><li>对已完成的动作补记确认，避免再次提交副作用。</li></ol><div class="notion-text notion-block-4010e3562fd680f99775f13111f1f076">实验报告通过 7 个核心场景、344 项断言。不过它只覆盖单 Worker、单 Bucket、集群与下游服务继续运行时的进程崩溃，且恢复读取期间要求停止写入。</div><div class="notion-text notion-block-4010e3562fd680c09291ceb1e75a8ddd"><b>这不是 Fluss 自动提供通用外部 Exactly-once 的证明</b>：下游幂等键、回执契约和故障模型仍是必要条件。</div><div class="notion-text notion-block-4010e3562fd680f89946c9913cff0c04"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680f3a62fdea85ff314d8"><li><a class="notion-link" href="https://fluss.apache.org/blog/tracing-job-retries/" target="_blank" rel="noopener noreferrer">Crash-safe retries for side-effecting workers with Apache Fluss</a></li></ul><div class="notion-text notion-block-4010e3562fd680c6835dfbc027e6a62c"><b>编辑评价：价值在于明确说明“日志知道什么、外部系统知道什么”。</b> 适合借鉴到异步任务和外部 API 调用，但不能跳过实验边界直接套用到分布式生产系统。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680b08311caa2605b5810" data-id="4010e3562fd680b08311caa2605b5810"><span><div id="4010e3562fd680b08311caa2605b5810" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680b08311caa2605b5810" title="7. dbt State 为自托管用户提供持续免费额度"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. dbt State 为自托管用户提供持续免费额度</span></span></h4><div class="notion-text notion-block-4010e3562fd680e08cc7e430e02f2c68">dbt Labs 为已 GA 的 dbt State 增加免费计划，让自托管用户在试用结束后继续使用每月额度。</div><div class="notion-text notion-block-4010e3562fd6801fab7ac1c4397c1518">需要注意的条件包括：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680a48012f6fb04a84bce"><li>免费额度为每月 1,000 DATT，并在每月 1 日重置；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6801cb381f0652ee6a0e4"><li>DATT 按一天内被跳过或克隆的目标模型／测试计量，同一对象当天多次复用只计一次；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6802ba40fc8846c4473ba"><li>dbt State 是共享运行状态的独立服务，仍需要 dbt 账号；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6802d8775e6f953839c68"><li>支持 Snowflake、BigQuery、Databricks 和 Redshift；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680bab0f6f8934f295453"><li>多数 dbt Platform 用户的新增额度有效期到 2027 年 3 月，不能与自托管方案的长期免费额度混为一谈。</li></ul><div class="notion-text notion-block-4010e3562fd680cd9c64fdac82b1eaad"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6803c808fc781feab20bc"><li><a class="notion-link" href="https://www.getdbt.com/blog/dbt-state-now-available-free-forever" target="_blank" rel="noopener noreferrer">dbt State 免费计划与额度说明</a></li></ul><div class="notion-text notion-block-4010e3562fd680dabfe6f5f53495b05f"><b>编辑评价：对数据工程团队的意义是降低状态复用的试用门槛。</b> “Free forever”不等于无限用量，也不等于底层数据仓库计算免费。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680248f0cf22e896dd196" data-id="4010e3562fd680248f0cf22e896dd196"><span><div id="4010e3562fd680248f0cf22e896dd196" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680248f0cf22e896dd196" title="8. OpenReplay 分享单实例 ClickHouse 承载大规模行为事件的实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. OpenReplay 分享单实例 ClickHouse 承载大规模行为事件的实践</span></span></h4><div class="notion-text notion-block-4010e3562fd680e89bbfe50dc9707cc8">ClickHouse 发布 OpenReplay 客户案例，重点是自托管产品如何控制数据管道与运维复杂度：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680b49452e841c71695f7"><li>行为事件集中写入，再通过物化视图转换到目标表；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680a0990ffa67dd6bc0eb"><li>使用 TTL 管理保留周期，替代原先大量手工清理工作；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680e9a485d01cc137bf52"><li>PostgreSQL 继续保存元数据，并非完全移除；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6806b8494e7672f717ee3"><li>以纵向扩容控制部署复杂度，而不是立即引入分片集群。</li></ul><div class="notion-text notion-block-4010e3562fd680ef8636c20eb3204bf3">文中报告，最大客户场景每天接收数十亿事件、约 6 TB 数据，并提供亚秒级查询；部分管道变更的开发调试时间从两天缩短到半天。</div><div class="notion-text notion-block-4010e3562fd680a8bcd3cdd15fd5ca88">这些是厂商发布、客户口述的特定部署经验，<b>不是所有查询的延迟承诺，也不是经过独立复现的通用单机容量上限</b>。</div><div class="notion-text notion-block-4010e3562fd68035b09ac83fef3423ce"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680d69427cc93f579fcdc"><li><a class="notion-link" href="https://clickhouse.com/blog/openreplay-front-end-observability-at-scale-clickhouse" target="_blank" rel="noopener noreferrer">OpenReplay 与 ClickHouse 的工程案例</a></li></ul><div class="notion-text notion-block-4010e3562fd680bca148c537f64a14fd"><b>编辑评价：值得借鉴的是数据生命周期与部署复杂度的取舍。</b> 架构收益不只有峰值吞吐，还包括保留策略、管道修改成本和客户侧维护负担。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd6803da35fec4d931e8c7b" data-id="4010e3562fd6803da35fec4d931e8c7b"><span><div id="4010e3562fd6803da35fec4d931e8c7b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6803da35fec4d931e8c7b" title="9. Databricks AI Runtime 正式 GA"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. Databricks AI Runtime 正式 GA</span></span></h4><div class="notion-text notion-block-4010e3562fd680639110fc0fb134ce41">Databricks 宣布 AI Runtime（AIR）正式可用，将托管 GPU 基础设施、开发工具和数据治理放进同一个平台边界。</div><div class="notion-text notion-block-4010e3562fd6809ebc76fb3388d57f41">主要能力包括：</div><ul class="notion-list notion-list-disc notion-block-4010e3562fd68018b231ef348e256005"><li>按需 GPU 与多节点训练；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680b3b77ac3f7f676fc83"><li>GPU、网络健康检查和故障资源管理；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6808595bbf99dc903ae7c"><li>自带代码、容器与 Ray 工作负载；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd68095a71bd67ec7e5a84f"><li>训练数据流式加载与缓存；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680859c71e7cdceed0c61"><li>Unity Catalog 权限、隔离与审计。</li></ul><div class="notion-text notion-block-4010e3562fd680739e71c09aec9c2913">这里的变化不只是“平台可以调用模型”，而是训练执行与数据访问治理进一步整合。公告中的启动延迟、训练规模和客户加速数据均来自厂商披露，不能据此直接判断自身任务的性能或成本。</div><div class="notion-text notion-block-4010e3562fd68050b354da4277bbab36"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd680c1b91de35e815fed47"><li><a class="notion-link" href="https://www.databricks.com/blog/ai-runtime-generally-available" target="_blank" rel="noopener noreferrer">AI Runtime GA 公告</a></li></ul><div class="notion-text notion-block-4010e3562fd680fea3bdcc0477429b8c"><b>编辑评价：Lakehouse 正在承接更多训练基础设施职责。</b> 对已有独立 GPU 平台的团队，评估重点应是数据路径、权限边界、可观测性和故障处理，而不是只比较入口便利性。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd68084aad3d32d3ab20445" data-id="4010e3562fd68084aad3d32d3ab20445"><span><div id="4010e3562fd68084aad3d32d3ab20445" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68084aad3d32d3ab20445" title="10. ClickHouse 公布 NVIDIA Vera CPU 扩展性实测"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. ClickHouse 公布 NVIDIA Vera CPU 扩展性实测</span></span></h4><div class="notion-text notion-block-4010e3562fd680e0aa04e5563c172bb3">ClickHouse 使用未针对 Vera 定制的标准二进制，在早期访问服务器上测试 ClickBench，以及过滤、聚合和 Join 三组微基准。</div><div class="notion-text notion-block-4010e3562fd680eb88d1f1c4e3786257">测试机器为双路、176 个物理核心、352 个硬件线程。文中的计算密集型过滤和聚合测试，在 176 个线程时约达到单线程的 163 倍；继续增加 SMT 线程后，收益和并行效率下降。</div><div class="notion-text notion-block-4010e3562fd68070beddd11b31796aaf">重要边界是：部分微基准有意增加计算强度，以避免先受内存带宽限制。因此不能把接近线性扩展的曲线推广到所有分析查询，也不能替代实际成本比较。</div><div class="notion-text notion-block-4010e3562fd6801bad8cdebf1559d20d"><b>原文：</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd6800c9024dcf99a1769bf"><li><a class="notion-link" href="https://clickhouse.com/blog/clickhouse-performance-on-nvidia-vera" target="_blank" rel="noopener noreferrer">ClickHouse on NVIDIA Vera</a></li></ul><div class="notion-text notion-block-4010e3562fd680dbab25ed31fbb062f1"><b>编辑评价：更值得关注的是“什么先成为瓶颈”，而不是跑分排名。</b> CPU 核心数、内存带宽、算子类型与 SMT 收益需要放在一起看。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-4010e3562fd68018a9cadb5ca6056c3e" data-id="4010e3562fd68018a9cadb5ca6056c3e"><span><div id="4010e3562fd68018a9cadb5ca6056c3e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68018a9cadb5ca6056c3e" title="本周主要趋势"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">本周主要趋势</span></span></h3><div class="notion-text notion-block-4010e3562fd68094affff23f9d94b1aa">以下为基于本期材料的编辑归纳，不是独立测量结论。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd6805b9d10c0ffdb1f3808" data-id="4010e3562fd6805b9d10c0ffdb1f3808"><span><div id="4010e3562fd6805b9d10c0ffdb1f3808" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6805b9d10c0ffdb1f3808" title="1. 正确性与恢复语义，比“支持某项功能”更重要"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 正确性与恢复语义，比“支持某项功能”更重要</span></span></h4><div class="notion-text notion-block-4010e3562fd680bcab28dd58845e8f01">Kafka 的保留策略修复、pgBackRest 的恢复校验，以及 Fluss 的副作用恢复实验，都指向同一个问题：<b>一旦故障发生，系统到底能保证什么？</b></div><ul class="notion-list notion-list-disc notion-block-4010e3562fd68031b487dd43cb8d1ffb"><li>本地与远端同时存在，不代表保留策略一定安全；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680569eeefb73d3d0e4ea"><li>备份流程完成，不代表恢复出的页面一定正确；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd680e580e2d98d79d5b3a2"><li>日志记录了意图，不代表外部服务尚未完成动作；</li></ul><ul class="notion-list notion-list-disc notion-block-4010e3562fd6803c8363f23c3e02e5da"><li>API 返回成功，不代表 Broker 已确认，更不代表下游收到正确内容。</li></ul><div class="notion-text notion-block-4010e3562fd6801d8143efa3e06daff7">对应阅读：热点 1、4、5、6 的官方原文。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd68069b674edd241273ede" data-id="4010e3562fd68069b674edd241273ede"><span><div id="4010e3562fd68069b674edd241273ede" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68069b674edd241273ede" title="2. 数据系统的效率优化，越来越依赖元数据和状态复用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 数据系统的效率优化，越来越依赖元数据和状态复用</span></span></h4><div class="notion-text notion-block-4010e3562fd68058b499ee1267dc88f6">DuckLake 将更多文件信息放进 Catalog；dbt State 复用历史运行状态；OpenReplay 用生命周期策略减少维护工作；LinkedIn 则消除批次内重复上下文。</div><div class="notion-text notion-block-4010e3562fd680dbb9f3fd1dc1ff4973">这些案例的共同启发是：在增加机器之前，先检查能否避免重复计算、重复读取、重复传输和重复运维。</div><div class="notion-text notion-block-4010e3562fd6806ca30be6afa13fac53">对应阅读：热点 3、5、7、8 的官方原文。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd6808eb7eafddb43c0f39e" data-id="4010e3562fd6808eb7eafddb43c0f39e"><span><div id="4010e3562fd6808eb7eafddb43c0f39e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6808eb7eafddb43c0f39e" title="3. 数据平台与 AI 执行平台继续融合，但治理边界不能被省略"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 数据平台与 AI 执行平台继续融合，但治理边界不能被省略</span></span></h4><div class="notion-text notion-block-4010e3562fd6809e956ac6f12435627a">DuckDB 把 Agent 视为需要专门输出协议的客户端；Databricks AIR 把 GPU 训练纳入数据平台治理；观察名单中的 Agent Memory 则将持久记忆落在数据库服务上。</div><div class="notion-text notion-block-4010e3562fd6801b89e8dbad33dca229">从这些材料看，平台整合的价值正在从“提供模型接口”转向数据访问、状态保存、训练执行与可审计性。是否更适合生产，仍需逐项检查可用阶段和故障边界。</div><div class="notion-text notion-block-4010e3562fd680569b8ac0930b94bc86">对应阅读：热点 2、9，以及下文 Agent Memory 公告。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-4010e3562fd6805e955dd1b677510805" data-id="4010e3562fd6805e955dd1b677510805"><span><div id="4010e3562fd6805e955dd1b677510805" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd6805e955dd1b677510805" title="未进入前十但值得观察"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">未进入前十但值得观察</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680099902e365307ffb9d" data-id="4010e3562fd680099902e365307ffb9d"><span><div id="4010e3562fd680099902e365307ffb9d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680099902e365307ffb9d" title="PostgreSQL 部分操作系统版本仓库迁入归档"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PostgreSQL 部分操作系统版本仓库迁入归档</span></span></h4><div class="notion-text notion-block-4010e3562fd6804cbf13f30dceb00bd7">PGDG 将 RHEL 10.0／9.6（含对应 Rocky Linux、AlmaLinux）及 SLES 15.6 的仓库移入归档，归档仓库不再获得后续更新；滚动 EL-10、EL-9 仓库 RPM 不受前一项调整影响。</div><div class="notion-text notion-block-4010e3562fd680c98a9bc68077386158">仍依赖这些固定版本源的团队应核对升级计划；不能把“还能从归档安装”当作“仍在持续更新”。</div><div class="notion-text notion-block-4010e3562fd68088bfe2d005fbae9c37">原文：<a class="notion-link" href="https://www.postgresql.org/about/news/rhel-100-and-96-repositories-are-being-retired-3411/" target="_blank" rel="noopener noreferrer">RHEL 公告</a>、<a class="notion-link" href="https://www.postgresql.org/about/news/sles-156-repositories-are-being-retired-3415/" target="_blank" rel="noopener noreferrer">SLES 公告</a>。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd68077b5cae707cee5f722" data-id="4010e3562fd68077b5cae707cee5f722"><span><div id="4010e3562fd68077b5cae707cee5f722" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd68077b5cae707cee5f722" title="Unity Catalog 的 Catalog 间迁移接口仍处于 Private Preview"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Unity Catalog 的 Catalog 间迁移接口仍处于 Private Preview</span></span></h4><div class="notion-text notion-block-4010e3562fd680c6a309db76f8eeea0a">Databricks 介绍基于 Iceberg REST Catalog 的 <code class="notion-inline-code">REGISTER</code>／<code class="notion-inline-code">UNREGISTER</code>，用于不复制底层数据的表注册迁移。<b>相关接口仍是 Private Preview</b>，而原地转为 Managed Table 的后续能力仍在路线图中，不能写成已经全面可用。</div><div class="notion-text notion-block-4010e3562fd68048ac0fffc7fcf36930">原文：<a class="notion-link" href="https://www.databricks.com/blog/what-makes-catalog-open-unity-catalog-advances-open-lakehouse" target="_blank" rel="noopener noreferrer">Unity Catalog 与开放 Catalog</a>。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680efbcbee02ab7504f74" data-id="4010e3562fd680efbcbee02ab7504f74"><span><div id="4010e3562fd680efbcbee02ab7504f74" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680efbcbee02ab7504f74" title="Databricks Agent Memory 进入 Beta"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Databricks Agent Memory 进入 Beta</span></span></h4><div class="notion-text notion-block-4010e3562fd68002adc1c83e3cf749d8">Agent Memory 基于 Lakebase，结合自动上下文加载、按需工具和离线记忆整理。它值得作为数据库承接 Agent 持久状态的方向观察，但仍处于 Beta；公告中的成功率和 Token 收益来自内部评测。</div><div class="notion-text notion-block-4010e3562fd6808a9cbdd933dca74819">原文：<a class="notion-link" href="https://www.databricks.com/blog/introducing-agent-memory-databricks" target="_blank" rel="noopener noreferrer">Agent Memory 公告</a>。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680c7b0fcccf76612ad78" data-id="4010e3562fd680c7b0fcccf76612ad78"><span><div id="4010e3562fd680c7b0fcccf76612ad78" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680c7b0fcccf76612ad78" title="TiDB Cloud BYOC 进入 Public Preview"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">TiDB Cloud BYOC 进入 Public Preview</span></span></h4><div class="notion-text notion-block-4010e3562fd68039b07dfec20e3587ae">数据平面运行在客户 AWS 账号中，由 TiDB Cloud 执行经授权的生命周期管理。其价值在数据驻留和托管运维的结合，但仍是 Public Preview，区域可用性也受实例与可用区条件约束。</div><div class="notion-text notion-block-4010e3562fd680838202e3cae6f345c3">原文：<a class="notion-link" href="https://www.pingcap.com/blog/tidb-cloud-byoc-public-preview/" target="_blank" rel="noopener noreferrer">TiDB Cloud BYOC 公告</a>。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-4010e3562fd680d1980fc0351a2cc787" data-id="4010e3562fd680d1980fc0351a2cc787"><span><div id="4010e3562fd680d1980fc0351a2cc787" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4010e3562fd680d1980fc0351a2cc787" title="Lance 14.0.0 RC 与 LanceDB 0.41 Beta"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Lance 14.0.0 RC 与 LanceDB 0.41 Beta</span></span></h4><div class="notion-text notion-block-4010e3562fd680649fc2d9f36f3c2c83">本周候选包含多次 Beta／RC 更新，统一作为一个观察主题，不逐个版本占用热点名额。Lance 14.0.0-rc.1 明确标为 Pre-release，涉及编码、索引与 MemWAL 等变化，不能写成 14.0 已正式发布。</div><div class="notion-text notion-block-4010e3562fd6805eb07ae394f082ba44">原文：<a class="notion-link" href="https://github.com/lance-format/lance/releases/tag/v14.0.0-rc.1" target="_blank" rel="noopener noreferrer">Lance 14.0.0-rc.1</a>、<a class="notion-link" href="https://github.com/lancedb/lancedb/releases" target="_blank" rel="noopener noreferrer">LanceDB Releases</a>。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3e10e3562fd680c0a75fd93062ccab25" data-id="3e10e3562fd680c0a75fd93062ccab25"><span><div id="3e10e3562fd680c0a75fd93062ccab25" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3e10e3562fd680c0a75fd93062ccab25" title="2026/10/09～2026/10/15"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2026/10/09～2026/10/15</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3fa0e3562fd680fdafbcf801eb2309b9" data-id="3fa0e3562fd680fdafbcf801eb2309b9"><span><div id="3fa0e3562fd680fdafbcf801eb2309b9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680fdafbcf801eb2309b9" title="本周十大热点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">本周十大热点</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680719dcdf2b7b4000cd4" data-id="3fa0e3562fd680719dcdf2b7b4000cd4"><span><div id="3fa0e3562fd680719dcdf2b7b4000cd4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680719dcdf2b7b4000cd4" title="1. PostgreSQL 生态集中发布安全修复"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. PostgreSQL 生态集中发布安全修复</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680c4a0dbcdc36a0c17cc">本周 PostgreSQL 生态连续出现三组安全更新。</div><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3fa0e3562fd680119cd9df8523ef417e" data-id="3fa0e3562fd680119cd9df8523ef417e"><span><div id="3fa0e3562fd680119cd9df8523ef417e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680119cd9df8523ef417e" title="PgBouncer 1.26.1"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PgBouncer 1.26.1</span></span></h5><div class="notion-text notion-block-3fa0e3562fd6802a92ecf3b23c264b37">修复三个 CVE：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68015bc7ff66930b6fee7"><li><code class="notion-inline-code">CVE-2026-107350</code>：SCRAM 身份验证绕过。知道一个用户密码的客户端可能冒充其他用户，包括管理员和后端超级用户；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b6aae3d3e3e79c1b9c"><li><code class="notion-inline-code">CVE-2026-107349</code>：未经身份验证的客户端可以触发无限循环，导致拒绝服务；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b7bf63d558794e54d4"><li><code class="notion-inline-code">CVE-2026-107348</code>：特定 <code class="notion-inline-code">max_packet_size</code> 配置下的整数溢出可能触发无限循环和拒绝服务。</li></ul><div class="notion-text notion-block-3fa0e3562fd680b391eaf8604863a621">原文：</div><div class="notion-text notion-block-3fa0e3562fd680de83b4ca21abebbec2"><a class="notion-link" href="https://www.postgresql.org/about/news/pgbouncer-1261-released-fixes-three-cves-3403/" target="_blank" rel="noopener noreferrer">https://www.postgresql.org/about/news/pgbouncer-1261-released-fixes-three-cves-3403/</a></div><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3fa0e3562fd6805db0dac46db5bdf3c4" data-id="3fa0e3562fd6805db0dac46db5bdf3c4"><span><div id="3fa0e3562fd6805db0dac46db5bdf3c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6805db0dac46db5bdf3c4" title="psqlODBC 18.00.0005"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">psqlODBC 18.00.0005</span></span></h5><div class="notion-text notion-block-3fa0e3562fd680c28b57db0a9acf57d0">修复 <code class="notion-inline-code">CVE-2026-109448</code>。旧版本使用有符号 16 位字段保存绑定参数数量，当应用绑定超过
32767 个参数时可能发生堆内存越界写入，造成崩溃或内存损坏。</div><div class="notion-text notion-block-3fa0e3562fd680598e37ceb9dec77314">原文：</div><div class="notion-text notion-block-3fa0e3562fd6802fa308e5570e7412a3"><a class="notion-link" href="https://www.postgresql.org/about/news/psqlodbc-18000005-released-with-security-fix-for-cve-2026-109448-3404/" target="_blank" rel="noopener noreferrer">https://www.postgresql.org/about/news/psqlodbc-18000005-released-with-security-fix-for-cve-2026-109448-3404/</a></div><h5 class="notion-h notion-h4 notion-h-indent-3 notion-block-3fa0e3562fd68048a043e1271c14edd9" data-id="3fa0e3562fd68048a043e1271c14edd9"><span><div id="3fa0e3562fd68048a043e1271c14edd9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd68048a043e1271c14edd9" title="PostgreSQL JDBC 42.7.14"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PostgreSQL JDBC 42.7.14</span></span></h5><div class="notion-text notion-block-3fa0e3562fd680a3a3fed3c6331dca75">修复两个 CVE：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680208d8eec678390e166"><li><code class="notion-inline-code">CVE-2026-107314</code></li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680c49d27e8b8b624728a"><li><code class="notion-inline-code">CVE-2026-107315</code></li></ul><div class="notion-text notion-block-3fa0e3562fd680218937d808221432c0">原文：</div><div class="notion-text notion-block-3fa0e3562fd680e0a3a8f25b36964669"><a class="notion-link" href="https://www.postgresql.org/about/news/2026-10-07-postgresql-jdbc-42714-security-update-for-multiple-cves-3399/" target="_blank" rel="noopener noreferrer">https://www.postgresql.org/about/news/2026-10-07-postgresql-jdbc-42714-security-update-for-multiple-cves-3399/</a></div><div class="notion-text notion-block-3fa0e3562fd680fea567fa2f62ed2fed"><b>编辑评价：本周运维优先级最高。</b> 使用 PgBouncer、PostgreSQL ODBC/JDBC
驱动的团队应优先核对部署版本和升级窗口。</div><hr class="notion-hr notion-block-3fa0e3562fd6800ca923eb783e0e07f6"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680588b2df0692f0bea13" data-id="3fa0e3562fd680588b2df0692f0bea13"><span><div id="3fa0e3562fd680588b2df0692f0bea13" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680588b2df0692f0bea13" title="2. Apache Paimon 2.1.0 正式发布"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. Apache Paimon 2.1.0 正式发布</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68000bc23e76f354d82f3">Apache Paimon 发布 2.1.0，更新横跨核心格式、索引、并发写入、Flink、Spark、
Python 和对象存储。</div><div class="notion-text notion-block-3fa0e3562fd6806897a9ffbed618d18a">值得关注的变化包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680eda243ff82b6ccc73e"><li>DV 表支持向量索引；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68002a5c4f8cc773ef90d"><li>DV 表支持全文索引；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680308d48f1673f61d001"><li>BTree 全局索引支持 TopN 下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6801f9811fc7dcc669e00"><li>增加并发 <code class="notion-inline-code">MERGE INTO</code> 与 Compaction 冲突检测；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680c7b447e60c9e3b26bc"><li>改进 Parquet 谓词下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680deb5c7c4cde87d77c9"><li>支持 ORC Time 类型谓词下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680359a6ee1a2cdb90737"><li>改进数据演进场景中的索引和统计信息；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6805c8786fe3d45dbdb5a"><li>扩展 Python/Rust 原生扫描规划；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680be8430e103ba7bdb90"><li>增强 Flink、Spark、Hive 和对象存储支持；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680aead2cfa9aa0c45e37"><li>修复 Chain Table DV 行可能静默丢失数据的问题。</li></ul><div class="notion-text notion-block-3fa0e3562fd680238e92f4a4769b204b">原文：</div><div class="notion-text notion-block-3fa0e3562fd6809a9684c84b2ff0985d"><a class="notion-link" href="https://github.com/apache/paimon/releases/tag/release-2.1.0" target="_blank" rel="noopener noreferrer">https://github.com/apache/paimon/releases/tag/release-2.1.0</a></div><div class="notion-text notion-block-3fa0e3562fd6808a9221df923499694f"><b>编辑评价：本周 Lakehouse 方向最重要的开源版本之一。</b> 这不是普通补丁版本，
而是索引、并发写入、Python 和查询下推能力的集中增强。</div><hr class="notion-hr notion-block-3fa0e3562fd680338e41fc13213babb5"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680f295d4c5d02b1056c4" data-id="3fa0e3562fd680f295d4c5d02b1056c4"><span><div id="3fa0e3562fd680f295d4c5d02b1056c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680f295d4c5d02b1056c4" title="3. Apache Flink CDC 3.7.0 发布"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. Apache Flink CDC 3.7.0 发布</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680309dc0ff5c8f55960b">Flink CDC 3.7.0 从单纯的 CDC 工具继续向流式数据转换平台发展。</div><div class="notion-text notion-block-3fa0e3562fd680378a3deb3ab4455d57">主要变化包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6805fb429c21665d67648"><li>增加可插拔模型 API；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680be9d5dc683d45d0569"><li>增加 OpenAI 兼容模型客户端；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680fa8bd3e02ce1b903da"><li>内置文本生成、分类、翻译、摘要、情感分析、信息提取、脱敏、Embedding
和图像理解函数；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806e8abcec3a0b5b4b10"><li>Pipeline YAML 支持内联 Python UDF；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680c0a669f3328de036f5"><li>增加有序异步执行，在保留数据和 Schema 事件顺序的同时改善 I/O 密集转换吞吐；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680269372d04b0658b47e"><li>新增 SQL Server Pipeline Source；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68034b7afd74b32b7b7bf"><li>新增 Apache Fluss Pipeline Source；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6801bb5a3fa1ce1258c2a"><li>Fluss Source 支持主键表、日志表、快照读取和日志读取；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680bc8cc1e34d594cf6e4"><li>改进 Paimon、Fluss Sink 的现有表 Schema 检查和自动扩展；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808ab48ff12daf36945e"><li>扩展 YAML Transform 表达式、日期、字符串、集合和空值处理能力。</li></ul><div class="notion-text notion-block-3fa0e3562fd680cd922dc8baed33bbfd">原文：</div><div class="notion-text notion-block-3fa0e3562fd6803084e1ff59d8643386"><a class="notion-link" href="https://flink.apache.org/2026/10/10/apache-flink-cdc-3.7.0-release-announcement/" target="_blank" rel="noopener noreferrer">https://flink.apache.org/2026/10/10/apache-flink-cdc-3.7.0-release-announcement/</a></div><div class="notion-text notion-block-3fa0e3562fd680a2ae20d1678cb6b4f2"><b>编辑评价：Flink CDC 正进一步打通 Fluss、Paimon、Hudi、Iceberg 和 Kafka
等实时湖仓组件，同时将模型调用引入流式转换。</b></div><hr class="notion-hr notion-block-3fa0e3562fd680e8a173da40aae86b6a"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd6803eac1fd63fdf4d8514" data-id="3fa0e3562fd6803eac1fd63fdf4d8514"><span><div id="3fa0e3562fd6803eac1fd63fdf4d8514" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6803eac1fd63fdf4d8514" title="4. Amazon Redshift 自动解决部分 Iceberg 并发写冲突"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. Amazon Redshift 自动解决部分 Iceberg 并发写冲突</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68056825beb8a33673d9f">Amazon Redshift 开始自动解决实际不重叠的 Apache Iceberg 并发写入，而不是让所有
竞争提交失败并整体重试。</div><div class="notion-text notion-block-3fa0e3562fd680b8a873cec19e7faab7">新的检查过程会逐步判断：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fa0e3562fd680bf99e2d2a3b9100b0b" style="list-style-type:decimal"><li>两个操作的类型是否可能冲突；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fa0e3562fd68021911aec971475775c" style="list-style-type:decimal"><li>是否修改相同分区；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fa0e3562fd68012b122ce9d922abd6e" style="list-style-type:decimal"><li>是否修改相同数据文件。</li></ol><div class="notion-text notion-block-3fa0e3562fd68032824fd01e3f901ba8">AWS 给出的追加写测试中：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6807daae4c12938af82ed"><li>基础乐观并发模式在 16 个并发写入者时，吞吐下降到单写入者的约 0.17 倍；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680ada7fdfafde405fe57"><li>开启自动冲突解决后，同一测试约达到单写入者吞吐的 2 倍；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68015ab8ff5373ca98341"><li>同一时间窗口完成的提交数量提高约 12 倍；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68069aee4d9f56c0e0ded"><li>测试中的追加写没有再被冲突拒绝。</li></ul><div class="notion-text notion-block-3fa0e3562fd680798372ee07a071dfb3">需要注意，这组测试主要针对互不重叠的追加写。修改相同分区或相同文件时，仍需要更细
粒度的冲突检查。</div><div class="notion-text notion-block-3fa0e3562fd680b78b94d60fd743c88f">原文：</div><div class="notion-text notion-block-3fa0e3562fd680e29eeec5b56bf4a848"><a class="notion-link" href="https://aws.amazon.com/blogs/big-data/resolving-concurrent-write-conflicts-for-apache-iceberg-tables-in-amazon-redshift/" target="_blank" rel="noopener noreferrer">https://aws.amazon.com/blogs/big-data/resolving-concurrent-write-conflicts-for-apache-iceberg-tables-in-amazon-redshift/</a></div><div class="notion-text notion-block-3fa0e3562fd68089a9ead2ce7170e77a"><b>编辑评价：这标志着 Iceberg 的关注重点从“支持事务写入”进一步转向多写入者生产环境
中的吞吐、冲突解决和可观测性。</b></div><hr class="notion-hr notion-block-3fa0e3562fd6805e8fefd05c47959496"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680798a7edcb38555aeae" data-id="3fa0e3562fd680798a7edcb38555aeae"><span><div id="3fa0e3562fd680798a7edcb38555aeae" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680798a7edcb38555aeae" title="5. LinkedIn 公布 Apache Celeborn 大规模生产实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. LinkedIn 公布 Apache Celeborn 大规模生产实践</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68005a981ce789c7d2330">LinkedIn 已经在大多数 Spark 和 Flink 工作负载中部署 Apache Celeborn 远程 Shuffle
服务。</div><div class="notion-text notion-block-3fa0e3562fd680e48ef1e84fd7413846">架构和运营改造包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680988da0cdf75db1b03b"><li>五节点 Raft Master，跨故障域部署；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806c9760f7552d46d4de"><li>基于网络拓扑和故障域的副本放置；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680a7b051d840594b4ca6"><li>对维护状态感知的 Slot 分配；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6807eaf65e4d46e2492e3"><li>使用 NVMe SSD 替代旋转磁盘；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680f0a8c4d68770fbbcf6"><li>针对高并发场景优化 Slot 选择、文件 Flush、GC 和堆外内存；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680168f3fe235fcbb7e0e"><li>增加 RPC/HTTP 身份验证、授权、TLS 和静态加密；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680929356e90268977b6b"><li>增加生产 CLI、Dashboard、SLO 和原生 IPv6；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68019ae6ade530d24e72a"><li>通过 Kubernetes StatefulSet 和持久卷运行 Worker。</li></ul><div class="notion-text notion-block-3fa0e3562fd6802c8261fb6e499cdeff">公开结果包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b8b652c48075fc439f"><li>Shuffle Fleet 所需规模减少约 35%；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808eabcaf4e91314763b"><li>Slot 选择性能提升约 6 倍；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6803795cccc46ceb6723b"><li>Flink 大规模历史回填达到每小时数亿事件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680f59445de0d831239fd"><li>原本持续多天的回填在数小时内完成；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68042b2f1d1746e409b60"><li>支撑数千个 Pipeline 实例；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6802b8beefaafcc8c6030"><li>逐步取消 Spark 历史处理和 Flink 近实时处理两套重复实现。</li></ul><div class="notion-text notion-block-3fa0e3562fd68028b506c1eaef996f30">原文：</div><div class="notion-text notion-block-3fa0e3562fd680bbb626cf99e4ac5fff"><a class="notion-link" href="https://www.linkedin.com/blog/engineering/infrastructure/scaling-spark-and-flink-shuffle-at-linkedin-with-apache-celeborn" target="_blank" rel="noopener noreferrer">https://www.linkedin.com/blog/engineering/infrastructure/scaling-spark-and-flink-shuffle-at-linkedin-with-apache-celeborn</a></div><div class="notion-text notion-block-3fa0e3562fd680c884fcd2189147f92f"><b>编辑评价：这是本周信息密度最高的生产工程文章之一，覆盖架构、可靠性、资源效率、
安全、运维和开源回馈，不是普通客户案例。</b></div><hr class="notion-hr notion-block-3fa0e3562fd680169b1fc4dbd2f2995c"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680c4a9a0f2ea561bcd3e" data-id="3fa0e3562fd680c4a9a0f2ea561bcd3e"><span><div id="3fa0e3562fd680c4a9a0f2ea561bcd3e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680c4a9a0f2ea561bcd3e" title="6. AWS 将数据质量检查原生集成到 EMR Spark"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. AWS 将数据质量检查原生集成到 EMR Spark</span></span></h4><div class="notion-text notion-block-3fa0e3562fd6802ca432e1deda7769ce">Amazon EMR Data Quality 现在直接集成在 <code class="notion-inline-code">emr-spark-8.1.0</code> 及后续版本中。</div><div class="notion-text notion-block-3fa0e3562fd68036aed4f63e136a5254">主要能力包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6804991eac3bd7200e087"><li>支持 EMR on EC2、EMR on EKS 和 EMR Serverless；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680829ee4c13a9c7ca070"><li>在 Spark Job 内直接执行 DQDL 数据质量规则；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680d3a8bbcf388c7c126d"><li>规则可以直接写在 Job 中，也可以存储在 Glue Data Catalog；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680a68997e8d33e79b550"><li>支持完整性、唯一性、值域、引用完整性和统计分布检查；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680378959f2679c14df00"><li>支持基于历史运行结果的异常检测；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808abaa3e7a647ea7150"><li>评估结果可以停止 Pipeline、隔离错误记录、发送告警或控制后续写入；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680fb871cf3960b7e3fed"><li>可以与 Apache Iceberg Write-Audit-Publish 结合；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680639c3bef59db150eac"><li>适用于 Iceberg、Hudi 和 Delta Lake。</li></ul><div class="notion-text notion-block-3fa0e3562fd680f5a7dcc41dd95c0afe">原文：</div><div class="notion-text notion-block-3fa0e3562fd680be897ce1155fb1b968"><a class="notion-link" href="https://aws.amazon.com/blogs/big-data/bring-data-quality-to-your-amazon-emr-workloads-with-amazon-emr-data-quality-built-on-aws-glue-data-quality/" target="_blank" rel="noopener noreferrer">https://aws.amazon.com/blogs/big-data/bring-data-quality-to-your-amazon-emr-workloads-with-amazon-emr-data-quality-built-on-aws-glue-data-quality/</a></div><div class="notion-text notion-block-3fa0e3562fd680778104cddc9d35f136"><b>编辑评价：数据质量正在从独立外围任务进入数据处理运行时，适合生产级 Lakehouse
管道和集中治理场景。</b></div><hr class="notion-hr notion-block-3fa0e3562fd680a1bb1bf4c25b241c06"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd6804782fed82416e7798b" data-id="3fa0e3562fd6804782fed82416e7798b"><span><div id="3fa0e3562fd6804782fed82416e7798b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6804782fed82416e7798b" title="7. Databricks 发布 Lakebase Search 实际容量测试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. Databricks 发布 Lakebase Search 实际容量测试</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680c2a184d33936f62342">Databricks 使用真实内部应用和最多 400 万条 MIRACL Passage 测试 Lakebase Postgres
中的 BM25 与向量混合检索。</div><div class="notion-text notion-block-3fa0e3562fd68076bbabc86eda10e6ec">关键结果包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6802d9eb2ce82c1d0233f"><li>Lakebase Search 将向量检索和 BM25 作为 Postgres 扩展运行；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68063b940c88f15738954"><li>当 Local File Cache 大小接近向量索引时，缓存命中率约为 95%～98%；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680a88463fbcbfa30caa4"><li>候选数量从 1000 降到 200，仍保留 90.5% 的 Top-10 结果；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68072bcf6f4433b9a38de"><li>200 个候选读取的页面约为 1000 个候选的三分之一；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6800e8e27cf0c6ff5ac55"><li>400 万条数据的向量索引约为 23 GB；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680929660d6b60e7ef1ee"><li>400 万行通过 Binary COPY 在 8 CU 下用约 19 分钟载入；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680408ed2f0b5d96687a6"><li>文中给出了连接池、冷启动、CU、并发和缓存比例的容量规划数据。</li></ul><div class="notion-text notion-block-3fa0e3562fd680689e67cd2f3eb27686">原文：</div><div class="notion-text notion-block-3fa0e3562fd6807391c6ccd1a41d734a"><a class="notion-link" href="https://www.databricks.com/blog/sizing-lakebase-search-lessons-real-app-and-4-million-passages" target="_blank" rel="noopener noreferrer">https://www.databricks.com/blog/sizing-lakebase-search-lessons-real-app-and-4-million-passages</a></div><div class="notion-text notion-block-3fa0e3562fd68095962dd0b29383f441"><b>编辑评价：该文章比普通产品发布更有价值，因为它给出了容量规划方法、缓存比例和可复用
的性能数据。</b></div><hr class="notion-hr notion-block-3fa0e3562fd6806e8b98f350c9d13b8e"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd6807eaf2dd0de390a35b4" data-id="3fa0e3562fd6807eaf2dd0de390a35b4"><span><div id="3fa0e3562fd6807eaf2dd0de390a35b4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6807eaf2dd0de390a35b4" title="8. dbt 增加 Amazon Redshift Data Sharing 支持"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. dbt 增加 Amazon Redshift Data Sharing 支持</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68098a3c1c1139b116d29">dbt-redshift 现在支持 Redshift Data Sharing 的读写场景。</div><div class="notion-text notion-block-3fa0e3562fd6807a962af13d987b187d">新的能力包括：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68053919eddd1a3b5eac0"><li>跨 Redshift 数据仓库和数据库物化模型；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680a1bccdec8d656a383b"><li>使用共享数据而不复制或移动数据；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680008a81f6227bfea236"><li>支持跨项目引用；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680e8a005eb2aac46025f"><li>支持将 CI 环境放在独立集群，同时读取生产共享数据；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680169aebd3c039edd8bc"><li>支持将 ETL 与 BI 查询隔离到不同集群；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680669129d876938cafd5"><li>将元数据查询从传统 PostgreSQL Catalog 迁移到 Redshift 原生 <code class="notion-inline-code">SVV_*</code>
System View 和 <code class="notion-inline-code">SHOW</code> API；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6807985a7efb47131a3e6"><li>改善大型项目和高并发环境下的元数据解析性能。</li></ul><div class="notion-text notion-block-3fa0e3562fd6800d8f64d64815c2bc66">已知限制：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680518c95dd34a16da1a2"><li>消费者侧的普通 View 不能直接引用 Datashare 对象；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680a2862de69f81b017d8"><li>第一层通常需要物化为 Table 或 Incremental Model；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680f39f93e05419cf91f8"><li>相关能力仍处于 dbt Platform Latest Release Track 的 Beta 阶段。</li></ul><div class="notion-text notion-block-3fa0e3562fd680ec9455ee81d79c0b0f">原文：</div><div class="notion-text notion-block-3fa0e3562fd680b9af15e5b8e8f177d8"><a class="notion-link" href="https://www.getdbt.com/blog/dbt-now-supports-amazon-redshift-data-sharing" target="_blank" rel="noopener noreferrer">https://www.getdbt.com/blog/dbt-now-supports-amazon-redshift-data-sharing</a></div><div class="notion-text notion-block-3fa0e3562fd68069a08afa1b9a971f04"><b>编辑评价：对使用 Redshift、dbt Mesh、隔离 CI 和多团队数据架构的组织具有直接价值。</b></div><hr class="notion-hr notion-block-3fa0e3562fd680fd8c6cdd20798a99f1"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd68038942cc9cceff6228b" data-id="3fa0e3562fd68038942cc9cceff6228b"><span><div id="3fa0e3562fd68038942cc9cceff6228b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd68038942cc9cceff6228b" title="9. ClickHouse 定位并修复额外 32ms 尾延迟"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. ClickHouse 定位并修复额外 32ms 尾延迟</span></span></h4><div class="notion-text notion-block-3fa0e3562fd6806d8089d1f1178933bf">ClickHouse 客户发现，客户端与服务器之间约有 32ms RTT 时，空闲连接上的下一条简单
查询会从约 32ms 增加到约 64ms。</div><div class="notion-text notion-block-3fa0e3562fd680df8bf3ed5dde6a7103">根因是：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680dfbccff0e348882d95"><li>Native Protocol 在数据包和 <code class="notion-inline-code">EndOfStream</code> 之间发送多种 Metadata Packet；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808ba3a1c08fdd3b266e"><li>连接空闲后，TCP 拥塞窗口重新缩小；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680e28a36edde71afc442"><li>多个未批量发送的小包超出初始拥塞窗口；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6802d8653feef101f5a81"><li>服务器必须等待客户端 ACK，增加一个完整 RTT。</li></ul><div class="notion-text notion-block-3fa0e3562fd6803c95cafafcf12d7852">修复方案是在应用层批量发送查询结束阶段的 Metadata Packet：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68079bd3bf39bd2035fda"><li>TCP PUSH 包从约 50 个下降到约 25 个；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6807b90d7e2f7e446965c"><li>额外约 32ms 尾延迟下降到约 1ms；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680bcaf27d5c640a31991"><li>不需要通过关闭 ProfileEvents 或修改系统 TCP 参数规避问题。</li></ul><div class="notion-text notion-block-3fa0e3562fd6808fb7c4e9d682a86d57">原文：</div><div class="notion-text notion-block-3fa0e3562fd6802f9ebdeb49165769a9"><a class="notion-link" href="https://clickhouse.com/blog/chasing-32ms-tail-latency-clickhouse" target="_blank" rel="noopener noreferrer">https://clickhouse.com/blog/chasing-32ms-tail-latency-clickhouse</a></div><div class="notion-text notion-block-3fa0e3562fd6807092b8f2f21c4382cb"><b>编辑评价：这是典型的高质量数据库工程复盘，结论可以迁移到其他自定义 TCP 协议和
低延迟服务。</b></div><hr class="notion-hr notion-block-3fa0e3562fd680e08dd7c2bc86f55762"/><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd68059b3daed806f6a101c" data-id="3fa0e3562fd68059b3daed806f6a101c"><span><div id="3fa0e3562fd68059b3daed806f6a101c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd68059b3daed806f6a101c" title="10. DuckDB CLI 增加 Agent Mode"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. DuckDB CLI 增加 Agent Mode</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68052ae8fec72993d03b4">DuckDB CLI 的 Agent Mode 针对 Coding Agent 优化输出格式，减少终端输出对模型造成的
误导和 Token 消耗。</div><div class="notion-text notion-block-3fa0e3562fd680919335ee99c389eaaa">DuckDB 官方实验使用 Claude Code 回答 22 个 TPC-H SF100 问题：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68052bf2de9dcb208df49"><li>每个问题分别使用 Agent Mode 和普通模式运行三次；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b18656ee7fbc7daed1"><li>总计 132 次运行；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680218f2de16b1e81e5e8"><li>所有结果均正确；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6801ebf2df644cc1cee03"><li>模型读取的 DuckDB 输出从 123.6k Token 降到 50.8k；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b0948de9782c132c35"><li>输出 Token 减少约 59%。</li></ul><div class="notion-text notion-block-3fa0e3562fd6803a9493fbaac2ed31cb">原文：</div><div class="notion-text notion-block-3fa0e3562fd68086ac31faca943b65c5"><a class="notion-link" href="https://duckdb.org/2026/10/09/agent-mode" target="_blank" rel="noopener noreferrer">https://duckdb.org/2026/10/09/agent-mode</a></div><div class="notion-text notion-block-3fa0e3562fd680e8b64cfdf132b8085b"><b>编辑评价：它不是数据库执行引擎的核心突破，但说明数据库 CLI 正开始将 Agent
视为一等客户端。</b></div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3fa0e3562fd68046b6a5c3228bce27ad" data-id="3fa0e3562fd68046b6a5c3228bce27ad"><span><div id="3fa0e3562fd68046b6a5c3228bce27ad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd68046b6a5c3228bce27ad" title="本周主要趋势"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">本周主要趋势</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680e0916cef1d2e2705a5" data-id="3fa0e3562fd680e0916cef1d2e2705a5"><span><div id="3fa0e3562fd680e0916cef1d2e2705a5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680e0916cef1d2e2705a5" title="1. Lakehouse 进入“可写、可索引、可治理”阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. Lakehouse 进入“可写、可索引、可治理”阶段</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680eca0e3e0f0fd8467ae">本周的多个重要事件围绕同一方向：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680809cd1e39dfde333d5"><li>Paimon 增强索引、并发写入和查询下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680aab610ed02a8136500"><li>Redshift 自动解决部分 Iceberg 并发写冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68045aac3dd6e132c9d3e"><li>EMR 将数据质量检查放进 Spark 运行时；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68045ae9ac89216e9a6d1"><li>ClickHouse 通过 Iceberg Connector 统一查询历史与实时数据；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808f9484e04d9b515325"><li>dbt 和 Redshift Data Sharing 减少跨数据仓库的数据复制。</li></ul><div class="notion-text notion-block-3fa0e3562fd680b987c8fe79ca7e7420">关注点正在从“能否读取开放表格式”转向：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd68014803df877d6273a2d"><li>多写入者并发；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680049604d0d1c950062d"><li>索引和谓词下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680f78afdf1e420cdd627"><li>数据质量；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680e1bcc6ea7339748b4c"><li>数据共享；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806886f5cd10378c4d14"><li>实时和历史数据统一查询。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680c69af6f830162f8158" data-id="3fa0e3562fd680c69af6f830162f8158"><span><div id="3fa0e3562fd680c69af6f830162f8158" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680c69af6f830162f8158" title="2. 实时计算与数据湖进一步融合"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 实时计算与数据湖进一步融合</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680b8ad90ea30c8ef385b">Flink CDC 3.7 新增 Fluss Source，并加强 Paimon、Fluss Sink；Databricks 继续推动
实时分析直接运行在统一的 Lakehouse 数据和治理体系上。</div><div class="notion-text notion-block-3fa0e3562fd680fd9ab3c10426e11af7">实时系统与 Lakehouse 的边界继续缩小，新的竞争点逐渐变成：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806086bfd365276be9f3"><li>数据进入查询状态的速度；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680e7a846f6a81f28a1a0"><li>是否需要复制到独立 Serving Layer；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6800fa136d28b3ef03a3f"><li>实时与批处理是否共享 Schema、权限和治理；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806c8424ffe98435ffb4"><li>写入、Compaction 和查询之间如何协同。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680ea8e5cf53ae75645d3" data-id="3fa0e3562fd680ea8e5cf53ae75645d3"><span><div id="3fa0e3562fd680ea8e5cf53ae75645d3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680ea8e5cf53ae75645d3" title="3. 数据基础设施开始面向 Agent 工作负载优化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 数据基础设施开始面向 Agent 工作负载优化</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68035ac6bfe9dbb6f3640">本周多个项目都出现 Agent 或 AI 数据工作负载相关变化：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680668d8ec4d4f53e6564"><li>DuckDB 为 Agent 优化 CLI 输出；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680b9a1dce7bb81aecd8d"><li>Lakebase 测试 BM25 和向量混合检索容量；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6802e9b12e9cabdf264d7"><li>Flink CDC 将模型调用和 Embedding 引入流式转换；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6808087a4dcec97751926"><li>Paimon DV 表增加向量和全文索引；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd680c6bdb5e5e8f051d1ba"><li>数据平台开始同时服务人类分析、应用和 Agent。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3fa0e3562fd6805d9771e595a83abd44" data-id="3fa0e3562fd6805d9771e595a83abd44"><span><div id="3fa0e3562fd6805d9771e595a83abd44" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6805d9771e595a83abd44" title="未进入前十但值得观察"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">未进入前十但值得观察</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680308ce5c2424c11906d" data-id="3fa0e3562fd680308ce5c2424c11906d"><span><div id="3fa0e3562fd680308ce5c2424c11906d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680308ce5c2424c11906d" title="ClickHouse 与 Redshift Serverless 的 CostBench 对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">ClickHouse 与 Redshift Serverless 的 CostBench 对比</span></span></h4><div class="notion-text notion-block-3fa0e3562fd68043a912ddeafcdc2723">ClickHouse 发布厂商 Benchmark，声称在持续写入 1132 亿条股票报价的测试中，
ClickHouse Cloud 相对 Redshift Serverless 获得约 1996 倍的端到端性能成本优势。</div><div class="notion-text notion-block-3fa0e3562fd68091a124dd1c57a569cc">原文：</div><div class="notion-text notion-block-3fa0e3562fd6809caa19ef11608abe48"><a class="notion-link" href="https://clickhouse.com/blog/clickhouse-vs-redshift-serverless-real-time-performance-per-dollar" target="_blank" rel="noopener noreferrer">https://clickhouse.com/blog/clickhouse-vs-redshift-serverless-real-time-performance-per-dollar</a></div><div class="notion-text notion-block-3fa0e3562fd6808b9616d87cd9475db6">该结果具有讨论价值，但测试由 ClickHouse 自己设计和发布，需要等待独立复现。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680caa936fa6a87e0376e" data-id="3fa0e3562fd680caa936fa6a87e0376e"><span><div id="3fa0e3562fd680caa936fa6a87e0376e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680caa936fa6a87e0376e" title="Lance 和 LanceDB beta 版本密集发布"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Lance 和 LanceDB beta 版本密集发布</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680269881d7ba23963e7c">时间窗口内，Lance 14.0 和 LanceDB 0.41 发布了多个 beta：</div><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6805dbdecdfbc441fb3a0"><li>Lance 增强编码、索引、Mem-WAL、DataFusion 和对象存储支持；</li></ul><ul class="notion-list notion-list-disc notion-block-3fa0e3562fd6806198a2c9eabea22353"><li>LanceDB 增加 JSON 字段全文索引、SQL 参数绑定及多项远程 API 改进。</li></ul><div class="notion-text notion-block-3fa0e3562fd680889919f0e1228fe69e">由于均为高频 beta，本期未将单个版本列入正式热点。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-3fa0e3562fd680b99f16ca8821b8c149" data-id="3fa0e3562fd680b99f16ca8821b8c149"><span><div id="3fa0e3562fd680b99f16ca8821b8c149" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd680b99f16ca8821b8c149" title="Apache Fluss"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Apache Fluss</span></span></h4><div class="notion-text notion-block-3fa0e3562fd680ff9b1af467841bab5b">本时间窗口内，Apache Fluss 没有发布新的独立官方文章，但通过 Flink CDC 3.7.0
新增的 Fluss Pipeline Source 和 Sink 改进进入了本周重要事件。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3fa0e3562fd6803b8549de3a60b674aa" data-id="3fa0e3562fd6803b8549de3a60b674aa"><span><div id="3fa0e3562fd6803b8549de3a60b674aa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fa0e3562fd6803b8549de3a60b674aa" title="信息源"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">信息源</span></span></h3><div class="notion-text notion-block-3fa0e3562fd68044b6ede9c30421578d">1. 数据库与 OLAP/列式存储</div><table class="notion-simple-table notion-block-3fa0e3562fd680b6ac39d978717bf145"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fa0e3562fd680a5a23ecf379de410dc"><td class="" style="width:120px"><div class="notion-simple-table-cell">信息源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要方向</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">RSS/Atom</div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6808597f7d187504b8a50"><td class="" style="width:120px"><div class="notion-simple-table-cell">PostgreSQL News</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">PostgreSQL 版本、安全公告及生态扩展</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.postgresql.org/news.rss</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6801d9d0cfc16ada6c734"><td class="" style="width:120px"><div class="notion-simple-table-cell">DuckDB Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">嵌入式 OLAP、向量化执行、Parquet</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://duckdb.org/feed.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6807cb473d310bb392631"><td class="" style="width:120px"><div class="notion-simple-table-cell">PingCAP Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">TiDB、分布式数据库、HTAP</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.pingcap.com/feed/</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6802f829ac5482359500c"><td class="" style="width:120px"><div class="notion-simple-table-cell">ClickHouse Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">列式数据库、实时分析、OLAP</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://clickhouse.com/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6802f821dde6dee86a325"><td class="" style="width:120px"><div class="notion-simple-table-cell">StarRocks Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">MPP、实时数仓、Lakehouse 查询</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.starrocks.io/blog/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6805c9839f390a42ad85f"><td class="" style="width:120px"><div class="notion-simple-table-cell">Apache Doris Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">MPP、实时数仓、湖仓分析</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://doris.apache.org/blog/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd680379b5fce493a7d54cc"><td class="" style="width:120px"><div class="notion-simple-table-cell">Databend Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">云原生数仓、列式存储、对象存储</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.databend.com/blog/rss.xml</code></div></td></tr></tbody></table><div class="notion-text notion-block-3fa0e3562fd680cdb81ce6a26cb21148">2. 查询引擎与计算框架</div><table class="notion-simple-table notion-block-3fa0e3562fd680f1a31adf845d3f9a72"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fa0e3562fd680be85f4d982e17cc80f"><td class="" style="width:120px"><div class="notion-simple-table-cell">信息源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要方向</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">RSS/Atom</div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6802abaa0dbb7826d7631"><td class="" style="width:120px"><div class="notion-simple-table-cell">Trino Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">联邦查询、分布式 SQL、数据湖查询</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://trino.io/feed.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd680058af2ebcca99e65fc"><td class="" style="width:120px"><div class="notion-simple-table-cell">Apache Flink</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">流计算、CDC、流批一体</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://flink.apache.org/posts/index.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd680f594dac9cf4d5cf0a9"><td class="" style="width:120px"><div class="notion-simple-table-cell">Apache Arrow</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">内存列式格式、Parquet、跨语言计算</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://arrow.apache.org/feed.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd680d6ae92f0f22e1f01cf"><td class="" style="width:120px"><div class="notion-simple-table-cell">Velox Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">向量化执行引擎、查询算子、Nimble</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://velox-lib.io/blog/rss.xml</code></div></td></tr></tbody></table><div class="notion-text notion-block-3fa0e3562fd680b781c2f3056ee8496e">3. 数据湖与 Lakehouse</div><table class="notion-simple-table notion-block-3fa0e3562fd6809c9660e8cc9424b9e6"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fa0e3562fd6804a9c75ca77d508f22e"><td class="" style="width:120px"><div class="notion-simple-table-cell">信息源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要方向</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">RSS/Atom</div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6809aa234ed069a0361ce"><td class="" style="width:120px"><div class="notion-simple-table-cell">Delta Lake Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lakehouse、事务表格式、Delta Kernel</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://delta.io/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6802599c2e02e6918d97f"><td class="" style="width:120px"><div class="notion-simple-table-cell">Apache Hudi Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">数据湖、增量处理、索引、流式写入</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://hudi.apache.org/blog/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6809fa8eee02a7d92dae1"><td class="" style="width:120px"><div class="notion-simple-table-cell">Databricks Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark、Delta Lake、Lakehouse、数据平台</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.databricks.com/feed</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd68054893dc53bea1f5695"><td class="" style="width:120px"><div class="notion-simple-table-cell">AWS Big Data Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Redshift、EMR、Iceberg、Glue、Kinesis</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://aws.amazon.com/blogs/big-data/feed/</code></div></td></tr></tbody></table><div class="notion-text notion-block-3fa0e3562fd68088b5ade08201adfdf6">4. 流数据与数据工程</div><table class="notion-simple-table notion-block-3fa0e3562fd6807fb21eeb13140b0c4b"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fa0e3562fd68061a6fbd82eaa96fd78"><td class="" style="width:120px"><div class="notion-simple-table-cell">信息源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要方向</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">RSS/Atom</div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd68083bbf8ecfa7e0d6335"><td class="" style="width:120px"><div class="notion-simple-table-cell">Confluent Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Kafka、流数据平台、实时架构</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.confluent.io/rss.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd680b1a3a8e71fcfc96f5d"><td class="" style="width:120px"><div class="notion-simple-table-cell">dbt Labs Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">数据转换、Analytics Engineering、数仓开发</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.getdbt.com/blog/feed.xml</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd68006b1c7f31c2f19cf58"><td class="" style="width:120px"><div class="notion-simple-table-cell">Decodable Blog</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Flink、CDC、流处理和数据管道</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.decodable.co/blog/rss.xml</code></div></td></tr></tbody></table><div class="notion-text notion-block-3fa0e3562fd6803d8a82f5588292afd6">5.媒体与行业聚合源</div><table class="notion-simple-table notion-block-3fa0e3562fd680cc9a18f91b3fdaec0a"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fa0e3562fd68094b0c4fdf3c7a985c1"><td class="" style="width:120px"><div class="notion-simple-table-cell">信息源</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">特点</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">RSS</div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6800f825ecfde3361beb2"><td class="" style="width:120px"><div class="notion-simple-table-cell">The New Stack · Data</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">数据基础设施、数据库和工程实践</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://thenewstack.io/data/feed/</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6801288e3eb2e8ceba102"><td class="" style="width:120px"><div class="notion-simple-table-cell">InfoQ · Architecture &amp; Design</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">架构、分布式系统、数据库和工程案例</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://feed.infoq.com/architecture-design</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fa0e3562fd6802481abc93bd8177fdc"><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Engineering Weekly</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">数据工程文章和社区动态周报</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">https://www.dataengineeringweekly.com/feed</code></div></td></tr></tbody></table></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Paimon学习笔记： Data Evolution表]]></title>
            <link>https://kunni.top//article/3e30e356-2fd6-8042-bf76-c1017d4907a6</link>
            <guid>https://kunni.top//article/3e30e356-2fd6-8042-bf76-c1017d4907a6</guid>
            <pubDate>Sat, 17 Oct 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3e30e3562fd68042bf76c1017d4907a6"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680458f83c691e83236eb" data-id="3fc0e3562fd680458f83c691e83236eb"><span><div id="3fc0e3562fd680458f83c691e83236eb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680458f83c691e83236eb" title="1. 一句话理解 Data Evolution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 一句话理解 Data Evolution</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680189957c3e2c0f341e4">Paimon Data Evolution 是一种面向 <b>无主键 Append Table</b> 的列级更新机制：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68023a941e3976a7a44e6"><li>每一行由 Paimon 分配稳定的 <code class="notion-inline-code">_ROW_ID</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a69482c5b5470796dd"><li>更新时只写发生变化的列，不重写未变化的列或大对象；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e4a316dc4272e8a347"><li>同一逻辑行的不同列可以来自不同物理文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d48f46eaa63345292b"><li>读取时按 <code class="notion-inline-code">_ROW_ID</code> 对齐，并按文件版本为每一列选择最新值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806590d5d1f4e9eececf"><li>多次更新产生的列文件最终通过 compaction 合并。</li></ul><div class="notion-text notion-block-3fc0e3562fd680a7bae9c4d75704540d">它特别适合如下流水线：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680b6aa58dc7922f4736c" style="list-style-type:decimal"><li>先写入原始数据；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f6b148cfad6fa6669b" style="list-style-type:decimal"><li>后续异步补充标签、描述、特征、Embedding 等列；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68099b9e3d92f5d83bca6" style="list-style-type:decimal"><li>原始图片、音视频等大对象保持不动；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680bdb749efa76a4cd0d0" style="list-style-type:decimal"><li>持续构建或刷新向量、全文、标量索引。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd68007a5e9c90124812207"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680468d05e6f0775f8518" data-id="3fc0e3562fd680468d05e6f0775f8518"><span><div id="3fc0e3562fd680468d05e6f0775f8518" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680468d05e6f0775f8518" title="2. Data Evolution 不等于 Schema Evolution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. Data Evolution 不等于 Schema Evolution</span></span></h3><div class="notion-text notion-block-3fc0e3562fd68006afa1edf5ba5fb130">这两个概念很容易混淆。</div><table class="notion-simple-table notion-block-3fc0e3562fd6805ba802ebabf013f40c"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6802ba22cc91ef8b013cd"><td class="" style="width:120px"><div class="notion-simple-table-cell">概念</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">解决的问题</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">示例</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680aba234d9ad9f2e1904"><td class="" style="width:120px"><div class="notion-simple-table-cell">Schema Evolution</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">表中有哪些列、列叫什么、列类型是什么</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">ALTER TABLE ADD COLUMN caption STRING</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68058bd78efb105110343"><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Evolution</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">已有行的新列值或旧列值如何补充、替换</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">为历史图片计算 <code class="notion-inline-code">caption</code> 并写回</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd6806fb4d1ca9a77a17619">执行：</div><div class="notion-text notion-block-3fc0e3562fd680c6abd1e6ac96722c1d">只会修改 Schema，不会自动为历史行计算 <code class="notion-inline-code">caption</code>。还需要通过 <code class="notion-inline-code">UPDATE</code>、<code class="notion-inline-code">MERGE INTO</code>、PyPaimon shard update 等方式执行数据回填。</div><hr class="notion-hr notion-block-3fc0e3562fd68021a358dea289e86888"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6806c8990e614c97b69b8" data-id="3fc0e3562fd6806c8990e614c97b69b8"><span><div id="3fc0e3562fd6806c8990e614c97b69b8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6806c8990e614c97b69b8" title="3. 与普通 Append Table、主键表的区别"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 与普通 Append Table、主键表的区别</span></span></h3><table class="notion-simple-table notion-block-3fc0e3562fd680d1b1eeddbb33a9f300"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6801a824ef2f42f450dc2"><td class="" style="width:120px"><div class="notion-simple-table-cell">特性</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Append Table</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Evolution Table</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Primary Key Table</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68096824cc51b9a62218f"><td class="" style="width:120px"><div class="notion-simple-table-cell">Primary Key</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">有</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68022ae98c3e3bb791fb5"><td class="" style="width:120px"><div class="notion-simple-table-cell">相同业务键再次 INSERT</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">新增一行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">新增一行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">按合并引擎更新</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806e8347f9de03c6033f"><td class="" style="width:120px"><div class="notion-simple-table-cell">行身份</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通常不暴露稳定行身份</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">_ROW_ID</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Primary Key</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68009acebf46601d642a4"><td class="" style="width:120px"><div class="notion-simple-table-cell">更新方式</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通常需要重写数据</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">按 <code class="notion-inline-code">_ROW_ID</code> 做列级更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">按 Primary Key 合并</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6801b827ac4af414785c3"><td class="" style="width:120px"><div class="notion-simple-table-cell">未更新列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">随文件一起重写</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留旧列文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">由 merge engine 决定</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680fab2b1c0220646cf9a"><td class="" style="width:120px"><div class="notion-simple-table-cell">BLOB/Vector 专用存储</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不适用</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">核心场景</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">部分场景支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680928c58ddfbebbb07bf"><td class="" style="width:120px"><div class="notion-simple-table-cell">典型用途</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">日志、事件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">多模态和异步特征生产</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">CDC、业务实体状态</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd680e795ccf6c2e5d9f2fb">最重要的区别是：</div><blockquote class="notion-quote notion-block-3fc0e3562fd680d586e3d83e75d7f737"><div>Data Evolution 表中的业务字段 <code class="notion-inline-code">id</code> 不是 Primary Key。</div></blockquote><div class="notion-text notion-block-3fc0e3562fd680f69f06edfa6d52cb94">例如：</div><div class="notion-text notion-block-3fc0e3562fd68053b239fad1671392b9">这会产生两条不同的逻辑行，并获得两个不同的 <code class="notion-inline-code">_ROW_ID</code>。</div><hr class="notion-hr notion-block-3fc0e3562fd68077bc6bec0081290f6a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680818e9cd0312f4261e3" data-id="3fc0e3562fd680818e9cd0312f4261e3"><span><div id="3fc0e3562fd680818e9cd0312f4261e3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680818e9cd0312f4261e3" title="4. 建表前提与硬约束"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 建表前提与硬约束</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680948ec7c118c5461c18" data-id="3fc0e3562fd680948ec7c118c5461c18"><span><div id="3fc0e3562fd680948ec7c118c5461c18" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680948ec7c118c5461c18" title="4.1 必须同时开启的选项"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.1 必须同时开启的选项</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6806fb719c179f4bf25e8">这两个选项都是不可变选项，应在建表时确定。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680a3936fe405615c0041" data-id="3fc0e3562fd680a3936fe405615c0041"><span><div id="3fc0e3562fd680a3936fe405615c0041" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a3936fe405615c0041" title="4.2 表模型约束"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.2 表模型约束</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680f4ba8bebc58e2137c7">Data Evolution 表必须满足：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68086b296f7b63c0d2f34" style="list-style-type:decimal"><li>是 Append Table；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680dfa283d89ed4353482" style="list-style-type:decimal"><li>没有 Primary Key；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6808baec8c46cc81c746e" style="list-style-type:decimal"><li><code class="notion-inline-code">bucket = -1</code>，即 bucket-unaware；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68019aa95f14229b33da6" style="list-style-type:decimal"><li>必须启用 Row Tracking；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680e3b29accc23b71dac2" style="list-style-type:decimal"><li>不能启用 <code class="notion-inline-code">clustering.incremental</code>。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68084a3c1e252d3d3dcaa" data-id="3fc0e3562fd68084a3c1e252d3d3dcaa"><span><div id="3fc0e3562fd68084a3c1e252d3d3dcaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68084a3c1e252d3d3dcaa" title="4.3 Spark 建表示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.3 Spark 建表示例</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680009649fdb645da539c"><code class="notion-inline-code">deletion-vectors.enabled</code> 不是普通列更新的必要条件，但执行行级 <code class="notion-inline-code">DELETE</code> 或 <code class="notion-inline-code">MERGE INTO ... DELETE</code> 时需要开启。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d8a5aaecaa5a338dd7" data-id="3fc0e3562fd680d8a5aaecaa5a338dd7"><span><div id="3fc0e3562fd680d8a5aaecaa5a338dd7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d8a5aaecaa5a338dd7" title="4.4 Flink 建表示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.4 Flink 建表示例</span></span></h4><hr class="notion-hr notion-block-3fc0e3562fd68048b797e45d36b6e8b6"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680b5aa02f55e15cbdf93" data-id="3fc0e3562fd680b5aa02f55e15cbdf93"><span><div id="3fc0e3562fd680b5aa02f55e15cbdf93" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b5aa02f55e15cbdf93" title="5. 核心概念一：Row ID"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 核心概念一：Row ID</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680a6a4d2c598e5d770d1" data-id="3fc0e3562fd680a6a4d2c598e5d770d1"><span><div id="3fc0e3562fd680a6a4d2c598e5d770d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a6a4d2c598e5d770d1" title="5.1 _ROW_ID 是什么"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.1 <code class="notion-inline-code">_ROW_ID</code> 是什么</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6804a8889fc834874b738">Row Tracking 为每一条 Append Table 记录分配一个 <code class="notion-inline-code">BIGINT</code> 类型的内部行 ID。</div><div class="notion-text notion-block-3fc0e3562fd68032bcfdc18c13481897">可以通过 <code class="notion-inline-code">$row_tracking</code> 系统表查看：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680aa8616eabfc7fdf152" data-id="3fc0e3562fd680aa8616eabfc7fdf152"><span><div id="3fc0e3562fd680aa8616eabfc7fdf152" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680aa8616eabfc7fdf152" title="5.2 Row ID 如何分配"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.2 Row ID 如何分配</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680ee80ebf0a600f020e7">普通追加文件在写出时可以还没有 <code class="notion-inline-code">firstRowId</code>。提交快照时，提交层根据上一个快照的 <code class="notion-inline-code">nextRowId</code> 为新文件分配连续区间。</div><div class="notion-text notion-block-3fc0e3562fd680d5a504cc320507ba36">假设两个新文件分别有 3 行和 2 行：</div><div class="notion-text notion-block-3fc0e3562fd68088b6e2c80a796ce42c">文件的 Row ID 范围定义为：</div><div class="notion-text notion-block-3fc0e3562fd680969183ca2f3cd9cc63">文件中第 <code class="notion-inline-code">i</code> 个位置对应：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68021986fcd9556c37a29" data-id="3fc0e3562fd68021986fcd9556c37a29"><span><div id="3fc0e3562fd68021986fcd9556c37a29" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68021986fcd9556c37a29" title="5.3 Row ID 不是永久业务 ID"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.3 Row ID 不是永久业务 ID</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680b49780c5386c746c48">以下操作会保留 Row ID：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c5a7d5f1de21604a7c"><li>普通列更新；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e79c92d5c84eb1715c"><li>列回填；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e6b80bc7272af51e53"><li>逻辑删除；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802a8a31e9cbade1c94d"><li>普通 Data Evolution compaction；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805a90bfe71f594ada75"><li>compaction 中拆分大文件。</li></ul><div class="notion-text notion-block-3fc0e3562fd6807c9b49c824c5fbdd2c">以下操作可能改变或移除 Row ID：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68008a717ec1cf92bd79e"><li><code class="notion-inline-code">materialize_deletion_vectors</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e9b494f52f82af10e7"><li><code class="notion-inline-code">reassign_row_id</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b6bf1ac5aa80452faf"><li>overwrite；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800990b4f19016eab6c8"><li>分区删除或分区替换。</li></ul><div class="notion-text notion-block-3fc0e3562fd68054a5bac5010a1bc743">因此：</div><blockquote class="notion-quote notion-block-3fc0e3562fd680ff851ce7e9652fb2b5"><div><code class="notion-inline-code">_ROW_ID</code> 是存储层行定位符，不应直接当成永久业务主键。</div></blockquote><div class="notion-text notion-block-3fc0e3562fd6802996fce2ec5b25a0d0">如果其他表持久化保存了 <code class="notion-inline-code">_ROW_ID</code>，必须与 Row ID 重分配、Deletion Vector 物化等维护任务协调。</div><hr class="notion-hr notion-block-3fc0e3562fd68089824dd18b5b3294ca"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680549a4ec83b37afc722" data-id="3fc0e3562fd680549a4ec83b37afc722"><span><div id="3fc0e3562fd680549a4ec83b37afc722" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680549a4ec83b37afc722" title="6. 核心概念二：文件组和范围契约"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. 核心概念二：文件组和范围契约</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6809ea224cc1aa1479e7b">Data Evolution 的正确性依赖严格的 Row ID Range 文件布局。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680fdb49bf603d7217841" data-id="3fc0e3562fd680fdb49bf603d7217841"><span><div id="3fc0e3562fd680fdb49bf603d7217841" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680fdb49bf603d7217841" title="6.1 Normal File"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.1 Normal File</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6802cb6c9e58336127b2f">Normal File 使用普通表文件格式，例如 Parquet 或 ORC，存储：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806a9d08e962367551c4"><li>全部普通列；或者</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804092f4f5580a289607"><li>一次更新选择的部分普通列。</li></ul><div class="notion-text notion-block-3fc0e3562fd6800c99a0f3ccc67fbeec">任意两个存活的 Normal File，其 Row ID Range 必须：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68028aed5cb12e34ddef5"><li>完全相同；或者</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809f9717c8efafce7744"><li>完全不相交。</li></ul><div class="notion-text notion-block-3fc0e3562fd680e4b184e77a953d8545">不允许部分重叠，也不允许一个严格包含另一个。</div><div class="notion-text notion-block-3fc0e3562fd680548f73ca6d235f74d9">Row ID Range 完全相同的一组 Normal File 构成一个逻辑文件组。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680158d46e8f62f525eba" data-id="3fc0e3562fd680158d46e8f62f525eba"><span><div id="3fc0e3562fd680158d46e8f62f525eba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680158d46e8f62f525eba" title="6.2 Dedicated File"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.2 Dedicated File</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680e9a697c2fe317999a8">Dedicated File 是专用格式文件，例如：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680af910fdb0118928e9a"><li>BLOB 文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802e9013f511a11b2331"><li>Vector Store 文件。</li></ul><div class="notion-text notion-block-3fc0e3562fd680b28b21d0ea356c19c7">Dedicated File 的范围可以小于 Normal File，但必须完全包含在某一个 Normal Range 内：</div><div class="notion-text notion-block-3fc0e3562fd68063b14adb2db378b315">例如 Normal Range 为 <code class="notion-inline-code">[0, 5]</code> 和 <code class="notion-inline-code">[6, 9]</code>：</div><table class="notion-simple-table notion-block-3fc0e3562fd680e7a93ac469f8975353"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680259242cc4f6d77d9f2"><td class="" style="width:120px"><div class="notion-simple-table-cell">Dedicated Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是否合法</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">原因</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c0af5df879373f18d7"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[0, 5]</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">与一个 Normal Range 完全相同</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6804f873fc21868520168"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[2, 4]</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">完全包含在 <code class="notion-inline-code">[0, 5]</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c1b5bcf991d3dd7756"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[4, 7]</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">否</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">跨越两个 Normal Range</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680899ee6f56f5afc1e45"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">[0, 9]</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">否</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不能依赖两个 Normal Range 的并集</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680799563ec020b989178" data-id="3fc0e3562fd680799563ec020b989178"><span><div id="3fc0e3562fd680799563ec020b989178" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680799563ec020b989178" title="6.3 为什么普通列更新必须重写完整范围"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6.3 为什么普通列更新必须重写完整范围</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6806d8c55e330d62cc0e6">假设原始文件：</div><div class="notion-text notion-block-3fc0e3562fd680428054f02b582a1005">执行：</div><div class="notion-text notion-block-3fc0e3562fd680949f49ebd5c31e64d8">不能只写一行 <code class="notion-inline-code">[rowId=1, b=22]</code>，而是要生成：</div><div class="notion-text notion-block-3fc0e3562fd680a0b90cee1b413cffb8">逻辑结果由两个文件合并：</div><div class="notion-text notion-block-3fc0e3562fd68083a973c8e5220311b2">结果：</div><div class="notion-text notion-block-3fc0e3562fd68035997df9804ddd9a16">这说明 Data Evolution 节省的是 <b>未更新列的重写成本</b>，而不是把一次普通列更新缩小到单行文件。</div><div class="notion-text notion-block-3fc0e3562fd680309db6e6ee7fcf35d6">更新一行，也可能需要处理其所在文件范围内的所有行。</div><hr class="notion-hr notion-block-3fc0e3562fd6804f837fc622c26df02e"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680a8b9a6c01e595b2e41" data-id="3fc0e3562fd680a8b9a6c01e595b2e41"><span><div id="3fc0e3562fd680a8b9a6c01e595b2e41" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a8b9a6c01e595b2e41" title="7. 文件元数据"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7. 文件元数据</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6801cb456c092e59e128a">理解以下 <code class="notion-inline-code">DataFileMeta</code> 字段非常重要：</div><table class="notion-simple-table notion-block-3fc0e3562fd6801dbf4ac25a7ccb32da"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680f9b52cd1505b9c1dbd"><td class="" style="width:120px"><div class="notion-simple-table-cell">字段</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c99d2afd1795c6be6d"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">firstRowId</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件第一个逻辑位置的 Row ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809a9060e4b84dd4836e"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">rowCount</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">物理位置数，包含被 Deletion Vector 隐藏的位置</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68083b314e0f9b1b8c11c"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">schemaId</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">写出文件时使用的 Schema</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680d4a94eec51746b44ca"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">writeCols</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件实际写入的列或嵌套字段路径</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68013b36fe3273a06d0f4"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">minSequenceNumber</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件中最小数据版本</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6800d8d5de71c5639c3bb"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">maxSequenceNumber</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件中最大数据版本</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806ba1dec53cd2fd7712"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">writeColsSequences</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">compaction 后每个物理字段保留的最大版本</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6807cb6c6c5120de271e8"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">extraFiles</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Sidecar 等与主文件对齐的附属文件</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6808d992dc2cc2906be33" data-id="3fc0e3562fd6808d992dc2cc2906be33"><span><div id="3fc0e3562fd6808d992dc2cc2906be33" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6808d992dc2cc2906be33" title="7.1 writeCols"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.1 <code class="notion-inline-code">writeCols</code></span></span></h4><div class="notion-text notion-block-3fc0e3562fd68044890de06354bd9ab3">例如：</div><div class="notion-text notion-block-3fc0e3562fd6808ca773d4b01ab931d6">必须结合文件自己的 <code class="notion-inline-code">schemaId</code> 解析 <code class="notion-inline-code">writeCols</code>，不能只按最新表 Schema 的字段名解析。</div><div class="notion-text notion-block-3fc0e3562fd68013be30ce1a0fee7bec">这是为了正确处理：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f8a737f867b2c18b34"><li>字段重命名；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680beb904e5172519724e"><li>新增字段；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804da6d7f10cef5b243c"><li>不同 Schema 版本下的字段 ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a0bd5ed78f4999717e"><li>嵌套字段演进。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680f5a339f64e05043a99" data-id="3fc0e3562fd680f5a339f64e05043a99"><span><div id="3fc0e3562fd680f5a339f64e05043a99" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f5a339f64e05043a99" title="7.2 writeCols = null 的优化编码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">7.2 <code class="notion-inline-code">writeCols = null</code> 的优化编码</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6800d899ec2f92c18ad6b">开启：</div><div class="notion-text notion-block-3fc0e3562fd68089b0c2d303d19de64d">当 Normal File 包含全部非 Dedicated 列时，可以省略 <code class="notion-inline-code">writeCols</code>。</div><div class="notion-text notion-block-3fc0e3562fd680cdbda1ca9f254e2fdf">该选项默认关闭，主要原因是老版本 Reader 可能把 <code class="notion-inline-code">null</code> 错误理解为“文件包含表中全部列”。启用前应升级所有 Reader、Writer、Compactor 和维护任务。</div><hr class="notion-hr notion-block-3fc0e3562fd6806eb0b5f4c1af6f5df7"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680aeab4fc506286a3974" data-id="3fc0e3562fd680aeab4fc506286a3974"><span><div id="3fc0e3562fd680aeab4fc506286a3974" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680aeab4fc506286a3974" title="8. 读取流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8. 读取流程</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680e48525df7a77063dab" data-id="3fc0e3562fd680e48525df7a77063dab"><span><div id="3fc0e3562fd680e48525df7a77063dab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680e48525df7a77063dab" title="8.1 总体流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.1 总体流程</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68081a012f85e625fad95" data-id="3fc0e3562fd68081a012f85e625fad95"><span><div id="3fc0e3562fd68081a012f85e625fad95" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68081a012f85e625fad95" title="8.2 主要处理层次"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.2 主要处理层次</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6808cb99ce5f143eac83e" data-id="3fc0e3562fd6808cb99ce5f143eac83e"><span><div id="3fc0e3562fd6808cb99ce5f143eac83e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6808cb99ce5f143eac83e" title="8.3 Scan 阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.3 Scan 阶段</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680828b7efc1075835b74">Data Evolution Scan 不能像普通 Append Scan 一样独立判断每个文件。</div><div class="notion-text notion-block-3fc0e3562fd680c7a3cef97e505ba61c">原因是：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68091ab11cbea3aa04e66"><li>老文件的某个列可能已被新文件覆盖；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680abb84df4f90d5028ff"><li>老文件统计信息不能用来判断新版本列值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802c8eabe258bafe435e"><li>查询投影可能只需要一个文件组中的部分列文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803dbae1e441aa587cbc"><li>即使查询列在所有文件中都不存在，也要保留一个文件来提供正确行数并补 <code class="notion-inline-code">NULL</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800dad4bf25c47a1ea67"><li>开启 Deletion Vector 时必须保留 Anchor File。</li></ul><div class="notion-text notion-block-3fc0e3562fd6809e9c72f039ee370400">因此 Scan 会：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a8bd49cae844a89ae4" style="list-style-type:decimal"><li>按重叠 Row ID Range 对文件分组；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680289472d44c6ddf9d92" style="list-style-type:decimal"><li>合并最新列 Provider 的统计信息；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680098d6dd16c907e241f" style="list-style-type:decimal"><li>基于逻辑最新值做文件组级过滤；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6808a93dad30f75e4c94b" style="list-style-type:decimal"><li>根据 Projection 和 Predicate 需要，删除不贡献列的物理文件；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68017a97cf326ddfb5ad3" style="list-style-type:decimal"><li>必要时保留 Anchor 或行数代表文件。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68057b80ac5c7f21e4459" data-id="3fc0e3562fd68057b80ac5c7f21e4459"><span><div id="3fc0e3562fd68057b80ac5c7f21e4459" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68057b80ac5c7f21e4459" title="8.4 Split 生成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.4 Split 生成</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680a49905d68e815af0bf">Split 规划会先把重叠 Row ID Range 合并成不可拆的逻辑组，再根据目标 Split 大小做打包。</div><div class="notion-text notion-block-3fc0e3562fd6805b9152c9bc92425a85">这样可以保证需要一起进行列合并的文件不会被分配到不同 Split。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68009acefcdf6aef11ee6" data-id="3fc0e3562fd68009acefcdf6aef11ee6"><span><div id="3fc0e3562fd68009acefcdf6aef11ee6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68009acefcdf6aef11ee6" title="8.5 Provider 选择"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.5 Provider 选择</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6803ba64dc670a53947fc">同一文件组中的 Normal File 按新版本优先排序。对每个请求字段，Reader 选择第一个能够提供该字段的文件。</div><div class="notion-text notion-block-3fc0e3562fd68083a125e66f8332a5f6">例如：</div><div class="notion-text notion-block-3fc0e3562fd6802b8da3ec12f4138c60">读取 <code class="notion-inline-code">id,b,c</code> 时：</div><div class="notion-text notion-block-3fc0e3562fd680b6ba8ddccb8146de3f">这不是按业务键进行 Join，而是按 Row ID 位置做列拼装。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d78514ef07e3b663ab" data-id="3fc0e3562fd680d78514ef07e3b663ab"><span><div id="3fc0e3562fd680d78514ef07e3b663ab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d78514ef07e3b663ab" title="8.6 缺列、NULL 和 BLOB Placeholder"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.6 缺列、NULL 和 BLOB Placeholder</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680aba6b2de6dd37e09dc">三种情况语义完全不同：</div><table class="notion-simple-table notion-block-3fc0e3562fd680b8941ce952c2c00d80"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6806d81cef7892c991b30"><td class="" style="width:120px"><div class="notion-simple-table-cell">表示</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">读取语义</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68021a80adb9877a66e28"><td class="" style="width:120px"><div class="notion-simple-table-cell">文件没有写该列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件不提供新值，继续找旧 Provider</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68031b503d0653c39d1a5"><td class="" style="width:120px"><div class="notion-simple-table-cell">文件写了该列且值为 <code class="notion-inline-code">NULL</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">最新值就是 <code class="notion-inline-code">NULL</code>，不能回退</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680ec955df17d9fdf98e4"><td class="" style="width:120px"><div class="notion-simple-table-cell">BLOB Placeholder</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留旧 BLOB，继续向旧版本查找</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd680ffb235c5d5bce049b2">不要使用 <code class="notion-inline-code">NULL</code> 表示“保持旧 BLOB 不变”。BLOB Placeholder 是内部写入语义，由 Paimon Writer 管理。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680e6adcefc4af824aebe" data-id="3fc0e3562fd680e6adcefc4af824aebe"><span><div id="3fc0e3562fd680e6adcefc4af824aebe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680e6adcefc4af824aebe" title="8.7 Filter Pushdown 为什么更谨慎"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.7 Filter Pushdown 为什么更谨慎</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68067b78acd24645c3a3a">多文件位置合并要求所有列 Reader 保持严格对齐。</div><div class="notion-text notion-block-3fc0e3562fd6802db265e9db5b710767">如果只对其中一个 Reader 下推行过滤，可能出现：</div><div class="notion-text notion-block-3fc0e3562fd6808d8565c1806f3b25ea">此时列会错位。</div><div class="notion-text notion-block-3fc0e3562fd68080a604f5603bbc38ad">因此：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68073ae79ebb7c0e3965f"><li>单文件读取可以正常执行文件索引和格式级下推；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b58a44df530526d7fe"><li>可证明安全的合并组可共享一个 Bitmap Selection；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800c833ce863ebcb6d19"><li>其他合并读取通常只能用索引跳过整个文件组；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c1b336ce0b017e47d5"><li>系统字段的物理值可能因 Row ID 重分配而过期，不直接下推到物理文件。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68075af20c4867eb7b190" data-id="3fc0e3562fd68075af20c4867eb7b190"><span><div id="3fc0e3562fd68075af20c4867eb7b190" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68075af20c4867eb7b190" title="8.8 Row Sidecar"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">8.8 Row Sidecar</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68057b1a9fe9368f6a09e">可选配置：</div><div class="notion-text notion-block-3fc0e3562fd6807ea837e4cccb99372f">Writer 会为 Normal File 生成行存 Sidecar，用于加速稀疏 Row ID 读取。</div><div class="notion-text notion-block-3fc0e3562fd680beb856e7c14100e3a5">默认使用 Sidecar 的两个门槛：</div><div class="notion-text notion-block-3fc0e3562fd68045b069f8f5d96dee66">只有同时满足以下条件时才使用 Sidecar：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68078ac52fd3a54c60143" style="list-style-type:decimal"><li>选中行数不超过 4096；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68076ad74f97c44b24401" style="list-style-type:decimal"><li>选中行比例不超过 5%；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a59eced92ae1fd9fea" style="list-style-type:decimal"><li>不是全文件读取；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806395b8d4c9e521740c" style="list-style-type:decimal"><li>文件存在唯一的 Row Sidecar；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a28ef5f2f18b77635e" style="list-style-type:decimal"><li>不是 BLOB 或 Vector Store 文件。</li></ol><div class="notion-text notion-block-3fc0e3562fd6807eab41fa0d0b546127">Row Sidecar 适合全局索引返回少量 Row ID 后的点查，不适合大范围扫描。</div><hr class="notion-hr notion-block-3fc0e3562fd680c29297f458c194f151"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68016b39dc69ba9541469" data-id="3fc0e3562fd68016b39dc69ba9541469"><span><div id="3fc0e3562fd68016b39dc69ba9541469" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68016b39dc69ba9541469" title="9. 普通列更新流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9. 普通列更新流程</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680bb874ad715bf861781" data-id="3fc0e3562fd680bb874ad715bf861781"><span><div id="3fc0e3562fd680bb874ad715bf861781" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bb874ad715bf861781" title="9.1 端到端流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.1 端到端流程</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680fa83f7f0a7c940e71e" data-id="3fc0e3562fd680fa83f7f0a7c940e71e"><span><div id="3fc0e3562fd680fa83f7f0a7c940e71e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680fa83f7f0a7c940e71e" title="9.2 为什么关闭 File Rolling"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.2 为什么关闭 File Rolling</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680c5a436e56398c436a4">部分列文件必须与原 Normal Range 完全对齐。因此 Spark 和 Flink 的 Data Evolution Writer 都会禁用普通文件滚动：</div><div class="notion-text notion-block-3fc0e3562fd68068963de8630eb1d0aa">Flink 还会关闭 Append Write Buffer，以避免中途 Flush 导致文件提前关闭。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680efac56dd0a1607df59" data-id="3fc0e3562fd680efac56dd0a1607df59"><span><div id="3fc0e3562fd680efac56dd0a1607df59" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680efac56dd0a1607df59" title="9.3 未命中行也要写"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.3 未命中行也要写</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6800b815dd01eb3d47b92">一个范围内只更新少量行时，Writer 会：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68064983cfc8f3cadbe21"><li>匹配行写新值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680be802edf66cd4d5d5b"><li>未匹配行复制旧值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808bb75eeb10db5b0ce2"><li>被 Deletion Vector 隐藏的位置仍然保留占位；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809bb218d1ef45f1d336"><li>最终写出的行数必须等于原范围 <code class="notion-inline-code">rowCount</code>。</li></ul><div class="notion-text notion-block-3fc0e3562fd680c19d4fe784cd05242d">这保证其他列文件仍可按位置对齐。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68046a250c53b93b16c98" data-id="3fc0e3562fd68046a250c53b93b16c98"><span><div id="3fc0e3562fd68046a250c53b93b16c98" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68046a250c53b93b16c98" title="9.4 更新分区列"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">9.4 更新分区列</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6801db697d7d77ee11c52">Matched partial update 不支持修改分区列。</div><div class="notion-text notion-block-3fc0e3562fd68077ae01f93e4f3cd443">分区决定文件所在目录和文件组归属，直接修改分区列不是简单的列 Provider 替换，而是删除旧行并向另一个分区插入新行。</div><hr class="notion-hr notion-block-3fc0e3562fd6806bbdddd53fe2a6907f"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680e9922bef324b7fb776" data-id="3fc0e3562fd680e9922bef324b7fb776"><span><div id="3fc0e3562fd680e9922bef324b7fb776" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680e9922bef324b7fb776" title="10. Spark UPDATE 与 MERGE INTO"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10. Spark UPDATE 与 MERGE INTO</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680e39f8fe6e950d51049" data-id="3fc0e3562fd680e39f8fe6e950d51049"><span><div id="3fc0e3562fd680e39f8fe6e950d51049" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680e39f8fe6e950d51049" title="10.1 UPDATE"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.1 UPDATE</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68000ba62f476b4986fca">Spark 的 Data Evolution <code class="notion-inline-code">UPDATE</code> 内部会构造成基于 <code class="notion-inline-code">_ROW_ID</code> 的 self-merge。</div><div class="notion-text notion-block-3fc0e3562fd6809c8dc4c52b79c83534">当条件可以安全放入 <code class="notion-inline-code">MergeRows</code> 时，可优化为：</div><div class="notion-text notion-block-3fc0e3562fd680a78963e5864e036009">避免普通 self join、shuffle 和 sort。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d5a9bbd0c0cee9fd5f" data-id="3fc0e3562fd680d5a9bbd0c0cee9fd5f"><span><div id="3fc0e3562fd680d5a9bbd0c0cee9fd5f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d5a9bbd0c0cee9fd5f" title="10.2 MERGE INTO"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.2 MERGE INTO</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68076addbd1f0b3b5f802">语义：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809f80b5d5540bde2486"><li>Matched Update：保留现有 <code class="notion-inline-code">_ROW_ID</code>，写部分列文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680029016ecad7574e10d"><li>Not Matched Insert：追加新行，提交时分配新 <code class="notion-inline-code">_ROW_ID</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68030b002fbe06ed29214"><li>Matched Delete：需要 Deletion Vector；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c39860c9a6cb214537"><li>Not Matched By Source Delete：需要 Deletion Vector。</li></ul><div class="notion-text notion-block-3fc0e3562fd680569a90ec40a6567c45">Spark Data Evolution MERGE 支持的 Action 形态：</div><table class="notion-simple-table notion-block-3fc0e3562fd680678f31d24ce48e7de5"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680ecbdeedf70ab452ade"><td class="" style="width:120px"><div class="notion-simple-table-cell">Clause</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持的 Action</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c1865ac8e687c905e3"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">WHEN MATCHED</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">UPDATE</code>、<code class="notion-inline-code">DELETE</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6802eac47e1de13852334"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">WHEN NOT MATCHED</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">INSERT</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68050a7d3f6a276ef960e"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">WHEN NOT MATCHED BY SOURCE</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DELETE</code></div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd68065ab96ce7b97065bb1"><code class="notion-inline-code">WHEN NOT MATCHED BY SOURCE</code> 需要 Spark 3.4 或更高版本。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6803589a3d67dc2081f2c" data-id="3fc0e3562fd6803589a3d67dc2081f2c"><span><div id="3fc0e3562fd6803589a3d67dc2081f2c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6803589a3d67dc2081f2c" title="10.3 _ROW_ID 快捷路径"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.3 <code class="notion-inline-code">_ROW_ID</code> 快捷路径</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680c1b983f767ba77114e">如果匹配条件为：</div><div class="notion-text notion-block-3fc0e3562fd68016bb5ed993bd9fd335">Paimon 可以跳过普通业务条件 Join，直接定位目标范围。</div><div class="notion-text notion-block-3fc0e3562fd68078919cd124de710881">Self-merge <code class="notion-inline-code">_ROW_ID</code> 快捷路径只支持 <code class="notion-inline-code">WHEN MATCHED</code>，不能同时包含：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f18732ed603b08948e"><li><code class="notion-inline-code">WHEN NOT MATCHED</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680908c4cef940f8e91e1"><li><code class="notion-inline-code">WHEN NOT MATCHED BY SOURCE</code>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68012ae65d5243e305e30" data-id="3fc0e3562fd68012ae65d5243e305e30"><span><div id="3fc0e3562fd68012ae65d5243e305e30" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68012ae65d5243e305e30" title="10.4 File Pruning"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.4 File Pruning</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68066b4e6d64a76fefe91">默认开启。Paimon 会先收集实际被更新的目标文件 ID，从后续部分列写入中裁剪未触碰文件。</div><div class="notion-text notion-block-3fc0e3562fd680a2b5f6f9a406af8bf3">如果预期目标分区的大多数文件都会被更新，收集文件 ID 的成本可能高于收益，可以关闭。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6803da651f64734b862c5" data-id="3fc0e3562fd6803da651f64734b862c5"><span><div id="3fc0e3562fd6803da651f64734b862c5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6803da651f64734b862c5" title="10.5 Spark UPDATE 冲突重试"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">10.5 Spark UPDATE 冲突重试</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680de96bceee65254b93d">Spark V1 UPDATE 默认配置：</div><div class="notion-text notion-block-3fc0e3562fd68089a9e1db1ab11ea9a7">只有确定性条件和确定性更新表达式才适合自动重试。</div><hr class="notion-hr notion-block-3fc0e3562fd680bb8bfbc1caa6f80713"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680db92f4e331072e34e5" data-id="3fc0e3562fd680db92f4e331072e34e5"><span><div id="3fc0e3562fd680db92f4e331072e34e5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680db92f4e331072e34e5" title="11. Flink Data Evolution 更新"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">11. Flink Data Evolution 更新</span></span></h3><div class="notion-text notion-block-3fc0e3562fd68043a08ef8bc367372cf">Flink 提供专门的 procedure：</div><div class="notion-text notion-block-3fc0e3562fd6805c8bcdd8fb75ffb8bc">该 procedure 是精简版 Merge：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805c8552f44a596c44c4"><li>支持匹配后更新；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c79a58ff770839fdd1"><li>不追加 source 中未匹配的行；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68089ab6dd59ff3be22fe"><li>不执行删除；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805da49aeb4b6cf8d4dc"><li>目标表不能是空表；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804991ace5f700bed62e"><li>更新前固定一个 base snapshot；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68098b2a7ed24c90a0047"><li>输入按 <code class="notion-inline-code">firstRowId</code> Shuffle，并按 <code class="notion-inline-code">_ROW_ID</code> 排序；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68054b9cbe2ade090b936"><li>每个范围补齐未更新行后写部分列文件。</li></ul><div class="notion-text notion-block-3fc0e3562fd680c887daeb8709cee056">删除应使用：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e1b902f7d6ad5a0113"><li>Flink 1.17+ Batch SQL <code class="notion-inline-code">DELETE FROM</code>；或者</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68059a651daf1bc604dda"><li><code class="notion-inline-code">delete</code> Action。</li></ul><hr class="notion-hr notion-block-3fc0e3562fd68098a2c6f8338282b973"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6805fb5ebd094413bb1e2" data-id="3fc0e3562fd6805fb5ebd094413bb1e2"><span><div id="3fc0e3562fd6805fb5ebd094413bb1e2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6805fb5ebd094413bb1e2" title="12. PyPaimon 更新方式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12. PyPaimon 更新方式</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6806584e7de0c153633cc">PyPaimon 提供多种 API。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6807081e8e67a32d1fde8" data-id="3fc0e3562fd6807081e8e67a32d1fde8"><span><div id="3fc0e3562fd6807081e8e67a32d1fde8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6807081e8e67a32d1fde8" title="12.1 按 Predicate 更新"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.1 按 Predicate 更新</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68039bfa2c21fd55ae175" data-id="3fc0e3562fd68039bfa2c21fd55ae175"><span><div id="3fc0e3562fd68039bfa2c21fd55ae175" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68039bfa2c21fd55ae175" title="12.2 按 Row ID 更新"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.2 按 Row ID 更新</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68064a498d3228c0e0949">输入只需要 <code class="notion-inline-code">_ROW_ID</code> 和待更新列：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680bba7c8d690bf204ad7" data-id="3fc0e3562fd680bba7c8d690bf204ad7"><span><div id="3fc0e3562fd680bba7c8d690bf204ad7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bba7c8d690bf204ad7" title="12.3 Shard Update"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">12.3 Shard Update</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6802d8a38d941ee60f9b7">适合批量计算派生列：</div><div class="notion-text notion-block-3fc0e3562fd680a9be5ff1c6680fffb9">必须遵守：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680bcaecbcadd07548f2e" style="list-style-type:decimal"><li>输出批次与输入批次行数相同；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68018b416d7ccc67a0ada" style="list-style-type:decimal"><li>顺序相同；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680678f1afe626cd9e3b4" style="list-style-type:decimal"><li>不能过滤、排序、复制行；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680649555fd34ab2a0ff5" style="list-style-type:decimal"><li>不同 Worker 使用不同 shard index，但 shard count 必须一致。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd680af9e5fe51fa3e44106"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680b79299ce1abe828f5b" data-id="3fc0e3562fd680b79299ce1abe828f5b"><span><div id="3fc0e3562fd680b79299ce1abe828f5b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b79299ce1abe828f5b" title="13. Nested Field Evolution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13. Nested Field Evolution</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680d59533e29e42db4757">默认情况下，更新单位是顶层列。</div><div class="notion-text notion-block-3fc0e3562fd6802a9720c856b4b09905">例如：</div><div class="notion-text notion-block-3fc0e3562fd680e1b8f6f4e15eb75765">更新 <code class="notion-inline-code">payload.caption</code> 时，默认会把整个 <code class="notion-inline-code">payload</code> 当作更新列。</div><div class="notion-text notion-block-3fc0e3562fd680238860fedd11160bf3">启用：</div><div class="notion-text notion-block-3fc0e3562fd680a2b5b3ced400db379a">后，<code class="notion-inline-code">writeCols</code> 可以记录：</div><div class="notion-text notion-block-3fc0e3562fd6806baeeff1481488494a">Reader 会按叶子字段选择最新 Provider，并重新组合 Struct。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680429e25caa7c506bdec" data-id="3fc0e3562fd680429e25caa7c506bdec"><span><div id="3fc0e3562fd680429e25caa7c506bdec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680429e25caa7c506bdec" title="13.1 当前限制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.1 当前限制</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801fb13cc5083a38a614"><li>支持把一层 Struct 的直接子字段分散到不同文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680dabcc1e5ae58987c23"><li>不支持把更深层的同一个子 Struct 再分散到多个文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805d9374e162c72c1905"><li>顶层 Struct 整体写入与任意子字段写入会产生冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807fa443ec8851fbfa37"><li>是否支持具体赋值语法还取决于 Spark/Flink Engine。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680948fb1d69402d22951" data-id="3fc0e3562fd680948fb1d69402d22951"><span><div id="3fc0e3562fd680948fb1d69402d22951" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680948fb1d69402d22951" title="13.2 升降级风险"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">13.2 升降级风险</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68013b798d5a12764cac1">该选项具有明显的混合版本风险：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68087ab8cff19216ff1a3" style="list-style-type:decimal"><li>必须先升级所有 Reader、Writer、Compactor 和维护任务；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680148d8dd193d0d48a86" style="list-style-type:decimal"><li>只能通过持久化表选项开启；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680afa246f2bd9afca35a" style="list-style-type:decimal"><li>开启后不能关闭或删除；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680929842cec1dd090844" style="list-style-type:decimal"><li>一旦提交了嵌套路径文件，旧版本 Reader 无法正确重建；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a38d54e47e10fd9a9f" style="list-style-type:decimal"><li>二进制降级不安全。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd6801d870eca35b06bc25e"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68020882bd9091f64c266" data-id="3fc0e3562fd68020882bd9091f64c266"><span><div id="3fc0e3562fd68020882bd9091f64c266" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68020882bd9091f64c266" title="14. BLOB 和 Vector 文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14. BLOB 和 Vector 文件</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680089e2de251245cd7c4" data-id="3fc0e3562fd680089e2de251245cd7c4"><span><div id="3fc0e3562fd680089e2de251245cd7c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680089e2de251245cd7c4" title="14.1 BLOB"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.1 BLOB</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6807383e5e35643cd3418">对于托管 BLOB：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cb85f2e230c606da66"><li>Normal File 提供普通列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68095a8b1c14a8ab361b1"><li>BLOB 数据写入专用 BLOB 文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68023b12eddc7db20d90e"><li>BLOB 文件可按独立大小滚动；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a59c4ff3664e30000f"><li>每个 BLOB 文件必须包含在一个 Normal Range 中；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e4a8cad8c5a846c2d9"><li>新 BLOB 版本可以只覆盖部分范围；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d99392df8938bd51ad"><li>Placeholder 表示沿用旧值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801c8544d5e9da9ad601"><li>显式 <code class="notion-inline-code">NULL</code> 表示把值更新为 <code class="notion-inline-code">NULL</code>。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680b2b9cbed0782f8bd2a" data-id="3fc0e3562fd680b2b9cbed0782f8bd2a"><span><div id="3fc0e3562fd680b2b9cbed0782f8bd2a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b2b9cbed0782f8bd2a" title="14.2 Vector"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.2 Vector</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6809eae8bca04fff67220">专用 Vector File 可以独立于 Normal File 滚动，但读取一个完整向量列时，选中的 Vector 文件应按 Row ID 顺序完整覆盖对应 Normal Range。</div><div class="notion-text notion-block-3fc0e3562fd6800e8b32fa6894ce0138">当前维护限制：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b3a4cbdbdf6f7db0a6"><li>Dedicated Vector File Compaction 尚未支持；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808eb879d731e4087605"><li>包含 Dedicated Vector File 的组不能执行 Deletion Vector Materialization。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6802ebb82c00c0e18e816" data-id="3fc0e3562fd6802ebb82c00c0e18e816"><span><div id="3fc0e3562fd6802ebb82c00c0e18e816" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6802ebb82c00c0e18e816" title="14.3 Flink BLOB 更新注意"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">14.3 Flink BLOB 更新注意</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680bb9e2ae6f342f5dc43">Flink procedure 支持多种 BLOB 更新形态，但托管 BLOB 值会进入 Merge Sort Buffer。</div><div class="notion-text notion-block-3fc0e3562fd68071bbfef601081c2823">单行托管 BLOB 如果大于 <code class="notion-inline-code">write-buffer-size</code>（默认 256 MB），任务会失败。</div><hr class="notion-hr notion-block-3fc0e3562fd68097ab2cf57f6a9e31d7"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68006bf5cc7bac8e41cbc" data-id="3fc0e3562fd68006bf5cc7bac8e41cbc"><span><div id="3fc0e3562fd68006bf5cc7bac8e41cbc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68006bf5cc7bac8e41cbc" title="15. 删除与 Deletion Vector"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15. 删除与 Deletion Vector</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d7a312d7e2b7aca886" data-id="3fc0e3562fd680d7a312d7e2b7aca886"><span><div id="3fc0e3562fd680d7a312d7e2b7aca886" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d7a312d7e2b7aca886" title="15.1 为什么不能直接移除位置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.1 为什么不能直接移除位置</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68049a504c5de1a3915de">假设范围为 <code class="notion-inline-code">[0, 5]</code>，删除 Row ID 2。</div><div class="notion-text notion-block-3fc0e3562fd680349327e2aeb1cf27b3">如果直接把物理位置移除，后面的 Row ID 会错位：</div><div class="notion-text notion-block-3fc0e3562fd68034bd78e6f38b41af0e">其他列文件仍然有 6 个位置，无法继续按位置合并。</div><div class="notion-text notion-block-3fc0e3562fd6801a96bcc32203f29218">因此普通删除只写 Deletion Vector：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6809ea75ee6b9b133f078" data-id="3fc0e3562fd6809ea75ee6b9b133f078"><span><div id="3fc0e3562fd6809ea75ee6b9b133f078" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809ea75ee6b9b133f078" title="15.2 Anchor File"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.2 Anchor File</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680a391b8db1abdb279d7">同一 Row Range Group 中最老的 Normal File 是 Anchor File。</div><div class="notion-text notion-block-3fc0e3562fd680c99f71c3c50b38dd68">排序规则：</div><div class="notion-text notion-block-3fc0e3562fd6801bb144f9f89eac49b4">Deletion Vector 关联到 Anchor，读取时应用到整个逻辑文件组，从而同时隐藏：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d98fe6e3b33e09d54d"><li>普通列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e5b42ccaf2bab1539a"><li>BLOB；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680419e65fbc742d30178"><li>Vector。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6800da90ee7946e9ef42c" data-id="3fc0e3562fd6800da90ee7946e9ef42c"><span><div id="3fc0e3562fd6800da90ee7946e9ef42c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6800da90ee7946e9ef42c" title="15.3 Spark 删除"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.3 Spark 删除</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680c89c3ef2b758bc2504">或者：</div><div class="notion-text notion-block-3fc0e3562fd68032a16bfe1e870635dc">必须配置：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6806e9d21f61e19d5c84b" data-id="3fc0e3562fd6806e9d21f61e19d5c84b"><span><div id="3fc0e3562fd6806e9d21f61e19d5c84b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6806e9d21f61e19d5c84b" title="15.4 Flink 删除"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">15.4 Flink 删除</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680f387f1e6ab5b58609f">Flink 1.17+ 可以在 Batch 模式执行：</div><div class="notion-text notion-block-3fc0e3562fd680ddaacadeea3763c9bd">也可以提交 <code class="notion-inline-code">delete</code> Action。Action 会固定一个 <code class="notion-inline-code">$row_tracking</code> Snapshot，找到匹配 Row ID 并写入 Deletion Vector。</div><hr class="notion-hr notion-block-3fc0e3562fd680b09096c366af655c0a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680db8d7ff3a503c35e97" data-id="3fc0e3562fd680db8d7ff3a503c35e97"><span><div id="3fc0e3562fd680db8d7ff3a503c35e97" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680db8d7ff3a503c35e97" title="16. 并发与冲突检测"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16. 并发与冲突检测</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6806bb43fef5e443bcbf6">Data Evolution 的并发冲突分为两类。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6803d9f28d08a38b84766" data-id="3fc0e3562fd6803d9f28d08a38b84766"><span><div id="3fc0e3562fd6803d9f28d08a38b84766" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6803d9f28d08a38b84766" title="16.1 Layout Conflict"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.1 Layout Conflict</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680358578c8a789d045d0">操作基于旧 Snapshot 计划时，认为 Normal Range 是：</div><div class="notion-text notion-block-3fc0e3562fd680c183c8f42da7c009e9">在提交前，另一个 compaction 把它们合并为：</div><div class="notion-text notion-block-3fc0e3562fd68071b882ff0565c65103">Row ID 没变，但文件边界变了。旧 Writer 生成的 <code class="notion-inline-code">[0, 5]</code> 部分列文件不再符合当前布局。</div><div class="notion-text notion-block-3fc0e3562fd68062aac2dabd584b7812">这属于 Row ID Range/Layout Conflict。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6808b8ff3f99abee6666a" data-id="3fc0e3562fd6808b8ff3f99abee6666a"><span><div id="3fc0e3562fd6808b8ff3f99abee6666a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6808b8ff3f99abee6666a" title="16.2 Logical Update Conflict"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.2 Logical Update Conflict</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68094a8ecd46d9027bf5e">冲突判断不仅看 Range，还看写入字段 ID：</div><div class="notion-text notion-block-3fc0e3562fd6803e8eb9d20d6f7709ec">两个写入范围相同，但列不重叠，可以不构成列更新冲突。</div><div class="notion-text notion-block-3fc0e3562fd6808482caf4a9bec23d7d">即使两个 Predicate 命中了不同业务行，也会冲突，因为两个文件都覆盖完整 <code class="notion-inline-code">[0,5]</code> 范围，并且都替换 <code class="notion-inline-code">b</code>。</div><div class="notion-text notion-block-3fc0e3562fd6801482fded5b00f2172c">冲突条件可简化为：</div><div class="notion-text notion-block-3fc0e3562fd680ea9006ea87a459b492">Nested Field 开启时，冲突会细化到叶子字段；但整列 Struct 更新会与其任意子字段更新冲突。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680a2b937de4143262503" data-id="3fc0e3562fd680a2b937de4143262503"><span><div id="3fc0e3562fd680a2b937de4143262503" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a2b937de4143262503" title="16.3 Compaction 后 Rebase"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">16.3 Compaction 后 Rebase</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680f3bb51e83f35baa17a">Spark MERGE 可以在并发 compaction 改变边界后，把已写出的普通部分列文件重新映射到最新范围，而不重新执行 source 和 join。</div><div class="notion-text notion-block-3fc0e3562fd68053a893d7f77f34f13e">PyPaimon 也支持类似恢复，大小由：</div><div class="notion-text notion-block-3fc0e3562fd68054aeb8ea22fc7b4f57">限制。设置为 <code class="notion-inline-code">0 B</code> 可关闭。</div><div class="notion-text notion-block-3fc0e3562fd68020a983d8fbe0d47262">以下情况不执行这种恢复：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680fca3e9fdf9d02292ba"><li>启用了 Deletion Vector；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807ba8cfcb98044f1674"><li>同一提交包含已有行的 BLOB 文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c6b218d95f666b673c"><li>同一提交包含已有行的 Vector 文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d9a117c25f9d15b963"><li>存在真正的同列并发更新冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68037b4afc27476889c6a"><li>当前文件总大小超过 PyPaimon 配置上限。</li></ul><hr class="notion-hr notion-block-3fc0e3562fd680328e8bc820dce2d91b"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6808bb30de223a2ff8949" data-id="3fc0e3562fd6808bb30de223a2ff8949"><span><div id="3fc0e3562fd6808bb30de223a2ff8949" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6808bb30de223a2ff8949" title="17. Compaction"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17. Compaction</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6809e81dbea2658e0359c" data-id="3fc0e3562fd6809e81dbea2658e0359c"><span><div id="3fc0e3562fd6809e81dbea2658e0359c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809e81dbea2658e0359c" title="17.1 普通 Data Evolution Compaction"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17.1 普通 Data Evolution Compaction</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68097a272e40737013e7a">目的：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680aa9cd4f3d963b1b252"><li>合并多次部分列更新；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68065800ec7712ae61f7f"><li>降低读取文件数；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ef9bd5f3dcc6335172"><li>合并相邻 Normal Range；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801a9c78d797d5b5ca10"><li>保留 Row ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680269f64ff564fe0ed0d"><li>保留逻辑删除；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e3bedfccedeae42cac"><li>保留字段版本信息。</li></ul><div class="notion-text notion-block-3fc0e3562fd680169b93ebf22a510838">例如：</div><div class="notion-text notion-block-3fc0e3562fd680e28b26ebaf6984869d">逻辑值不变，Row ID 不变。</div><div class="notion-text notion-block-3fc0e3562fd680c28915fcc551d64330">普通 compaction 不会物理删除被 Deletion Vector 隐藏的位置，因为这会破坏未重写列文件的对齐。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680b6b1e0d854366cce5d" data-id="3fc0e3562fd680b6b1e0d854366cce5d"><span><div id="3fc0e3562fd680b6b1e0d854366cce5d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b6b1e0d854366cce5d" title="17.2 合并相邻范围"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17.2 合并相邻范围</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680b1b78cd6d6575d6b68">普通 compaction 可以：</div><div class="notion-text notion-block-3fc0e3562fd680359143fcf833e3e44c">Row ID 不变，但边界改变，这也是并发部分列写入可能遇到 Layout Conflict 的原因。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680bb9d59c4bc8b13aa5d" data-id="3fc0e3562fd680bb9d59c4bc8b13aa5d"><span><div id="3fc0e3562fd680bb9d59c4bc8b13aa5d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bb9d59c4bc8b13aa5d" title="17.3 拆分大 Normal File"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17.3 拆分大 Normal File</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680ca9eeadbefecf90183">配置：</div><div class="notion-text notion-block-3fc0e3562fd680698284ef00ba000510">只有文件严格大于：</div><div class="notion-text notion-block-3fc0e3562fd6807ba4b5e20e8cdf3a67">才会因为“大文件”被选择。</div><div class="notion-text notion-block-3fc0e3562fd6809b9987fd95852f0242">拆分时：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805b82eefae065191780"><li>只重写 Normal File；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801caa18cec88d042d1f"><li>Row ID 保持不变；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808092cddfb8bdf88ff6"><li>BLOB/Vector 文件不重写；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68023bcd3d6b15cce35b9"><li>切分点不能落在 Dedicated File Range 内；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800681dbc440691e4533"><li>实际输出大小可能大于目标值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680399c31f64fd9c00bae"><li>Dedicated Range 如果阻止所有安全切分，则不会仅因大小触发任务。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68063ad37d909b1506a41" data-id="3fc0e3562fd68063ad37d909b1506a41"><span><div id="3fc0e3562fd68063ad37d909b1506a41" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68063ad37d909b1506a41" title="17.4 BLOB Compaction"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">17.4 BLOB Compaction</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68004b10cce6f6fb3fb16">默认关闭，应根据 BLOB 文件碎片情况单独决定是否开启。</div><div class="notion-text notion-block-3fc0e3562fd680e886cdcbc40e1499e3">Vector Dedicated Compaction 当前未支持。</div><hr class="notion-hr notion-block-3fc0e3562fd680e19449c5a000f827ed"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680cc8490c9ecc1760011" data-id="3fc0e3562fd680cc8490c9ecc1760011"><span><div id="3fc0e3562fd680cc8490c9ecc1760011" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680cc8490c9ecc1760011" title="18. Deletion Vector Materialization"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">18. Deletion Vector Materialization</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680b18994d62b53f207ed">当需要真正移除删除位置时，运行：</div><div class="notion-text notion-block-3fc0e3562fd6803d83a9eb949a63f4bb">该过程会：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680fcb7f4e373d01dfe37" style="list-style-type:decimal"><li>读取受影响文件组；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6804c890ef1db00093a63" style="list-style-type:decimal"><li>应用 Deletion Vector；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680e1a8add3ad60480831" style="list-style-type:decimal"><li>只写存活行；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680c893bdc6583b2656b7" style="list-style-type:decimal"><li>为存活行分配新 Row ID；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6804c9a56e28a7000a7ba" style="list-style-type:decimal"><li>删除已物化的 Deletion Vector；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ef8e74d3b71585c0ba" style="list-style-type:decimal"><li>删除受影响的 Global Index；</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68083932fdb5d5e818293" style="list-style-type:decimal"><li>对受影响 Row Range 做并发冲突检查。</li></ol><div class="notion-text notion-block-3fc0e3562fd6805b9e1fda9f1eea4ff1">因此它与普通 compaction 的关键区别是：</div><table class="notion-simple-table notion-block-3fc0e3562fd68033b184dece84749afa"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd68092b26ef56fe5349a3e"><td class="" style="width:120px"><div class="notion-simple-table-cell">操作</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">删除位置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Row ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680ea9252d7910c0de35d"><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留逻辑删除位置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e58be0ce1d04360e3b"><td class="" style="width:120px"><div class="notion-simple-table-cell">Materialize DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">物理移除删除位置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">重新分配</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd680f8abb8e9ed86633c32">当前不支持物化包含 Dedicated Vector File 的文件组。</div><div class="notion-text notion-block-3fc0e3562fd680d99104d6cc5bec0fa2">历史 Snapshot 或 Tag 仍可能引用旧文件。只有引用过期并执行 Snapshot Expiration 后，存储空间才会被真正回收。</div><hr class="notion-hr notion-block-3fc0e3562fd680fe8280e5eececfcfb8"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68081b956d2817ba04d71" data-id="3fc0e3562fd68081b956d2817ba04d71"><span><div id="3fc0e3562fd68081b956d2817ba04d71" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68081b956d2817ba04d71" title="19. Global Index 与 Data Evolution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">19. Global Index 与 Data Evolution</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680229c9ecea62d327d5d" data-id="3fc0e3562fd680229c9ecea62d327d5d"><span><div id="3fc0e3562fd680229c9ecea62d327d5d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680229c9ecea62d327d5d" title="19.1 为什么索引会过期"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">19.1 为什么索引会过期</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68045b089f0576173593e">Global Index 通常保存：</div><div class="notion-text notion-block-3fc0e3562fd680cb9edadd33025b712d">Data Evolution 更新列时 Row ID 不变，但列值可能改变：</div><div class="notion-text notion-block-3fc0e3562fd680edada2f3d2ccacefe7">旧索引仍把 <code class="notion-inline-code">a200</code> 指向 Row ID 100，因此索引已过期。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6807dbcd3cc5d99a0c8b8" data-id="3fc0e3562fd6807dbcd3cc5d99a0c8b8"><span><div id="3fc0e3562fd6807dbcd3cc5d99a0c8b8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6807dbcd3cc5d99a0c8b8" title="19.2 更新索引列的策略"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">19.2 更新索引列的策略</span></span></h4><table class="notion-simple-table notion-block-3fc0e3562fd6809cb195ec8ab0d8e15e"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd68028ba30e2b825dab524"><td class="" style="width:120px"><div class="notion-simple-table-cell">值</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">行为</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680cda9dac89a3e629098"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">THROW_ERROR</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认值，拒绝更新已建立 Global Index 的列</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809e8727cbf97c223d0b"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DROP_PARTITION_INDEX</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">提交更新时删除受影响分区索引</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68080b2d6d09160280c0a"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">IGNORE</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留旧索引，之后必须刷新或重建</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd6806b9407f0852d999583">使用 <code class="notion-inline-code">IGNORE</code> 时：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804489a7c32d7ee453c9"><li>Spark、Flink 增量构建可根据索引源元数据定位发生变化的 Row Range；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68018b9a7cdbc7c14000e"><li>老索引没有 Data Evolution Source Metadata 时不能自动增量刷新；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803e9f65fc3e7f19bbcf"><li>PyPaimon 当前的增量构建主要补未覆盖范围，已覆盖行发生值更新后应显式删除并重建相关索引。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680dfa1bac7c858312e65" data-id="3fc0e3562fd680dfa1bac7c858312e65"><span><div id="3fc0e3562fd680dfa1bac7c858312e65" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680dfa1bac7c858312e65" title="19.3 Search Mode 与覆盖范围"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">19.3 Search Mode 与覆盖范围</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680c9b3a6fc47160d1a98">索引覆盖和索引新鲜度是两个不同概念：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e4afccd3683b1d4321"><li>Coverage：这个 Row ID Range 是否有索引文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68055b7bcebf72df5fcaf"><li>Freshness：索引中的值是否仍然是最新列值。</li></ul><div class="notion-text notion-block-3fc0e3562fd6805aa80efc311f6d7961"><code class="notion-inline-code">detail</code> 等搜索模式可以补扫未覆盖范围，但不能自动识别“覆盖范围内的旧值”。</div><hr class="notion-hr notion-block-3fc0e3562fd68024bf91fc816e69785a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6807db947f2e18c16c442" data-id="3fc0e3562fd6807db947f2e18c16c442"><span><div id="3fc0e3562fd6807db947f2e18c16c442" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6807db947f2e18c16c442" title="20. 与 Lance、LanceDB 和 Apache Iceberg 的对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20. 与 Lance、LanceDB 和 Apache Iceberg 的对比</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680859ee6e95e5c795dcb">Data Evolution 并不是 Paimon 独有的需求。随着湖仓系统开始承载图片、音视频、Embedding、模型分数和大量派生特征，多个项目都在解决同一个问题：</div><blockquote class="notion-quote notion-block-3fc0e3562fd680b9a7d1dfbffb9abd63"><div>如何只写发生变化的列，同时保持行身份、快照隔离、索引正确性和可维护性？</div></blockquote><div class="notion-text notion-block-3fc0e3562fd6807cb364cbdf888b3fa6">Lance 已经具备成熟的整列追加和整列替换能力，并正在设计更细粒度的 Data Overlay；LanceDB 在其上提供面向特征工程和检索的高级接口。Iceberg 现有 Copy-on-Write 和 Merge-on-Read 仍主要工作在行粒度，但 V4 规范和社区开发计划已经明确加入 Column File。</div><div class="notion-text notion-block-3fc0e3562fd680709097c716db1aae1e">本章以 2026-10-17 时各项目的官方文档、格式规范、主分支行为和公开 Roadmap 为依据。由于 LanceDB 与 Lance Core 的发布节奏并不完全同步，对只存在于最新格式设计中的能力会单独标记为实验性，不假设上层产品已经公开支持。</div><div class="notion-text notion-block-3fc0e3562fd6807d870ff8a6d4d25624">这里需要区分三个 Lance 相关概念：</div><table class="notion-simple-table notion-block-3fc0e3562fd680aea607c06ec096bdaa"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680d0a1e2f40157be6c87"><td class="" style="width:120px"><div class="notion-simple-table-cell">名称</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">含义</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808cbb14d7e28aea8512"><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance File Format</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持独立列文件、Fragment、随机访问和索引的底层格式与 Dataset 实现</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f9a683ccea6bb5d976"><td class="" style="width:120px"><div class="notion-simple-table-cell">LanceDB</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">基于 Lance 的检索数据库和 SDK，提供 Update、Merge Insert、Feature Engineering、Vector/FTS 等高级能力</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e2994ae5308e3ff2a7"><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon <code class="notion-inline-code">file.format=lance</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon 使用 Lance 编码读写物理数据文件，表元数据、快照、Row ID、冲突和 Compaction 仍由 Paimon 管理</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd6806ca5a8dee97bc4f4a6">因此：</div><blockquote class="notion-quote notion-block-3fc0e3562fd6809aa6bfc6eab0312d2e"><div>在 Paimon 中选择 Lance 作为文件格式，不等于把 Paimon 表转换成 Lance Dataset，也不会自动使用 Lance 的 Fragment、Transaction 或 Stable Row ID 语义。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680f8847ed410aa3d8e2c" data-id="3fc0e3562fd680f8847ed410aa3d8e2c"><span><div id="3fc0e3562fd680f8847ed410aa3d8e2c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f8847ed410aa3d8e2c" title="20.1 三者共同要解决的问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.1 三者共同要解决的问题</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680b1ac5dfe40a37c21ab">三种设计都面对同样的写放大问题。</div><div class="notion-text notion-block-3fc0e3562fd680b8bc2cfaee108b10f2">假设一行包括：</div><div class="notion-text notion-block-3fc0e3562fd6802cb997c3388ea007d0">如果只更新 <code class="notion-inline-code">model_score</code>，传统 Row Rewrite 可能重写整行，甚至重新处理大型图片。列级更新希望把写入缩小为：</div><div class="notion-text notion-block-3fc0e3562fd680b99bf1ff886ca2e95e">三者的共同思想是：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6807aaceafac398671c22" style="list-style-type:decimal"><li>逻辑行不再要求全部列位于一个物理文件；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a99d9fe9f8816a0130" style="list-style-type:decimal"><li>数据文件需要某种稳定的位置或行身份；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6808eac44f3915a4afcd5" style="list-style-type:decimal"><li>Reader 负责把多个物理来源拼成逻辑行；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680aab450c3f45ff12765" style="list-style-type:decimal"><li>更新文件积累后需要 Compaction；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806f9e35c52835291f19" style="list-style-type:decimal"><li>更新过的索引不能继续无条件使用；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6804c90f0eb7e1d854dce" style="list-style-type:decimal"><li>Snapshot 必须原子切换，不能暴露半完成状态。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680849cd5d4986c5b92e0" data-id="3fc0e3562fd680849cd5d4986c5b92e0"><span><div id="3fc0e3562fd680849cd5d4986c5b92e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680849cd5d4986c5b92e0" title="20.2 Lance 的 Fragment 模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.2 Lance 的 Fragment 模型</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68013aab0e48091bb18ae">Lance 的核心组织单位是 Fragment：</div><div class="notion-text notion-block-3fc0e3562fd680be8f9cff25a30b8511">Lance 把 Fragment 定义为“表示同一批行的多个列文件集合”。</div><div class="notion-text notion-block-3fc0e3562fd6805e856ec2b18884466b">一个 Fragment 的多个 Data File：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d38a40db1343cd88d8"><li>表示同一批物理行；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e6b4b2d49ba87d0121"><li>每个文件通过 <code class="notion-inline-code">fields</code> 声明自己保存的 Field ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802eb7b8c4592f12383c"><li>缺失列在没有其他 Provider 时读作 <code class="notion-inline-code">NULL</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803395bae031e25d6722"><li>文件按物理位置对齐；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e3a7ade4ee15ff9bf8"><li>Fragment 通过 <code class="notion-inline-code">physical_rows</code> 记录原始物理位置数；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806c9157c54d6dd851e0"><li>Deletion File 记录被逻辑删除的本地 Row Offset。</li></ul><div class="notion-text notion-block-3fc0e3562fd680d6b112cd4ccbe901a8">这与 Paimon 的 Normal Row ID Range Group 很相似：</div><div class="notion-text notion-block-3fc0e3562fd6805fac57f28b5644a0e9">但两者的身份边界不同：</div><table class="notion-simple-table notion-block-3fc0e3562fd68011a031f8b9a95f34e9"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6804489dcc4d1f7fbcfb5"><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680aabaeac70d8d87a82b"><td class="" style="width:120px"><div class="notion-simple-table-cell">文件通过 <code class="notion-inline-code">firstRowId + rowCount</code> 建立对齐</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">文件直接归属于同一个 Fragment</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68092b483c50537479851"><td class="" style="width:120px"><div class="notion-simple-table-cell">相同范围的 Normal File 构成文件组</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment 元数据显式包含多个列文件</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f8afd5c8c7045d9cdc"><td class="" style="width:120px"><div class="notion-simple-table-cell">Dedicated File 可覆盖 Normal Range 的子区间</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment Base Data File 通常描述同一组物理行</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806f80ddd3baf98580c7"><td class="" style="width:120px"><div class="notion-simple-table-cell">Compaction 可以合并相邻 Row ID Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Compaction 可以合并或重写 Fragment</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680ddaef0c4b7cb2842c7" data-id="3fc0e3562fd680ddaef0c4b7cb2842c7"><span><div id="3fc0e3562fd680ddaef0c4b7cb2842c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680ddaef0c4b7cb2842c7" title="20.3 Lance 增加和回填新列"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.3 Lance 增加和回填新列</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680bf95c8ce35eaab2441">Lance 的新增列能力支持三种重要模式。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680a3ab47deaefd3af924" data-id="3fc0e3562fd680a3ab47deaefd3af924"><span><div id="3fc0e3562fd680a3ab47deaefd3af924" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a3ab47deaefd3af924" title="20.3.1 只增加 Schema"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.3.1 只增加 Schema</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68097926ef3cab7896d5b">该模式只更新元数据。旧 Fragment 不包含新列文件，Reader 为历史行补 <code class="notion-inline-code">NULL</code>。它与 Paimon 单纯增加一个可空列的初始效果相同：只增加列定义，不自动计算历史值。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680be833ac0d394e5e9a7" data-id="3fc0e3562fd680be833ac0d394e5e9a7"><span><div id="3fc0e3562fd680be833ac0d394e5e9a7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680be833ac0d394e5e9a7" title="20.3.2 增加列并立即回填"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.3.2 增加列并立即回填</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680b1b38ae84145c4091f">Lance 可以通过 SQL 表达式计算新列，也可以通过批处理函数计算 Embedding、模型输出等复杂结果。耗时函数还可以使用 Checkpoint，失败后从已完成批次继续。</div><div class="notion-text notion-block-3fc0e3562fd680c38a13fa01102b925a">实现会逐个 Fragment 读取必要输入列，并为新列写出额外 Data File，而不重写旧列文件。</div><div class="notion-text notion-block-3fc0e3562fd680eda122ee332c6454f7">其逻辑结构为：</div><div class="notion-text notion-block-3fc0e3562fd68083a406c403286d3c6d">与 Paimon Shard Update 的共同点是：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805cac38d2ecd0fce30c"><li>按已有物理顺序读取；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808ab689e9dcd2b55b83"><li>输出行数和顺序必须保持一致；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680bdbd07c3d40a59c691"><li>只写新列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680eaa970f0da25e236ae"><li>不复制大型未更新列。</li></ul><div class="notion-text notion-block-3fc0e3562fd680449a58d904a79d2277">Lance 的 API 对 Batch UDF 和 Checkpoint 支持更直接；Paimon 的优势是同一存储语义已经接入 Spark SQL、Flink Procedure 和 PyPaimon。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680bfabb0c2404538fcec" data-id="3fc0e3562fd680bfabb0c2404538fcec"><span><div id="3fc0e3562fd680bfabb0c2404538fcec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bfabb0c2404538fcec" title="20.4 Lance 整列替换"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.4 Lance 整列替换</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680268eb3c9e018655d5a">Lance 的整列替换事务用于替换现有 Fragment 的列文件。它把“目标 Fragment”和“新的列文件”作为一个原子替换单元提交。</div><div class="notion-text notion-block-3fc0e3562fd680459592faa073c27819">要求：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6803cbf01d88725494b2c" style="list-style-type:decimal"><li>目标字段必须已经存在于 Dataset Schema；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68046ba0ed58e7418b0bf" style="list-style-type:decimal"><li>当前 API 按顶层列整体替换，不能只暂存一个嵌套叶子字段；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68015b704d4f3028b8530" style="list-style-type:decimal"><li>输入必须产生与 Fragment <code class="notion-inline-code">physical_rows</code> 完全相同的行数；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680aba3dbf683eaab4110" style="list-style-type:decimal"><li>输入包含被删除的物理位置，不能先应用 Deletion File 后缩短；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680c1ab80ef42ed5352bf" style="list-style-type:decimal"><li>新文件与 Fragment 按物理位置对齐；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ddbe31d43ff2e2a118" style="list-style-type:decimal"><li>调用方需要基于正确 Read Version 提交，才能检测同字段并发替换。</li></ol><div class="notion-text notion-block-3fc0e3562fd68033b63ad05ec806e006">这与 Paimon Normal Partial File 的契约高度相似：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68058996bd81760439076" data-id="3fc0e3562fd68058996bd81760439076"><span><div id="3fc0e3562fd68058996bd81760439076" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68058996bd81760439076" title="20.5 Lance 列重写与 Paimon 部分列 MERGE"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.5 Lance 列重写与 Paimon 部分列 MERGE</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6800f8fe7cb3726b0ad83">Lance Merge Insert 提供两种写入形态：</div><div class="notion-text notion-block-3fc0e3562fd680b8b255d2763ea2a76a">列重写模式的语义是：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f39f0dc1be21d61053"><li>Source 只携带 Join Key 和待更新列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680eeb074fe1b11fe4ac8"><li>不读写 Source 省略的列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b3b923d576ac91695a"><li>在命中的 Fragment 上附加新的列文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806aa336cb2524ae8d73"><li>新列文件仍覆盖整个 Fragment；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680bf994bf6cd76b97de7"><li>未命中行需要保留原值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a7a12fd296a889b0b6"><li>不移动逻辑行，也不新增 Fragment；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804ca268cb75ca9c4c69"><li>Commit 会声明这是保持行位置不变的列重写；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805ab5afe35f7fbc0b5a"><li>提交元数据记录被修改字段，用于处理索引覆盖失效；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68055b5d6f3d14ce7ae38"><li>提交元数据记录实际命中位置，用于更新 Stable Row ID 的行级版本信息。</li></ul><div class="notion-text notion-block-3fc0e3562fd680f3b2c7f7049feb5da6">这几乎就是 Paimon Data Evolution MERGE 的 Lance 对应物：</div><div class="notion-text notion-block-3fc0e3562fd68058b16dc81638f0246d">Lance 文档还给出了一个重要成本模型：</div><div class="notion-text notion-block-3fc0e3562fd6800db26de2dca06e313d">可以用近似条件选择：</div><div class="notion-text notion-block-3fc0e3562fd680ff8011d8cc7a7cd802">例如：</div><div class="notion-text notion-block-3fc0e3562fd6801e9544cae5d7acd090">只要一个 Fragment 中更新超过约 0.1% 的行，整列替换就可能比移动完整行更便宜。</div><div class="notion-text notion-block-3fc0e3562fd680c99a99f9c409dedce2">Paimon Data Evolution 当前主要采用整列范围写法，没有在普通 UPDATE 中自动切换为 Row Rewrite。其优势是模型统一、未更新 BLOB 不动；代价是极稀疏普通列更新仍会处理完整 Normal Range。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6804ea2c6f1266ac0da6a" data-id="3fc0e3562fd6804ea2c6f1266ac0da6a"><span><div id="3fc0e3562fd6804ea2c6f1266ac0da6a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6804ea2c6f1266ac0da6a" title="20.6 Lance 普通 UPDATE 与 Paimon UPDATE 不完全相同"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.6 Lance 普通 UPDATE 与 Paimon UPDATE 不完全相同</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68026ba38ebb1e92b5304">Lance 普通行更新默认采用 Row Rewrite。</div><div class="notion-text notion-block-3fc0e3562fd6807491a2f21e07ff9276">其执行方式是：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680b59091ce4a586994ad" style="list-style-type:decimal"><li>找出匹配行；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680d1ad0ce30381314140" style="list-style-type:decimal"><li>将旧物理行加入 Deletion File；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680b1b744cb8dd224d892" style="list-style-type:decimal"><li>写出包含更新后完整行的新 Fragment；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6804d90d3c8456e360016" style="list-style-type:decimal"><li>Stable Row ID 开启时把原 Row ID 复制给新物理行；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680cc9c64d6bee23a9d60" style="list-style-type:decimal"><li>新地址替换旧地址。</li></ol><div class="notion-text notion-block-3fc0e3562fd6804da415c74cbd605d65">因此不能笼统地说：</div><blockquote class="notion-quote notion-block-3fc0e3562fd680428fdff4bbbb88e566"><div>Lance 的所有 UPDATE 都是列级更新。</div></blockquote><div class="notion-text notion-block-3fc0e3562fd6804dabf1c345734f9f0f">更准确的说法是：</div><table class="notion-simple-table notion-block-3fc0e3562fd6804ab550e6e6696630c9"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680529599d14b13264d4a"><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance 操作</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">物理更新粒度</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6800daef2d3dba4a9a128"><td class="" style="width:120px"><div class="notion-simple-table-cell">新增列并回填</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">给每个 Fragment 增加新列文件</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680a985f8e7df724b1854"><td class="" style="width:120px"><div class="notion-simple-table-cell">整列替换</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">替换 Fragment 的完整列文件</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f5befccb830999b402"><td class="" style="width:120px"><div class="notion-simple-table-cell">Merge Insert 列重写</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">更新选中列，但文件覆盖完整命中 Fragment</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68035a37fe12b5a862c32"><td class="" style="width:120px"><div class="notion-simple-table-cell">普通行更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认删除旧物理行并写完整新行</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680bea813d056a990cb19"><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Overlay</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">只写变化 Cell，目前实验性</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd68017a3f1c351b3055f04">Paimon Data Evolution 表的 Spark <code class="notion-inline-code">UPDATE</code> 和匹配型 <code class="notion-inline-code">MERGE</code> 默认走部分列文件语义，这是两者 API 默认行为的重要差异。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6804eaab0d690e0b6c8a6" data-id="3fc0e3562fd6804eaab0d690e0b6c8a6"><span><div id="3fc0e3562fd6804eaab0d690e0b6c8a6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6804eaab0d690e0b6c8a6" title="20.7 Stable Row ID 对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.7 Stable Row ID 对比</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680448656e69b0a6bbfec" data-id="3fc0e3562fd680448656e69b0a6bbfec"><span><div id="3fc0e3562fd680448656e69b0a6bbfec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680448656e69b0a6bbfec" title="Paimon"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Paimon</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680eaa0fbfd3cc53c3e1b">Paimon Row ID 以文件范围元数据为基础：</div><div class="notion-text notion-block-3fc0e3562fd6805d8c56cd9e256dee95">普通更新和普通 Compaction 保留 Row ID。Deletion Vector Materialization 会移除位置，并为重写范围中的存活行重新分配 Row ID。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680719344fe8dc29318ff" data-id="3fc0e3562fd680719344fe8dc29318ff"><span><div id="3fc0e3562fd680719344fe8dc29318ff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680719344fe8dc29318ff" title="Lance"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Lance</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680319360c9dfb7cf754b">Lance 同时区分：</div><div class="notion-text notion-block-3fc0e3562fd6805a8198d2d0535263dc">未开启 Stable Row ID 时，<code class="notion-inline-code">_rowid</code> 实际等同于物理 Row Address，会在 Compaction 或 Row Rewrite 后变化。</div><div class="notion-text notion-block-3fc0e3562fd68017b34de83d745c18e5">开启 Stable Row ID 后：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801aa3d7fa33956e2992"><li>新行从 Manifest 的 <code class="notion-inline-code">next_row_id</code> 单调分配；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680728a8de7058379ee10"><li>Fragment 保存 Row ID Sequence；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808ab0c1ee8e6fc8644d"><li>Update 把同一 Stable Row ID 搬到新物理地址；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806d8f4befa67e52127b"><li>旧物理位置通过 Deletion File 隐藏；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680bcbd2fd5dc3f8f4900"><li>Compaction 可以删除物理墓碑，但保留存活行的 Stable Row ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680dd83e3cc53d35dacb4"><li>Row ID Sequence 可以内联在 Manifest，也可以溢写到隐藏列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802787cee85d28a9eed1"><li><code class="notion-inline-code">_row_created_at_version</code> 和 <code class="notion-inline-code">_row_last_updated_at_version</code> 支持增量处理和 Change Feed。</li></ul><div class="notion-text notion-block-3fc0e3562fd680f4abfbecf68dc18de9">对比：</div><table class="notion-simple-table notion-block-3fc0e3562fd680c38470ee33f2a5740f"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680f58854d30e9aa1d7b4"><td class="" style="width:120px"><div class="notion-simple-table-cell">行身份特性</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e0990cf4138f8a96c6"><td class="" style="width:120px"><div class="notion-simple-table-cell">默认是否开启</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Evolution 必须开启 Row Tracking</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认可不开启 Stable Row ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680b0b1cdcb6480610ca0"><td class="" style="width:120px"><div class="notion-simple-table-cell">物理地址</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不作为主要公开模型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">fragmentId + localOffset</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68013a4b1efe6c19883f1"><td class="" style="width:120px"><div class="notion-simple-table-cell">逻辑 ID 存储</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要通过 <code class="notion-inline-code">firstRowId + position</code> 推导</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment Row ID Sequence</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f386d4e027f02d765b"><td class="" style="width:120px"><div class="notion-simple-table-cell">Update 后</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留原 ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开启 Stable ID 时保留</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68055be80cab9e5e6d025"><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留 ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开启 Stable ID 时保留</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68071bd6ae3a578c147e5"><td class="" style="width:120px"><div class="notion-simple-table-cell">物理删除墓碑</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Materialize DV 会重分配 ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可重写物理文件并保留存活行 ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680d980d7e3d5aa3da256"><td class="" style="width:120px"><div class="notion-simple-table-cell">行版本元数据</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主要依赖 Snapshot 和 Sequence</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">有显式 created/last-updated version sequence</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd680768176f926d96649d5">这里 Lance 的 Stable Row ID 更接近“永久逻辑行身份”；Paimon <code class="notion-inline-code">_ROW_ID</code> 更接近“在不执行重分配维护时稳定的存储层位置标识”。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68000a383c13970ce864f" data-id="3fc0e3562fd68000a383c13970ce864f"><span><div id="3fc0e3562fd68000a383c13970ce864f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68000a383c13970ce864f" title="20.8 删除与 Compaction 对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.8 删除与 Compaction 对比</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6807d9cb5f7fb2438b1e0">两者都采用逻辑删除文件：</div><div class="notion-text notion-block-3fc0e3562fd6804ba745cebb841bb7d2">共同点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d3bdddd6db33ccf179"><li>删除不立即重写大型数据文件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cfad28e11de9a72de6"><li>删除记录的是物理位置；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a4af97e128dadcd13d"><li>Reader 在输出前过滤这些位置；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804abe14c50317c557dd"><li>历史版本仍可以引用旧数据；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68077b714c9e721a72660"><li>真正回收空间需要重写与清理历史版本。</li></ul><div class="notion-text notion-block-3fc0e3562fd6807694a4c81db2c4ed4b">主要区别：</div><table class="notion-simple-table notion-block-3fc0e3562fd68090829cdda5b0f3dcb4"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6800286d0dc63de99c677"><td class="" style="width:120px"><div class="notion-simple-table-cell">项目</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c7956ce9e9ad8b25fc"><td class="" style="width:120px"><div class="notion-simple-table-cell">删除定位</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Row Range Group 的 Anchor File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment 本地 Row Offset</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68082a9d1f172f957592b"><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保留逻辑删除位置，以维持未重写列对齐</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可以重写整个 Fragment 并移除删除位置</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e294caee904b9693f6"><td class="" style="width:120px"><div class="notion-simple-table-cell">删除物化后的 Row ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前 Paimon 会重分配受影响范围的 Row ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Stable Row ID 开启时可保留存活行 ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680db9325c9c97eff20b2"><td class="" style="width:120px"><div class="notion-simple-table-cell">专用列文件约束</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">BLOB/Vector 可能阻止切分或 DV Materialization</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">重写 Fragment 时统一处理 Fragment 文件与 Row ID Sequence</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd68013ae79c027ebda53bb">这种差异来自文件组织：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807184c7e792e82aad57"><li>Paimon 普通 Compaction 可以只重写 Normal File，同时保留 Dedicated File；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68095b677f99ca23b7cac"><li>Lance Fragment Rewrite 可以把所有当前逻辑列重新组织到新 Fragment，并通过 Row ID Sequence 保留逻辑身份。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68022adf6c0e1dae06aaa" data-id="3fc0e3562fd68022adf6c0e1dae06aaa"><span><div id="3fc0e3562fd68022adf6c0e1dae06aaa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68022adf6c0e1dae06aaa" title="20.9 Lance Data Overlay：比整列更新更细的未来方向"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.9 Lance Data Overlay：比整列更新更细的未来方向</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680bcb48ff431aba7325f">Lance 的最新格式设计中已经包含 Data Overlay 的元数据、读取、事务、冲突和维护规则，但官方格式文档明确标记：</div><div class="notion-text notion-block-3fc0e3562fd680eaaeb7fda1cd48011e">所以它代表正在开发的方向，不能当成当前稳定生产 API。</div><div class="notion-text notion-block-3fc0e3562fd680618da0d74aca2dc9e3">Data Overlay 的目标是只写变化的 Cell：</div><div class="notion-text notion-block-3fc0e3562fd6800daae4ecae72c764b1">例如，当一次更新只改变 Fragment 中第 1、3 个位置的 <code class="notion-inline-code">age</code> 时，Overlay 可以只保存：</div><div class="notion-text notion-block-3fc0e3562fd68017a2d1d0572e6dbda9">而不保存同一 Fragment 中未命中的 <code class="notion-inline-code">age</code>。</div><div class="notion-text notion-block-3fc0e3562fd680f8a198ff874d2e641a">读取规则：</div><div class="notion-text notion-block-3fc0e3562fd680dfa0d1d5326a47b0e8">这与 Paimon 的区别非常关键：</div><div class="notion-text notion-block-3fc0e3562fd6805dae8dc4897cbc80c2">从粒度看：</div><div class="notion-text notion-block-3fc0e3562fd680659589c62501a10a11">Overlay 会降低极稀疏更新的写放大，但会增加：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680379bb7fae9fcd1a21b"><li>Coverage Bitmap；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680649893c1b3870b21a8"><li>Overlay 文件打开；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f09587e9e5b22398de"><li>读取时版本查找；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800e9cfec8d80658ea23"><li>Base 与 Overlay 合并；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803d9d5ef0d2f511a3d6"><li>索引排除和重新计算；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806aab69f280705fc39c"><li>Overlay Compaction。</li></ul><div class="notion-text notion-block-3fc0e3562fd680ef8b63c938c218ad07">Lance 规划两种 Overlay Compaction：</div><div class="notion-text notion-block-3fc0e3562fd6807e9a2ed2082e4f3125">Paimon 如果未来要支持稀疏普通列更新，也会面临类似设计选择：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680fd9b52da493ae145e4"><li>是否增加 Cell Coverage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680988a87e55b5b453014"><li>如何表达显式 NULL 与未覆盖；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807db266daac7d56bf29"><li>如何与 Deletion Vector 叠加；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d89a35e97c5d015fb7"><li>如何维护字段级索引新鲜度；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68027961cf576ca2cb37d"><li>如何限制 Overlay 层数；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807c80fcd2e23fb2f79c"><li>如何在 Compaction 中折叠版本。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68040900ffec8b97963b3" data-id="3fc0e3562fd68040900ffec8b97963b3"><span><div id="3fc0e3562fd68040900ffec8b97963b3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68040900ffec8b97963b3" title="20.10 索引一致性对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.10 索引一致性对比</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd68006a170d92622bc69c2" data-id="3fc0e3562fd68006a170d92622bc69c2"><span><div id="3fc0e3562fd68006a170d92622bc69c2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68006a170d92622bc69c2" title="Paimon"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Paimon</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6807aaa80f941ad781051">Paimon Global Index 使用 Row ID Range，更新索引列时由：</div><div class="notion-text notion-block-3fc0e3562fd6801eb275f634461aa1aa">决定：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c8a482d8b7576b86f7"><li><code class="notion-inline-code">THROW_ERROR</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cc913ceb76114866fd"><li><code class="notion-inline-code">DROP_PARTITION_INDEX</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e6b0d6dc12926ff096"><li><code class="notion-inline-code">IGNORE</code> 后刷新。</li></ul><div class="notion-text notion-block-3fc0e3562fd680eba36fdcca388138f2">增量 Index Planner 根据字段版本和 Row Range 判断需要重建的索引范围。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6807ba24dd3b06657bcfc" data-id="3fc0e3562fd6807ba24dd3b06657bcfc"><span><div id="3fc0e3562fd6807ba24dd3b06657bcfc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6807ba24dd3b06657bcfc" title="Lance"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Lance</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6809885a6eaa04989d008">Lance 索引通常与 Fragment 和 Row Address/Stable Row ID 关联。</div><div class="notion-text notion-block-3fc0e3562fd68026aa9ed714a5886ddb">对于列文件替换：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c482e8d0cf8e45b860"><li>被修改字段列表用于识别失效的索引覆盖；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c89178fb24f3e278b8"><li>覆盖这些字段的索引移除受影响 Fragment Coverage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f5a034e8211bae8670"><li>查询退回 Flat Scan；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cf8edde54511e0c619"><li>后续 Optimize 或 Reindex 重新纳入。</li></ul><div class="notion-text notion-block-3fc0e3562fd68085a926d5a45778c466">对于 Row Rewrite：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e5a602f6caa4bfa39e"><li>旧地址通过 Deletion File 隐藏；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cab237f82e157fc172"><li>新物理行可能暂时未进入已有索引；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800d8278d934b0770547"><li>Flat Tail 保证仍可搜索；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680489ce2f4555fae41e7"><li>Optimize 把新行折入索引。</li></ul><div class="notion-text notion-block-3fc0e3562fd68020b59afbed989b3168">实验性 Overlay 设计则使用：</div><div class="notion-text notion-block-3fc0e3562fd6808d9916c04300ed65de">计算字段级 Exclusion Set：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68017af6ac0c0bc5f1468" style="list-style-type:decimal"><li>从索引结果排除 Overlay 更新过的位置；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802e9528e398bce7e201" style="list-style-type:decimal"><li>用当前值重新扫描和判断这些位置；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6801e9b99c5631c28a41a" style="list-style-type:decimal"><li>将仍然匹配的行补回结果。</li></ol><div class="notion-text notion-block-3fc0e3562fd6807baa1aeaceb04011d9">相比之下：</div><table class="notion-simple-table notion-block-3fc0e3562fd68070879fe52555550d38"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd68038aefaec900e7bdfa1"><td class="" style="width:120px"><div class="notion-simple-table-cell">设计</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">优点</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">代价</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c68dcec19246a0cac8"><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon Throw/Drop/Rebuild</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">语义简单，易保证正确</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">更新索引列可能阻塞或导致较大重建</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680b88fceebd166c2ffff"><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance Fragment Coverage Pruning</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">允许保留其他 Fragment 的索引</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">受影响 Fragment 暂时退化为 Flat Scan</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68066b27ac535b0e4cc1f"><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance Overlay Exclusion</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可继续利用旧索引大部分结果</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">查询链路更复杂，需要排除和重新计算</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680c4ba31ede5c005ba49" data-id="3fc0e3562fd680c4ba31ede5c005ba49"><span><div id="3fc0e3562fd680c4ba31ede5c005ba49" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680c4ba31ede5c005ba49" title="20.11 Paimon 与 Lance 的能力矩阵"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.11 Paimon 与 Lance 的能力矩阵</span></span></h4><table class="notion-simple-table notion-block-3fc0e3562fd6800ab9c5e8447a831abc"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680789dadf747e10f7bc4"><td class="" style="width:120px"><div class="notion-simple-table-cell">维度</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon Data Evolution</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance/LanceDB</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806eaf11e0fdb54785c5"><td class="" style="width:120px"><div class="notion-simple-table-cell">核心定位</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">湖仓 Append Table 的列级演进</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ML/检索优化的列式 Dataset 和数据库</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680dfba6fc30eb5950a1a"><td class="" style="width:120px"><div class="notion-simple-table-cell">物理分组</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Row ID Range Group</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68017a01bd78583ad7ec5"><td class="" style="width:120px"><div class="notion-simple-table-cell">新增空列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Schema Evolution</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Metadata-only Schema Change</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e2b200cad22e0708ba"><td class="" style="width:120px"><div class="notion-simple-table-cell">新列回填</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark/Flink/Python 部分列写</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">SQL、Batch UDF、Stream/Reader</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680cea4a9c494cba56543"><td class="" style="width:120px"><div class="notion-simple-table-cell">已有列整列替换</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">部分列文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment Column Replacement</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6804c8a3fe2f7788d8bb2"><td class="" style="width:120px"><div class="notion-simple-table-cell">匹配型列更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认 Data Evolution 路径</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Merge Insert Column Rewrite，需显式选择或由特定路径使用</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806b81d9e00f40fde0ba"><td class="" style="width:120px"><div class="notion-simple-table-cell">极稀疏更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">仍写完整 Range 的更新列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认 Row Rewrite 或整列 Fragment Rewrite</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809a89fec49a91f5c182"><td class="" style="width:120px"><div class="notion-simple-table-cell">Cell Overlay</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Main 中实验性，尚非稳定 Library 能力</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68005a71add5b0186afeb"><td class="" style="width:120px"><div class="notion-simple-table-cell">Nested Leaf 更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可选，一层组合</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Update 不支持嵌套路径；Overlay Reader 设计可按叶子合并</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808998fcffc843f5aa57"><td class="" style="width:120px"><div class="notion-simple-table-cell">BLOB</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon 托管 BLOB、Placeholder、Dedicated File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance 原生 Blob；列重写路径当前对 Blob 存在限制</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6802da5d4f20c3931fb97"><td class="" style="width:120px"><div class="notion-simple-table-cell">Vector</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Dedicated Vector File + Global Index</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">原生 Vector 类型与 ANN Index</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680a68843e4a5d3d71772"><td class="" style="width:120px"><div class="notion-simple-table-cell">Stable Row ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Evolution 必须有，但维护可重分配</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可选；开启后以 Row ID Sequence 跨 Rewrite 保持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e199d8e31eb938f0ca"><td class="" style="width:120px"><div class="notion-simple-table-cell">删除</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Deletion Vector</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Deletion File/Bitmap</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680bdaaa5d35875c0e89b"><td class="" style="width:120px"><div class="notion-simple-table-cell">删除物化</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">重分配受影响 Row ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可保留 Stable Row ID</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68091809dde0d96f07cb6"><td class="" style="width:120px"><div class="notion-simple-table-cell">SQL/引擎生态</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark、Flink、PyPaimon</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">SDK、LanceDB SQL/Enterprise、DataFusion</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68067aa30cd7aa5f76010"><td class="" style="width:120px"><div class="notion-simple-table-cell">索引更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Throw/Drop/Ignore+Refresh</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment Coverage、Flat Tail、Optimize；未来 Overlay Exclusion</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680a8854ae3fd5b45da76"><td class="" style="width:120px"><div class="notion-simple-table-cell">Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">合并列版本和 Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">合并/重写 Fragment、折叠删除、维护索引</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680aabdf0c9df779e17e1" data-id="3fc0e3562fd680aabdf0c9df779e17e1"><span><div id="3fc0e3562fd680aabdf0c9df779e17e1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680aabdf0c9df779e17e1" title="20.12 Iceberg 当前的 UPDATE 模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.12 Iceberg 当前的 UPDATE 模型</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6805a802dffc35212eaa4">Iceberg V2/V3 的 Row-Level Update 主要有两类：</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd68037b3f5f0729316e716" data-id="3fc0e3562fd68037b3f5f0729316e716"><span><div id="3fc0e3562fd68037b3f5f0729316e716" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68037b3f5f0729316e716" title="Copy-on-Write"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Copy-on-Write</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68065a41af7c992b9e92d">优点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68093bf5ccb149304dce3"><li>读取简单；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680aba302cb363f20e849"><li>最新 Snapshot 没有额外 Merge-on-Read 成本；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ea8cc1f279339561ea"><li>普通 Data File 可直接使用标准 Parquet/ORC/Avro Reader。</li></ul><div class="notion-text notion-block-3fc0e3562fd68087bc62dbc523309da6">缺点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f8b726f9e1f18a9d39"><li>更新一个窄列也会重写其他列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68047a479d2d4c99f8671"><li>宽表、Embedding 和大型载荷写放大明显。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd68060b3bdc004eea11925" data-id="3fc0e3562fd68060b3bdc004eea11925"><span><div id="3fc0e3562fd68060b3bdc004eea11925" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68060b3bdc004eea11925" title="Merge-on-Read"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Merge-on-Read</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680839a93dd81cd289028">典型更新可表达为：</div><div class="notion-text notion-block-3fc0e3562fd6803c947dd844c3727b27">V2 使用 Position Delete File，V3 可以使用 Deletion Vector。</div><div class="notion-text notion-block-3fc0e3562fd68021b38ff9235e544cc8">它减少了立即重写原文件的成本，但新行通常仍是完整 Row，不是只含更新列的 Column File。</div><div class="notion-text notion-block-3fc0e3562fd68037b75bfe8829a56991">因此在 Iceberg V4 Column File 完整落地前：</div><blockquote class="notion-quote notion-block-3fc0e3562fd680fbb661f0c03d7211fc"><div>Iceberg 有 Row-Level Update 和 Delete，但没有与 Paimon Data Evolution 等价的稳定、通用 Column Provider 读取模型。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68060bb6ace6ef4b27a05" data-id="3fc0e3562fd68060bb6ace6ef4b27a05"><span><div id="3fc0e3562fd68060bb6ace6ef4b27a05" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68060bb6ace6ef4b27a05" title="20.13 Iceberg V3 Row Lineage"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.13 Iceberg V3 Row Lineage</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68043b5f8e8d3cb68dbb3">Iceberg V3 引入：</div><div class="notion-text notion-block-3fc0e3562fd680bd9f59d5326c6b3d40">新行可以通过：</div><div class="notion-text notion-block-3fc0e3562fd680c08621d06aecfdd666">继承 Row ID。</div><div class="notion-text notion-block-3fc0e3562fd680e9ae54d295e20a7a5b">当已有行移动到新 Data File 时，Writer 应：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680d08f9af53f4fb9675b" style="list-style-type:decimal"><li>复制原 <code class="notion-inline-code">_row_id</code>；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806b92b8f9a91f331b4c" style="list-style-type:decimal"><li>修改行时把 <code class="notion-inline-code">_last_updated_sequence_number</code> 写为 <code class="notion-inline-code">NULL</code>，在提交后继承新 Sequence；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f9accadf5233e8bd2b" style="list-style-type:decimal"><li>未修改行保留原 Last Updated Sequence。</li></ol><div class="notion-text notion-block-3fc0e3562fd6806fade4c1b73b7d3d26">这与 Paimon、Lance 的共同方向一致：</div><div class="notion-text notion-block-3fc0e3562fd680c8af95e534e9bd04b2">但 Iceberg Spec 特别指出：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680fd971bc920ced20772"><li>Equality Delete 型更新无法保留原 Row ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680978608ee109c746b55"><li>因为 Writer 不读取旧行，无法知道新行对应哪个旧 Row ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809c8032d9ae75ceff12"><li>这种更新被视为删除旧行并新增一个新身份的行。</li></ul><div class="notion-text notion-block-3fc0e3562fd6806b8025fc914ea1e8b9">所以 Iceberg 的 Row ID 是否稳定，还取决于 Engine 采用何种更新路径。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68065adadfef318ad2221" data-id="3fc0e3562fd68065adadfef318ad2221"><span><div id="3fc0e3562fd68065adadfef318ad2221" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68065adadfef318ad2221" title="20.14 Iceberg V4 Column File"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.14 Iceberg V4 Column File</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68005b6fcdd0b451fac1a">Iceberg V4 规范已经增加 <code class="notion-inline-code">column_files</code>：</div><div class="notion-text notion-block-3fc0e3562fd680fc8da0c654b49c5a72">约束包括：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680199b81cc4c154632a8"><li>Column File 只能关联到 Data File 或 V4 Leaf Manifest；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ccba88f0b90373f208"><li>同一个 Field ID 在一个 Tracked File 的 Column File 列表中最多出现一次；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ddbc46eda1d947b08d"><li>Column File 更新后，当前版本使用 <code class="notion-inline-code">MODIFIED</code> Entry；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f99120d502a0372d16"><li>旧元数据通过 <code class="notion-inline-code">REPLACED</code> Entry 记录，支持 Change Detection；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68041b93ecce5f23620bb"><li>添加 Column File 时可以更新 Data Sequence Number；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808faffbca5f6ec634de"><li>Reader 需要把 Base File 和 Column File 按行位置 Stitch。</li></ul><div class="notion-text notion-block-3fc0e3562fd680daa3ddd81ad1a751bd">社区提案的目标非常明确：</div><div class="notion-text notion-block-3fc0e3562fd68070a3f8ce339b29e7c5">这与 Paimon Data Evolution 和 Lance Fragment 整列替换的核心思想相同。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680bd8f3ffac6f3ab5069" data-id="3fc0e3562fd680bd8f3ffac6f3ab5069"><span><div id="3fc0e3562fd680bd8f3ffac6f3ab5069" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bd8f3ffac6f3ab5069" title="20.15 Iceberg V4 当前实现状态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.15 Iceberg V4 当前实现状态</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680c98d23f52406a7d7ad">截至本章分析的 2026-10-17：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680188a5ef6a18e6ef21a" style="list-style-type:decimal"><li>Iceberg 主规范已经描述 V4 <code class="notion-inline-code">column_files</code>；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680c89419da8f11afb2a9" style="list-style-type:decimal"><li>V4 Adaptive Metadata Tree Spec PR 已合并；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802faec3e4958a3ab1dc" style="list-style-type:decimal"><li>主实现已支持 Format Version 4 的部分基础元数据和 Manifest 读写；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6808fb639dd7dc40524e4" style="list-style-type:decimal"><li>当前主分支中还没有完整、稳定的 Column File 公共模型和 Reader Stitching；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a0b838eb04d66741d2" style="list-style-type:decimal"><li>当前主分支中的兼容性元数据读写层还没有把 <code class="notion-inline-code">column_files</code> 完整暴露为成熟的数据文件模型；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68069ac80ef840520d1c9" style="list-style-type:decimal"><li>Column File 相关实现仍在多个开放 PR 中推进。</li></ol><div class="notion-text notion-block-3fc0e3562fd680598ea7e5dffd0ffc95">社区当前已经完成或正在推进的里程碑包括：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f69a3dcfa0869a3346" style="list-style-type:decimal"><li>V4 Adaptive Metadata Tree 规范；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68004a1e9d5580fc5a4e3" style="list-style-type:decimal"><li>Column File 的基础元数据模型；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680599cc7e193608eaf48" style="list-style-type:decimal"><li>Manifest 中 Column File 的读取；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802a81c0d300844e5090" style="list-style-type:decimal"><li>Row-based Reader 的列拼接；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680d38768f0c79f1216b6" style="list-style-type:decimal"><li>Vectorized Reader 的列向量拼接；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6805fb214c8bdddbbe04c" style="list-style-type:decimal"><li>Generic Reader、Spark、Flink 和 Encryption 的统一接入。</li></ol><div class="notion-text notion-block-3fc0e3562fd680179bcdca32e4cd11ed">因此应把 Iceberg Column File 定位为：</div><blockquote class="notion-quote notion-block-3fc0e3562fd6806abcebe082af947649"><div>已进入 V4 规范、正在快速实现，但尚不能按成熟生产能力与 Paimon Data Evolution 或 Lance 整列更新直接等同。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68070b48cf6909547b4ba" data-id="3fc0e3562fd68070b48cf6909547b4ba"><span><div id="3fc0e3562fd68070b48cf6909547b4ba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68070b48cf6909547b4ba" title="20.16 Iceberg Proposal 与 Paimon 的关键差异"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.16 Iceberg Proposal 与 Paimon 的关键差异</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68022a55fd62c5a634e3f">Iceberg Issue <code class="notion-inline-code">#15146</code> 明确说明：</div><div class="notion-text notion-block-3fc0e3562fd6809d902be86f0ba4fa80">这意味着当前 Iceberg Column Update Proposal 更接近：</div><div class="notion-text notion-block-3fc0e3562fd680efaa3ec8fe88ff9781">而 Paimon 已经支持：</div><div class="notion-text notion-block-3fc0e3562fd680e78cd6f5224d34597d">两者都在物理上写完整对齐列文件，但操作入口不同：</div><table class="notion-simple-table notion-block-3fc0e3562fd680cd9850e0b9b5849c42"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680ff849ffa11d5837030"><td class="" style="width:120px"><div class="notion-simple-table-cell">场景</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Iceberg V4 Proposal</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68061b088e3c52506ac7e"><td class="" style="width:120px"><div class="notion-simple-table-cell">全表新列回填</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">目标场景</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680eab55cd0583cabc5b4"><td class="" style="width:120px"><div class="notion-simple-table-cell">全 Data File 某列刷新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">目标场景</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6803ea411e880f8a95604"><td class="" style="width:120px"><div class="notion-simple-table-cell">Predicate 命中部分行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持，补齐 Range 内旧值</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前 Proposal 明确列为 Non-goal</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680fface2fc342f0116db"><td class="" style="width:120px"><div class="notion-simple-table-cell">行级删除</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Deletion Vector</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">V3/V4 Deletion Vector</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6807faa9ce3108a0eb622"><td class="" style="width:120px"><div class="notion-simple-table-cell">稀疏 Cell Update</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前 Proposal 不支持</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680349838e17cfac84920" data-id="3fc0e3562fd680349838e17cfac84920"><span><div id="3fc0e3562fd680349838e17cfac84920" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680349838e17cfac84920" title="20.17 三者总对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.17 三者总对比</span></span></h4><table class="notion-simple-table notion-block-3fc0e3562fd68000a5edc212779acfc6"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd68075b3f4ed0e5458bce5"><td class="" style="width:120px"><div class="notion-simple-table-cell">维度</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon Data Evolution</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance/LanceDB</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Iceberg V2/V3</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Iceberg V4 Column File</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68000bc9bd643f5f9529b"><td class="" style="width:120px"><div class="notion-simple-table-cell">当前成熟度</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">已实现</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">整列更新已实现；Overlay 实验中</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">行级更新成熟</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">规范已进入，Reader/Writer 开发中</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68009b1b0fd41c5b43100"><td class="" style="width:120px"><div class="notion-simple-table-cell">主要更新单位</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">列 × Normal Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">列 × Fragment，或完整匹配行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">完整行/Data File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">列 × Tracked Data File</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808ab15bd1b6bb5bbbbb"><td class="" style="width:120px"><div class="notion-simple-table-cell">部分行部分列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持，但写完整 Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Column Rewrite 支持；普通 Update 默认 Row Rewrite</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通过行级 MOR/COW，不是列文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前 Proposal 非目标</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680d3b4b1e80204b611df"><td class="" style="width:120px"><div class="notion-simple-table-cell">稀疏 Cell 文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Overlay 设计</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680ccb3bcff026b1ad135"><td class="" style="width:120px"><div class="notion-simple-table-cell">行身份</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">_ROW_ID</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Stable <code class="notion-inline-code">_rowid</code> 可选</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">V3 <code class="notion-inline-code">_row_id</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">继承 V3 Row Lineage</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680b0ba7fd1da4261167b"><td class="" style="width:120px"><div class="notion-simple-table-cell">删除</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Deletion File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Position/Equality Delete、DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Colocated DV</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808fb547ebc4ca3d55ea"><td class="" style="width:120px"><div class="notion-simple-table-cell">Reader 拼接</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">按 Row ID 位置合并 Provider</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment 内按位置合并 Data File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">合并 Delete 与完整行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Base + Column File Stitch</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680118babdfb708318239"><td class="" style="width:120px"><div class="notion-simple-table-cell">大对象支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">托管 BLOB、Vector Dedicated File</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Blob、Vector 原生</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">依赖 Data File 类型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Column File 可存标准格式列</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680cf8273fa1690ea5627"><td class="" style="width:120px"><div class="notion-simple-table-cell">索引</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Global Index + Row Range</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">原生 ANN/Scalar/FTS</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">外部/引擎级能力为主</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Secondary Index Spec 也在推进</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6801a9d3ded8bcbff47c2"><td class="" style="width:120px"><div class="notion-simple-table-cell">更新后索引</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Throw/Drop/Refresh</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Coverage Pruning/Flat Tail/Optimize</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通常重写或重新维护</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">实现仍在设计和开发</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680ac96e2f16b69236929"><td class="" style="width:120px"><div class="notion-simple-table-cell">Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">合并列版本；DV 物化独立</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Fragment Rewrite，可保留 Stable ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Rewrite Data Files/Delete Files</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">需要整合 Column File</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809c836aed2005488f20"><td class="" style="width:120px"><div class="notion-simple-table-cell">生态重点</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark/Flink/Python 湖仓</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ML、检索、嵌入式/服务</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">跨引擎湖仓标准</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">未来 V4 跨引擎列级更新</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6809eb394c47a96a90f9e" data-id="3fc0e3562fd6809eb394c47a96a90f9e"><span><div id="3fc0e3562fd6809eb394c47a96a90f9e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809eb394c47a96a90f9e" title="20.18 对 Paimon 设计的启示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.18 对 Paimon 设计的启示</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd68023b424d1831f93a92a" data-id="3fc0e3562fd68023b424d1831f93a92a"><span><div id="3fc0e3562fd68023b424d1831f93a92a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68023b424d1831f93a92a" title="启示一：Paimon 和 Lance 的成熟整列设计高度趋同"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启示一：Paimon 和 Lance 的成熟整列设计高度趋同</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6802a825ec161afc5fc7e">两者都选择：</div><div class="notion-text notion-block-3fc0e3562fd680dc928dff46e49a5623">这说明 Paimon 的 Row ID Range Group 并不是孤立设计，而是与 ML 数据格式的发展方向一致。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6800d8ddec264dc262348" data-id="3fc0e3562fd6800d8ddec264dc262348"><span><div id="3fc0e3562fd6800d8ddec264dc262348" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6800d8ddec264dc262348" title="启示二：Paimon 的优势在湖仓引擎集成"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启示二：Paimon 的优势在湖仓引擎集成</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68012a9bdf7ed4daf034f">Lance 在格式、随机访问、向量索引、UDF 回填和 Stable Row ID 方面更原生；Paimon 则已把列级更新统一接入：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a39efad289a41c65a7"><li>Spark SQL UPDATE/MERGE；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68011bb08ed37ee8a71e4"><li>Flink Procedure 和 Delete；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68049bda1e35594bbca15"><li>PyPaimon；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680df8b47ea5d80c18526"><li>Catalog、Snapshot、Branch、System Table；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68079bd0ae8adb76b7307"><li>BLOB/Vector/Global Index。</li></ul><div class="notion-text notion-block-3fc0e3562fd6807b9398e66118c0424a">对于已有 Flink/Spark 湖仓管道，Paimon 的使用门槛更低。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680bc8ccee2185838e8d4" data-id="3fc0e3562fd680bc8ccee2185838e8d4"><span><div id="3fc0e3562fd680bc8ccee2185838e8d4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680bc8ccee2185838e8d4" title="启示三：Lance Stable Row ID 更适合跨重写外部引用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启示三：Lance Stable Row ID 更适合跨重写外部引用</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680939613fd540c0f1762">Paimon 的 Row ID 在 DV Materialization 和显式 Reassign 时会变化。如果跨表引用 <code class="notion-inline-code">_ROW_ID</code> 是关键需求，可以借鉴 Lance：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b4b5fcf37cd10a0b97"><li>为逻辑 ID 建立独立 Sequence；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68014974ded5e91c0673f"><li>物理位置改变时保留逻辑 ID；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802a95e5c5f50dba4f36"><li>Row ID 与 Row Address 明确分离；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b6aeaed24a244decf4"><li>为创建版本和最后更新版本建立行级元数据。</li></ul><div class="notion-text notion-block-3fc0e3562fd680a59c0ff840ebf388ab">代价是 Row ID Sequence、映射索引和 Compaction 复杂度上升。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd68020b348f02c24bfcd1a" data-id="3fc0e3562fd68020b348f02c24bfcd1a"><span><div id="3fc0e3562fd68020b348f02c24bfcd1a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68020b348f02c24bfcd1a" title="启示四：稀疏 Overlay 是值得关注但代价很高的方向"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启示四：稀疏 Overlay 是值得关注但代价很高的方向</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680c78d6ef9944fbc520f">Paimon 当前对普通列的极稀疏更新仍有较大读取和写入放大。Lance Overlay 展示了可行方向，但也同时引入：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680579b42dc5d6f71ad7b"><li>Cell Coverage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68070acb2ce75b908a789"><li>多层版本；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ee9d69dce478e26f56"><li>索引 Exclusion；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c1839aeac330833475"><li>Overlay 合并；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e8bd2cc1bc8d5035e5"><li>Base Fold；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68028820cdac68c9d205d"><li>Row Rewrite 冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680dcb811fd268bfb5abe"><li>Feature Flag 和混合版本兼容。</li></ul><div class="notion-text notion-block-3fc0e3562fd68040afc9d24897730cf4">在没有明确稀疏更新比例和收益数据前，完整 Range 列文件仍是更简单可靠的设计。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6803b8591f9c8378c1ff8" data-id="3fc0e3562fd6803b8591f9c8378c1ff8"><span><div id="3fc0e3562fd6803b8591f9c8378c1ff8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6803b8591f9c8378c1ff8" title="启示五：Iceberg V4 会缩小格式能力差距"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">启示五：Iceberg V4 会缩小格式能力差距</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680969df4f7e252c1143f">Iceberg 一旦完成 Column File：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b0b071fa3f3f077838"><li>宽表新列回填不再需要重写 Base File；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68041ba45c9109152c6b8"><li>标准 Parquet/ORC/Avro 可以作为 Column File；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807dbfe5ca84ca4715d0"><li>跨引擎兼容会成为强项；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c6b065ccd1b071a320"><li>Paimon 不能只依赖“支持列级更新”作为差异点。</li></ul><div class="notion-text notion-block-3fc0e3562fd68045926acae17c72e2a1">Paimon 更需要突出：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68088a475c584e778949d"><li>部分行匹配更新已经可用；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805989f2e2962dbb3d7b"><li>Spark/Flink/Python 统一语义；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807a97a4c502a0fd9795"><li>BLOB Placeholder 和 Dedicated Storage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680fa86c2d5be1128954a"><li>Global Index 刷新；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68087b535cdbd8dbb2ad0"><li>Compaction Conflict Rebase；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f4bf90ca5ac5b4475b"><li>多模态端到端能力。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680319c8bffb94b998c81" data-id="3fc0e3562fd680319c8bffb94b998c81"><span><div id="3fc0e3562fd680319c8bffb94b998c81" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680319c8bffb94b998c81" title="20.19 选型建议"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.19 选型建议</span></span></h4><table class="notion-simple-table notion-block-3fc0e3562fd68025bcfee855942b4514"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd6801b8260e81a96bea79c"><td class="" style="width:120px"><div class="notion-simple-table-cell">需求</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">更适合的方向</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f0b288fb34bab98264"><td class="" style="width:120px"><div class="notion-simple-table-cell">Flink/Spark 湖仓中持续补充特征列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon Data Evolution</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809b8101c47fc18c087d"><td class="" style="width:120px"><div class="notion-simple-table-cell">图片/BLOB、Embedding、全文和向量检索一体化，同时仍需湖仓批处理</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon 或 LanceDB，取决于计算生态</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6807999bacc875e41f20e"><td class="" style="width:120px"><div class="notion-simple-table-cell">Python/Rust 为主的 ML Dataset、随机访问和训练数据加载</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Lance</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680aa936cdd5f1acc115d"><td class="" style="width:120px"><div class="notion-simple-table-cell">Retrieval、Vector/FTS、低延迟 SDK 查询</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">LanceDB</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e0b0d2ce9af7e0e767"><td class="" style="width:120px"><div class="notion-simple-table-cell">最大化跨引擎开放格式兼容</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Iceberg</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806fbe9cd1ceb0ade69e"><td class="" style="width:120px"><div class="notion-simple-table-cell">当前就要生产可用的列级部分更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Paimon 或 Lance 的整列重写路径</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809ab98ddb567f21f156"><td class="" style="width:120px"><div class="notion-simple-table-cell">等待标准化 Column File 后让多引擎共同读写</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">关注 Iceberg V4</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809e8a88c68dacfe933d"><td class="" style="width:120px"><div class="notion-simple-table-cell">大量极稀疏 Cell Update</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">当前应基准测试 Row Rewrite 与整列 Rewrite；持续关注 Lance Overlay</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680a29137e989c57ea5a7" data-id="3fc0e3562fd680a29137e989c57ea5a7"><span><div id="3fc0e3562fd680a29137e989c57ea5a7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a29137e989c57ea5a7" title="20.20 延伸材料与 Roadmap"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">20.20 延伸材料与 Roadmap</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680b8b7a5f7ece0f1c212">为了降低对内部代码结构的依赖，建议优先按文档主题阅读，而不是按具体文件或类名查找：</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680358ca4cbc1598b85ef" data-id="3fc0e3562fd680358ca4cbc1598b85ef"><span><div id="3fc0e3562fd680358ca4cbc1598b85ef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680358ca4cbc1598b85ef" title="Paimon"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Paimon</span></span></h5><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b0a8a1e36151c1f7eb"><li>Data Evolution 总览；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68021bd73f3581f04e155"><li>File Layout and Reads；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68053b78cda68dde1ee95"><li>Data Evolution Maintenance；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68037b815e33db9ed7492"><li>PyPaimon Data Evolution；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809ab190d712fa697cd6"><li>Global Index 的更新与维护；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c98d9cd669a44dd3ee"><li>Lance 文件格式集成说明。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6800a81a1d4432c3c4249" data-id="3fc0e3562fd6800a81a1d4432c3c4249"><span><div id="3fc0e3562fd6800a81a1d4432c3c4249" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6800a81a1d4432c3c4249" title="Lance 与 LanceDB"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Lance 与 LanceDB</span></span></h5><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680abbe13ddc96dbe93de"><li>Lance Data Evolution；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680898104f2d3c2954e6a"><li>Fragment 与多列文件布局；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680fe90abdfdab3b1394d"><li>Row ID and Lineage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806a88f2c0060315c729"><li>Transaction Conflict Rules；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68025a2fcdacb1f0171ba"><li>Data Overlay Files；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680728458da5e352fd18d"><li>LanceDB Feature Engineering、Computed Column 和 Column Refresh；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680eaa326ed6362244844"><li>Update、Merge Insert、Compaction 与 Index Maintenance。</li></ul><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680b6a2e7f4641ad66e0a" data-id="3fc0e3562fd680b6a2e7f4641ad66e0a"><span><div id="3fc0e3562fd680b6a2e7f4641ad66e0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b6a2e7f4641ad66e0a" title="Iceberg"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Iceberg</span></span></h5><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805da834c4a288740ded"><li>Table Format Specification 中的 Row Lineage、Deletion Vector 和 V4 Column File；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e78900c1a81c354ab2"><li>V4 Adaptive Metadata Tree；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d6a2fbea4f62b95f62"><li>Efficient Column Updates Proposal；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d0a0b5e5af79d540bb"><li>Column File Metadata、Manifest Reader 和 Reader Stitching 的实现进展。</li></ul><div class="notion-text notion-block-3fc0e3562fd68024a4dedb91fcf4ebc7">Iceberg 社区 Roadmap 应以 Issue <code class="notion-inline-code">#15146</code> 及其关联的 V4 Column File PR 为入口。具体 PR 编号和拆分方式会随开发过程变化，学习时应关注以下里程碑，而不是绑定某个内部实现名称：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680339abfdfaf6400cbd4" style="list-style-type:decimal"><li>Column File 元数据进入公共数据模型；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68058ba36d02320a82283" style="list-style-type:decimal"><li>V4 Manifest 能够稳定读写 Column File；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68062b55ee7433707d5a0" style="list-style-type:decimal"><li>Row-based Reader 能按位置拼接 Base 和 Column File；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6803c907fe3e1d1d7c03a" style="list-style-type:decimal"><li>Vectorized Reader 能零拷贝或低拷贝拼接列向量；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f2b666e604c8a45268" style="list-style-type:decimal"><li>Spark、Flink 和 Generic Reader 形成一致语义；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6805dba0cef028f3fcef4" style="list-style-type:decimal"><li>Encryption、Projection、Deletion Vector 和 Change Detection 完整接入；</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680929f4fe05144ae7a81" style="list-style-type:decimal"><li>Writer 和 Column Update API 达到可生产使用状态。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd6807f8821fbf2bc25d061"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680caaf39c68818d3b0e4" data-id="3fc0e3562fd680caaf39c68818d3b0e4"><span><div id="3fc0e3562fd680caaf39c68818d3b0e4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680caaf39c68818d3b0e4" title="21. 关键配置表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">21. 关键配置表</span></span></h3><table class="notion-simple-table notion-block-3fc0e3562fd6805f91aeef86c977485e"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680a587caef1f0496a6c6"><td class="" style="width:120px"><div class="notion-simple-table-cell">配置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认值</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">说明</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809898c9e3ba33cbb30d"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">row-tracking.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">为 Append Table 开启 Row ID，不可变</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680c195c6f60b1b247797"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">row-tracking.partition-group-on-commit</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">true</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">提交时按分区组织新文件，使分区内 Row ID 更连续</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6809e9dbec7cd5108a8c1"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开启 Data Evolution，不可变</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6802ca151dc68bdbb80e3"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">deletion-vectors.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开启行级逻辑删除</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680848354e6a7aebaf5c7"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.write-cols-optimization.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">完整非 Dedicated 列文件省略 <code class="notion-inline-code">writeCols</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680ebb618d25427b3179d"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.nested-field.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">开启 Struct 子字段级更新</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e2a9e0fe90b0c99208"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.row-id-conflict-rewrite.max-size</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">256 MB</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">PyPaimon 边界冲突自动重写上限</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808ab330eef2673de8e4"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.row-sidecar.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">生成稀疏 Row ID 读取 Sidecar</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680269dc4eb8a22440d3b"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.row-sidecar.max-selected-rows</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">4096</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Sidecar 最大选中行数</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680618f26c8bd114a9144"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.row-sidecar.max-selection-ratio</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">0.05</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Sidecar 最大选中比例</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808eba29c18cf9c3ecc1"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.merge-into.file-pruning</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">true</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark MERGE 部分列写前裁剪未触碰文件</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680e0aa99e13473eec969"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.merge-into.source-persist</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Data Evolution Merge 是否缓存 Source</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6800bb30ef75b65027ffa"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.compaction.split-large-files</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Compaction 是否拆分大 Normal File</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680cda928e57a34cdac14"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">data-evolution.compaction.large-file-ratio</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">2.0</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">大文件判定倍率</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806eaca2e48c9d69200b"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">blob-compaction.enabled</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">false</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是否执行 BLOB Compaction</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f984a0ef76517adaa4"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">global-index.column-update-action</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">THROW_ERROR</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">更新索引列时的行为</div></td></tr></tbody></table><div class="notion-text notion-block-3fc0e3562fd68002b9c9c8529a4c61db">Spark Connector 专用配置：</div><table class="notion-simple-table notion-block-3fc0e3562fd68044b8cce4c5ab1e74d6"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680ec865fe8e7e511518a"><td class="" style="width:120px"><div class="notion-simple-table-cell">配置</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">默认值</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6807c9b92e9ddf36040ca"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">spark.paimon.write.data-evolution.update-conflict-retry.max-attempts</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">20</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f0af12eddd96242f65"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">spark.paimon.write.data-evolution.update-conflict-retry.wait-ms</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">10</code></div></td></tr></tbody></table><hr class="notion-hr notion-block-3fc0e3562fd68059b767f6783e3bea64"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68064bfc1f1db9aacf270" data-id="3fc0e3562fd68064bfc1f1db9aacf270"><span><div id="3fc0e3562fd68064bfc1f1db9aacf270" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68064bfc1f1db9aacf270" title="22. 引擎能力对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">22. 引擎能力对比</span></span></h3><table class="notion-simple-table notion-block-3fc0e3562fd680d0abb4f64f4267bdb5"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3fc0e3562fd680958540fe58e2bae9b0"><td class="" style="width:120px"><div class="notion-simple-table-cell">能力</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Flink</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">PyPaimon</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68024aa36c2a6b12421d0"><td class="" style="width:120px"><div class="notion-simple-table-cell">INSERT 新行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6806e9dcfccfa75390e24"><td class="" style="width:120px"><div class="notion-simple-table-cell">UPDATE 普通列</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通过专用 procedure</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680fcbf0becbb2b289591"><td class="" style="width:120px"><div class="notion-simple-table-cell">MERGE Matched Update</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68088b584f783997c1ba5"><td class="" style="width:120px"><div class="notion-simple-table-cell">MERGE Not Matched Insert</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">专用 procedure 不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68008b299e86f88eac517"><td class="" style="width:120px"><div class="notion-simple-table-cell">MERGE Matched Delete</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持，需 DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">专用 procedure 不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持，需 DV</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6808ab0e9f8e6698c9400"><td class="" style="width:120px"><div class="notion-simple-table-cell">Not Matched By Source Delete</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Spark 3.4+，需 DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">专用 procedure 不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">视 API 规则</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68009abbfeffe18a79cb4"><td class="" style="width:120px"><div class="notion-simple-table-cell">DELETE FROM</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持，需 DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Flink 1.17+ Batch，需 DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">delete_by_predicate</code></div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd680f78f24e5d8ef397937"><td class="" style="width:120px"><div class="notion-simple-table-cell">按 <code class="notion-inline-code">_ROW_ID</code> 更新</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">内部和 SQL 快捷路径</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">内部支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">直接 API</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68033bdecdee858d4ec8c"><td class="" style="width:120px"><div class="notion-simple-table-cell">Shard 派生列回填</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可通过 Spark SQL/DF</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">可通过任务实现</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">原生支持</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd68069a14ec0cc4fcca459"><td class="" style="width:120px"><div class="notion-simple-table-cell">普通 Compaction</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">依赖相应维护能力</div></td></tr><tr class="notion-simple-table-row notion-block-3fc0e3562fd6803da45ecf3e414bcce4"><td class="" style="width:120px"><div class="notion-simple-table-cell">Materialize DV</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">依赖相应维护能力</div></td></tr></tbody></table><hr class="notion-hr notion-block-3fc0e3562fd68035b3cccff552bf1b4a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6805bbdebfd75c7070bab" data-id="3fc0e3562fd6805bbdebfd75c7070bab"><span><div id="3fc0e3562fd6805bbdebfd75c7070bab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6805bbdebfd75c7070bab" title="23. 观测与排障"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">23. 观测与排障</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680a19623fb01f838c6a9" data-id="3fc0e3562fd680a19623fb01f838c6a9"><span><div id="3fc0e3562fd680a19623fb01f838c6a9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680a19623fb01f838c6a9" title="23.1 查看逻辑行和 Row ID"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">23.1 查看逻辑行和 Row ID</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680408194f696c54a2343" data-id="3fc0e3562fd680408194f696c54a2343"><span><div id="3fc0e3562fd680408194f696c54a2343" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680408194f696c54a2343" title="23.2 查看当前文件布局"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">23.2 查看当前文件布局</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6801c8f46f6c3e9902deb">检查要点：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68050916bf8c1421641ed" style="list-style-type:decimal"><li>Normal File Range 是否相同或不相交；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ec9336f71ba5b72b1c" style="list-style-type:decimal"><li>相同 <code class="notion-inline-code">first_row_id</code> 的 Normal File 是否有相同 <code class="notion-inline-code">record_count</code>；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6803d968cd7d3bef60fde" style="list-style-type:decimal"><li>Dedicated File 是否完整包含于一个 Normal Range；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680119032f80c190a9b04" style="list-style-type:decimal"><li><code class="notion-inline-code">write_cols</code> 是否符合预期；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a19ac9cb6cfb2f986b" style="list-style-type:decimal"><li>同一列是否存在过多版本；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ddb99fdc5411e41be5" style="list-style-type:decimal"><li>文件数是否因频繁更新持续增长。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680f3a667c64290171694" data-id="3fc0e3562fd680f3a667c64290171694"><span><div id="3fc0e3562fd680f3a667c64290171694" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f3a667c64290171694" title="23.3 不要用 $files.record_count 求逻辑行数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">23.3 不要用 <code class="notion-inline-code">$files.record_count</code> 求逻辑行数</span></span></h4><div class="notion-text notion-block-3fc0e3562fd6804bb0f7cb1b3e407282">多个列文件可能代表相同 Row ID Range：</div><div class="notion-text notion-block-3fc0e3562fd680009ec7def3211cc367">逻辑行数仍可能只有 100，而不是 300。</div><div class="notion-text notion-block-3fc0e3562fd680c68baef1e2c7d139a0">此外，Deletion Vector 还会减少可见行数。应查询表本身获取逻辑行数。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6806f91e4c0fd496a402a" data-id="3fc0e3562fd6806f91e4c0fd496a402a"><span><div id="3fc0e3562fd6806f91e4c0fd496a402a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6806f91e4c0fd496a402a" title="23.4 常见问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">23.4 常见问题</span></span></h4><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6801e9d0be0608008e869" data-id="3fc0e3562fd6801e9d0be0608008e869"><span><div id="3fc0e3562fd6801e9d0be0608008e869" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6801e9d0be0608008e869" title="更新一行为什么写了很多行？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">更新一行为什么写了很多行？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6803b83b7f14d66ed249f">因为普通列更新单位是“选中列 × 完整 Normal Range”，不是单个匹配行。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680b08510f1c03abe35b5" data-id="3fc0e3562fd680b08510f1c03abe35b5"><span><div id="3fc0e3562fd680b08510f1c03abe35b5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b08510f1c03abe35b5" title="UPDATE 后读取文件越来越多？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">UPDATE 后读取文件越来越多？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68064988fd59fc788ccc7">每次部分列更新会增加列版本，需要定期 compaction。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd6803caeb5c9b272fcc3de" data-id="3fc0e3562fd6803caeb5c9b272fcc3de"><span><div id="3fc0e3562fd6803caeb5c9b272fcc3de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6803caeb5c9b272fcc3de" title="同一文件范围内更新不同业务行为什么冲突？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">同一文件范围内更新不同业务行为什么冲突？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6802d96c8c2dba97fc6d8">两个 Writer 如果都更新相同列，就都在替换该列的完整 Range。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680f2867bf268129ef005" data-id="3fc0e3562fd680f2867bf268129ef005"><span><div id="3fc0e3562fd680f2867bf268129ef005" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f2867bf268129ef005" title="新增列后为什么历史行是 NULL？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">新增列后为什么历史行是 NULL？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68048a02aefdb233022ca">Schema Evolution 只新增列定义，不自动执行数据回填。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680048f55da85e5607716" data-id="3fc0e3562fd680048f55da85e5607716"><span><div id="3fc0e3562fd680048f55da85e5607716" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680048f55da85e5607716" title="删除后文件大小为什么没有下降？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">删除后文件大小为什么没有下降？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd680e68716d88c54ca8de6">普通删除只写 Deletion Vector。需要 <code class="notion-inline-code">materialize_deletion_vectors</code> 才会移除位置，但 Row ID 会改变。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680838916e78d5c350721" data-id="3fc0e3562fd680838916e78d5c350721"><span><div id="3fc0e3562fd680838916e78d5c350721" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680838916e78d5c350721" title="Compaction 后更新提交为什么失败？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Compaction 后更新提交为什么失败？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd6802db83bed6d71ea907b">可能是 Normal Range 边界变化导致 Layout Conflict。重新规划，或使用支持 Rebase 的 Spark/PyPaimon 路径。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3fc0e3562fd680f7af2adae3314a74c7" data-id="3fc0e3562fd680f7af2adae3314a74c7"><span><div id="3fc0e3562fd680f7af2adae3314a74c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f7af2adae3314a74c7" title="更新索引列为什么报错？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">更新索引列为什么报错？</span></span></h5><div class="notion-text notion-block-3fc0e3562fd68062998eeb9264b63c34">默认 <code class="notion-inline-code">global-index.column-update-action=THROW_ERROR</code>，需要选择删除分区索引、忽略后重建，或先手动删除索引。</div><hr class="notion-hr notion-block-3fc0e3562fd680e1a14bd60fef67f658"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6802ba703cc924d4b8187" data-id="3fc0e3562fd6802ba703cc924d4b8187"><span><div id="3fc0e3562fd6802ba703cc924d4b8187" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6802ba703cc924d4b8187" title="24. 文件大小设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">24. 文件大小设计</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6806ba3f8eb55dd3fbda5"><code class="notion-inline-code">target-file-size</code> 不只是影响扫描性能，也影响未来的更新成本。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d3a7ccfe244dd54cf1" data-id="3fc0e3562fd680d3a7ccfe244dd54cf1"><span><div id="3fc0e3562fd680d3a7ccfe244dd54cf1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d3a7ccfe244dd54cf1" title="大文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">大文件</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680b79843dc414634eedf">优点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a1a278ddf578643ffa"><li>全表扫描文件数少；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6809aa2c5ded198d363f8"><li>Manifest 和文件打开开销低。</li></ul><div class="notion-text notion-block-3fc0e3562fd680e5902ffae8754b5a31">缺点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68076937acea166820f44"><li>更新一行也要处理更大的 Normal Range；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c1bad9eda202da9815"><li>单次部分列更新成本高；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68039b732d2e75a055f13"><li>并发更新更容易落入同一个 Range。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68021938ef6438e1ceb52" data-id="3fc0e3562fd68021938ef6438e1ceb52"><span><div id="3fc0e3562fd68021938ef6438e1ceb52" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68021938ef6438e1ceb52" title="小文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">小文件</span></span></h4><div class="notion-text notion-block-3fc0e3562fd68044969dece1466b0acc">优点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c0904de7aa1e5122f3"><li>更新粒度更小；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808d8aa6e47b6bd23482"><li>冲突域更小；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680cd8ba2f3a69cf4c4e6"><li>稀疏更新成本低。</li></ul><div class="notion-text notion-block-3fc0e3562fd68075a274d65fa0d0ed50">缺点：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68073843dffbd1a14115c"><li>文件数多；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680d0819cc597ef7894ff"><li>扫描和元数据开销高；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803aab31d1f02ddccc98"><li>compaction 压力更大。</li></ul><div class="notion-text notion-block-3fc0e3562fd68098998ff7c3270483b8">可同时考虑：</div><div class="notion-text notion-block-3fc0e3562fd680e58c3ec87903d41f31"><code class="notion-inline-code">target-file-row-num</code> 只约束支持该选项的新写入，不会在普通部分更新时拆开已有 Normal Range。Data Evolution compaction 也可能产生更大的合并范围。</div><hr class="notion-hr notion-block-3fc0e3562fd6803d99efff5e07ebbfc2"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68094a734c8b099155aae" data-id="3fc0e3562fd68094a734c8b099155aae"><span><div id="3fc0e3562fd68094a734c8b099155aae" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68094a734c8b099155aae" title="25. 已知限制和使用边界"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">25. 已知限制和使用边界</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806db6ede6f19dee2c6e" style="list-style-type:decimal"><li>不能定义 Primary Key；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6807fa3e5e7db13ab9a39" style="list-style-type:decimal"><li>只支持 <code class="notion-inline-code">bucket = -1</code>；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802999c9c6d85917db0c" style="list-style-type:decimal"><li>不能开启 <code class="notion-inline-code">clustering.incremental</code>；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680e8a7abf7c86538c74f" style="list-style-type:decimal"><li>Matched partial update 不能修改分区列；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6800aba08c69748754e2a" style="list-style-type:decimal"><li>普通列的稀疏更新仍要处理完整文件范围；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68014a17cfb8d00f5bdcd" style="list-style-type:decimal"><li>Dedicated Vector File Compaction 尚未支持；</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f0a012e4120713d3d8" style="list-style-type:decimal"><li>包含 Dedicated Vector File 的组不能 Materialize DV；</li></ol><ol start="8" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6800c974bfec23457aa8a" style="list-style-type:decimal"><li><code class="notion-inline-code">data-evolution.compaction.rewrite-row-ids=true</code> 已废弃并会被拒绝；</li></ol><ol start="9" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68049933eec14106cb688" style="list-style-type:decimal"><li>Branch Merge 不支持 Data Evolution 表；</li></ol><ol start="10" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680539e14d89c9e27e907" style="list-style-type:decimal"><li><code class="notion-inline-code">import_files</code> 不支持 Row Tracking 或 Data Evolution 表；</li></ol><ol start="11" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6801b8f66e9d75c7d25ae" style="list-style-type:decimal"><li>Nested Field 开启后存在严格的混合版本和降级风险；</li></ol><ol start="12" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68075abeee75540ce3438" style="list-style-type:decimal"><li><code class="notion-inline-code">_ROW_ID</code> 不能作为永久业务标识；</li></ol><ol start="13" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6809895b9cd8371c0174c" style="list-style-type:decimal"><li>更新已建立 Global Index 的列必须处理索引新鲜度；</li></ol><ol start="14" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ae99efecffa7be13f3" style="list-style-type:decimal"><li>并发 Delete、Append、Compact、Overwrite 可能发生提交冲突，应做好任务编排和重试；</li></ol><ol start="15" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680bb8caccaea1b9d3390" style="list-style-type:decimal"><li>历史 Snapshot/Tag 会延迟旧文件的空间回收。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd680fab3bbed63c322187f"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6806b9b71e85761787f44" data-id="3fc0e3562fd6806b9b71e85761787f44"><span><div id="3fc0e3562fd6806b9b71e85761787f44" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6806b9b71e85761787f44" title="26. 推荐实践"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">26. 推荐实践</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d1b3d3f7606bbc2609" data-id="3fc0e3562fd680d1b3d3f7606bbc2609"><span><div id="3fc0e3562fd680d1b3d3f7606bbc2609" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d1b3d3f7606bbc2609" title="26.1 表设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">26.1 表设计</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68022bf0dcc24240b87e2"><li>保留稳定的业务 ID，但不要把它误认为 Paimon Primary Key；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68071893ac415dfb13557"><li>根据更新粒度设计 <code class="notion-inline-code">target-file-size</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680218fa4de18619e3e67"><li>大 BLOB、Vector 使用 Dedicated Storage；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680eb846eda5688bf37b2"><li>需要行级删除时，从建表阶段就规划 Deletion Vector；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68059be9ed11f50f6b3d6"><li>对长期保存的 <code class="notion-inline-code">_ROW_ID</code> 引用建立维护协议。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68090bfcaf386a9a7974b" data-id="3fc0e3562fd68090bfcaf386a9a7974b"><span><div id="3fc0e3562fd68090bfcaf386a9a7974b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68090bfcaf386a9a7974b" title="26.2 更新任务"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">26.2 更新任务</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b89501d0d7fceaf80c"><li>只声明真正需要更新的列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680218bddedad22793c45"><li>避免 <code class="notion-inline-code">UPDATE SET</code> 中无意义地重写全部列；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ebb962d947b4c9297a"><li>尽量按分区限制更新范围；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680feb4eafd77673a02be"><li>对大范围更新评估是否关闭 MERGE File Pruning；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680559fb0c499dd4ac31e"><li>对确定性 Spark UPDATE 配置合理冲突重试；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803a811ec22a6b12e82a"><li>对频繁更新的列设置定期 compaction。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680f19953e29471227da4" data-id="3fc0e3562fd680f19953e29471227da4"><span><div id="3fc0e3562fd680f19953e29471227da4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f19953e29471227da4" title="26.3 索引"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">26.3 索引</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806d80b7f53623788a57"><li>更新索引列前明确选择 <code class="notion-inline-code">global-index.column-update-action</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68067ab82e15a951d2a68"><li><code class="notion-inline-code">IGNORE</code> 后必须安排索引刷新或重建；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a29d06cbc3bbedf447"><li>用 Row Sidecar 优化全局索引后的稀疏 Row ID 回表；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680599d76f8ffbe189ad9"><li>DV Materialization 后重新构建受影响索引。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680358daff9425fbce475" data-id="3fc0e3562fd680358daff9425fbce475"><span><div id="3fc0e3562fd680358daff9425fbce475" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680358daff9425fbce475" title="26.4 运维"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">26.4 运维</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808fb4dceb43b71add1c"><li>定期查询 <code class="notion-inline-code">$files</code> 检查列版本数量；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680769cdcc3dc71991892"><li>监控小文件数量、单 Range 文件数量和读取放大；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68092af4efdec51ad74ec"><li>普通 compaction 与 DV materialization 分开调度；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6800090efc3b5b9c27bc8"><li>Materialize DV 前确认下游没有长期依赖旧 <code class="notion-inline-code">_ROW_ID</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805f9846f7427b379446"><li>结合 Snapshot/Tag 保留策略安排空间回收。</li></ul><hr class="notion-hr notion-block-3fc0e3562fd6808790c4d346a7cfc39d"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680e4a622d90bfe05d929" data-id="3fc0e3562fd680e4a622d90bfe05d929"><span><div id="3fc0e3562fd680e4a622d90bfe05d929" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680e4a622d90bfe05d929" title="27. 实现原理核对路线"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">27. 实现原理核对路线</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680aa80c0edfdf034756a">不建议从具体类名开始阅读，因为内部结构会随重构变化。更稳定的方法是按问题和模块逐层核对。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680fea6cafac77cbf5555" data-id="3fc0e3562fd680fea6cafac77cbf5555"><span><div id="3fc0e3562fd680fea6cafac77cbf5555" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680fea6cafac77cbf5555" title="第一阶段：表模型与配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第一阶段：表模型与配置</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680ad9131e295b424378f">重点理解：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e7a782c848c68ec568"><li>为什么必须无主键、<code class="notion-inline-code">bucket=-1</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680699f3dd93b28833151"><li>Data Evolution 如何改变普通 Append Table 的扫描和读取语义；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68081b383cdeee2a8d0ea"><li>哪些选项不可变。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680ad8c28c2ec9c128228" data-id="3fc0e3562fd680ad8c28c2ec9c128228"><span><div id="3fc0e3562fd680ad8c28c2ec9c128228" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680ad8c28c2ec9c128228" title="第二阶段：Row ID 分配"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第二阶段：Row ID 分配</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680ebb384c0ec2f594550">重点理解：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ed943bf77bebfb5769"><li><code class="notion-inline-code">nextRowId</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805da88cddff81532f5f"><li><code class="notion-inline-code">firstRowId</code>；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802c879bef1d36d628d0"><li>Append、Partial Update、Compact 文件的不同处理。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6808cb50fdb5c56d92b3b" data-id="3fc0e3562fd6808cb50fdb5c56d92b3b"><span><div id="3fc0e3562fd6808cb50fdb5c56d92b3b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6808cb50fdb5c56d92b3b" title="第三阶段：文件扫描与读取"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第三阶段：文件扫描与读取</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680e79c93f003dae726a6">重点理解：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a580d4f02654ed308f"><li>Row Range Group；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68008abc7eadaca422353"><li>Provider 选择；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680339406ca15334c2c84"><li>Projection Pruning；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802c9f1edb62c42bd97d"><li>Deletion Vector；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68065a026d6db6642dfc7"><li>Nested Field；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a58a3adaf7a5cb46d9"><li>BLOB Fallback；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68094bf25e0b023270837"><li>Row Sidecar。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680c3931cfcce03b4310c" data-id="3fc0e3562fd680c3931cfcce03b4310c"><span><div id="3fc0e3562fd680c3931cfcce03b4310c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680c3931cfcce03b4310c" title="第四阶段：Spark 写入"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第四阶段：Spark 写入</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680718d27ce4b43f45d18">重点理解：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b49a0afe97412e7581"><li>UPDATE 如何转换成 Self Merge；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68007ac4af11949e6c05e"><li><code class="notion-inline-code">_ROW_ID</code> 快捷路径；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c99b81db6a81b6bd3e"><li>完整 Range 补齐；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680e89afdebdbd9beeb77"><li>File Pruning；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c99fb0c0d6798718af"><li>Compaction Conflict Rebase。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680f1bc52e6d9593c3e7f" data-id="3fc0e3562fd680f1bc52e6d9593c3e7f"><span><div id="3fc0e3562fd680f1bc52e6d9593c3e7f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680f1bc52e6d9593c3e7f" title="第五阶段：Flink 写入"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第五阶段：Flink 写入</span></span></h4><div class="notion-text notion-block-3fc0e3562fd680d3b830cba1bc28cf8d">重点理解：</div><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68005ba8eca6591ceb00c"><li>固定 Snapshot；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68034ad95d573035a34b0"><li>按 <code class="notion-inline-code">firstRowId</code> Shuffle；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803abe1ae6d344d5a0e8"><li><code class="notion-inline-code">_ROW_ID</code> 排序；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f199c1ff0a62fe2b82"><li>原值补齐；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680b08a4fe7fe479b4503"><li>BLOB Placeholder；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6808d93c3f09735445c83"><li>Deletion Vector 写入。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68087b9d7d09c88422d66" data-id="3fc0e3562fd68087b9d7d09c88422d66"><span><div id="3fc0e3562fd68087b9d7d09c88422d66" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68087b9d7d09c88422d66" title="第六阶段：冲突和维护"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第六阶段：冲突和维护</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680aebe97f09189e15457"><li>找到提交冲突检测模块，核对 Range 与 Field ID 的冲突条件；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680c69367c1aa4197be89"><li>找到普通 Compaction 规划和执行模块，核对 Row ID 保留规则；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68090bfc3d1f21a7ee952"><li>找到 Deletion Vector Materialization，核对物理删除和 Row ID 重分配；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68099af94dd152ac80671"><li>找到边界变化后的重试或 Rebase 路径，核对其适用条件。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680d3b47df7260c10210f" data-id="3fc0e3562fd680d3b47df7260c10210f"><span><div id="3fc0e3562fd680d3b47df7260c10210f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680d3b47df7260c10210f" title="第七阶段：索引"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第七阶段：索引</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a5927cc581c5684e6f"><li>核对索引文件如何记录 Row Range 和源 Snapshot；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a9b931c4b2f5d17a96"><li>核对更新索引列后的 Throw、Drop 或 Ignore 行为；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6806e9ab0f4fc2cecab5f"><li>核对未覆盖范围与已覆盖但可能过期范围的区别；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68074b717c0d115b74b1e"><li>核对增量刷新如何识别字段版本变化。</li></ul><hr class="notion-hr notion-block-3fc0e3562fd680c8ad19d6f10ac5d182"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680ae869be9c19d41440b" data-id="3fc0e3562fd680ae869be9c19d41440b"><span><div id="3fc0e3562fd680ae869be9c19d41440b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680ae869be9c19d41440b" title="28. 推荐验证场景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">28. 推荐验证场景</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680b2a803efcb8f3d4f7a">比记住测试类名更重要的是理解每组测试验证的契约。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6807ea2ede8f8287bc9a5" data-id="3fc0e3562fd6807ea2ede8f8287bc9a5"><span><div id="3fc0e3562fd6807ea2ede8f8287bc9a5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6807ea2ede8f8287bc9a5" title="Core 语义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Core 语义</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ae8ec7edca169f10e1"><li>同一 Row ID Range 的多列文件能正确合并；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68072a4c8d6525e16e740"><li>缺失列、显式 <code class="notion-inline-code">NULL</code> 和 BLOB Placeholder 的语义不同；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680379198c15997176a5f"><li>Projection Pruning 不会丢失行数或 Deletion Vector Anchor；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680f59ac2c411767b7ca1"><li>普通文件索引和 Bitmap Selection 不破坏列位置对齐；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6804dbe64e67ef7efbace"><li>Nested Field Provider 能按支持的层级正确组合；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6802583a9f2d6fecb08ec"><li>非法 Normal/Dedicated Range 会在提交或读取时被拒绝。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680b8a686dbf78583c97d" data-id="3fc0e3562fd680b8a686dbf78583c97d"><span><div id="3fc0e3562fd680b8a686dbf78583c97d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b8a686dbf78583c97d" title="并发与提交"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">并发与提交</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805d9704cf10fdf3b174"><li>同一 Range 更新不同字段可以提交；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803f858cc5eb2d9b6474"><li>同一 Range 更新相同字段发生冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680a4b101ec43f0483db7"><li>Compaction 改变边界后能够 Rebase，或给出明确冲突；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68013a1b5ca7d7a950581"><li>Overwrite、分区删除和 Row ID 重分配不会被旧计划静默覆盖；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680509571ce6d0e181908"><li>Deletion Vector 与部分列更新的并发行为符合预期。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6809eb38de8e785b17313" data-id="3fc0e3562fd6809eb38de8e785b17313"><span><div id="3fc0e3562fd6809eb38de8e785b17313" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809eb38de8e785b17313" title="Spark 与 Flink"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Spark 与 Flink</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680ec93a6edf835388bb2"><li>UPDATE 和 MERGE 只写声明更新的字段；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6803a9a42c5b9074f2a8e"><li>未命中行在输出列文件中得到正确旧值；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6805eb576ed009513f0a2"><li><code class="notion-inline-code">_ROW_ID</code> 快捷路径和普通业务条件路径结果一致；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68011a36df22f1cf5ecbf"><li>DELETE 正确生成并应用 Deletion Vector；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68027b7bae8f7b8589966"><li>分区裁剪、文件裁剪和 Self Merge 优化不改变结果。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68074bdd2c1d20918eb35" data-id="3fc0e3562fd68074bdd2c1d20918eb35"><span><div id="3fc0e3562fd68074bdd2c1d20918eb35" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68074bdd2c1d20918eb35" title="Python"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Python</span></span></h4><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68073ab6be4b48a79f060"><li>Predicate、Row ID 和 Shard Update 结果一致；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6801b8c71ce357e8c148d"><li>Shard Update 对行数和顺序进行严格校验；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd6807d8d64c03558705943"><li>Stream Commit Identifier 生命周期正确；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd680668e3ecf6fa899f7f9"><li>Native Commit、REST Commit 和普通 Catalog 行为一致；</li></ul><ul class="notion-list notion-list-disc notion-block-3fc0e3562fd68004b57cdf6b079a660e"><li>Row Sidecar 只在稀疏读取阈值内启用。</li></ul><hr class="notion-hr notion-block-3fc0e3562fd680d1a565dc484a1b1661"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd680b3838ad2291921f222" data-id="3fc0e3562fd680b3838ad2291921f222"><span><div id="3fc0e3562fd680b3838ad2291921f222" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680b3838ad2291921f222" title="29. 建议动手实验"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">29. 建议动手实验</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd6809d864ee6325940085c" data-id="3fc0e3562fd6809d864ee6325940085c"><span><div id="3fc0e3562fd6809d864ee6325940085c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809d864ee6325940085c" title="实验一：观察一次部分列更新"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">实验一：观察一次部分列更新</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68084a80bc4f1cec52033" style="list-style-type:decimal"><li>建 Data Evolution 表；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6804ab2f9c88a342ed762" style="list-style-type:decimal"><li>插入 5 行；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68091ba5dda2d41280235" style="list-style-type:decimal"><li>查询 <code class="notion-inline-code">$row_tracking</code>；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680bb81d1fe303d934fd3" style="list-style-type:decimal"><li>查询 <code class="notion-inline-code">$files</code>；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6805e9edac7e0f279a1b6" style="list-style-type:decimal"><li>只更新其中一行的一个列；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6801da4a7d005c65c99d6" style="list-style-type:decimal"><li>再次查询 <code class="notion-inline-code">$files</code>；</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806591bafc19ec2c12bc" style="list-style-type:decimal"><li>验证新文件与原 Normal File 的 Row Range 完全相同。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68066884ac1bea2e7b554" data-id="3fc0e3562fd68066884ac1bea2e7b554"><span><div id="3fc0e3562fd68066884ac1bea2e7b554" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68066884ac1bea2e7b554" title="实验二：验证不同列并发更新模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">实验二：验证不同列并发更新模型</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680d1987ef6b885109bb4" style="list-style-type:decimal"><li>两个任务固定同一个 Snapshot；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68002b4d7fa40fc9ed829" style="list-style-type:decimal"><li>一个更新 <code class="notion-inline-code">b</code>，一个更新 <code class="notion-inline-code">c</code>；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68079a9b0cefdc3ee9fcf" style="list-style-type:decimal"><li>对比更新相同列 <code class="notion-inline-code">b</code> 的行为；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680c1a101e964747642a1" style="list-style-type:decimal"><li>对照“Range 相交且字段集合相交”的冲突模型解释结果。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680609c00f6ba32760782" data-id="3fc0e3562fd680609c00f6ba32760782"><span><div id="3fc0e3562fd680609c00f6ba32760782" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680609c00f6ba32760782" title="实验三：删除与物化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">实验三：删除与物化</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a8ae06e790b1294168" style="list-style-type:decimal"><li>开启 Deletion Vector；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680548576dfbc059e93b0" style="list-style-type:decimal"><li>删除一行；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802b9b57c6c6570b06ad" style="list-style-type:decimal"><li>验证 Row ID Range 和 <code class="notion-inline-code">record_count</code> 不变；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f5ad6bf34f603c7fa8" style="list-style-type:decimal"><li>执行普通 compaction，确认 Row ID 不变；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f29ddde13f5bcb91bc" style="list-style-type:decimal"><li>执行 <code class="notion-inline-code">materialize_deletion_vectors</code>；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68018bc63e79c9ecd5399" style="list-style-type:decimal"><li>观察新 Row ID 和索引变化。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd68088a4f2e95dbcfc2cb5" data-id="3fc0e3562fd68088a4f2e95dbcfc2cb5"><span><div id="3fc0e3562fd68088a4f2e95dbcfc2cb5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68088a4f2e95dbcfc2cb5" title="实验四：Compaction 边界变化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">实验四：Compaction 边界变化</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680f89b12e1e7d625e766" style="list-style-type:decimal"><li>创建两个相邻 Normal Range；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680e9b2d5fed94be61f1e" style="list-style-type:decimal"><li>固定旧 Snapshot 规划更新；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a2859bd06db1498c27" style="list-style-type:decimal"><li>运行 compaction 合并范围；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68061ac2fca5da2cae9c9" style="list-style-type:decimal"><li>提交旧更新；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6802dbccde6739d894570" style="list-style-type:decimal"><li>观察 Layout Conflict 或 Rebase。</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3fc0e3562fd680ce8d06d10c843e2649" data-id="3fc0e3562fd680ce8d06d10c843e2649"><span><div id="3fc0e3562fd680ce8d06d10c843e2649" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd680ce8d06d10c843e2649" title="实验五：Row Sidecar"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">实验五：Row Sidecar</span></span></h4><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680b8a840c6b97eda8147" style="list-style-type:decimal"><li>开启 <code class="notion-inline-code">data-evolution.row-sidecar.enabled</code>；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680da9003e88269d81d1e" style="list-style-type:decimal"><li>构建标量 Global Index；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68059a6abe03e434a5721" style="list-style-type:decimal"><li>查询少量 Row ID；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680ab8dcde238184586b6" style="list-style-type:decimal"><li>对比 Sidecar 开关下读取的物理文件和性能。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd680a68e30f505520c917a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd68014a116eeea3088071c" data-id="3fc0e3562fd68014a116eeea3088071c"><span><div id="3fc0e3562fd68014a116eeea3088071c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd68014a116eeea3088071c" title="30. 最终心智模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">30. 最终心智模型</span></span></h3><div class="notion-text notion-block-3fc0e3562fd680b8977ae86cacc23c32">可以把 Data Evolution 看成一个以 Row ID Range 为单位的、支持多版本列文件的存储模型：</div><div class="notion-text notion-block-3fc0e3562fd680f0aa8bea4458013812">读取时：</div><div class="notion-text notion-block-3fc0e3562fd680289d5dcd75fbf58b89">更新时：</div><div class="notion-text notion-block-3fc0e3562fd6801a8117fd7f4898007f">维护时：</div><div class="notion-text notion-block-3fc0e3562fd68058a584e55211aad13d">只要始终抓住三个关键词，就能理解大部分实现：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68030a483d35eb3207f00" style="list-style-type:decimal"><li><b>Row ID 对齐</b>；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68080b35ac02b2854afef" style="list-style-type:decimal"><li><b>列 Provider 最新版本胜出</b>；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680448794c0094c7eadd4" style="list-style-type:decimal"><li><b>Normal Range 必须完全相同或完全不相交</b>。</li></ol><hr class="notion-hr notion-block-3fc0e3562fd6809d9a4ff87d96987981"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fc0e3562fd6809ab5e8ce19d7918e11" data-id="3fc0e3562fd6809ab5e8ce19d7918e11"><span><div id="3fc0e3562fd6809ab5e8ce19d7918e11" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fc0e3562fd6809ab5e8ce19d7918e11" title="31. 延伸阅读"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">31. 延伸阅读</span></span></h3><div class="notion-text notion-block-3fc0e3562fd6805ebd03eb1156c51c6e">建议优先阅读以下稳定主题：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68069a1b6e0f31c29a18a" style="list-style-type:decimal"><li><b>Data Evolution</b>：建表、更新、删除和并发行为；</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6801e90a8f4a855a12b15" style="list-style-type:decimal"><li><b>File Layout and Reads</b>：Row ID Range、Provider 选择和文件契约；</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68041868ed367945d9950" style="list-style-type:decimal"><li><b>Data Evolution Maintenance</b>：普通 Compaction、文件拆分和 DV Materialization；</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a18679d83040c783b9" style="list-style-type:decimal"><li><b>PyPaimon Data Evolution</b>：Predicate、Row ID、Shard 和 Stream Update；</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806da73fe7bf47b5561b" style="list-style-type:decimal"><li><b>Global Index Management</b>：索引覆盖、新鲜度和更新策略；</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fc0e3562fd68098b53ad7eb5ee03403" style="list-style-type:decimal"><li><b>Flink Action 与 Procedure</b>：Merge、Delete 和维护任务；</li></ol><ol start="7" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806b9bc3cc45c6c46399" style="list-style-type:decimal"><li><b>Spark Maintenance 与 Index Procedure</b>：Compaction、DV 和 Global Index；</li></ol><ol start="8" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6803db4e7f38b68fae32d" style="list-style-type:decimal"><li><b>Lance Data Evolution 与 Row Lineage</b>：Fragment、Column Replacement 和 Stable Row ID；</li></ol><ol start="9" class="notion-list notion-list-numbered notion-block-3fc0e3562fd6806a91b6eafbaf164934" style="list-style-type:decimal"><li><b>Lance Data Overlay</b>：稀疏 Cell 更新的实验性设计；</li></ol><ol start="10" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680e9a98ef39e80c4453d" style="list-style-type:decimal"><li><b>Iceberg Table Format Specification</b>：V3 Row Lineage、Deletion Vector 和 V4 Column File；</li></ol><ol start="11" class="notion-list notion-list-numbered notion-block-3fc0e3562fd680a5b154e1ad4347b57b" style="list-style-type:decimal"><li><b>Iceberg Efficient Column Updates Proposal</b>：Column File 的目标、非目标和实施进展。</li></ol><div class="notion-text notion-block-3fc0e3562fd68038bc66c3942542aaa7">阅读在线文档时应注意版本选择。<code class="notion-inline-code">master</code> 或 <code class="notion-inline-code">main</code> 页面反映正在开发的行为，未必代表某个已发布版本已经具备相同能力。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Apache Paimon 2.1.0 正式发布：强化多模态 AI、原生 Python 与湖仓互操作]]></title>
            <link>https://kunni.top//article/3fa0e356-2fd6-80f9-8b4f-db92b3ec8507</link>
            <guid>https://kunni.top//article/3fa0e356-2fd6-80f9-8b4f-db92b3ec8507</guid>
            <pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3fa0e3562fd680f98b4fdb92b3ec8507"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><blockquote class="notion-quote notion-block-3fb0e3562fd68090a13bdecb1e7d42e3"><div>发布日期：2026 年 10 月 12 日</div></blockquote><div class="notion-text notion-block-3fb0e3562fd680c9b207e4aeff24b623">Apache Paimon 社区正式发布 Apache Paimon 2.1.0 和 PyPaimon 2.1.0。</div><div class="notion-text notion-block-3fb0e3562fd6804e9eabcc3c84a60cbc">相比 2.0.0，本版本经过约两个月迭代，两个正式 Tag 之间涉及约 1,000 个提交，重点完善了多模态数据管理、Data Evolution、PyPaimon 原生执行、全局索引、REST Catalog、Iceberg 兼容以及 Flink、Spark 集成。</div><div class="notion-text notion-block-3fb0e3562fd6809399a7ccc79dbc75dc">正式源码包已经发布，Java 构件和 PyPaimon 也分别可以从 Maven Central 与 PyPI 获取。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd6808f8557e9b6f2598807" data-id="3fb0e3562fd6808f8557e9b6f2598807"><span><div id="3fb0e3562fd6808f8557e9b6f2598807" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd6808f8557e9b6f2598807" title="版本亮点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">版本亮点</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-3fb0e3562fd680d09e46d7b02efa0d81" style="list-style-type:decimal"><li><b>Data Evolution 能力进一步完善</b>，支持更加灵活的列级、嵌套字段级更新与数据回填。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3fb0e3562fd6804a9b99c4db03bdc973" style="list-style-type:decimal"><li><b>多模态数据能力增强</b>，持续完善 BLOB、VECTOR、VARIANT、视频和 LeRobot 数据集支持。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3fb0e3562fd68024aaf0c5b882694523" style="list-style-type:decimal"><li><b>PyPaimon 原生执行路径扩展</b>，加强 Rust Native、Ray 和 PyTorch 等 AI 数据处理生态。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3fb0e3562fd6807484a5f79048d3662f" style="list-style-type:decimal"><li><b>全局索引与搜索能力升级</b>，增强 BTree、Bitmap、Multivalue、FM、向量和全文索引。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3fb0e3562fd6804e9fc7fa2b0ea9633f" style="list-style-type:decimal"><li><b>REST Catalog 与数据治理能力增强</b>，新增权限、策略、查询授权和语义视图等管理能力。</li></ol><ol start="6" class="notion-list notion-list-numbered notion-block-3fb0e3562fd680dc827ef60d431b3c19" style="list-style-type:decimal"><li><b>Iceberg、Flink、Spark 和 CDC 集成持续增强</b>，并修复大量并发、Compaction 和格式兼容问题。</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd680eb815bddb3a428f8d0" data-id="3fb0e3562fd680eb815bddb3a428f8d0"><span><div id="3fb0e3562fd680eb815bddb3a428f8d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd680eb815bddb3a428f8d0" title="多模态与 Data Evolution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">多模态与 Data Evolution</span></span></h3><div class="notion-text notion-block-3fb0e3562fd6801f8acaf2b692192e39">Paimon 2.1.0 继续完善面向 AI 数据管道的 Data Evolution 模型。对于启用 Row Tracking 的 Append Table，可以只更新指定列，而无需重写未发生变化的大字段文件；逻辑行可以由普通列文件、BLOB 文件和向量文件按照 Row ID 组合而成。</div><div class="notion-text notion-block-3fb0e3562fd6807abaa0e2feade5b84f">本版本主要增强包括：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680f09e6ecd948d9384d0"><li>支持嵌套字段级 Data Evolution。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6802d8d56d60ea6b88101"><li>完善 Spark <code class="notion-inline-code">UPDATE</code>、<code class="notion-inline-code">MERGE INTO</code> 和 Flink SQL <code class="notion-inline-code">DELETE</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68026a0fdd7e8a48d7232"><li>增强 PyPaimon 按 Row ID、业务键和条件进行更新、删除与合并。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680f0ae78de2c22f102b9"><li>优化并发更新和 Compaction 之间的冲突检测与重试。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680ed9605de48064958f2"><li>支持 Data Evolution 表上的 Deletion Vector、索引下推和统计信息裁剪。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680ca8100e9cad0d14a68"><li>增强 BLOB 数组、MAP BLOB、向量文件和局部列回填能力。</li></ul><div class="notion-text notion-block-3fb0e3562fd680ddb8d3ece4c1ee594b">Data Evolution 能够避免在更新标签、描述、向量等派生数据时重复改写图片、视频等大型原始数据，尤其适合数据标注、Embedding 生成和模型训练数据迭代场景。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd6807b9697d5f1702f565c" data-id="3fb0e3562fd6807b9697d5f1702f565c"><span><div id="3fb0e3562fd6807b9697d5f1702f565c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd6807b9697d5f1702f565c" title="PyPaimon 与 AI 数据处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">PyPaimon 与 AI 数据处理</span></span></h3><div class="notion-text notion-block-3fb0e3562fd680a3ba5bf3529420dbbb">PyPaimon 2.1.0 是本次发布的重点方向之一。Native 读取、写入、扫描规划和提交能力得到扩展，更多主键表、动态 Bucket、Data Evolution、BLOB、VARIANT 和分支写入场景可以进入 Rust 原生执行路径。</div><div class="notion-text notion-block-3fb0e3562fd68029b1b6d4682c1f48f1">在分布式 AI 数据处理方面，本版本增强了：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6802880f9fbf3b1d49888"><li>基于 Ray 的分布式向量搜索、全文搜索和混合搜索。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680b39fe1c0e9377025e8"><li>Ray Row ID 更新和大规模 MERGE。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680cca8c9edcf73739e67"><li>PyTorch 流式、批式和分布式 Dataset。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680e1af97f7881bde83e1"><li>LeRobot 数据集导入、直接采集写入和训练窗口读取。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68063a338d81f00cc0dcc"><li>Packed Video 存储、关键帧索引和并行视频解码。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680189756ce87c49ff97c"><li>HDFS Native Client，以及 BLOB、VARIANT 和向量数据的原生读取。</li></ul><div class="notion-text notion-block-3fb0e3562fd68052898ec73c70800a6a">PyPaimon 进一步从“Python 访问接口”演进为面向 AI 和多模态工作负载的数据处理 SDK。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd680ddbcadde90ab594071" data-id="3fb0e3562fd680ddbcadde90ab594071"><span><div id="3fb0e3562fd680ddbcadde90ab594071" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd680ddbcadde90ab594071" title="全局索引与搜索能力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">全局索引与搜索能力</span></span></h3><div class="notion-text notion-block-3fb0e3562fd680989ee3ca7d1370c1ca">Paimon 2.1.0 对全局索引进行了较大范围的增强：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6804ba83dc84002f06085"><li>BTree 支持复合键、前缀、范围、<code class="notion-inline-code">IN</code> 和空值查询。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68009ba35dee6aa50936b"><li>BTree 可选 Bloom Filter，并优化 Posting List 编码。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6809fbb97f739175733bf"><li>新增面向数组成员查询的 Multivalue Index。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680a882c8dc9aefe50659"><li>完善 FM Index，支持精确子串查询和主键表。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68098884cc187da2439da"><li>支持索引增量刷新和并行构建。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68063948ade45d76bbeae"><li>向量索引和全文索引支持 Deletion Vector 表。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68000bff0d57643e3557f"><li>支持向量、全文和混合搜索的预过滤及分布式执行。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6806da68ffb59db04fe25"><li>改进索引覆盖范围、残余谓词和统计信息处理的正确性。</li></ul><div class="notion-text notion-block-3fb0e3562fd68095b4b0fb3ce1827364">2.1.0 的全局索引体系覆盖标量过滤、数组成员检索、子串搜索、向量相似度搜索和全文搜索，为统一分析与 AI 检索提供了更加完整的能力。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd6802ea575f5ecef94bd74" data-id="3fb0e3562fd6802ea575f5ecef94bd74"><span><div id="3fb0e3562fd6802ea575f5ecef94bd74" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd6802ea575f5ecef94bd74" title="REST Catalog 与数据治理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">REST Catalog 与数据治理</span></span></h3><div class="notion-text notion-block-3fb0e3562fd68042b27af4e75024fbfb">REST Catalog 在 2.1.0 中进一步从远程元数据访问接口扩展为统一的 Catalog 与治理入口，新增或增强了：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680f8b05dd91a39b04e76"><li>REST Schema Management。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680bc950dfe0a8d7c8398"><li>权限和策略管理。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680aa9661e06a1de49d4d"><li>行级过滤与列掩码。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68068a483fc1e2364d20a"><li>Query Authorization。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680b48accdcffc968bb96"><li>Semantic View 和实体标签管理。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680ec8a6fe9e84f165c30"><li>分区统计信息注册。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680c8a28cf5d29002b854"><li>PyPaimon REST Commit 与权限管理。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680d1b110c7c39d2613db"><li>REST Management OpenAPI。</li></ul><div class="notion-text notion-block-3fb0e3562fd6805984bcd799d33d6a4d">此外，Paimon 视图现在可以在 REST、JDBC 和 Hive Catalog 中保存，并可维护不同 SQL 引擎方言的查询定义。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd680c3811acfa738357332" data-id="3fb0e3562fd680c3811acfa738357332"><span><div id="3fb0e3562fd680c3811acfa738357332" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd680c3811acfa738357332" title="Iceberg 兼容性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Iceberg 兼容性</span></span></h3><div class="notion-text notion-block-3fb0e3562fd680deb356cdfc66257e17">本版本继续增强 Paimon 表的 Iceberg 元数据发布能力：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68017916cfc9c38baad84"><li>支持 Iceberg Format V3 Row Lineage 元数据。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680daa0cbd4d5a1bd9b37"><li>支持将 VARIANT 列发布为 Iceberg V3。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68070a68dea3d53950089"><li>增强 Iceberg REST Catalog 属性透传与异常恢复。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680faa620f5fb6a2b748e"><li>改进 Tag 到 Iceberg Snapshot Reference 的映射。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680708d64e1088382b2e9"><li>完善时间精度、NaN Bounds 和不兼容类型校验。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6804290a3d94b2302a43d"><li>修复回滚、元数据过期和 REST 短暂故障场景。</li></ul><div class="notion-text notion-block-3fb0e3562fd68018ab76de578c6736a5">其他引擎可通过 Iceberg Connector 读取 Paimon 发布的元数据，而数据写入、Compaction 和生命周期管理仍由 Paimon 负责。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3fb0e3562fd680819ccdde566dcd8347" data-id="3fb0e3562fd680819ccdde566dcd8347"><span><div id="3fb0e3562fd680819ccdde566dcd8347" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3fb0e3562fd680819ccdde566dcd8347" title="Flink、Spark、CDC 与可靠性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Flink、Spark、CDC 与可靠性</span></span></h3><div class="notion-text notion-block-3fb0e3562fd680feaa76f3ab773793f7">围绕计算引擎集成，2.1.0 增强了：</div><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68060affae920dba5aa71"><li>Flink Data Evolution SQL DELETE、Savepoint Auto Tag 和异步 Lookup 刷新。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680beb55bef4cb5f94fe8"><li>Spark Data Evolution Self-Merge、<code class="notion-inline-code">MERGE INTO</code>、Row ID 重分配及 Format Table 操作。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6801ca2c8ffa3f2043221"><li>Format Table 的 <code class="notion-inline-code">TRUNCATE TABLE</code>、<code class="notion-inline-code">ANALYZE TABLE</code>、分区统计和 Overwrite。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd6800c8607ff7fc3fdf507"><li>MySQL CDC 表级配置、PostgreSQL <code class="notion-inline-code">jsonb</code>、Debezium 主键解析和多表 CDC 状态恢复。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd680dda0a3c85d4c37d0fe"><li>并发 MERGE 与 Compaction 冲突检测。</li></ul><ul class="notion-list notion-list-disc notion-block-3fb0e3562fd68048bbf2c20ed2dc5cf8"><li>Manifest、Block Cache、文件索引、向量搜索和 BLOB 读取性能优化。</li></ul><div class="notion-text notion-block-3fb0e3562fd6806bb3e1e835c69d9d46">2.1.0 继续提供 Flink 1.16—2.2、Spark 3.2—4.1，以及多个 Hive 版本的构件。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Variant 二进制编码]]></title>
            <link>https://kunni.top//article/3f40e356-2fd6-8021-9f78-ce6049792c96</link>
            <guid>https://kunni.top//article/3f40e356-2fd6-8021-9f78-ce6049792c96</guid>
            <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3f40e3562fd680219f78ce6049792c96"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-3f40e3562fd68098b1aae1336ae49787">原文：<a class="notion-link" href="http://variantencoding.md/" target="_blank" rel="noopener noreferrer">VariantEncoding.md</a></div><div class="notion-blank notion-block-3f40e3562fd680a88064d4dad75ceede"> </div><div class="notion-text notion-block-3f40e3562fd680a1aa92fbceb8417111">一个 Variant 表示以下三种类型之一：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f38ff9dc262c25f3f2"><li>原始类型（Primitive）：一种类型及其对应的值，例如 <code class="notion-inline-code">INT</code>、<code class="notion-inline-code">STRING</code></li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680ab91b1fd7c0fa99bd8"><li>数组（Array）：由 Variant 值组成的有序列表</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680e1a348e9e8590084b5"><li>对象（Object）：由字符串和 Variant 组成的无序键值对集合。一个对象不能包含重复的键</li></ul><div class="notion-text notion-block-3f40e3562fd680afb978de400b15831a">一个 Variant 使用两个二进制值进行编码：值和元数据。</div><div class="notion-text notion-block-3f40e3562fd680c9a356f5b15b531903">允许使用的原始类型数量是固定的，具体见下表。这些类型是 Parquet 格式所支持的<a class="notion-link" href="https://github.com/apache/parquet-format/blob/master/LogicalTypes.md" target="_blank" rel="noopener noreferrer">逻辑类型</a>中被普遍支持的一个子集。</div><div class="notion-text notion-block-3f40e3562fd6805eabe1d97f5e1355b1">Variant 二进制编码可以将半结构化数据（例如 JSON）表示为一种能够按路径进行高效查询的形式。即使数据结构非常宽或嵌套非常深，该设计也能够高效访问嵌套数据。</div><div class="notion-text notion-block-3f40e3562fd680f591c4f5ab4a310142">采用这种表示方式的另一个原因是：除元数据外，每个嵌套的 Variant 值都是连续存储且自包含的。</div><div class="notion-text notion-block-3f40e3562fd6800b8ee3e165ca21c696">例如，当一个 Variant 包含由多个 Variant 值组成的数组时，只要将其中某个内部 Variant 值与完整 Variant 的元数据配对，该内部值本身就是一个合法的 Variant。</div><div class="notion-text notion-block-3f40e3562fd680e3a580ce1ec9ebecc0">本文档描述 Variant 二进制编码方案。</div><div class="notion-text notion-block-3f40e3562fd68068bb04e4a0db9462e9">Variant 字段还可以进行“拆分”（shredding）。拆分是指把 Variant 中的某些元素提取到单独的列中，以实现更高效的数据提取和过滤下推。[Variant 拆分规范](VariantShredding.md)描述了如何将 Variant 值拆分成带类型的 Parquet 列。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd68076b786f6ceb78d89d1" data-id="3f40e3562fd68076b786f6ceb78d89d1"><span><div id="3f40e3562fd68076b786f6ceb78d89d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68076b786f6ceb78d89d1" title="Parquet 中的 Variant"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Parquet 中的 Variant</span></span></h3><div class="notion-text notion-block-3f40e3562fd680a0b034f5109905b06c">在 Parquet 中，一个 Variant 值由一个包含两个字段的 Group 表示，这两个字段分别名为 <code class="notion-inline-code">value</code> 和 <code class="notion-inline-code">metadata</code>。</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680428fe1d277312923c4"><li>Variant Group 必须使用 <code class="notion-inline-code">VARIANT</code> 逻辑类型进行标注。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680b7bc54dd58305095eb"><li><code class="notion-inline-code">value</code> 和 <code class="notion-inline-code">metadata</code> 字段都必须是 <code class="notion-inline-code">binary</code> 类型，即 Parquet Thrift 定义中的 <code class="notion-inline-code">BYTE_ARRAY</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68092ba12c7348871c858"><li><code class="notion-inline-code">metadata</code> 字段必须标记为 <code class="notion-inline-code">required</code>，并且必须是符合下文定义的有效 Variant 元数据。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6802f8181d2d111dbe1f7"><li>对于未拆分的 Variant 值，<code class="notion-inline-code">value</code> 字段必须标记为 <code class="notion-inline-code">required</code>；如果值的一部分已经被[拆分](VariantShredding.md)为带类型的 Parquet 列，则应标记为 <code class="notion-inline-code">optional</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6805e8c35f342691c34de"><li>如果 <code class="notion-inline-code">value</code> 字段存在，它必须是符合下文定义的有效 Variant 值。</li></ul><div class="notion-text notion-block-3f40e3562fd6806fa0a5fcf777e60f3b">以下是 Parquet 中未拆分 Variant 的预期表示形式：</div><div class="notion-text notion-block-3f40e3562fd68042891fdb09fd4d7fcd">以下是 Parquet 中已拆分 Variant 的一个示例：</div><div class="notion-text notion-block-3f40e3562fd68047ba3bdb4f29ab69b0"><code class="notion-inline-code">VARIANT</code> 注解本身不会对 Variant Group 的重复性施加额外限制，但包含它的类型（例如 <code class="notion-inline-code">MAP</code> 和 <code class="notion-inline-code">LIST</code>）可能对此作出限制。</div><div class="notion-text notion-block-3f40e3562fd680078527e636c5cc2b48">Variant Group 的名称就是 Variant 列的名称。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd6801fb7d1d81f40d18c4e" data-id="3f40e3562fd6801fb7d1d81f40d18c4e"><span><div id="3f40e3562fd6801fb7d1d81f40d18c4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6801fb7d1d81f40d18c4e" title="元数据编码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">元数据编码</span></span></h3><div class="notion-text notion-block-3f40e3562fd6807da03eec3d4edff0c2">编码后的元数据始终以一个头字节开始：</div><div class="notion-text notion-block-3f40e3562fd680a9b89ff1d7461b53aa"><code class="notion-inline-code">version</code> 是一个 4 位值，当前必须始终为 <code class="notion-inline-code">1</code>。</div><div class="notion-text notion-block-3f40e3562fd68088b390d71a566c339b"><code class="notion-inline-code">sorted_strings</code> 是一个 1 位值，表示字典中的字符串是否经过排序且互不重复。</div><div class="notion-text notion-block-3f40e3562fd6807c80b4dfc984f3d065"><code class="notion-inline-code">offset_size_minus_one</code> 是一个 2 位值，用于表示每个字典大小字段和偏移量字段所占的字节数。实际字节数 <code class="notion-inline-code">offset_size</code> 的计算方式为：</div><div class="notion-text notion-block-3f40e3562fd6802e9aa6ca4cb8c3819a">第 5 位（标记为 <code class="notion-inline-code">R</code>）是保留位，读取器必须忽略它。</div><div class="notion-text notion-block-3f40e3562fd680dc8a21d610ab87a6bb">完整元数据的编码结构如下：</div><div class="notion-text notion-block-3f40e3562fd680deba5bd67f51744307">元数据首先编码 <code class="notion-inline-code">header</code> 字节，然后编码 <code class="notion-inline-code">dictionary_size</code>。</div><div class="notion-text notion-block-3f40e3562fd680b8b0c3d2c7f9436cf1"><code class="notion-inline-code">dictionary_size</code> 是一个长度为 <code class="notion-inline-code">offset_size</code> 字节的无符号小端序整数，表示字典中的字符串数量。</div><div class="notion-text notion-block-3f40e3562fd6804784d9fbe31dcd1300">接下来是 <code class="notion-inline-code">offset</code> 列表，其中包含 <code class="notion-inline-code">dictionary_size + 1</code> 个值。每个 <code class="notion-inline-code">offset</code> 都是一个长度为 <code class="notion-inline-code">offset_size</code> 字节的无符号小端序整数，表示第 i 个字符串在 <code class="notion-inline-code">bytes</code> 中的起始字节偏移量。</div><div class="notion-text notion-block-3f40e3562fd680e4b4b7e28e81825199">第一个 <code class="notion-inline-code">offset</code> 始终为 <code class="notion-inline-code">0</code>，最后一个 <code class="notion-inline-code">offset</code> 始终等于 <code class="notion-inline-code">bytes</code> 的总长度。</div><div class="notion-text notion-block-3f40e3562fd680deaff4c1d44c0223a5">元数据的最后一部分是 <code class="notion-inline-code">bytes</code>，用于保存字典中的所有字符串。所有字符串都必须使用 UTF-8 编码。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd6809a9da2d40965268c9f" data-id="3f40e3562fd6809a9da2d40965268c9f"><span><div id="3f40e3562fd6809a9da2d40965268c9f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6809a9da2d40965268c9f" title="元数据编码语法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">元数据编码语法</span></span></h4><div class="notion-text notion-block-3f40e3562fd6807cb109f8a3cabd154b">编码后元数据的语法如下：</div><div class="notion-text notion-block-3f40e3562fd680fe89c3d0f0a51a9bff">对应说明如下：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680748863c4484c48e918"><li><code class="notion-inline-code">metadata</code>：由 <code class="notion-inline-code">&lt;header&gt;</code>、<code class="notion-inline-code">&lt;dictionary_size&gt;</code> 和 <code class="notion-inline-code">&lt;dictionary&gt;</code> 组成。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f99125c4573ec44e19"><li><code class="notion-inline-code">header</code>：1 个字节，编码方式为：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f99125c4573ec44e19"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680c5aeaffb08fb301b8f"><li><code class="notion-inline-code">version</code>：4 位版本 ID，当前必须始终为 <code class="notion-inline-code">1</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6800a956fea3e7e859cfd"><li><code class="notion-inline-code">sorted_strings</code>：1 位值，表示字典中的字符串是否已排序且互不重复。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680c59dcdf5d8c84379e1"><li><code class="notion-inline-code">offset_size_minus_one</code>：2 位值，表示字典大小字段和偏移量字段各自使用多少字节。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6804a8315e65b32ca1d79"><li><code class="notion-inline-code">dictionary_size</code>：长度为 <code class="notion-inline-code">offset_size</code> 字节的无符号小端序整数，表示字典中的字符串数量。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680899807fadf428ab58c"><li><code class="notion-inline-code">dictionary</code>：由若干 <code class="notion-inline-code">&lt;offset&gt;</code> 和 <code class="notion-inline-code">&lt;bytes&gt;</code> 组成。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6807aaf5be913b1d4c987"><li><code class="notion-inline-code">offset</code>：长度为 <code class="notion-inline-code">offset_size</code> 字节的无符号小端序整数，表示第 i 个字符串在 <code class="notion-inline-code">bytes</code> 中的起始位置。列表中应包含 <code class="notion-inline-code">dictionary_size + 1</code> 个值，最后一个值是 <code class="notion-inline-code">bytes</code> 的总长度。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f7b241c4cbf09a0ee0"><li><code class="notion-inline-code">bytes</code>：采用 UTF-8 编码的字典字符串值。</li></ul><div class="notion-text notion-block-3f40e3562fd680b98aeadf42270b9725">注意事项：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6804a9629c7dee99e0e1d"><li>所有偏移量都相对于 <code class="notion-inline-code">bytes</code> 数组的起始位置。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6802aaef0c55c4810f3ac"><li>第 i 个字符串的长度可以按以下方式计算：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6802aaef0c55c4810f3ac"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680648cebd57bd0f74d21"><li>第一个字符串的偏移量始终为 <code class="notion-inline-code">0</code>，因此从信息角度看它是冗余的。规范仍然保留该值，以简化内存中的处理。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680d0b5bbc5f2332af115"><li><code class="notion-inline-code">offset_size_minus_one</code> 表示每个 <code class="notion-inline-code">dictionary_size</code> 和 <code class="notion-inline-code">offset</code> 条目使用的字节数：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680d0b5bbc5f2332af115"><li>值为 <code class="notion-inline-code">0</code>：1 字节</li><li>值为 <code class="notion-inline-code">1</code>：2 字节</li><li>值为 <code class="notion-inline-code">2</code>：3 字节</li><li>值为 <code class="notion-inline-code">3</code>：4 字节</li></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68027a7ebc185629514f8"><li>如果 <code class="notion-inline-code">sorted_strings</code> 为 <code class="notion-inline-code">1</code>，字典中的字符串必须互不重复，并按字典序排序。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680068181e42d75837ff9"><li>如果 <code class="notion-inline-code">sorted_strings</code> 为 <code class="notion-inline-code">0</code>，读取器不能对字符串的顺序或唯一性作任何假设。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd680499135ea460bb133d1" data-id="3f40e3562fd680499135ea460bb133d1"><span><div id="3f40e3562fd680499135ea460bb133d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680499135ea460bb133d1" title="值编码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">值编码</span></span></h3><div class="notion-text notion-block-3f40e3562fd6803cb40cc29fdeea8b7c">完整的 Variant 值编码首先包含 <code class="notion-inline-code">value_metadata</code> 字节，然后包含零个或多个用于表示 <code class="notion-inline-code">val</code> 的字节：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd68001a003c4589714650d" data-id="3f40e3562fd68001a003c4589714650d"><span><div id="3f40e3562fd68001a003c4589714650d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68001a003c4589714650d" title="基本类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">基本类型</span></span></h4><div class="notion-text notion-block-3f40e3562fd680ad9b21d00c95207410"><code class="notion-inline-code">basic_type</code> 是一个 2 位值，表示 Variant 值属于哪一种基本类型。每个值的含义见基本类型表。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd68002bfe9d84b594d9aa1" data-id="3f40e3562fd68002bfe9d84b594d9aa1"><span><div id="3f40e3562fd68002bfe9d84b594d9aa1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68002bfe9d84b594d9aa1" title="值头部"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">值头部</span></span></h4><div class="notion-text notion-block-3f40e3562fd680479ebffa02ed9d6d0a"><code class="notion-inline-code">value_header</code> 是一个 6 位值，用于保存更多类型信息。其格式取决于 <code class="notion-inline-code">basic_type</code>。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd6806aa9c5cd8aed4a3625" data-id="3f40e3562fd6806aa9c5cd8aed4a3625"><span><div id="3f40e3562fd6806aa9c5cd8aed4a3625" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6806aa9c5cd8aed4a3625" title="原始类型的值头部（basic_type=0）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原始类型的值头部（<code class="notion-inline-code">basic_type=0</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680b4a3b5f06e584f5792">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">0</code> 时，<code class="notion-inline-code">value_header</code> 是一个 6 位的 <code class="notion-inline-code">primitive_header</code>。</div><div class="notion-text notion-block-3f40e3562fd68018a14bfc0c06577224">每个值的含义见原始类型表。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd680efacf5d3d577af5904" data-id="3f40e3562fd680efacf5d3d577af5904"><span><div id="3f40e3562fd680efacf5d3d577af5904" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680efacf5d3d577af5904" title="短字符串的值头部（basic_type=1）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">短字符串的值头部（<code class="notion-inline-code">basic_type=1</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680c79be7fd58102d0607">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">1</code> 时，<code class="notion-inline-code">value_header</code> 是一个 6 位的 <code class="notion-inline-code">short_string_header</code>：</div><div class="notion-text notion-block-3f40e3562fd680e89a2be4fcd8b4e499"><code class="notion-inline-code">short_string_header</code> 的值就是字符串的长度。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd68073ae0ec15d939d1ad6" data-id="3f40e3562fd68073ae0ec15d939d1ad6"><span><div id="3f40e3562fd68073ae0ec15d939d1ad6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68073ae0ec15d939d1ad6" title="对象的值头部（basic_type=2）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">对象的值头部（<code class="notion-inline-code">basic_type=2</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680ca865eebe6bc5f02c3">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">2</code> 时，<code class="notion-inline-code">value_header</code> 由以下字段组成：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6805a9b10e2da5fbe6006"><li><code class="notion-inline-code">field_offset_size_minus_one</code></li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680c4a0b0f73ebb9a1cbd"><li><code class="notion-inline-code">field_id_size_minus_one</code></li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6807a99b7d690206e4d0f"><li><code class="notion-inline-code">is_large</code></li></ul><div class="notion-text notion-block-3f40e3562fd680dd8e21d1cc3ebd5990"><code class="notion-inline-code">field_offset_size_minus_one</code> 和 <code class="notion-inline-code">field_id_size_minus_one</code> 都是 2 位值，分别表示字段偏移量和字段 ID 使用多少字节进行编码。</div><div class="notion-text notion-block-3f40e3562fd6806993e8cb26153f47ce">实际字节数的计算方式如下：</div><div class="notion-text notion-block-3f40e3562fd680fbb2f3cfa9cd7f1994"><code class="notion-inline-code">is_large</code> 是一个 1 位值，表示使用多少字节来编码元素数量：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6808da518fdd2abba9983"><li><code class="notion-inline-code">is_large=0</code>：使用 1 个字节</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680bf80d2f803284c64d7"><li><code class="notion-inline-code">is_large=1</code>：使用 4 个字节</li></ul><div class="notion-text notion-block-3f40e3562fd680bd97f1c4e86997dc5b">第 5 位（标记为 <code class="notion-inline-code">R</code>）是保留位，读取器必须忽略它。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd68091b7ddc2c2bd5d01e1" data-id="3f40e3562fd68091b7ddc2c2bd5d01e1"><span><div id="3f40e3562fd68091b7ddc2c2bd5d01e1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68091b7ddc2c2bd5d01e1" title="数组的值头部（basic_type=3）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数组的值头部（<code class="notion-inline-code">basic_type=3</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680e6b02fd8196d28dbb0">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">3</code> 时，<code class="notion-inline-code">value_header</code> 由以下字段组成：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6805fbef0d1530aef3a96"><li><code class="notion-inline-code">field_offset_size_minus_one</code></li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680a5b1e9c9413607d34d"><li><code class="notion-inline-code">is_large</code></li></ul><div class="notion-text notion-block-3f40e3562fd680a8b850e1db70a6497b"><code class="notion-inline-code">field_offset_size_minus_one</code> 是一个 2 位值，表示用于编码字段偏移量的字节数。</div><div class="notion-text notion-block-3f40e3562fd6801f99f5deb553755a33">实际字节数为：</div><div class="notion-text notion-block-3f40e3562fd68049af5ae1c0f334cfb1"><code class="notion-inline-code">is_large</code> 是一个 1 位值，表示元素数量字段使用多少字节：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68068af38eff01b3c4543"><li><code class="notion-inline-code">is_large=0</code>：使用 1 个字节</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68081ba14d076d0603bb1"><li><code class="notion-inline-code">is_large=1</code>：使用 4 个字节</li></ul><div class="notion-text notion-block-3f40e3562fd6808c9d4fd8376cc2cb9f">第 5～3 位（标记为 <code class="notion-inline-code">RRR</code>）是保留位，读取器必须忽略它们。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd680fcbae1fe94253b1947" data-id="3f40e3562fd680fcbae1fe94253b1947"><span><div id="3f40e3562fd680fcbae1fe94253b1947" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680fcbae1fe94253b1947" title="值数据"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">值数据</span></span></h4><div class="notion-text notion-block-3f40e3562fd6800eaa2cd1a81ecfe5d6"><code class="notion-inline-code">value_data</code> 的编码格式取决于 <code class="notion-inline-code">value_metadata</code> 指定的类型。对于某些类型，<code class="notion-inline-code">value_data</code> 的长度为零字节。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd68025bdfef08dddcda594" data-id="3f40e3562fd68025bdfef08dddcda594"><span><div id="3f40e3562fd68025bdfef08dddcda594" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68025bdfef08dddcda594" title="原始类型的值数据（basic_type=0）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原始类型的值数据（<code class="notion-inline-code">basic_type=0</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd6804c9765e928f4e97b2d">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">0</code> 时，<code class="notion-inline-code">value_data</code> 的格式取决于 <code class="notion-inline-code">primitive_header</code>。</div><div class="notion-text notion-block-3f40e3562fd680fcb6c9c34dbead8820">每种原始类型的具体编码格式见原始类型表。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd680e594fec4614d5b6310" data-id="3f40e3562fd680e594fec4614d5b6310"><span><div id="3f40e3562fd680e594fec4614d5b6310" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680e594fec4614d5b6310" title="短字符串的值数据（basic_type=1）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">短字符串的值数据（<code class="notion-inline-code">basic_type=1</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680d49e44e4979f3f78ea">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">1</code> 时，<code class="notion-inline-code">value_data</code> 是表示该字符串的一系列 UTF-8 编码字节。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd6808a8614f8acddd00877" data-id="3f40e3562fd6808a8614f8acddd00877"><span><div id="3f40e3562fd6808a8614f8acddd00877" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6808a8614f8acddd00877" title="对象的值数据（basic_type=2）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">对象的值数据（<code class="notion-inline-code">basic_type=2</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd68044ac9fcaafb95657a5">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">2</code> 时，<code class="notion-inline-code">value_data</code> 用于编码对象。其编码格式如下：</div><div class="notion-text notion-block-3f40e3562fd680fd84f5c8ad89f879ea">对象的 <code class="notion-inline-code">value_data</code> 首先是 <code class="notion-inline-code">num_elements</code>。它是一个长度为 1 字节或 4 字节的无符号小端序整数，表示对象中的元素数量。</div><div class="notion-text notion-block-3f40e3562fd680ccb298eba4b750a08c"><code class="notion-inline-code">num_elements</code> 的字节数由 <code class="notion-inline-code">value_header</code> 中的 <code class="notion-inline-code">is_large</code> 指定。</div><div class="notion-text notion-block-3f40e3562fd680e3987bf068a7ac2025">接下来是 <code class="notion-inline-code">field_id</code> 列表。该列表包含 <code class="notion-inline-code">num_elements</code> 个条目，每个 <code class="notion-inline-code">field_id</code> 都是一个长度为 <code class="notion-inline-code">field_id_size</code> 字节的无符号小端序整数。</div><div class="notion-text notion-block-3f40e3562fd68077a69acdfb3c94888c"><code class="notion-inline-code">field_id</code> 是元数据字典的索引。</div><div class="notion-text notion-block-3f40e3562fd6806e8db8efd0a6116cc6"><code class="notion-inline-code">field_id</code> 列表之后是 <code class="notion-inline-code">field_offset</code> 列表。该列表包含 <code class="notion-inline-code">num_elements + 1</code> 个条目，每个 <code class="notion-inline-code">field_offset</code> 都是一个长度为 <code class="notion-inline-code">field_offset_size</code> 字节的无符号小端序整数。</div><div class="notion-text notion-block-3f40e3562fd68048b4b8e52bb1703544"><code class="notion-inline-code">field_offset</code> 表示第 i 个 <code class="notion-inline-code">value</code> 开始位置的字节偏移量。该偏移量相对于第一个 <code class="notion-inline-code">value</code> 的第一个字节。</div><div class="notion-text notion-block-3f40e3562fd6804e875df71505f5ecbb">最后一个 <code class="notion-inline-code">field_offset</code> 指向最后一个 <code class="notion-inline-code">value</code> 结束位置之后的第一个字节。</div><div class="notion-text notion-block-3f40e3562fd6806bb15dda7c2689b1e2"><code class="notion-inline-code">field_offset</code> 列表之后是 <code class="notion-inline-code">value</code> 列表。它包含 <code class="notion-inline-code">num_elements</code> 个 <code class="notion-inline-code">value</code> 条目，每个条目都是一个编码后的 Variant 值。</div><div class="notion-text notion-block-3f40e3562fd68097bac7f9eabde0d191">对于对象中的第 i 个键值对：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6801f9fa1da1fdc5dae26"><li>键是由第 i 个 <code class="notion-inline-code">field_id</code> 索引的元数据字典条目；</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6805eaaded47f58257226"><li>值是从第 i 个 <code class="notion-inline-code">field_offset</code> 所指向的字节位置开始的 Variant <code class="notion-inline-code">value</code>。</li></ul><div class="notion-text notion-block-3f40e3562fd68002ab9cd2420a0311a7">字段 ID 和字段偏移量必须按照元数据字典中对应字段名称的字典序排列。</div><div class="notion-text notion-block-3f40e3562fd680bf8da8d04fee1c9dcd">不过，实际的 <code class="notion-inline-code">value</code> 条目不必按照任何特定顺序存放。这意味着 <code class="notion-inline-code">field_offset</code> 的值不一定单调递增。</div><div class="notion-text notion-block-3f40e3562fd680998dc2ea1f2509ba64">例如，对于以下对象：</div><div class="notion-text notion-block-3f40e3562fd680e3b385f491b259c24d"><code class="notion-inline-code">field_id</code> 列表必须按照字段名称的字典序排列：</div><div class="notion-text notion-block-3f40e3562fd680789d0fcecc89b73eb4"><code class="notion-inline-code">field_offset</code> 列表必须是：</div><div class="notion-text notion-block-3f40e3562fd68080926efd5ba737f256">但 <code class="notion-inline-code">value</code> 列表本身可以采用任意顺序。</div><h5 class="notion-h notion-h4 notion-h-indent-2 notion-block-3f40e3562fd680409a9df2c0342b5a97" data-id="3f40e3562fd680409a9df2c0342b5a97"><span><div id="3f40e3562fd680409a9df2c0342b5a97" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680409a9df2c0342b5a97" title="数组的值数据（basic_type=3）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数组的值数据（<code class="notion-inline-code">basic_type=3</code>）</span></span></h5><div class="notion-text notion-block-3f40e3562fd680fc97e6ee22aef78a86">当 <code class="notion-inline-code">basic_type</code> 为 <code class="notion-inline-code">3</code> 时，<code class="notion-inline-code">value_data</code> 用于编码数组。其格式如下：</div><div class="notion-text notion-block-3f40e3562fd6802f8504d42b8b930d8c">数组的 <code class="notion-inline-code">value_data</code> 首先是 <code class="notion-inline-code">num_elements</code>。它是一个长度为 1 字节或 4 字节的无符号小端序整数，表示数组中的元素数量。</div><div class="notion-text notion-block-3f40e3562fd6809387f1cf4d9767036a"><code class="notion-inline-code">num_elements</code> 的字节数由 <code class="notion-inline-code">value_header</code> 中的 <code class="notion-inline-code">is_large</code> 指定。</div><div class="notion-text notion-block-3f40e3562fd68022bbb9d0a10f66e857">接下来是 <code class="notion-inline-code">field_offset</code> 列表。该列表包含 <code class="notion-inline-code">num_elements + 1</code> 个条目，每个 <code class="notion-inline-code">field_offset</code> 都是一个长度为 <code class="notion-inline-code">field_offset_size</code> 字节的无符号小端序整数。</div><div class="notion-text notion-block-3f40e3562fd680a5971ae3ccc1a56a9e"><code class="notion-inline-code">field_offset</code> 表示第 i 个 <code class="notion-inline-code">value</code> 的起始字节偏移量。该偏移量相对于第一个 <code class="notion-inline-code">value</code> 的第一个字节。</div><div class="notion-text notion-block-3f40e3562fd6804ebff4f248dc1ae36c">最后一个 <code class="notion-inline-code">field_offset</code> 指向最后一个 <code class="notion-inline-code">value</code> 的最后一个字节之后的位置。</div><div class="notion-text notion-block-3f40e3562fd6807db4dcd41440eaa234"><code class="notion-inline-code">field_offset</code> 列表之后是 <code class="notion-inline-code">value</code> 列表。它包含 <code class="notion-inline-code">num_elements</code> 个 <code class="notion-inline-code">value</code> 条目，每个条目都是一个编码后的 Variant 值。</div><div class="notion-text notion-block-3f40e3562fd680f797bdef7209cbdee2">对于数组中的第 i 个条目，其值是从第 i 个 <code class="notion-inline-code">field_offset</code> 所指向位置开始的 Variant <code class="notion-inline-code">value</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd680a78f68df43b2df6b7b" data-id="3f40e3562fd680a78f68df43b2df6b7b"><span><div id="3f40e3562fd680a78f68df43b2df6b7b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680a78f68df43b2df6b7b" title="值编码语法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">值编码语法</span></span></h4><div class="notion-text notion-block-3f40e3562fd6809993b6c6e270d350e4">编码后值的语法如下：</div><div class="notion-text notion-block-3f40e3562fd68092a86ae27cf7208855">对应说明如下：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6802c9f44d8a3f50bd826"><li><code class="notion-inline-code">value</code>：由 <code class="notion-inline-code">&lt;value_metadata&gt;</code> 和一个可选的 <code class="notion-inline-code">&lt;value_data&gt;</code> 组成。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6804498efd9035103ff8d"><li><code class="notion-inline-code">value_metadata</code>：1 个字节，编码方式为：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6804498efd9035103ff8d"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6809d8dbad3839e63ca49"><li><code class="notion-inline-code">basic_type</code>：基本类型表中的 ID。<code class="notion-inline-code">&lt;value_header&gt;</code> 必须采用与该基本类型对应的形式。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68001b594e715ba00e6ac"><li><code class="notion-inline-code">value_header</code>：以下类型之一：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68001b594e715ba00e6ac"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680da9831fefca1313e6d"><li><code class="notion-inline-code">primitive_header</code>：原始类型表中的 ID。<code class="notion-inline-code">&lt;val&gt;</code> 必须是对应的 <code class="notion-inline-code">&lt;primitive_val&gt;</code> 形式。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6805c9260f87b159f663f"><li><code class="notion-inline-code">short_string_header</code>：以字节为单位的无符号字符串长度，范围为 0～63。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680958ee7c787aa676845"><li><code class="notion-inline-code">object_header</code>：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680958ee7c787aa676845"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6809c8e91f48771357ff2"><li><code class="notion-inline-code">array_header</code>：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6809c8e91f48771357ff2"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680d19c1ed462940b366e"><li><code class="notion-inline-code">value_data</code>：原始值、短字符串值、对象值或数组值之一。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6809eaacbee61739533a7"><li><code class="notion-inline-code">primitive_val</code>：二进制表示形式见类型表。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68013bd7cfa734bfd3507"><li><code class="notion-inline-code">short_string_val</code>：UTF-8 编码的字节。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68005a4c9fae21713d25b"><li><code class="notion-inline-code">object_val</code>：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68005a4c9fae21713d25b"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f49c8fcefd4c8daf85"><li><code class="notion-inline-code">array_val</code>：</li><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680f49c8fcefd4c8daf85"></ul></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68077bb49fd74801e524f"><li><code class="notion-inline-code">num_elements</code>：长度为 1 字节或 4 字节的无符号小端序整数，具体取决于 <code class="notion-inline-code">&lt;object_header&gt;</code> 或 <code class="notion-inline-code">&lt;array_header&gt;</code> 中的 <code class="notion-inline-code">is_large</code>。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6801383f2f78e2df9ded8"><li><code class="notion-inline-code">field_id</code>：长度为 1、2、3 或 4 字节的无符号小端序整数。其长度由 <code class="notion-inline-code">&lt;object_header&gt;</code> 中的 <code class="notion-inline-code">field_id_size_minus_one</code> 决定，用于索引字典。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680299b8ecfeacbb75728"><li><code class="notion-inline-code">field_offset</code>：长度为 1、2、3 或 4 字节的无符号小端序整数。其长度由 <code class="notion-inline-code">&lt;object_header&gt;</code> 或 <code class="notion-inline-code">&lt;array_header&gt;</code> 中的 <code class="notion-inline-code">field_offset_size_minus_one</code> 决定，表示在 <code class="notion-inline-code">fields</code> 内的字节偏移量。</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680d791f2e1557114f043"><li><code class="notion-inline-code">fields</code>：零个或多个 <code class="notion-inline-code">&lt;value&gt;</code>。</li></ul><div class="notion-text notion-block-3f40e3562fd68049a024c18f5df9c5fa">每个 <code class="notion-inline-code">value_data</code> 都必须与 <code class="notion-inline-code">value_metadata</code> 定义的类型相对应。</div><div class="notion-text notion-block-3f40e3562fd680d584a1cec92d571f48">布尔类型和空值类型没有相应的 <code class="notion-inline-code">value_data</code>，因为它们的类型本身已经定义了对应的值。</div><div class="notion-text notion-block-3f40e3562fd680178284eb04126ac57b">每个 <code class="notion-inline-code">array_val</code> 和 <code class="notion-inline-code">object_val</code> 必须为 <code class="notion-inline-code">field_offset</code> 包含恰好 <code class="notion-inline-code">num_elements + 1</code> 个值。</div><div class="notion-text notion-block-3f40e3562fd68006bbd9f4f9fdd9439c">最后一个条目表示最后一个字段之后一个字节的位置，也就是所有字段的总字节数。所有偏移量都相对于对象或数组中第一个字段的第一个字节。</div><div class="notion-text notion-block-3f40e3562fd680db9c8de09dcede5c25"><code class="notion-inline-code">field_id_size_minus_one</code> 和 <code class="notion-inline-code">field_offset_size_minus_one</code> 表示每个字段 ID 或偏移量使用的字节数：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6803b879ad1975e8c7685"><li>值为 <code class="notion-inline-code">0</code>：1 字节</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680b19983ea800efd5c93"><li>值为 <code class="notion-inline-code">1</code>：2 字节</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680fc816ad72043dd0eb1"><li>值为 <code class="notion-inline-code">2</code>：3 字节</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6807b992cfbf144ba82f7"><li>值为 <code class="notion-inline-code">3</code>：4 字节</li></ul><div class="notion-text notion-block-3f40e3562fd68076a2a9cfbd0857edac">数组和对象的 <code class="notion-inline-code">is_large</code> 标志用于表示元素数量使用 1 字节还是 4 字节编码。</div><div class="notion-text notion-block-3f40e3562fd68036a78af4859adb2054">当元素数量超过 255 时，<code class="notion-inline-code">is_large</code> 必须设置为 <code class="notion-inline-code">true</code>。</div><div class="notion-text notion-block-3f40e3562fd680e3a536da8b1c4c8563">实现也可以为这些字段使用大于实际所需的编码宽度。例如，一个少于 256 个元素的对象也可以将 <code class="notion-inline-code">is_large</code> 设置为 <code class="notion-inline-code">true</code>。</div><div class="notion-text notion-block-3f40e3562fd680e99c79e0788723f4c9">“短字符串”基本类型是一种优化方式。对于长度小于 64 字节的字符串，可以直接把字符串长度编码进类型字节中。它在语义上与原始类型中的“字符串”完全相同。</div><div class="notion-text notion-block-3f40e3562fd6806db2e3fc0354c3f422">Decimal 类型包含 Scale，但不包含 Precision。十进制值的隐含精度为：</div><div class="notion-text notion-block-3f40e3562fd6805eb8bef345477c969a">当 <code class="notion-inline-code">val</code> 为 <code class="notion-inline-code">0</code> 时，精度为 <code class="notion-inline-code">1</code>。</div><div class="notion-text notion-block-3f40e3562fd680c99a13fc12429a2097">注意：Variant 二进制编码中的 Decimal 值使用小端序保存未缩放值。这与 Parquet 的 <code class="notion-inline-code">DECIMAL</code> 逻辑类型不同：后者对于 <code class="notion-inline-code">BYTE_ARRAY</code> 和 <code class="notion-inline-code">FIXED_LEN_BYTE_ARRAY</code> 物理类型使用大端序补码编码。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd68079aec2f18c119e9459" data-id="3f40e3562fd68079aec2f18c119e9459"><span><div id="3f40e3562fd68079aec2f18c119e9459" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68079aec2f18c119e9459" title="编码类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">编码类型</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd6801bb4f0f89690222df1" data-id="3f40e3562fd6801bb4f0f89690222df1"><span><div id="3f40e3562fd6801bb4f0f89690222df1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6801bb4f0f89690222df1" title="Variant 基本类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Variant 基本类型</span></span></h4><table class="notion-simple-table notion-block-3f40e3562fd680208567eb9b84a5f701"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3f40e3562fd680e19760de89dd4f83da"><td class="" style="width:120px"><div class="notion-simple-table-cell">基本类型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">说明</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680de8b03f631445839b9"><td class="" style="width:120px"><div class="notion-simple-table-cell">原始类型（Primitive）</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">0</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">原始类型之一</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680bfaac9de7190747ec2"><td class="" style="width:120px"><div class="notion-simple-table-cell">短字符串（Short string）</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">1</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">长度小于 64 字节的字符串</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68030aa2ce922f58596fa"><td class="" style="width:120px"><div class="notion-simple-table-cell">对象（Object）</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">2</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">由“字符串键、Variant 值”键值对组成的集合</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680d9b852c8d103c80da9"><td class="" style="width:120px"><div class="notion-simple-table-cell">数组（Array）</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">3</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Variant 值组成的有序序列</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd6803085a0c4315fd9a0bb" data-id="3f40e3562fd6803085a0c4315fd9a0bb"><span><div id="3f40e3562fd6803085a0c4315fd9a0bb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6803085a0c4315fd9a0bb" title="Variant 原始类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Variant 原始类型</span></span></h4><table class="notion-simple-table notion-block-3f40e3562fd68079a37aed0e70ba91b9"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3f40e3562fd680b991cce61596e1c0d6"><td class="" style="width:120px"><div class="notion-simple-table-cell">等价类别</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Variant 物理类型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">类型 ID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">等价的 Parquet 类型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">二进制格式</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680429b97f0f826498045"><td class="" style="width:120px"><div class="notion-simple-table-cell">NullType</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">null</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">0</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">UNKNOWN</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680baa632f26d062aa88f"><td class="" style="width:120px"><div class="notion-simple-table-cell">Boolean</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">boolean (True)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">1</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">BOOLEAN</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680e9bda1d01c511ef04b"><td class="" style="width:120px"><div class="notion-simple-table-cell">Boolean</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">boolean (False)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">2</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">BOOLEAN</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">无</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68074b952efe9a5be5969"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int8</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">3</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">INT(8, true)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">1 字节</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680e98b4fc26e70184a41"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int16</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">4</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">INT(16, true)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">2 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680e6b0d0e2c0cc84bb83"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int32</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">5</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">INT(32, true)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">4 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680718d7ee9604ea7f049"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int64</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">6</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">INT(64, true)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6803c8001f4257b0941b6"><td class="" style="width:120px"><div class="notion-simple-table-cell">Double</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">double</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">7</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DOUBLE</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">IEEE 小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68002b1a9d7bb37126022"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal4</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">8</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DECIMAL(precision, scale)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">1 字节 Scale，范围为 <code class="notion-inline-code">[0, 38]</code>；随后是小端序的未缩放值，参见 Decimal 表</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680d2a7bef2b3fee0bd0a"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal8</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">9</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DECIMAL(precision, scale)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">1 字节 Scale，范围为 <code class="notion-inline-code">[0, 38]</code>；随后是小端序的未缩放值，参见 Decimal 表</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6802e88a8ed5f1f63c617"><td class="" style="width:120px"><div class="notion-simple-table-cell">Exact Numeric</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal16</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">10</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DECIMAL(precision, scale)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">1 字节 Scale，范围为 <code class="notion-inline-code">[0, 38]</code>；随后是小端序的未缩放值，参见 Decimal 表</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6806bb40bd2e811b51ac3"><td class="" style="width:120px"><div class="notion-simple-table-cell">Date</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">date</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">11</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">DATE</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">4 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680bc9206fa504fd50e85"><td class="" style="width:120px"><div class="notion-simple-table-cell">Timestamp</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">timestamp</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">12</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">TIMESTAMP(isAdjustedToUTC=true, MICROS)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6809584d9d6519191af71"><td class="" style="width:120px"><div class="notion-simple-table-cell">TimestampNTZ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">timestamp without time zone</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">13</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">TIMESTAMP(isAdjustedToUTC=false, MICROS)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680098234f52435889ffa"><td class="" style="width:120px"><div class="notion-simple-table-cell">Float</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">float</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">14</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">FLOAT</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">IEEE 小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6800aaddafd08315b7e6d"><td class="" style="width:120px"><div class="notion-simple-table-cell">Binary</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">binary</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">15</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">BYTE_ARRAY</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">4 字节小端序长度，随后是数据字节</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68049bc4fd3435b9b2549"><td class="" style="width:120px"><div class="notion-simple-table-cell">String</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">string</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">16</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">STRING</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">4 字节小端序长度，随后是 UTF-8 编码字节</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6807cb49cfefa1a575fcc"><td class="" style="width:120px"><div class="notion-simple-table-cell">TimeNTZ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">time without time zone</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">17</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">TIME(isAdjustedToUTC=false, MICROS)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680679accde6e99aef25e"><td class="" style="width:120px"><div class="notion-simple-table-cell">Timestamp</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">timestamp with time zone</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">18</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">TIMESTAMP(isAdjustedToUTC=true, NANOS)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68063865cd12e2b284690"><td class="" style="width:120px"><div class="notion-simple-table-cell">TimestampNTZ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">timestamp without time zone</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">19</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">TIMESTAMP(isAdjustedToUTC=false, NANOS)</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">8 字节，小端序</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68009944ad2e7fe77ade4"><td class="" style="width:120px"><div class="notion-simple-table-cell">UUID</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">uuid</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">20</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">UUID</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">16 字节，大端序</div></td></tr></tbody></table><div class="notion-text notion-block-3f40e3562fd680a0973ef1d9c5459255">“等价类别”列表示采用不同物理编码的类型在逻辑上是等价的。</div><div class="notion-text notion-block-3f40e3562fd6809fab18cccf5cfeb020">例如，一个用户表达式在处理内容为 <code class="notion-inline-code">&quot;hello&quot;</code> 的字符串时，无论该字符串使用短字符串优化，还是使用长字符串编码，都应该表现出相同的行为。</div><div class="notion-text notion-block-3f40e3562fd680f8ada5de4d0a3796b0">同样，一个用户表达式在处理值为 <code class="notion-inline-code">1</code> 的 <code class="notion-inline-code">int8</code> 时，其行为应该与处理 Scale 为 <code class="notion-inline-code">2</code>、未缩放值为 <code class="notion-inline-code">100</code> 的 <code class="notion-inline-code">decimal16</code> 相同。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3f40e3562fd6800abcf9d093b1a26bba" data-id="3f40e3562fd6800abcf9d093b1a26bba"><span><div id="3f40e3562fd6800abcf9d093b1a26bba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6800abcf9d093b1a26bba" title="Decimal 表"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Decimal 表</span></span></h4><table class="notion-simple-table notion-block-3f40e3562fd680eeb092eee85b3647c7"><tbody><tr class="notion-simple-table-row notion-simple-table-header-row notion-block-3f40e3562fd68095861bfe08f493ff31"><td class="" style="width:120px"><div class="notion-simple-table-cell">Decimal 精度</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Decimal 值类型</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Variant 物理类型</div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68037b059ce668112094c"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">1 &lt;= precision &lt;= 9</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int32</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal4</code></div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd680ac9dc2d361710dd953"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">10 &lt;= precision &lt;= 18</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int64</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal8</code></div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd68032a73cd848c0304525"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">19 &lt;= precision &lt;= 38</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">int128</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">decimal16</code></div></td></tr><tr class="notion-simple-table-row notion-block-3f40e3562fd6808c9b12c5e331d3733c"><td class="" style="width:120px"><div class="notion-simple-table-cell"><code class="notion-inline-code">&gt; 38</code></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">不支持</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td></tr></tbody></table><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd6807cb804ce243b493d05" data-id="3f40e3562fd6807cb804ce243b493d05"><span><div id="3f40e3562fd6807cb804ce243b493d05" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd6807cb804ce243b493d05" title="字符串值必须使用 UTF-8 编码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">字符串值必须使用 UTF-8 编码</span></span></h3><div class="notion-text notion-block-3f40e3562fd68057bee6f923bdd8aeb7">Variant 二进制格式中的所有字符串都必须使用 UTF-8 编码，包括：</div><ul class="notion-list notion-list-disc notion-block-3f40e3562fd6802391a6f85e91abcf7b"><li>字典中的键字符串；</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd680c58657e5711147509d"><li>“短字符串”值；</li></ul><ul class="notion-list notion-list-disc notion-block-3f40e3562fd68095abe3dcfa3bdffca3"><li>“长字符串”值。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd68010aee7d0bf93d1a080" data-id="3f40e3562fd68010aee7d0bf93d1a080"><span><div id="3f40e3562fd68010aee7d0bf93d1a080" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd68010aee7d0bf93d1a080" title="对象字段 ID 的顺序和唯一性"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">对象字段 ID 的顺序和唯一性</span></span></h3><div class="notion-text notion-block-3f40e3562fd680448ad3e923d4d4bdf4">对于对象，字段 ID 和偏移量必须按照对应字段名称的字典序排列。排序时，对 UTF-8 字节使用无符号字节顺序。</div><div class="notion-text notion-block-3f40e3562fd680098206e1ce9545942a">需要注意的是，字段值本身不必遵循该顺序。因此，偏移量不一定按照升序排列。</div><div class="notion-text notion-block-3f40e3562fd68082b687c8283f69adff">为了让 Variant 值的构造更加灵活，字段值不必与字段 ID 使用相同的顺序。</div><div class="notion-text notion-block-3f40e3562fd68017beb2f6018d18d3eb">实现可以依赖字段 ID 的这种顺序来搜索字段名称。例如，可以结合元数据查询，对字段 ID 执行二分查找，从而找到指定名称的字段。</div><div class="notion-text notion-block-3f40e3562fd68051964fdc824b489e5d">字段名称区分大小写。</div><div class="notion-text notion-block-3f40e3562fd68091ae1acf8fa93dfc71">每个对象中的字段名称必须唯一。无论两个同名字段是否使用不同的字典 ID，对象中包含两个相同名称的字段都属于错误。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd680d98b12c176b6f482b4" data-id="3f40e3562fd680d98b12c176b6f482b4"><span><div id="3f40e3562fd680d98b12c176b6f482b4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680d98b12c176b6f482b4" title="版本与扩展"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">版本与扩展</span></span></h3><div class="notion-text notion-block-3f40e3562fd68011a3e7f97271885911">实现不需要解析元数据版本高于其所支持版本的 Variant 值。</div><div class="notion-text notion-block-3f40e3562fd680db94c9e8011d740663">不过，规范可以在不递增版本 ID 的情况下添加新类型。出现这种情况时，如果实现希望继续读取，它应当能够读取 Variant 值的其余部分。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3f40e3562fd680bda302d452f97f5cba" data-id="3f40e3562fd680bda302d452f97f5cba"><span><div id="3f40e3562fd680bda302d452f97f5cba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3f40e3562fd680bda302d452f97f5cba" title="拆分"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">拆分</span></span></h3><div class="notion-text notion-block-3f40e3562fd68024acebf6ff34939754">当只需要读取少数字段时，把整个 Variant 对象保存在单列中可能导致较差的读取性能。</div><div class="notion-text notion-block-3f40e3562fd6803ab155e373c49c10b7">更好的方法是为各个字段创建独立的列。这种方式称为拆分（shredding）或子列化（subcolumnarization）。</div><div class="notion-text notion-block-3f40e3562fd68076989fd46ebf91692f">[VariantShredding.md](VariantShredding.md) 描述了 Parquet 中的 Variant 拆分规范。</div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>