简体   繁体   English

我应该如何在 JSON 中表示表格数据?

[英]How should I represent tabular data in JSON?

I'm writing an API for retrieving data from a JDBC-connected Java Servlet via JSON.我正在编写一个 API,用于通过 JSON 从 JDBC 连接的 Java Servlet 检索数据。 I've chosen to use JSON because we'll want to do sorts and other operations on the data in the browser, and we'll be accessing the data from across domains.我选择使用 JSON 因为我们想要对浏览器中的数据进行排序和其他操作,并且我们将跨域访问数据。

Since I'm essentially doing SQL queries in JavaScript, the data that comes back is tabular in nature.由于我本质上是在 JavaScript 中进行 SQL 查询,因此返回的数据本质上是表格的。 I started to write this so that you get back a list of column labels, then arrays of values, for example:我开始写这个是为了让你得到一个列标签列表,然后是 arrays 值,例如:

{
  "columns": [
    "given_name",
    "surname",
  ],
  "results": [
    [
      "Joe",
      "Schmoe"
    ],
    [
      "Jane",
      "Doe"
    ]
  ]
}

But as I start to write the JavaScript to deal with the returned data, I wonder if it might be better to just output the results with key/value pairs, such as:但是当我开始编写 JavaScript 来处理返回的数据时,我想知道是否最好只使用 output 键/值对的结果,例如:

{
  "results": [
    {
      "given_name": "Joe",
      "surname": "Schmoe"
    },
    {
      "given_name": "Jane",
      "surname" : "Doe"
    }
  ]
}

If you're returning a lot of results, that's a lot of repeated text.如果您要返回很多结果,那就是很多重复的文本。 But we're going to be transporting gzipped, so I'm not too concerned about bandwidth.但是我们将传输 gzipped,所以我不太关心带宽。

Basically, should I engineer this so that I'm accessing my data with基本上,我应该设计这个,以便我可以访问我的数据

$.getJSON(query, function(data) {
  var columns = data.columns;
  var results = data.results;
  $.each(results, function(key, row) {
    console.log(row[columns.indexOf('surname')]);
  });
});

or the much prettier或者更漂亮的

$.getJSON(query, function(data) {
  var results = data.results;
  $.each(results, function(key, row) {
    console.log(row.surname);
  });
});

? ?

Essentially, I want to know if the potential hit to performance justifies the much cleaner syntax of the latter option.本质上,我想知道对性能的潜在影响是否证明后一种选择更简洁的语法是合理的。

Follow up跟进

I did implement it both ways and profile.我确实以两种方式和配置文件实现了它。 Profiling was a great idea!分析是个好主意! The differences in performance were marginal.性能上的差异是微不足道的。 The differences in data transfer size were substantial, but with Gzip compression, the variance was down to 5-6% between both formats and between very large and very small data sets.数据传输大小的差异很大,但使用 Gzip 压缩,两种格式之间以及非常大和非常小的数据集之间的差异下降到 5-6%。 So I'm going with the prettier implementation.所以我要使用更漂亮的实现。 For this particular application, I can expect all clients to support Gzip/Deflate, so the size doesn't matter, and the computational complexity on both the client and server is similar enough that it doesn't matter.对于这个特定的应用程序,我可以期望所有客户端都支持 Gzip/Deflate,因此大小无关紧要,并且客户端和服务器上的计算复杂度足够相似,这无关紧要。

For anyone interested, here is my data with graphs ..对于任何感兴趣的人,这是我的图表数据..

Profile both.简介两者。 Optimize afterwards.后期优化。

Synthesizing other answers:综合其他答案:

  1. Your wire format doesn't have to be the same as your in-memory format.您的有线格式不必与您的内存格式相同。
  2. Profile which is better - see if it makes a difference.配置文件哪个更好 - 看看它是否有所作为。
  3. Simpler is usually better to start with.更简单通常是更好的开始。

Further:更远:

  • If you just have a page of results, and few users, then the 2nd format may be no worse than the 1st format.如果您只有一页结果,并且用户很少,那么第二种格式可能不会比第一种格式差。
  • If your data is quite sparse, the 2nd format may well be better.如果您的数据非常稀疏,则第二种格式可能会更好。
  • If you're sending 1000's or rows of data, and you have millions of users, then it's possible that the size of data you send can start to matter, and perhaps the 1st format may help.如果您要发送 1000 或多行数据,并且您拥有数百万用户,那么您发送的数据的大小可能会开始变得重要,也许第一种格式可能会有所帮助。
  • You can't guarantee that all user agents support gzip / deflate, so bear this in mind.您不能保证所有用户代理都支持 gzip / deflate,所以请记住这一点。

Just another JSON structure from which I got very nice results:只是另一个 JSON 结构,我从中得到了非常好的结果:

{
    "recordCount": 2,
    "data": {
        "Id": [1, 2],
        "Title": ["First record", "Second record"],
        "Value": [18192, 18176]
    }
}

Traversing all data:遍历所有数据:

for (var i = 0; i < recordSet.recordCount; ++i) {
    console.log("Record " + i.toString() + ":");
    for (var field in recordSet.data)
        console.log("\t" + field + ": " + recordSet.data[field][i].toString());
}

You don't have to tie your code to the more compact, but also more cumbersome format.您不必将代码绑定到更紧凑但也更繁琐的格式。 Just write a simple JS adapter to check the returned structure for the presence of columns .只需编写一个简单的 JS 适配器来检查返回的结构中是否存在columns If that's missing you're dealing with a plain array of objects.如果缺少那你正在处理一个简单的对象数组。 If it's present you can easily map the cumbersome format to the more convenient format.如果它存在,您可以轻松地将繁琐的格式转换为更方便的格式。

FWIW I'd go for the second option, it lends itself to cleaner JavaScript as you've observed and will also be easier for a human to read and understand. FWIW 我将 go 作为第二个选项,它适合于清洁 JavaScript 正如您所观察到的,并且人类也更容易阅读和理解。 It seems to me that readability trumps whatever little performance gain you get from option 1.在我看来,可读性胜过从选项 1 中获得的任何一点性能提升。

I also imagine if you were to add more columns or the order of columns changed someday, with the first option, you'll likely have to rewrite a lot of the JavaScript since you'll be working with the position of the data in the response.我还想象如果有一天您要添加更多列或更改列的顺序,使用第一个选项,您可能需要重写很多 JavaScript,因为您将使用响应中数据的 position .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM