Подтвердить что ты не робот

Как я должен представлять табличные данные в JSON?

Я пишу API для извлечения данных из JSBC-подключенного Java-сервлета через JSON. Я решил использовать JSON, потому что мы захотим делать сортировки и другие операции с данными в браузере, и мы будем получать доступ к данным из разных доменов.

Поскольку я выполняю SQL-запросы в JavaScript, возвращаемые данные носят табличный характер. Я начал писать так, чтобы вы вернули список меток столбцов, а затем массивы значений, например:

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

Но когда я начинаю писать JavaScript для обработки возвращаемых данных, мне интересно, лучше ли просто выводить результаты с помощью пар ключ/значение, например:

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

Если вы возвращаете много результатов, много повторяющегося текста. Но мы собираемся транспортировать gzipped, поэтому я не слишком обеспокоен пропускной способностью.

В принципе, должен ли я это сделать, чтобы получить доступ к моим данным с помощью

$.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, поэтому размер не имеет значения, а вычислительная сложность как для клиента, так и для сервера аналогична достаточно, чтобы это не имело значения.

Для всех, кто интересуется, вот мои данные с графиками!

4b9b3361

Ответ 1

Синтезируя другие ответы:

  • Формат вашего провода не должен быть таким же, как ваш формат в памяти.
  • Профиль, который лучше - см., если это имеет значение.
  • Упрощение обычно лучше начинать с.

Далее:

  • Если у вас есть только страница результатов и несколько пользователей, то второй формат может быть не хуже 1-го формата.
  • Если ваши данные довольно разреженные, второй вариант может быть лучше.
  • Если вы отправляете 1000 или строк данных, и у вас есть миллионы пользователей, тогда возможно, что размер отправляемых вами данных может начать иметь значение, и, возможно, может помочь 1-й формат.
  • Вы не можете гарантировать, что все пользовательские агенты поддерживают gzip/deflate, поэтому имейте это в виду.

Ответ 2

Профиль обоим. Оптимизируйте впоследствии.

Ответ 3

Вам не нужно привязывать код к более компактному, но также более громоздкому формату. Просто напишите простой JS-адаптер, чтобы проверить возвращенную структуру на наличие columns. Если это отсутствует, вы имеете дело с простым массивом объектов. Если он присутствует, вы можете легко сопоставить громоздкий формат с более удобным форматом.

Ответ 4

FWIW Я бы выбрал второй вариант, он поддается более чистому JavaScript, как вы заметили, а также будет проще для человека читать и понимать. Мне кажется, что читаемость превосходит любую небольшую выгоду, которую вы получаете от варианта 1.

Я также предполагаю, что если вы когда-нибудь добавите больше столбцов или порядок столбцов, с первым вариантом, вам, вероятно, придется переписать много JavaScript, так как вы будете работать с позицией данных в ответе.

Ответ 5

Еще одна структура 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());
}