V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
vone
V2EX  ›  程序员

[不懂就问] 为什么有的后端接口会使用二维数组输出表格数据

  •  
  •   vone · 2020-10-30 16:44:26 +08:00 · 3621 次点击
    这是一个创建于 1489 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天在调用一个接口时发现返回值如下:

    [
        [50024048,50008827,"宝宝布书",0,"std","Y",25,"玩具 /童车 /益智 /积木 /模型"],
        [124470013,124508010,"水枪",0,"std","Y",25,"玩具 /童车 /益智 /积木 /模型"],
        [50008281,50012922,"密封罐",0,"pro","Y",50016349,"厨房 /烹饪用具"],
        [50010101,50006778,"漏勺",0,"pro","Y",50016349,"厨房 /烹饪用具"],
        [50008281,50012921,"米桶 /米缸",0,"pro","Y",50016349,"厨房 /烹饪用具"],
        [50010101,50006777,"汤勺",0,"pro","Y",50016349,"厨房 /烹饪用具"],
        [50010101,50006776,"全套勺铲",0,"pro","Y",50016349,"厨房 /烹饪用具"],
        [122964001,50023167,"首饰架",0,"pro","Y",122928002,"收纳整理"]
    ]
    

    1 、从前端角度来看这种格式极为不合理,业务变更时无论是新增列还是删除列,都有可能导致大量的索引位置发生变化,进而需要大量的代码修改,非常容易出错。

    2 、从后端角度来看,Array 必须是同类型的数据,才能做到高效和节省内存,而且有些静态语言很难反序列化同一数组下类型却不一致的 JSON 。

    有没有人知道使用二维数组传输在哪些场景下是存在优势的。

    自己猜测两个:

    1 、结构更加紧凑,节省带宽

    2 、有隐藏字段名的需求

    33 条回复    2020-11-01 20:49:49 +08:00
    seakingii
        1
    seakingii  
       2020-10-30 17:00:32 +08:00
    省内存,省流量,加快解析。
    lzhnull
        2
    lzhnull  
       2020-10-30 17:08:04 +08:00
    电商平台也是这么返回的把
    seakingii
        3
    seakingii  
       2020-10-30 17:08:43 +08:00
    如果你用过 .NET 里的 DataTable,就明白这种做法 。

    模拟 Json:



    let user_table = {

    "columns": [
    { "column_name": "user_name", "data_type":"string" },
    { "column_name": "age", "data_type":"int" },
    { "column_name": "sex", "data_type":"int" },
    ],


    "rows":[

    ["张三",20,1],
    ["李四",20,0],
    ["王五",20,1],

    ]

    };



    一个通用的方案,在客户端,可以很简单写一个解析器,将上面的 json 解析 json 对象数组,解析后的

    let client_user_table = [
    {"user_name":"张三 ","age":20,"sex":1},
    {"user_name":"李四","age":20,"sex":0},
    {"user_name":"王五 ","age":20,"sex":1}
    ];


    ============
    这种做法,在几行数据,几十行数据时效果不明显 ,几百行 ,几千行甚至更多时,收益就多了
    vone
        4
    vone  
    OP
       2020-10-30 17:17:14 +08:00
    @lzhnull 就是某宝的接口。

    @seakingii 我是 .NET 开发,DataTable 的结构绝对是没问题的,但是在我遇到的这个接口里面是不存在列名和列类型的。

    补一下完整的响应数据:

    ![image.png]( https://i.loli.net/2020/10/30/XR8mztFJ69wPxgv.png)


    那是否说明阿里业务框架中可能还存在另一个接口可以一次性拿到业务接口的字段名,进而解析出对应的结构。
    fengmumu
        5
    fengmumu  
       2020-10-30 17:26:12 +08:00
    感觉应该有个地方有一个索引+对应字段的数据
    sunmoon1983
        6
    sunmoon1983  
       2020-10-30 17:28:27 +08:00
    @vone 你这数据返回来我,怎么才能知道哪个字段对应哪个值呀?{"user_name":"李四","age":20,"sex":0},这样才行吧?
    vone
        7
    vone  
    OP
       2020-10-30 17:33:13 +08:00
    @sunmoon1983 我的疑问和你一样,就是 JSON 传输时为什么不使用 obejct 而使用 array 这个反人类的结构。


    发帖主要是想搞明白在哪些场景下 array 会有优势(因为这是某宝的接口,所以我总觉着是阿里大佬特意设计的)。
    vone
        8
    vone  
    OP
       2020-10-30 17:34:17 +08:00
    @sunmoon1983 字段对应值现在看来只能通过文档去约定。
    oott123
        9
    oott123  
       2020-10-30 17:35:46 +08:00 via Android
    第一个前端的问题可以通过完善的工具链解决。

    第二个后端的性能问题不存在,这只是一种序列化而已,存储肯定不是这么存的。
    tesguest123
        10
    tesguest123  
       2020-10-30 17:45:11 +08:00 via Android
    @sunmoon1983 文档完善也没问题,按照索引拿对应的数据
    Kirsk
        11
    Kirsk  
       2020-10-30 18:52:54 +08:00 via Android
    后端的锅 只要不是 json 规范对前端都不友好
    simonlu9
        12
    simonlu9  
       2020-10-30 18:55:28 +08:00
    带宽是王道啊
    yeqizhang
        13
    yeqizhang  
       2020-10-30 18:58:31 +08:00 via Android
    geo 数据我才这么搞,特别是车辆的 GPS 数据,量太大了
    xuanbg
        14
    xuanbg  
       2020-10-30 19:17:08 +08:00
    特殊情况下可以这样搞没问题。
    zjsxwc
        15
    zjsxwc  
       2020-10-30 19:19:38 +08:00 via Android
    省了传 key 的带宽?
    BoarBoar
        16
    BoarBoar  
       2020-10-30 19:37:27 +08:00
    估计就是早期开发人员太菜,后来者又不敢动老代码,又不是不能用
    抖音接口视频数组里,每个视频 100 多个 json 字段,然而接口相应速度爆阿里 10 倍
    vone
        17
    vone  
    OP
       2020-10-30 19:53:52 +08:00
    @simonlu9
    @yeqizhang
    @zjsxwc 可能是唯一的解释了。

    @xuanbg 对的,我就是想问问看有没有人知道是哪种特殊场景下这样做的。

    @BoarBoar 这不会吧,早期的阿里开发更是大佬中的大佬吧。
    xcstream
        18
    xcstream  
       2020-10-30 19:54:45 +08:00
    只要不改需求就没问题
    FreeEx
        19
    FreeEx  
       2020-10-30 23:14:29 +08:00
    就真差这点带宽?感觉就像是把钱全花在维护这个破数据格式上面去了。
    TheCure
        20
    TheCure  
       2020-10-31 00:14:27 +08:00
    这样做的场景很多, protobuf 序列化之后也是没有 key 的, 数据库存每一行也不是存 key 的.

    知道 schema 的情况下, 少传 key 性能当然更好.

    性能不是问题的情况下, 用带 schema 和 type system 的写前端当然爽. 不是阿里程序员蠢, 是如果没在那种场景, 没有在西溪园区会议室通宵压测调试过就无法体会为什么要做这么多的 tradeoff
    oneonesv
        21
    oneonesv  
       2020-10-31 01:01:27 +08:00 via Android   ❤️ 1
    性能好 省带宽 数据量越大越明显 至于 index 定义可以单独一个接口
    noyle
        22
    noyle  
       2020-10-31 01:42:13 +08:00
    不懂就问:那楼主当时以为应该用什么来做最好?
    eudore
        23
    eudore  
       2020-10-31 09:10:26 +08:00
    首先第一层一定是数组[],用于虚拟 dom for 循环数据渲染 ui 。
    第二层可以是数组 []也可以是 json {},json 有键值对应,数组可以压缩传输量,序列化性能应该也有提升。
    seakingii
        24
    seakingii  
       2020-10-31 10:14:52 +08:00
    我发的,带有 columns 的,只是一个通用的,能自行解析的一个例子。我不知道你实际用的接口有没有地方有定义列,但是,只要接口不要经常性的改动,不带列也是可以的。只要约定好就可以。

    上面怀疑有没有这个必要的人,对于某些人某些场景来说,能省一点流量,内存,就多省一点。当数据量级,访问量级,以及客户端的响应时间要求(ms 级的考虑)都是问题是,能省一点都是好的。

    比如说电商平台,比如说上面说到的 GPS

    再举个例子,假设你现在有个新的业务,规定要用 JSON 上传数据 ,你的客户端是 物联网设备,你有几万这样的设备,要求每设备 5 秒上报一次数据,每次上报有几百条数据,在这种比较极端的场景,你是考虑这种 JSON OBJECT 数组,还是 JSON 对象数组?
    rodrick
        25
    rodrick  
       2020-10-31 10:18:30 +08:00
    这种数据肯定是得配套一套完善的接口文档说明或者中间处理工具的吧,不然回头你改动个啥前端不得要了老命
    MineDog
        26
    MineDog  
       2020-10-31 11:16:42 +08:00
    这就是表格数据的本质啊,只是缺一个表头没返回给你罢了
    daozhihun
        27
    daozhihun  
       2020-10-31 11:22:17 +08:00
    确实很蛋疼,而且省带宽也不是在这个地方省,这种东西能有多大,随便一个高清图、视频什么的就比它大好几个数量级
    Foxkeh
        28
    Foxkeh  
       2020-10-31 11:51:57 +08:00
    这结构已经精简到跟 csv 差不多了, 目的应该就是省流了. 有没必要这么省看业务场景吧
    niubee1
        29
    niubee1  
       2020-10-31 11:58:31 +08:00
    最好再加一个 meta 数据,描述每一列的标题,数据类型等,然后前端开发个组件根据 meta 来显示二位数组成为表格。那就很 amazing 了,需要改输出的表格结构的时候只需要后端修改就行了
    Baileys
        30
    Baileys  
       2020-10-31 19:48:29 +08:00
    @simonlu9 带宽高就可以一下子接受一行,这个意思吗?一般带宽是多少啊……
    abersheeran
        31
    abersheeran  
       2020-10-31 19:53:31 +08:00
    @daozhihun API 服务器的带宽肯定比静态文件的带宽宝贵啊。
    daozhihun
        32
    daozhihun  
       2020-11-01 11:04:48 +08:00
    @abersheeran 你说的对,静态资源和 API 服务器确实不能混为一谈。
    indo
        33
    indo  
       2020-11-01 20:49:49 +08:00
    最近自己造轮子,我从后端返回给前端的数据也是二位数组的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3359 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:02 · PVG 20:02 · LAX 04:02 · JFK 07:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.