V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
morri
V2EX  ›  问与答

请教一个功能设计的问题,关于英语阅读的。sql 要如何设计才能方便实现,单句的翻译并可以修改呢?

  •  
  •   morri · 353 天前 · 704 次点击
    这是一个创建于 353 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在的需求是这样的。想做一个英文文章阅读的网站,文章当中的每一句话都可以点击句末的上标翻译,然后句子的下面就显示中文。当然还可以点击句末的修改按钮修改这句话。

    现在遇到一个问题,就是文章可以由段落或列表组成, 一个段落(p)中可能会有多个句子(span),我现在想的是将文章的所有句子都存放在表中,根据不同的类型来判断这个句子在渲染成 html 时,应该使用哪些标签。

    例如句子的类型可以是

    • pb-span, 在渲染时则是这样 <p><span>内容</span>
    • pe-span, 渲染时则是 <span>内容</span></p>
    • ulb-lib-span, 渲染时则是 <ul><li><span>内容</span>
    • ule-lie-span, 渲染时则是 <span>内容</span></li></ul>
    • 等等

    b 就是 begin ,e 就是 end

    现在数据库中的 sql 是这样的

    
    create table en_article_sentence
    (
        id         bigint unsigned auto_increment
            primary key,
        article_id bigint                             not null,
        type       varchar(64)                        not null,
        en         text                               null,
        zh         text                               null,
        audio      varchar(64)                        null,
        created_at datetime default CURRENT_TIMESTAMP null,
        updated_at datetime default CURRENT_TIMESTAMP null
    );
    

    前台使用的是 react ,react 语法使用的是 JSX ,JSX 在使用 html 标签时,必须成对出现,所以在渲染时就不好处理了。

    如果我使用 <div dangerouslySetInnerHTML={{__html: sentence}}></div> 这种方式来渲染 html , 那么就不能调用函数组件中的方法,进行修改。 如果直接根据type 类型来判断,html 标签又必须成对出现。

    这篇帖子描述了 现在的困境 https://www.v2ex.com/t/936765

    有 v 友说这样设计不太好,所以想要请教一下,要如何设计才能比较好的实现我上述的需求呢?

    4 条回复    2023-05-02 21:29:30 +08:00
    pelloz
        1
    pelloz  
       353 天前
    存两张表。
    第一张表存完整的文章富文本格式,可以直接提供给前端渲染,并且每个需要翻译的句子的 span 标签有唯一的 id ,比如<span id="1-1">hello<span>
    第二章表存文章 id 和句子 id 和对应的翻译。
    NoOneNoBody
        2
    NoOneNoBody  
       353 天前
    不熟前端,只会少量 GUI 的工作,html 扔下太久了,只懂爬虫相关的部分

    第一眼,这个表至少缺一个标明顺序的字段,虽然 id 也是有序的,但应该有一个较明确标明该 id 相对 article_id 的顺序的标识,单靠 id 排序不保险;如果想在中间插入一句,没有相对顺序,你这个 article 就要重排了

    工作上是单句,但读取数据是否也是单句?如果确定“必然”是每次读取都是整篇文章,那未必需要每句作为 record ,只要整篇读取后可以顺利拆分每句就足够了;但如果确实有只读取某一句这种场合,就照这样吧,附加问题是累积数据量庞大时要考虑 IO

    前面说的“顺利拆分”,其实方法很多,例如可以在入库时,按粒度添加一些特殊分隔符,读取后 split 也很容易

    至于前端渲染的问题,个人觉得不应因为考虑前端而改变数据结构,只要能正确拆分粒度,后面就交给前端考虑了
    这样的话,即使前端换了一套技术,也不影响。如果“为了前端方便处理”而写死数据结构,遇到换前端、前端 BUG 怎么办?整个数据库重构么?

    前端问题
    “……就不能调用函数组件中的方法”,不清楚这个函数究竟是写得多么死,但即使这样,也能加个闭包预处理格式吧?
    类型那些最好不要从 html 语法判断,应该多利用 selector ,如 css selector 或者 dom/xpath 等等,html 只是堆砌元素,应该用 selector 提取,例如<p><span>写成<p><span class='pb-span'>或者<p><span id='pb-span-1'>,这样就容易了
    TomVista
        3
    TomVista  
       353 天前
    存个扁平树吧,取出来,再组织起来,然后渲染
    {
    id:'1'
    name:'小猪佩奇',
    paragraph:[{
    sentence:[{
    text:'天气晴朗,'
    zh:'',
    en:'',
    },{
    text:'猪爸爸和猪妈妈出去打工了.'
    zh:'',
    en:'',
    }]
    }]
    },

    `select * from sentence where articleid = 1`

    let article = sentence.forEacht(item=>{paragraph[item.paragraph].push(item.text)})
    kongkx
        4
    kongkx  
       353 天前 via iPhone   ❤️ 2
    可以借鉴一些 editor 的 doc 数据结构的设计,比如 draftjs 的扁平化 ,slatejs 的 nested ,或者 portable text

    https://docs.slatejs.org/v/v0.47/guides/data-model

    既然用 react 了,不一定需要组装成 html 再渲染。直接维护组件树就行,组件上还能继续做功能。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2631 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:49 · PVG 09:49 · LAX 18:49 · JFK 21:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.