---
title: Базы данных
seo:
  title: "Базы данных — С# Developer"
  description: "Тема «Базы данных» для собеседования С# Developer. Разница между реляционными и нереляционными базами, плюсы и минусы использования обоих вариантов. Что такое индексы в RDBMS?"
---

[Все темы С# Developer](/s-developer)

## <strong>Разница между реляционными и нереляционными базами, плюсы и минусы использования обоих вариантов</strong> [#q-14bee738d69b81f196ddfc16b69092fe]

Реляционные базы данных (<code>SQL</code>)&#58;

#### Преимущества&#58;

- <strong>Строгая схема&#58;</strong> Четко определенная структура данных.

- <strong>SQL&#58;</strong> Мощный язык запросов.

- <strong>Нормализация&#58;</strong> Минимизация дублирования данных.

- <strong>Транзакции&#58;</strong> Поддержка ACID-транзакций.

#### Недостатки&#58;

- <strong>Масштабируемость&#58;</strong> Трудности с горизонтальным
  масштабированием.

- <strong>Сложность схемы&#58;</strong> Изменение схемы может быть трудоемким.

- <strong>Производительность&#58;</strong> Может снижаться при больших объемах
  данных.

#### Нереляционные базы данных (<code>NoSQL</code>)&#58;

#### Преимущества&#58;

- <strong>Гибкость схемы&#58;</strong> Схема может быть динамической или
  отсутствовать.

- <strong>Масштабируемость&#58;</strong> Легче горизонтально масштабировать.

- <strong>Производительность&#58;</strong> Высокая производительность для
  определенных типов нагрузок.

#### Недостатки&#58;

- <strong>Отсутствие стандартизации&#58;</strong> Разные модели данных и
  интерфейсы.

- <strong>Ограниченные возможности запросов&#58;</strong> Менее мощные средства
  для сложных запросов.

- <strong>Последовательность&#58;</strong> Некоторые NoSQL базы данных могут не
  поддерживать полные ACID-транзакции.

#### Итог&#58;

- <strong>Реляционные&#58;</strong> Хорошо подходят для приложений с четко
  определенной структурой данных и необходимостью в сложных запросах и
  транзакциях.

- <strong>Нереляционные&#58;</strong> Идеальны для больших объемов данных,
  требующих гибкой схемы и высокой производительности при горизонтальном
  масштабировании.

:::note[Ссылки для изучения]

1. [Реляционные и нереляционные базы данных](https://wiki.merionet.ru/articles/chto-takoe-relyacionnye-bazy-dannyh)
   :::

---

## <strong>Что такое индексы в</strong> <code>RDBMS</code><strong>?</strong> [#q-14bee738d69b81a49be6c504c6cdef1e]

Индексы в <code>RDBMS</code>&#58;

{/* prettier-ignore */}
- <strong>Определение&#58;</strong> Специальные структуры, создаваемые в базах данных для быстрого поиска и доступа к данным.

- <strong>Назначение&#58;</strong> Улучшение скорости выполнения запросов (SELECT), особенно на больших таблицах.

- <strong>Типы&#58;</strong>

    - <strong>Кластерные (Clustered)&#58;</strong> Сортируют и хранят строки данных таблицы на основе ключевых значений индекса.

    - <strong>Некластерные (Non-Clustered)&#58;</strong> Создают отдельную структуру, указывающую на физические строки данных.

#### Преимущества&#58;

- <strong>Повышение производительности&#58;</strong> Значительно ускоряют
  операции поиска.

- <strong>Быстрое выполнение&#58;</strong> Улучшают скорость выполнения запросов
  на выборку.

#### Недостатки&#58;

- <strong>Затраты на обновление&#58;</strong> Замедляют операции вставки,
  обновления и удаления данных.

- <strong>Использование памяти&#58;</strong> Требуют дополнительного
  пространства для хранения индексных структур.

:::note[Ссылки для изучения]

1. [Overview of RDBMS](https://www.navicat.com/en/company/aboutus/blog/1782-overview-of-rdbms-index-types-2)
   :::

---

## <strong>Какие типы</strong> <code>JOIN</code> <strong>существуют в</strong> <code>SQL</code><strong>?</strong> [#q-14bee738d69b81f4b84fc27576deb2d1]

В <code>SQL</code> существует несколько типов <code>JOIN</code>&#58;

1. <strong>INNER JOIN&#58;</strong> Возвращает только те строки, которые имеют
   совпадающие значения в обеих таблицах.

   ```sql
   SELECT * FROM table1
   INNER JOIN table2 ON table1.id = table2.id;
   ```

1. <strong>LEFT JOIN (LEFT OUTER JOIN)&#58;</strong> Возвращает все строки из
   левой таблицы и совпадающие строки из правой таблицы. Если совпадений нет,
   возвращает NULL для правой таблицы.

   ```sql
   SELECT * FROM table1
   LEFT JOIN table2 ON table1.id = table2.id;
   ```

1. <strong>RIGHT JOIN (RIGHT OUTER JOIN)&#58;</strong> Возвращает все строки из
   правой таблицы и совпадающие строки из левой таблицы. Если совпадений нет,
   возвращает NULL для левой таблицы.

   ```sql
   SELECT * FROM table1
   RIGHT JOIN table2 ON table1.id = table2.id;
   ```

1. <strong>FULL JOIN (FULL OUTER JOIN)&#58;</strong> Возвращает все строки,
   когда есть совпадение в одной из таблиц. Если совпадений нет, возвращает NULL
   для не совпадающей таблицы.

   ```sql
   SELECT * FROM table1
   FULL JOIN table2 ON table1.id = table2.id;
   ```

1. <strong>CROSS JOIN&#58;</strong> Возвращает декартово произведение всех строк
   двух таблиц.

   ```sql
   SELECT * FROM table1
   CROSS JOIN table2;
   ```

:::note[Ссылки для изучения]

1. [Типы JOIN в SQL](https://learn.microsoft.com/ru-ru/sql/relational-databases/performance/joins?view=sql-server-ver16)
   :::

---

## <strong>Расскажите о нормальных формах в СУБД</strong> [#q-14bee738d69b81ec9688e5b56caa0f83]

Нормальные формы в СУБД (системах управления базами данных) используются для структурирования баз данных с целью минимизации избыточности и предотвращения аномалий при обновлении данных. Основные нормальные формы включают&#58;

{/* prettier-ignore */}
1. <strong>Первая нормальная форма (</strong><code>1NF</code><strong>)&#58;</strong>

    - <strong>Требование&#58;</strong> Все столбцы содержат только атомарные (неделимые) значения, и каждое значение в столбце однотипно.

    - <strong>Пример&#58;</strong> Таблица без повторяющихся групп.

1. <strong>Вторая нормальная форма (</strong><code>2NF</code><strong>)&#58;</strong>

    - <strong>Требование&#58;</strong> Таблица находится в 1NF и все неключевые столбцы зависят от всего первичного ключа (отсутствие частичных зависимостей).

    - <strong>Пример&#58;</strong> Таблица, где каждый неключевой столбец зависит от первичного ключа целиком.

1. <strong>Третья нормальная форма (</strong><code>3NF</code><strong>)&#58;</strong>

    - <strong>Требование&#58;</strong> Таблица находится во 2NF и все неключевые столбцы не зависят транзитивно от первичного ключа (отсутствие транзитивных зависимостей).

    - <strong>Пример&#58;</strong> Таблица, где неключевые столбцы зависят только от первичного ключа.

1. <strong>Бойс-Кодд нормальная форма (</strong><code>BCNF</code><strong>)&#58;</strong>

    - <strong>Требование&#58;</strong> Таблица находится в 3NF и для каждой функциональной зависимости X -\> Y, X является суперключом.

    - <strong>Пример&#58;</strong> Укрепляет 3NF, устраняя некоторые аномалии, не решаемые 3NF.

1. <strong>Четвёртая нормальная форма (</strong><code>4NF</code><strong>)&#58;</strong>

    - Требование 4NF&#58; в каждой нетривиальной многозначной зависимости X ↠ Y детерминант X должен быть суперключом. Тривиальные зависимости не запрещены.

    - <strong>Пример&#58;</strong> Таблица, где один факт не приводит к нескольким независимым многозначным зависимостям.

1. <strong>Пятая нормальная форма (</strong><code>5NF</code><strong>)&#58;</strong>

    - Требование 5NF&#58; каждая нетривиальная зависимость соединения должна следовать из кандидатных ключей.

    - Смысл 5NF&#58; устранить избыточность, связанную с зависимостями соединения; разложение должно позволять восстановить исходное отношение соединением без потерь и лишних строк.

:::note[Ссылки для изучения]

1. [Описание нормализации БД](https://learn.microsoft.com/ru-ru/office/troubleshoot/access/database-normalization-description)
   :::

---

## <strong>Что такое индекс в БД?</strong> [#q-14bee738d69b81b5bfe9f26f7e5cdec7]

Индекс в базе данных&#58;

- <strong>Определение&#58;</strong> Структура данных, созданная для ускорения
  поиска и доступа к строкам в таблице.

- <strong>Назначение&#58;</strong> Повышение производительности операций выборки
  (<code>SELECT</code>).

#### Типы индексов&#58;

- <strong>Кластерные (</strong>
  <code>Clustered</code>
  <strong>)&#58;</strong> Физически сортируют строки данных таблицы на основе
  ключа индекса. Каждая таблица может иметь только один кластерный индекс.

- <strong>Некластерные (</strong>
  <code>Non&#45;Clustered</code>
  <strong>)&#58;</strong> Хранят указатели на физические строки данных. Одна
  таблица может иметь множество некластерных индексов.

#### Преимущества&#58;

- <strong>Ускорение запросов&#58;</strong> Значительно увеличивают скорость
  выполнения запросов на выборку данных.

#### Недостатки&#58;

- <strong>Затраты на обновление&#58;</strong> Замедляют операции вставки,
  обновления и удаления из-за необходимости обновления индекса.

- <strong>Использование памяти&#58;</strong> Требуют дополнительного
  пространства для хранения индексных структур.

:::note[Ссылки для изучения]

1. [Как устроено индексирование в БД](https://habr.com/ru/companies/ruvds/articles/724066/)
   :::

---

## <strong>Когда следует использовать индексы? Преимущества и недостатки</strong> [#q-14bee738d69b8109af74f4f93a1138ac]

Когда следует использовать индексы&#58;

- <strong>Частые запросы&#58;</strong> Для столбцов, которые часто используются
  в условиях <code>WHERE</code>, <code>JOIN</code>, <code>ORDER BY</code> и
  <code>GROUP BY</code>.

- <strong>Уникальность&#58;</strong> Для обеспечения уникальности значений в
  столбце (например, первичные ключи).

- <strong>Ускорение поиска&#58;</strong> Для ускорения поиска и доступа к данным
  в больших таблицах.

#### Преимущества&#58;

- <strong>Ускорение выполнения запросов&#58;</strong> Значительно повышают
  скорость выборки данных.

- <strong>Упорядочение данных&#58;</strong> Кластерные индексы упорядочивают
  физическое хранение данных, что ускоряет доступ.

#### Недостатки&#58;

- <strong>Замедление операций записи&#58;</strong> Вставка, обновление и
  удаление данных становятся медленнее из-за необходимости обновления индексов.

- <strong>Использование памяти&#58;</strong> Индексы занимают дополнительное
  пространство на диске.

:::note[Ссылки для изучения]

1. [Всё что необходимо знать об индексах в SQL](https://otus.ru/journal/vse-chto-neobhodimo-znat-pro-indeksy-ms-sql/)
   :::

---

## <strong>Какие типы индексов существуют? Чем они отличаются?</strong> [#q-14bee738d69b810a8817e9a1e26874ee]

Типы индексов в базе данных&#58;

{/* prettier-ignore */}
1. <strong>Кластерные индексы (</strong><code>Clustered Index</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Физически сортируют строки данных таблицы на основе ключа индекса.

    - <strong>Отличие&#58;</strong> Таблица может иметь только один кластерный индекс. Данные хранятся в порядке кластерного ключа.

    - <strong>Пример&#58;</strong> Первичный ключ автоматически создаёт кластерный индекс, если не указано иное.

1. <strong>Некластерные индексы (</strong><code>Non&#45;Clustered Index</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Создают отдельную структуру, содержащую указатели на физические строки данных.

    - <strong>Отличие&#58;</strong> Таблица может иметь множество некластерных индексов. Не сортируют физически данные.

    - <strong>Пример&#58;</strong> Индексы для ускорения поиска по неключевым столбцам.

1. <strong>Уникальные индексы (</strong><code>Unique Index</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Гарантируют уникальность значений в столбце.

    - <strong>Отличие&#58;</strong> Не допускают дублирующихся значений в индексируемых столбцах.

    - <strong>Пример&#58;</strong> Индексы на столбцах с уникальными ограничениями.

1. <strong>Полнотекстовые индексы (</strong><code>Full&#45;Text Index</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Используются для текстового поиска в больших текстовых столбцах.

    - <strong>Отличие&#58;</strong> Обеспечивают быстрое выполнение полнотекстовых поисковых запросов.

    - <strong>Пример&#58;</strong> Поиск по документам, описаниям или другим текстовым данным.

1. <strong>Составные индексы (</strong><code>Composite Index</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Индексы, созданные на основе нескольких столбцов.

    - <strong>Отличие&#58;</strong> Учитывают комбинацию значений нескольких столбцов для индексации.

    - <strong>Пример&#58;</strong> Индексы на сочетание столбцов "Фамилия" и "Имя".

#### Отличия&#58;

- <strong>Кластерные vs Некластерные&#58;</strong> Кластерные сортируют данные
  физически, некластерные — логически.

- <strong>Уникальные&#58;</strong> Гарантируют уникальность значений.

- <strong>Полнотекстовые&#58;</strong> Оптимизированы для текстового поиска.

- <strong>Составные&#58;</strong> Индексируют комбинации значений нескольких
  столбцов.

:::note[Ссылки для изучения]

1. [Обзор типов индексов в БД](https://habr.com/ru/articles/102785/)
   :::

---

## <strong>Что такое</strong> <code>ACID</code><strong>?</strong> [#q-14bee738d69b81be8582de8382dd1f31]

<code>ACID</code> — это набор свойств, обеспечивающих надежность транзакций в
базе данных&#58;

{/* prettier-ignore */}
1. <code>Atomicity</code> <strong>(Атомарность)&#58;</strong>

    - <strong>Определение&#58;</strong> Транзакция выполняется полностью или не выполняется вовсе.

    - <strong>Пример&#58;</strong> Если часть транзакции не удалась, все изменения отменяются.

1. <code>Consistency</code> <strong>(Согласованность)&#58;</strong>

    - <strong>Определение&#58;</strong> Транзакция переводит базу данных из одного согласованного состояния в другое.

    - <strong>Пример&#58;</strong> Все правила и ограничения (такие как целостность данных) соблюдаются.

1. <code>Isolation</code> <strong>(Изоляция)&#58;</strong>

    - Определение&#58; изоляция ограничивает влияние конкурентных транзакций. Допустимые наблюдаемые эффекты зависят от уровня изоляции; Serializable дает результат, эквивалентный некоторому последовательному выполнению.

    - <strong>Пример&#58;</strong> Одновременные транзакции не влияют друг на друга.

1. <code>Durability</code> <strong>(Устойчивость)&#58;</strong>

    - <strong>Определение&#58;</strong> После завершения транзакции ее результаты сохраняются, даже в случае сбоя системы.

    - <strong>Пример&#58;</strong> Записанные данные остаются сохраненными после подтверждения транзакции.

:::note[Ссылки для изучения]

1. [Требования ACID на простом языке](https://habr.com/ru/articles/555920/)
   :::

---

## <strong>Проблема&#58; запрос долго выполняется. Какие есть методы ее диагностики и решения?</strong> [#q-14bee738d69b81e88c47f88a8d629a0a]

<strong>Методы диагностики&#58;</strong>

{/* prettier-ignore */}
1. <strong>Анализ плана выполнения (</strong><code>Execution Plan</code><strong>)&#58;</strong>

    - <strong>Инструмент&#58;</strong> Используйте SQL Server Management Studio (SSMS) или аналогичные инструменты.

    - <strong>Описание&#58;</strong> Показать, как база данных выполняет запрос, выявляя узкие места.

1. <strong>Индексация&#58;</strong>

    - <strong>Проверка&#58;</strong> Проверьте наличие и эффективность индексов.

    - <strong>Создание/Обновление&#58;</strong> Создайте или обновите индексы на ключевых столбцах.

1. <strong>Статистика&#58;</strong>

    - <strong>Обновление&#58;</strong> Убедитесь, что статистика актуальна.

    - <strong>Команда&#58;</strong> <code>UPDATE STATISTICS</code> или аналогичные команды для обновления.

1. <strong>Профилирование (Profiling)&#58;</strong>

    - <strong>Инструмент&#58;</strong> Используйте SQL Profiler или аналогичные инструменты.

    - <strong>Описание&#58;</strong> Отслеживайте и анализируйте запросы, чтобы выявить медленные.

<strong>Методы решения&#58;</strong>

{/* prettier-ignore */}
1. <strong>Оптимизация запросов&#58;</strong>

    - Переписать&#58; найдите узкое место по плану и измерениям. JOIN не всегда быстрее подзапроса; оптимизатор может построить одинаковый план.

    - <strong>Разделение&#58;</strong> Разделите сложные запросы на несколько более простых.

1. <strong>Индексы&#58;</strong>

    - <strong>Добавить&#58;</strong> Добавьте недостающие индексы.

    - <strong>Удалить&#58;</strong> Удалите неиспользуемые или дублирующиеся индексы.

1. <strong>Кеширование&#58;</strong>

    - <strong>Внедрение&#58;</strong> Используйте кеширование часто запрашиваемых данных.

    - <strong>Проверка&#58;</strong> Убедитесь, что кеширование актуально и эффективно.

1. <strong>Аппаратные ресурсы&#58;</strong>

    - <strong>Обновление&#58;</strong> Проверьте нагрузку на сервер и, если необходимо, обновите аппаратные ресурсы (CPU, RAM, диск).

1. <strong>Параллелизм&#58;</strong>

    - <strong>Настройка&#58;</strong> Настройте параметры параллелизма для улучшения производительности многоядерных систем.

:::note[Ссылки для изучения]

1. [Профилирование и отладка медленных запросов на SQL](https://sql-ex.ru/blogs/?/Instrumenty_i_metody_dlJa_profilirovaniJa_i_otladki_medlenno_vypolnJajuwihsJa_SQL-zaprosov.html)
   :::

---

## <strong>Как</strong> <code>ORM</code> <strong>(Entity Framework или Entity Framework Core) транслируют C# код в язык запросов базы данных? Что для этого используется?</strong> [#q-14bee738d69b8109a675c4c8f3993520]

Как <code>ORM</code> транслируют C# код в язык запросов базы данных&#58;

{/* prettier-ignore */}
1. <code>LINQ</code> <strong>(Language Integrated Query)&#58;</strong>

    - <strong>Описание&#58;</strong> Используется для написания запросов к базе данных на C#.

    - <strong>Пример&#58;</strong> <code>var users &#61; context&#46;Users&#46;Where&#40;u &#61;&#62; u&#46;IsActive&#41;&#46;ToList&#40;&#41;&#59;</code>

1. <strong>Компилятор выражений (Expression Trees)&#58;</strong>

    - <strong>Описание&#58;</strong> LINQ-запросы переводятся в дерево выражений, представляющее структуру запроса.

    - <strong>Пример&#58;</strong> <code>Expression&#60;Func&#60;User&#44; bool&#62;&#62; filter &#61; u &#61;&#62; u&#46;IsActive&#59;</code>

1. <strong>Провайдеры LINQ (LINQ Providers)&#58;</strong>

    - <strong>Описание&#58;</strong> Провайдер LINQ для Entity Framework обрабатывает дерево выражений и генерирует соответствующий SQL-запрос.

    - <strong>Пример&#58;</strong> Генерация SQL-кода&#58; <code>SELECT &#42; FROM Users WHERE IsActive &#61; 1&#59;</code>

1. <strong>Исполнение запроса&#58;</strong>

    - <strong>Описание&#58;</strong> Сформированный SQL-запрос отправляется в базу данных для выполнения.

    - Пример&#58; перечисление LINQ-запроса или ToListAsync() заставляет EF Core отправить SQL и материализовать результаты. ExecuteSqlRaw служит для отдельного выполнения SQL-команд и не является внутренним шагом LINQ-запроса.

#### Используемые компоненты&#58;

- <strong>LINQ&#58;</strong> Для написания запросов на C#.

- <strong>Expression Trees&#58;</strong> Для представления структуры запроса.

- <strong>LINQ Provider&#58;</strong> Для генерации SQL-запросов.

- <strong>Entity Framework&#58;</strong> Для взаимодействия с базой данных и
  выполнения запросов.

:::note[Ссылки для изучения]

1. [Введение в Entity Framework Core](https://metanit.com/sharp/entityframeworkcore/1.1.php)
   :::

---

## <strong>Какие вы знаете уровни изоляции транзакций?</strong> [#q-14bee738d69b81f5a51ef32309403060]

Уровни изоляции транзакций&#58;

{/* prettier-ignore */}
1. <code>Read Uncommitted</code> <strong>(Чтение неподтвержденных данных)&#58;</strong>

    - <strong>Описание&#58;</strong> Транзакция может читать данные, измененные другими транзакциями, даже если они не завершены.

    - <strong>Проблемы&#58;</strong> Грязное чтение (dirty reads).

1. <code>Read Committed</code> <strong>(Чтение подтвержденных данных)&#58;</strong>

    - <strong>Описание&#58;</strong> Транзакция может читать только данные, которые были подтверждены другими транзакциями.

    - <strong>Проблемы&#58;</strong> Неповторяющееся чтение (non-repeatable reads).

1. <code>Repeatable Read</code> <strong>(Повторяемое чтение)&#58;</strong>

    - <strong>Описание&#58;</strong> Транзакция гарантирует, что данные, прочитанные однажды, не изменятся до ее завершения.

    - <strong>Проблемы&#58;</strong> Фантомное чтение (phantom reads).

1. <code>Serializable</code> <strong>(Сериализуемый)&#58;</strong>

    - Описание&#58; результат эквивалентен некоторому последовательному выполнению транзакций. Фактически они могут выполняться конкурентно; конфликт может привести к откату и необходимости повтора.

    - <strong>Проблемы&#58;</strong> Наиболее строгий уровень, исключает фантомные чтения, но может снижать производительность из-за блокировок.

:::note[Ссылки для изучения]

1. [Обзор плана выполнения](https://learn.microsoft.com/ru-ru/sql/relational-databases/performance/execution-plans?view=sql-server-ver16)
   :::
