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

发布于 2024-11-04 07:41:50 字数 1538 浏览 0 评论 0原文

我正在编写一个 API,用于通过 JSON 从 JDBC 连接的 Java Servlet 检索数据。我选择使用 JSON 是因为我们想要对浏览器中的数据进行排序和其他操作,并且我们将跨域访问数据。

由于我本质上是在 JavaScript 中执行 SQL 查询,因此返回的数据本质上是表格形式的。我开始写这个是为了让你得到一个列标签列表,然后是值数组,例如:

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

但是当我开始编写 JavaScript 来处理返回的数据时,我想知道直接输出是否会更好具有键/值对的结果,例如:

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

如果您返回大量结果,则表示有大量重复文本。但我们将传输压缩文件,所以我不太关心带宽。

基本上,我应该对此进行设计,以便我可以使用

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

或更漂亮的

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

方式访问我的数据吗?

本质上,我想知道对性能的潜在影响是否证明后一个选项的更简洁的语法是合理的。

后续

我确实以两种方式和配置文件实现了它。 分析是个好主意!性能差异很小。数据传输大小的差异很大,但通过 Gzip 压缩,两种格式非常大和非常小的数据集之间的差异降至 5-6%。所以我将采用更漂亮的实现。对于这个特定的应用程序,我可以期望所有客户端都支持 Gzip/Deflate,因此大小并不重要,并且客户端和服务器上的计算复杂性足够相似,因此并不重要。

对于任何感兴趣的人,这里是我的数据和图表

I'm writing an API for retrieving data from a JDBC-connected Java Servlet via JSON. 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.

Since I'm essentially doing SQL queries in JavaScript, the data that comes back is tabular in nature. I started to write this so that you get back a list of column labels, then arrays of values, for example:

{
  "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:

{
  "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.

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. 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.

For anyone interested, here is my data with graphs!.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

生生不灭 2024-11-11 07:41:54

您始终可以将第一个选项转换为其 JSON 表示形式

const tabularDataToJSON = (rows: string[][], columns: { value: string }[]) => {
return rows.map(function (row) {
    const record: Record<string, string> = {}
    columns.forEach((col, index) => {
        record[col.value] = row[index]
    })
    return record
})}


const json = tabularDataToJSON(results, columns)

You can always convert your first option to its JSON representation

const tabularDataToJSON = (rows: string[][], columns: { value: string }[]) => {
return rows.map(function (row) {
    const record: Record<string, string> = {}
    columns.forEach((col, index) => {
        record[col.value] = row[index]
    })
    return record
})}


const json = tabularDataToJSON(results, columns)
我的鱼塘能养鲲 2024-11-11 07:41:53

综合其他答案:

  1. 您的有线格式不必与内存中的格式相同。
  2. 哪个更好 - 看看它是否有所不同。
  3. 通常越简单越好。

此外:

  • 如果您只有一页结果,并且用户很少,那么第二种格式可能不会比第一种格式差。
  • 如果您的数据非常稀疏,则第二种格式可能会更好。
  • 如果您要发送 1000 或 1000 行数据,并且拥有数百万用户,那么您发送的数据大小可能会开始产生影响,也许第一种格式可能会有所帮助。
  • 您不能保证所有用户代理都支持 gzip / deflate,因此请记住这一点。

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.
  • You can't guarantee that all user agents support gzip / deflate, so bear this in mind.
遗忘曾经 2024-11-11 07:41:53

只是另一个 JSON 结构,我从中得到了非常好的结果:

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

遍历所有数据:

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());
}

Just another JSON structure from which I got very nice results:

{
    "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());
}
无法言说的痛 2024-11-11 07:41:53

FWIW 我会选择第二个选项,正如您所观察到的,它适合更干净的 JavaScript,并且也更容易让人阅读和理解。在我看来,可读性胜过从选项 1 中获得的任何一点性能提升。

我还想象,如果您要添加更多列或有一天更改列的顺序,则使用第一个选项,您可能必须重写大量 JavaScript,因为您将处理响应中数据的位置。

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. It seems to me that readability trumps whatever little performance gain you get from option 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.

束缚m 2024-11-11 07:41:53

您不必将代码与更紧凑但也更麻烦的格式联系起来。只需编写一个简单的 JS 适配器来检查返回的结构是否存在。如果缺少它,那么您正在处理一个普通的对象数组。如果它存在,您可以轻松地将繁琐的格式映射到更方便的格式。

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. 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.

温柔一刀 2024-11-11 07:41:52

简介两者。之后优化。

Profile both. Optimize afterwards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文