<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>JSON - tag - 沐木</title><link>https://oldletter.cn/tags/json/</link><description>JSON - tag - 沐木</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://oldletter.cn/tags/json/" rel="self" type="application/rss+xml"/><item><title>问卷考试系统设计（二）：题目 DSL 设计——用 JSON 描述一切题型</title><link>https://oldletter.cn/posts/qnr-02-dsl-design/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/qnr-02-dsl-design/</guid><description><![CDATA[<p><strong>上一篇：<a href="/posts/qnr-01-architecture/" rel="">问卷考试系统设计（一）：架构选型与数据模型</a></strong></p>
<p>上一篇聊了整体架构和数据模型，这篇讲整个系统核心的部分：怎么用一套统一的 JSON 结构，把单选、多选、量表、矩阵、排序、填空……所有题型都描述清楚。然后让引擎把这些 JSON 跑起来，条件跳题、题目分组、随机排序，这些才是让问卷从&quot;能编辑&quot;变成&quot;能填写&quot;的关键。</p>
<hr>
<h2 id="为什么用-json-而不是多张表">为什么用 JSON 而不是多张表</h2>
<h3 id="传统建模的麻烦">传统建模的麻烦</h3>
<p>直观的做法，每种题型一张表：</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-sql">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title=""><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">question_single_choice</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">id</span><span class="w"> </span><span class="nb">BIGINT</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="p">,</span><span class="w"> </span><span class="n">stem</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">option_a</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">option_b</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">option_c</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">option_d</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">correct_answer</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">question_likert</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">id</span><span class="w"> </span><span class="nb">BIGINT</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="p">,</span><span class="w"> </span><span class="n">stem</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">scale_type</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span><span class="w"> </span><span class="n">is_reverse</span><span class="w"> </span><span class="nb">BOOLEAN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 10 种题型 10 张表……</span></span></span></code></pre></div></div>
<p>问题很明显：</p>]]></description></item></channel></rss>