Skip to content

Модель данных

Klepnev Danila edited this page Dec 11, 2024 · 15 revisions

Нереляционная модель

Графическое представление модели

JSON-схема для основных коллекций

Коллекция houses
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "House",
  "type": "object",
  "properties": {
    "house_id": { 
        "type": "string",
        "description": "Уникальный идентификатор дома" 
    },
    "address": {
      "type": "object",
      "properties": {
        "street_id": { 
            "type": "string",
            "description": "ID улицы, к которой относится дом" 
        },
        "number": {
            "type": "string",
            "description": "Номер дома"
        }
      },
      "required": ["street_id", "number"]
    },
    "built_year": { 
        "type": "integer",
        "description": "Год постройки дома"
    },
    "floors": {
        "type": "integer",
        "description": "Количество этажей"
    },
    "apartments": {
        "type": "integer",
        "description": "Количество квартир"
    },
    "condition": {
        "type": "string",
        "description": "Состояние дома"
    },
    "management_company": {
        "type": "string",
        "description": "Управляющая компания (УК)"
    },
    "series": {
        "type": "string",
        "description": "Серия или тип дома"
    },
    "district": {
        "type": "string",
        "description": "Район, в котором находится дом"
    },
    "image_url": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uri",
        "description": "Ссылка на изображение дома"
      },
      "description": "Массив ссылок на изображения дома"
    },
    "coordinates": {
      "type": "array",
      "items": [
        { "type": "number", "description": "Широта" },
        { "type": "number", "description": "Долгота" }
      ],
      "minItems": 2,
      "maxItems": 2,
      "description": "Координаты дома в формате [широта, долгота]"
    }
  },
  "required": [
    "house_id", 
    "address", 
    "built_year", 
    "floors", 
    "apartments", 
    "condition", 
    "management_company", 
    "district",
    "coordinates"
  ]
}
Коллекция streets
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Street",
  "type": "object",
  "properties": {
    "street_id": {
        "type": "string",
        "description": "Уникальный идентификатор улицы"
    },
    "name": {
        "type": "string",
        "description": "Название улицы"
    },
    "type": {
        "type": "string",
        "enum": ["переулок", "улица", "бульвар", "проезд", "тупик", "линия", "проспект", "шоссе", "набережная", "площадь", "аллея", "трасса"],
        "description": "Тип улицы"
    },
    "district": {
        "type": "string",
        "description": "Район, в котором расположена улица"
    },
    "coordinates": {
      "type": "array",
      "items": {
        "type": "array",
        "items": [
          { "type": "number", "description": "Широта" },
          { "type": "number", "description": "Долгота" }
        ],
        "minItems": 2,
        "maxItems": 2,
        "description": "Точка улицы в формате [широта, долгота]"
      },
      "description": "Координаты ломаной линии, задающей улицу"
    }
  },
  "required": ["street_id", "name", "type", "district", "coordinates"]
}
Коллекция districts
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "District",
  "type": "object",
  "properties": {
    "district_id": {
      "type": "string",
      "description": "Уникальный идентификатор района"
    },
    "name": {
      "type": "string",
      "description": "Название района"
    },
    "boundary": {
      "type": "array",
      "items": {
        "type": "array",
        "items": [
          { "type": "number", "description": "Широта" },
          { "type": "number", "description": "Долгота" }
        ],
        "minItems": 2,
        "maxItems": 2,
        "description": "Точка границы в формате [широта, долгота]"
      },
      "description": "Границы района, заданные массивом точек ломаной"
    }
  },
  "required": ["district_id", "name", "boundary"]
}

Описание назначений коллекций, типов данных и сущностей

Коллекция houses

  • Назначение: Хранение сведений о домах, предоставление информации для поиска и фильтрации по улице, району, году постройки, состоянию и другим параметрам.
  • Тип данных: Объект с вложенными объектами.
  • Сущности:
    • house_id (строка) — уникальный идентификатор дома.
    • address (объект) — содержит street_id (ID улицы) и number (номер дома).
    • built_year (целое число) — год постройки дома.
    • floors (целое число) — количество этажей.
    • apartments (целое число) — количество квартир.
    • condition (строка) — состояние дома.
    • management_company (строка) — управляющая компания дома.
    • series (строка) — серия или тип дома.
    • district (строка) — район, в котором расположен дом.
    • image_url (массив строк с форматом URI) — массив ссылок на фотографии дома.
    • coordinates (массив из двух чисел) — условная центральная точка дома в формате [широта, долгота].

Коллекция streets

  • Назначение: Позволяет фильтровать дома по улицам и районам, поддерживает статистику улиц.
  • Тип данных: Объект.
  • Сущности:
    • street_id (строка) — уникальный идентификатор улицы.
    • name (строка) — название улицы.
    • type (строка) — тип улицы (например, переулок, улица, бульвар, проезд, тупик, линия, проспект, шоссе, набережная, площадь, аллея, трасса).
    • district (строка) — район, в котором расположена улица.
    • coordinates (массив массивов из двух чисел) — координаты ломаной линии, задающей улицу, в формате [широта, долгота].

Коллекция districts

  • Назначение: Хранение информации о районах Санкт-Петербурга, включая их границы и возможность отображения на карте. Используется для фильтрации домов и улиц по районам.
  • Тип данных: Объект с массивами.
  • Сущности:
    • district_id (строка) — уникальный идентификатор района.
    • name (строка) — название района.
    • boundary (массив массивов из двух чисел) — границы района, заданные массивом точек в формате [широта, долгота].

Оценка объема информации, хранимой в модели

Для оценки объема информации, хранимой в модели данных, рассмотрим каждый из типов объектов (домов и улиц) и оценим размер их хранения в памяти. Затем выразим общий объем через переменную, представляющую количество объектов одного типа.

Шаг 1: Оценка объема хранения для одного объекта

1.1. Коллекция houses
  • Фактический объем хранения для одного объекта:
    • house_id: 36 байт
    • address:
      • street_id: 24 байта
      • number: 10 байт
    • built_year: 4 байта
    • floors: 4 байта
    • apartments: 4 байта
    • condition: 20 байт
    • management_company: 30 байт
    • series: 15 байт
    • district: 20 байт
    • image_url: 100 байт
    • coordinates: 16 байт (2 числа по 8 байт для широты и долготы)

Общий объем для одного объекта house:

$$ V_{\text{house}} = 36 + 24 + 10 + 4 + 4 + 4 + 20 + 30 + 15 + 20 + 100 + 16 = 283 \ \text{байт} $$

Чистый объем хранения для одного объекта house (минимально необходимые поля):

  • house_id: 36 байт
  • address (номер дома и ID улицы): 24 байта + 10 байт
  • coordinates: 16 байт

$$ V_{\text{houseclean}} = 36 + 24 + 10 + 16 = 86 \ \text{байт} $$


1.2. Коллекция streets
  • Фактический объем хранения для одного объекта:
    • street_id: 36 байт
    • name: 30 байт
    • type: 10 байт
    • district: 20 байт
    • coordinates: 128 байт (напр., массив из 8 точек, каждая по 16 байт)

Общий объем для одного объекта street:

$$ V_{\text{street}} = 36 + 30 + 10 + 20 + 128 = 224 \ \text{байт} $$

Чистый объем хранения для одного объекта street (минимально необходимые поля):

  • street_id: 36 байт
  • name: 30 байт
  • coordinates: 128 байт

$$ V_{\text{streetclean}} = 36 + 30 + 128 = 194 \ \text{байт} $$


1.3. Коллекция districts
  • Фактический объем хранения для одного объекта:
    • district_id: 36 байт
    • name: 30 байт
    • coordinates: 256 байт (напр., массив из 16 точек, каждая по 16 байт)

Общий объем для одного объекта district:

$$ V_{\text{district}} = 36 + 30 + 256 = 322 \ \text{байт} $$

Чистый объем хранения для одного объекта district (минимально необходимые поля):

  • district_id: 36 байт
  • coordinates: 256 байт

$$ V_{\text{districtclean}} = 36 + 256 = 292 \ \text{байт} $$


Шаг 2: Общий объем хранения в зависимости от количества объектов

Пусть количество домов (houses) — $$N_h$$, количество улиц (streets) — $$N_s$$, количество районов (districts) — $$N_d$$.
Общий объем хранения данных:

$$ V_{\text{total}} = N_h \cdot V_{\text{house}} + N_s \cdot V_{\text{street}} + N_d \cdot V_{\text{district}} $$

Подставляя значения:

$$ V_{\text{total}} = N_h \cdot 283 + N_s \cdot 224 + N_d \cdot 322 $$


Избыточность модели

Для оценки избыточности модели взяли фактический объем хранимых данных и сравнили его с минимально необходимым («чистым») объемом данных для каждой коллекции, а затем вычислили общую избыточность модели.

Общая избыточность:

$$\text{Избыточность}_{\text{total}} = \frac{N_h \cdot V_{\text{house}} + N_s \cdot V_{\text{street}} + N_d \cdot V_{\text{district}}}{N_h \cdot V_{\text{house\_clean}} + N_s \cdot V_{\text{street\_clean}} + N_d \cdot V_{\text{district\_clean}}}$$

Подставляя значения:

$$ \text{Избыточность}_{\text{total}} = \frac{N_h \cdot 283 + N_s \cdot 224 + N_d \cdot 322}{N_h \cdot 86 + N_s \cdot 194 + N_d \cdot 292} $$


Формулы через одну переменную

Если количество домов (N_h) намного превышает количество улиц (N_s) и районов (N_d), примем:

  • $$N_s = \frac{N_h}{K_s}$$ (где $$K_s$$ — среднее количество домов на одну улицу)
  • $$N_d = \frac{N_h}{K_d}$$ (где $$K_d$$ — среднее количество домов на один район)
Общий объем через $$N_h$$

Подставляем $$N_s = \frac{N_h}{K_s}$$ и $$N_d = \frac{N_h}{K_d}$$ в формулу для общего объема:

$$ V_{\text{total}} = N_h \cdot 283 + \frac{N_h}{K_s} \cdot 224 + \frac{N_h}{K_d} \cdot 322 $$

$$ V_{\text{total}} = N_h \cdot \left(283 + \frac{224}{K_s} + \frac{322}{K_d}\right) $$

Общая избыточность через $$N_h$$

Подставляем $$N_s = \frac{N_h}{K_s}$$ и $$N_d = \frac{N_h}{K_d}$$ в формулу для избыточности:

$$ \text{Избыточность}_{\text{total}} = \frac{283 + \frac{224}{K_s} + \frac{322}{K_d}}{86 + \frac{194}{K_s} + \frac{292}{K_d}} $$

Оценка коэффициентов $$K_s$$ и $$K_d$$

Для количественной оценки коэффициентов использована выборка данных из ресурса CityWalls:

  • Среднее количество домов на одну улицу: $$K_s \approx 25$$.
  • Среднее количество домов на один район: $$K_d \approx 500$$.
Итоговые формулы с подставленными коэффициентами

Подставляем значения $$K_s = 25$$ и $$K_d = 500$$ в формулы:

Общий объем через $$N_h$$

$$ V_{\text{total}} = N_h \cdot \left(283 + \frac{224}{25} + \frac{322}{500}\right) $$

$$ V_{\text{total}} = N_h \cdot \left(283 + 8.96 + 0.644\right) $$

$$ V_{\text{total}} \approx N_h \cdot 292.604 \ \text{байт} $$

Общая избыточность через $$N_h$$

$$ \text{Избыточность}_{\text{total}} = \frac{283 + \frac{224}{25} + \frac{322}{500}}{86 + \frac{194}{25} + \frac{292}{500}} $$

$$ \text{Избыточность}_{\text{total}} = \frac{283 + 8.96 + 0.644}{86 + 7.76 + 0.584} $$

$$ \text{Избыточность}_{\text{total}} \approx \frac{292.604}{94.344} \approx 3.10 $$


Итоговые формулы

  • Общий объем данных:

$$ V_{\text{total}} \approx N_h \cdot 292.604 \ \text{байт} $$

  • Общая избыточность:

$$ \text{Избыточность}_{\text{total}} \approx 3.10 $$

Направление роста модели при увеличении количества объектов каждой сущности

Пусть:

  • $$N_h$$ — количество объектов в коллекции houses,
  • $$N_s$$ — количество объектов в коллекции streets,
  • $$N_d$$ — количество объектов в коллекции districts.

При увеличении количества объектов каждой сущности общий объем данных, требуемый для хранения, возрастает линейно. Формула для общего объема данных выглядит так:

$$ V_{\text{total}} = N_h \cdot V_{\text{house}} + N_s \cdot V_{\text{street}} + N_d \cdot V_{\text{district}} $$

где:

  • $$V_{\text{house}} = 283$$ байт — объем одного объекта house,
  • $$V_{\text{street}} = 224$$ байта — объем одного объекта street,
  • $$V_{\text{district}} = 322$$ байта — объем одного объекта district.

Таким образом:

  1. При увеличении количества объектов house объем $$V_{\text{total}}$$ увеличивается линейно, поскольку каждый новый объект house добавляет $$V_{\text{house}}$$ байт к общему объему.
  2. Аналогично, при увеличении количества объектов street объем $$V_{\text{total}}$$ увеличивается линейно, добавляя $$V_{\text{street}}$$ байт на каждый новый объект street.
  3. При увеличении количества объектов district объем $$V_{\text{total}}$$ также увеличивается линейно, добавляя $$V_{\text{district}}$$ байт на каждый новый объект district.

В результате общий объем данных модели зависит от числа объектов houses, streets и districts, и рост модели происходит пропорционально этим параметрам.

Примеры данных

Примеры данных для коллекции houses

{
  "house_id": "h123",
  "address": {
    "street_id": "s456",
    "number": "12"
  },
  "built_year": 1955,
  "floors": 5,
  "apartments": 50,
  "condition": "удовлетворительное",
  "management_company": "УК Жилсервис",
  "series": "К-7",
  "district": "Центральный",
  "image_url": [
    "http://example.com/images/house123_1.jpg",
    "http://example.com/images/house123_2.jpg"
  ],
  "coordinates": [59.935, 30.325]
},
{
  "house_id": "h789",
  "address": {
    "street_id": "s321",
    "number": "45A"
  },
  "built_year": 1978,
  "floors": 9,
  "apartments": 90,
  "condition": "хорошее",
  "management_company": "УК Комфорт",
  "series": "П-44",
  "district": "Фрунзенский",
  "image_url": [
    "http://example.com/images/house789_1.jpg",
    "http://example.com/images/house789_2.jpg"
  ],
  "coordinates": [59.85, 30.38]
}

Примеры данных для коллекции streets

{
  "street_id": "s456",
  "name": "Невский проспект",
  "type": "улица",
  "district": "Центральный",
  "coordinates": [
    [59.938, 30.315],
    [59.940, 30.317],
    [59.943, 30.320]
  ]
},
{
  "street_id": "s321",
  "name": "Ленинский проспект",
  "type": "проспект",
  "district": "Фрунзенский",
  "coordinates": [
    [59.84, 30.37],
    [59.85, 30.38],
    [59.86, 30.39]
  ]
}

Примеры данных для коллекции districts

{
  "district_id": "d1",
  "name": "Центральный",
  "boundary": [
    {"lat": 59.9343, "lon": 30.3351},
    {"lat": 59.9344, "lon": 30.3352},
    {"lat": 59.9345, "lon": 30.3353},
    {"lat": 59.9346, "lon": 30.3354},
    {"lat": 59.9347, "lon": 30.3355}
  ]
},
{
  "district_id": "d2",
  "name": "Фрунзенский",
  "boundary": [
    {"lat": 59.8778, "lon": 30.2943},
    {"lat": 59.8780, "lon": 30.2945},
    {"lat": 59.8782, "lon": 30.2947},
    {"lat": 59.8784, "lon": 30.2949},
    {"lat": 59.8786, "lon": 30.2951}
  ]
}

Примеры запросов

7.1. Запросы к модели для реализации сценариев использования

7.1.1. Запрос для выгрузки всех данных в формате JSON
 FOR house IN houses
    RETURN house
7.1.2. Запрос для массового добавления данных в коллекцию houses
INSERT { 
  house_id: @house_id,
  address: @address,
  built_year: @built_year,
  floors: @floors,
  apartments: @apartments,
  condition: @condition,
  management_company: @management_company,
  series: @series,
  district: @district,
  image_url: @image_url 
} INTO houses
7.1.3. Запрос на получение списка улиц по фильтру
FOR street IN streets
  FILTER street.type == @type AND street.district == @district
  RETURN street
7.1.4. Запрос на получение домов на выбранной улице
FOR house IN houses
  FILTER house.address.street_id == @street_id
  RETURN house
7.1.5. Запрос на получение информации о конкретном доме
FOR house IN houses
  FILTER house.house_id == @house_id
  RETURN {
    "built_year": house.built_year,
    "floors": house.floors,
    "apartments": house.apartments,
    "condition": house.condition,
    "management_company": house.management_company,
    "series": house.series,
    "district": house.district,
    "image_url": house.image_url
  }
7.1.6. Запрос на получение домов по параметрам фильтра
FOR house IN houses
  FILTER house.built_year == @built_year 
    AND house.district == @district 
    AND house.floors == @floors 
    AND house.apartments == @apartments
    AND house.address.street_id == @street_id 
    AND house.management_company == @management_company 
    AND house.condition == @condition
  RETURN house
7.1.7. Запрос на получение домов с заданными параметрами для отображения на карте
FOR house IN houses
  FILTER house.built_year == @built_year 
    AND house.district == @district 
    AND house.floors == @floors 
    AND house.apartments == @apartments 
    AND house.address.street_id == @street_id 
    AND house.management_company == @management_company 
    AND house.condition == @condition
  RETURN {
    "coordinates": house.coordinates,
    "house_id": house.house_id,
    "description": {
      "built_year": house.built_year,
      "floors": house.floors,
      "apartments": house.apartments,
      "condition": house.condition,
      "management_company": house.management_company
    }
  }```

##### 7.1.8. Запрос на получение статистики по улицам

```aql
FOR street IN streets
  COLLECT type = street.type WITH COUNT INTO count
  RETURN { "type": type, "count": count }
7.1.9. Запрос на получение статистики по домам
FOR house IN houses
  COLLECT year = house.built_year WITH COUNT INTO count
  RETURN { "built_year": year, "count": count }
7.1.10. Запрос на получение статистики: сколько домов на какой улице было построено в каком десятилетии
FOR house IN houses
  LET decade = FLOOR(house.built_year / 10) * 10
  COLLECT street_id = house.address.street_id, decade INTO grouped
  LET count = LENGTH(grouped)
  RETURN {
    "street_id": street_id,
    "decade": decade,
    "house_count": count
  }

7.2. Количество запросов для совершения юзкейсов

7.2.1. Импорт и экспорт данных
  • Экспорт: 1 запрос для выгрузки всех данных из houses.
  • Импорт: 1 запрос для вставки данных в houses.

Итого: 2 запроса.

7.2.2. Получение информации о доме через фильтр улиц
  • Получение улиц по фильтру: 1 запрос.
  • Получение домов на выбранной улице: 1 запрос.
  • Получение информации о конкретном доме: 1 запрос.

Итого: 3 запроса.

7.2.3. Получение информации о доме через фильтр домов
  • Получение домов по заданным параметрам: 1 запрос.
  • Получение информации о конкретном доме: 1 запрос.

Итого: 2 запроса.

7.2.4. Найти дом на карте города
  • Получение домов с заданными параметрами для отображения на карте: 1 запрос.

Итого: 1 запрос.

7.2.5. Подсчет статистики в системе
  • Получение статистики по улицам: 1 запрос.
  • Получение статистики по домам: 1 запрос.

Итого: 2 запроса.

Реляционная модель

Графическое представление модели

ER-диаграмма для реляционной модели, включающая основные сущности houses и streets, а также связи между ними:

  • Таблица houses:

    • Поля:
      • house_id (PRIMARY KEY)
      • street_id (FOREIGN KEY ссылается на streets)
      • number
      • built_year
      • floors
      • apartments
      • condition
      • management_company
      • series
      • image_url
      • coordinates
  • Таблица streets:

    • Поля:
      • street_id (PRIMARY KEY)
      • name
      • type
      • district_id (FOREIGN KEY)
      • coordinates
  • Таблица districts:

    • Поля:
      • district_id (PRIMARY KEY)
      • name
      • boundary

Описание назначений таблиц, типов данных и сущностей

  • Таблица houses

    • Назначение: Хранение информации о домах с привязкой к улицам, состоянию, управляющей компании и т. д.
    • Типы данных: Идентификаторы и строки, целые числа, ссылки.
    • Сущности:
      • house_id (строка) — уникальный идентификатор дома.
      • street_id (строка) — ID улицы.
      • number (строка) — номер дома.
      • built_year (целое число) — год постройки.
      • floors (целое число) — этажность.
      • apartments (целое число) — количество квартир.
      • condition (строка) — состояние.
      • management_company (строка) — управляющая компания.
      • series (строка) — серия или тип.
      • image_url (массив строк) — массив ссылок на изображения.
      • coordinates (массив из двух чисел) — условная центральная точка дома в формате [широта, долгота].
  • Таблица streets

    • Назначение: Хранение информации о улицах.
    • Типы данных: Идентификаторы, строковые значения.
    • Сущности:
      • street_id (строка) — уникальный идентификатор улицы.
      • name (строка) — название.
      • type (строка) — тип улицы.
      • district_id (строка) — ID района, в котором расположена улица.
      • coordinates (массив массивов из двух чисел) — координаты ломаной линии, задающей улицу, в формате [широта, долгота]
  • Таблица districs

    • Назначение: Хранение информации о районах города, включая их границы, используемое для фильтрации домов и улиц по районам.
    • Типы данных: Идентификаторы, строки, массивы.
    • Сущности:
      • district_id (строка) — уникальный идентификатор района.
      • name (строка) — название района.
      • boundary (массив массивов из двух чисел) — границы района, заданные массивом точек в формате [широта, долгота]

Оценка объема информации, хранимой в модели

Общий объем для одного объекта house:

$$ V_{\text{house}} = 36 + 24 + 10 + 4 + 4 + 4 + 20 + 30 + 15 + 20 + 100 + 16 = 283 \ \text{байт} $$

Чистый объем хранения для одного объекта house

$$ V_{\text{houseclean}} = 36 + 24 + 10 + 16 = 86 \ \text{байт} $$


Общий объем для одного объекта street:

$$ V_{\text{street}} = 36 + 30 + 10 + 24 + 128 = 224 \ \text{байт} $$

Чистый объем хранения для одного объекта street

$$ V_{\text{streetclean}} = 36 + 30 + 128 = 194 \ \text{байт} $$


Общий объем для одного объекта district:

$$ V_{\text{district}} = 36 + 30 + 256 = 322 \ \text{байт} $$

Чистый объем хранения для одного объекта district

$$ V_{\text{districtclean}} = 36 + 256 = 292 \ \text{байт} $$


Общий объем хранения в зависимости от количества объектов, где количество домов (houses) — $$N_h$$, количество улиц (streets) — $$N_s$$, количество районов (districts) — $$N_d$$

$$ V_{\text{total}} = N_h \cdot 283 + N_s \cdot 224 + N_d \cdot 322 $$


Общая избыточность:

$$ \text{Избыточность}_{\text{total}} = \frac{N_h \cdot 283 + N_s \cdot 224 + N_d \cdot 322}{N_h \cdot 86 + N_s \cdot 194 + N_d \cdot 292} $$


Формулы через одну переменную

Общий объем через $$N_h$$

$$ V_{\text{total}} = N_h \cdot \left(283 + \frac{228}{K_s} + \frac{322}{K_d}\right) $$

Избыточность через $$N_h$$

$$ \text{Избыточность}_{\text{total}} = \frac{283 + \frac{224}{K_s} + \frac{322}{K_d}}{86 + \frac{194}{K_s} + \frac{292}{K_d}} $$


Направление роста модели при увеличении количества объектов каждой сущности

  • При увеличении числа объектов в таблице houses — объем хранимой информации увеличивается линейно, как функция от $$N_h$$.
  • При увеличении числа объектов в таблице streets — объем хранимой информации увеличивается линейно, как функция от $$N_s$$.
  • При увеличении числа объектов в таблице districts — объем хранимой информации увеличивается линейно, как функция от $$N_d$$.

Примеры данных

Примеры данных для таблицы houses

INSERT INTO houses (house_id, street_id, number, built_year, floors, apartments, condition, management_company, series, image_url, coordinates)
VALUES 
  ('h123', 's456', '12', 1955, 5, 50, 'удовлетворительное', 'УК Жилсервис', 'К-7', '{"http://example.com/images/house123_1.jpg", "http://example.com/images/house123_2.jpg"}', '[59.9343, 30.3351]' ),
  ('h789', 's321', '45A', 1978, 9, 90, 'хорошее', 'УК Комфорт', 'П-44', '{"http://example.com/images/house789.jpg"}', '[59.8765, 30.1234]');

Примеры данных для таблицы streets

INSERT INTO streets (street_id, name, type, district_id, coordinates)
VALUES 
  ('s456', 'Невский проспект', 'улица', 'd1', '[[59.9343, 30.3351], [59.9375, 30.3382]]'),
  ('s321', 'Ленинский проспект', 'проспект', 'd2', '[[59.8765, 30.1234], [59.8790, 30.1256]]');

Примеры данных для таблицы districts

INSERT INTO districts (district_id, name, boundary)
VALUES 
  ('d1', 'Центральный', '[[59.9280, 30.3150], [59.9370, 30.3250], [59.9390, 30.3400], [59.9300, 30.3550]]'),
  ('d2', 'Фрунзенский', '[[59.8700, 30.1100], [59.8800, 30.1200], [59.8850, 30.1300], [59.8760, 30.1400]]');

Примеры запросов

7.1. Запросы к модели для реализации сценариев использования

7.1.1. Выгрузка всех данных из таблицы houses
SELECT * FROM houses;
7.1.2. Вставка новых данных в таблицу houses
INSERT INTO houses (house_id, street_id, number, built_year, floors, apartments, condition, management_company, series, image_url, coordinates)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
7.1.3. Получение списка улиц по фильтру
SELECT * FROM streets
WHERE type = ? AND district_id = ?;
7.1.4. Получение списка домов на выбранной улице
SELECT * FROM houses
WHERE street_id = ?;
7.1.5. Получение информации о конкретном доме
SELECT * FROM houses
WHERE house_id = ?;
7.1.6. Получение списка домов по заданным параметрам
SELECT h.*
FROM houses h
JOIN streets st ON h.street_id = st.street_id
WHERE (h.built_year = ? OR ? IS NULL)
   AND (st.district_id = ? OR ? IS NULL)
   AND (h.floors = ? OR ? IS NULL)
   AND (h.apartments = ? OR ? IS NULL)
   AND (h.street_id = ? OR ? IS NULL)
   AND (h.management_company = ? OR ? IS NULL)
   AND (h.condition = ? OR ? IS NULL);
7.1.7. Получение списка домов с заданными параметрами для отображения на карте
SELECT 
    h.house_id,
    CONCAT(st.name, ', ', h.number) AS address,
    h.built_year,
    h.floors,
    h.apartments,
    h.condition,
    h.management_company,
    h.series,
    st.district_id,
    h.image_url
FROM 
    houses h
JOIN 
    streets st ON h.street_id = st.street_id
WHERE 
    (h.built_year = ? OR ? IS NULL)
    AND (st.district_id = ? OR ? IS NULL)
    AND (h.floors = ? OR ? IS NULL)
    AND (h.apartments = ? OR ? IS NULL)
    AND (h.street_id = ? OR ? IS NULL)
    AND (h.management_company = ? OR ? IS NULL)
    AND (h.condition = ? OR ? IS NULL);
7.1.8. Получение статистики по улицам
SELECT COUNT(street_id), type, district_id
FROM streets
GROUP BY type, district_id;
7.1.9. Получение статистики по домам
SELECT COUNT(house_id), built_year, floors, apartments, management_company, condition
FROM houses
GROUP BY built_year, floors, apartments, management_company, condition;
7.1.10. сколько домов на какой улице было построено в каком десятилетии
SELECT 
    st.name AS street_name,
    FLOOR(h.built_year / 10) * 10 AS decade,
    COUNT(h.house_id) AS house_count
FROM 
    houses h
JOIN 
    streets st ON h.street_id = st.street_id
GROUP BY 
    st.name, 
    FLOOR(h.built_year / 10)
ORDER BY 
    st.name, 
    decade;

7.2. Количество запросов для совершения юзкейсов

  1. Импорт и экспорт данных

    • Экспорт данных: 1 запрос SELECT * FROM houses
    • Импорт данных: 1 запрос INSERT для массовой загрузки.
      • Итого: 2 запроса
  2. Получение информации о доме через фильтр улиц

    • Получение списка улиц по фильтру: 1 запрос SELECT по таблице streets
    • Получение списка домов на выбранной улице: 1 запрос SELECT по таблице houses
    • Получение информации о конкретном доме: 1 запрос SELECT по таблице houses
    • Итого: 3 запроса
  3. Получение информации о доме через фильтр домов

    • Получение списка домов по фильтру: 1 запрос SELECT по таблице houses
    • Получение информации о конкретном доме: 1 запрос SELECT по таблице houses
    • Итого: 2 запроса
  4. Найти дом на карте города

    • Получение списка домов для отображения на карте с параметрами: 1 запрос SELECT
    • Итого: 1 запрос
  5. Подсчет статистики в системе

    • Подсчет количества домов по характеристикам: 1 запрос SELECT с группировкой по таблице houses
    • Подсчет количества улиц по типу и району: 1 запрос SELECT с группировкой по таблице streets
    • Итого: 2 запроса

Сравнение моделей

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

В запросах для ArongoDB и SQL требуется одинаковое количество операций.

Вывод

Для проекта, ориентированного на хранение информации о домах, как в историческом аспекте, так и в контексте удобного доступа и анализа, обе модели (SQL и NoSQL) имеют свои преимущества.

  • SQL модель: Подходит для строго структурированных данных с постоянными отношениями и обеспечивает строгую целостность данных. Она лучше для моделей, где требуется точное соблюдение связей, например, для реализации сложных отчетов и аналитики. SQL отлично поддерживает стандартизированные и табличные данные, что делает её оптимальной для моделей с фиксированными схемами и ограниченным количеством вложений и связей.

  • NoSQL модель (в частности, ArangoDB): Предлагает гибкость в структуре данных, что упрощает хранение и добавление новых свойств без необходимости изменять всю схему. ArangoDB, как база графов и документов, позволяет эффективно моделировать сложные отношения и вложения. В проектах с динамической структурой данных и при необходимости горизонтального масштабирования NoSQL будет более подходящим.

С учетом требований к проекту — высокой гибкости в хранении, работы с вложенными данными и возможных изменений в структуре данных — NoSQL может быть предпочтительным выбором, поскольку позволит легче адаптироваться к изменяющимся данным и требованиям.

Clone this wiki locally