Самый оптимальный способ хранения вложенной информации в базе данных - PullRequest
1 голос
/ 01 февраля 2020

Я хочу сохранить вложенную информацию в базе данных Postgres, и мне интересно, каков наиболее оптимальный способ сделать это.

У меня есть список автомобилей для аренды, структурированный следующим образом:

[Марка]> [Модель]> [Аренда отдельных автомобилей этой марки и модели], напр .:

[
{
    "id": 1,
    "name": "Audi",
    "models": [
        {
            "id": 1,
            "name": "A1",
            "cars": [
                {
                    "id": 1,
                    "license": "RPY9973",
                    "mileage": "41053"
                },
                {
                    "id": 2,
                    "license": "RPY3001",
                    "mileage": "102302"
                },
                {
                    "id": 3,
                    "license": "RPY9852",
                    "mileage": "10236"
                }
            ]
        },
        {
            "id": 2,
            "name": "A3",
            "cars": [
                {
                    "id": 1,
                    "license": "RPY1013",
                    "mileage": "66952"
                },
                {
                    "id": 2,
                    "license": "RPY3284",
                    "mileage": "215213"
                },
                {
                    "id": 3,
                    "license": "RPY0126",
                    "mileage": "19632"
                }
            ]
        }
        ...
    ]
}
...

]

В настоящее время имеет ограниченный опыт работы с базы данных и хранения массивов, я храню его в таблице «бренды» со следующими столбцами:

идентификатор (целое число) - идентификатор бренда название (текст) - название бренда models (текст) - содержит строковое содержимое моделей и автомобилей внутри них, которые анализируются при чтении

На практике это делает свою работу, однако я хотел бы знать, какой будет наиболее эффективный способ.

Например, должен ли я разделить одну таблицу на три таблицы: «бренды», «модели» и «автомобили» и сделать так, чтобы таблицы ссылались друг на друга (brands.models - это массив уникальных идентификаторов моделей, которые я можно использовать для чтения данных из таблицы 'models', а models.cars будет массивом уникальных идентификаторов автомобилей, которые я мог бы использовать для чтения данных из таблицы 'cars')?

Ответы [ 2 ]

1 голос
/ 01 февраля 2020

Вместо того, чтобы хранить их как json, jsonb или как массивы, наиболее эффективным способом хранения данных будет их сохранение в виде реляционных данных (исключая типы данных для краткости):

create table brands(
 id,
 name, 
 /* other columns */
PRIMARY KEY (id)
);

create table models(
 id,
 name,
 brand_id REFERENCES brands(id),
/* other columns */
PRIMARY KEY (id)
);

create table cars(
 id,
 model_id REFERENCES models(id),
 mileage, 
 license,
/* other columns */
PRIMARY KEY (id)
);

Затем вы можете извлекать и обновлять каждую сущность по отдельности, не анализируя json. Частичное обновление также намного проще, когда вам нужно сосредоточиться только на одной строке, а не беспокоиться об обновлении массивов или json. Для запроса вы должны присоединиться по первичным ключам. Например, чтобы получить арендуемые автомобили, доступные по марке:

select b.id, b.name, m.id, m.name, c.id, c.mileage, c.license
 FROM brands b
   LEFT JOIN models m 
   ON m.brand_id = b.id
   LEFT JOIN cars c 
   ON c.model_id = m.id
where b.id = ?

На основе шаблонов запросов / фильтрации вы также захотите создать индексы для часто используемых столбцов ...

CREATE INDEX idx_car_model ON cars(model_id);
CREATE INDEX idx_model_brand ON models(brand_id);
0 голосов
/ 01 февраля 2020

Лучшим решением для хранения вложенных данных в вашей базе данных postgres является поле json или jsonb. Преимущества использования json или jsonb заключаются в следующем:

  • значительно ускоряет обработку, поддерживает индексирование (что может быть существенным преимуществом),
  • упрощенные схемы (замена объекта таблицы значений атрибутов (EAV) со столбцами jsonb, которые можно запрашивать, индексировать и объединять, что позволяет повысить производительность вплоть до 1000X)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...