<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>数据同步 on CoreV.cn</title>
        <link>https://corev.cn/tags/%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5/</link>
        <description>Recent content in 数据同步 on CoreV.cn</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <copyright>CoreV.cn</copyright>
        <lastBuildDate>Wed, 26 Aug 2026 17:08:33 +0800</lastBuildDate><atom:link href="https://corev.cn/tags/%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>小程序也能秒开：本地缓存&#43;云端备份</title>
        <link>https://corev.cn/articles/04-local-cache-cloud-backup/</link>
        <pubDate>Thu, 06 Aug 2026 20:30:00 +0800</pubDate>
        
        <guid>https://corev.cn/articles/04-local-cache-cloud-backup/</guid>
        <description>&lt;p&gt;打开 App 卡在加载超过三秒，用户往往就直接关掉了。&lt;/p&gt;
&lt;p&gt;记录类工具最怕两件事：一是慢（打开半天刷不出来），二是丢（换手机或重装，记录全没了）。我做「简单记」时，在这上面花了最多心思。&lt;/p&gt;
&lt;p&gt;这套数据层，是我用 WorkBuddy 加腾讯混元（hy3）一点点调出来的。我本来不是程序员，在能源行业干了二十多年，写代码是半路出家。下面这套&amp;quot;本地为主、云端兜底&amp;quot;的取舍，你照着做，也能做出自己的小工具。&lt;/p&gt;
&lt;p&gt;说白了就是一件事：怎么既保住本地的快、离线可用，又拿到云端的跨设备、不丢失。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一矛盾本地快但不跨设备云上全但不实时&#34;&gt;一、矛盾：本地快但不跨设备，云上全但不实时
&lt;/h2&gt;&lt;p&gt;数据存本地，打开秒开、没网也能记。但换手机，记录全没了。&lt;/p&gt;
&lt;p&gt;存云端，哪儿都能看。可一断网就用不了，每次读取还得等网络往返。&lt;/p&gt;
&lt;p&gt;成年人说&amp;quot;我都要&amp;quot;，还真能办到。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;可直接复制的提示词：&lt;/strong&gt;
我的小工具要存数据，帮我对比&amp;quot;只存手机本地&amp;quot;和&amp;quot;只存云端&amp;quot;的优缺点，再给我一个&amp;quot;本地+云端&amp;quot;的折中方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二我的取舍本地为主云端兜底&#34;&gt;二、我的取舍：本地为主，云端兜底
&lt;/h2&gt;&lt;p&gt;核心在 &lt;code&gt;utils/cloudStore.js&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;读取时优先走本地缓存：数据已在手机上，打开即显示、断网也能看。写入时先落到本地存储（同样秒开、离线可用），再由程序在后台悄悄把这份数据镜像到云端，本地写成功就立刻返回，不卡界面、不等网络。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;真实的写入逻辑如下（已做精简，仅保留主干）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 写入：先落本地，再异步镜像云端
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;wx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setStorageSync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;// ① 本地先写，秒开、离线可用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;_openid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;callSync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;push&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;buildPushPayload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// ② 再异步推云端，失败进重试队列
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;好处很直白：没网也能记；云端哪怕挂了，本地照常跑。&lt;/p&gt;
&lt;p&gt;先保证&amp;quot;能用&amp;quot;，再追求&amp;quot;同步&amp;quot;，这个顺序不能反。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;可直接复制的提示词：&lt;/strong&gt;
我要&amp;quot;本地优先、云端兜底&amp;quot;地存数据，给我一段最小可运行的写入逻辑，并说明哪一步保证离线可用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三跨设备同步先认人是关键&#34;&gt;三、跨设备同步：先认人是关键
&lt;/h2&gt;&lt;p&gt;登录时，&lt;code&gt;app.js&lt;/code&gt; 的 &lt;code&gt;login()&lt;/code&gt; 用 &lt;code&gt;wx.login&lt;/code&gt; 拿到 &lt;code&gt;openid&lt;/code&gt;，绑到全局。&lt;/p&gt;
&lt;p&gt;云端数据按 &lt;code&gt;openid&lt;/code&gt; 分桶——你的记录不会混进我的。&lt;/p&gt;
&lt;p&gt;每次切回前台，做一次&lt;strong&gt;增量 pull&lt;/strong&gt;：只拉差异，不整库重刷。快，还省流量。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;可直接复制的提示词：&lt;/strong&gt;
我的工具要支持多设备，帮我说清楚：怎么识别&amp;quot;这是谁的数据&amp;quot;、怎么只同步变化的部分，而不是每次全量重传。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同步这事儿，第一步不是传数据，是认出这是谁的数据。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四一个工程细节记录为什么要拆表&#34;&gt;四、一个工程细节：记录为什么要拆表
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;record_entries&lt;/code&gt; 我拆成了&lt;strong&gt;独立集合&lt;/strong&gt;，每条一文档：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// docId = openid::entryId，存 _openid + date，便于按日期高效扫描
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;docId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;openid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;entryId&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么特意把记录拆成独立集合？因为后面要做&amp;quot;每日定时提醒&amp;quot;，需要按日期高效地一条条扫描。如果这些记录全都混在一个大对象里，定时任务每次都得翻整个库，扫得很慢；拆成独立集合、再给日期建索引，扫描就快了。&lt;/p&gt;
&lt;p&gt;配套加了 &lt;code&gt;reminder_log&lt;/code&gt; 做去重。&lt;/p&gt;
&lt;p&gt;今天的结构，就是给明天的功能留余地。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五部署前提坑先说清&#34;&gt;五、部署前提（坑先说清）
&lt;/h2&gt;&lt;p&gt;云开发控制台得建几个集合：&lt;code&gt;user_data / users / subscriptions / record_entries / reminder_log&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;云函数 &lt;code&gt;getOpenid&lt;/code&gt;、&lt;code&gt;syncData&lt;/code&gt; 要&amp;quot;云端安装依赖&amp;quot;部署；&lt;code&gt;sendSubscribe&lt;/code&gt; 还得在 CloudBase 控制台把小程序和微信公众平台关联、开通订阅消息权限。&lt;/p&gt;
&lt;p&gt;搭建服务端（建集合、部署云函数、关联权限）是用户完全看不见的准备工作，却替你挡掉了后面大量的联调和报错。这一步没做踏实，前面写得再漂亮，一运行就报错跑不起来。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六收藏这张数据架构自查清单&#34;&gt;六、收藏这张「数据架构自查清单」
&lt;/h2&gt;&lt;p&gt;截图存下来，设计任何数据存储前扫一遍：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;✅&lt;/th&gt;
          &lt;th&gt;数据架构自查&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td&gt;没网时，核心功能还能用吗？（本地为主）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td&gt;换设备，数据能跟过来吗？（云端兜底）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3&lt;/td&gt;
          &lt;td&gt;数据按&amp;quot;谁&amp;quot;分开了吗？（先认人再同步）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;4&lt;/td&gt;
          &lt;td&gt;同步只传变化的部分吗？（增量，别全量）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;5&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;每一次，我都亲自验收了吗？&lt;/strong&gt;（最重要的一条）&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;收尾&#34;&gt;收尾
&lt;/h2&gt;&lt;p&gt;数据架构没有标准答案，说到底就是&amp;quot;本地为主、云端兜底&amp;quot;这层取舍。&lt;/p&gt;
&lt;p&gt;下篇：数据齐了，怎么让小程序替我&amp;quot;看&amp;quot;出规律？讲接大模型做智能解读。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
