# Cобеседование по Java. Разбор вопросов и ответов.


<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
    <img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />        
  </a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
    <img src="https://mc.yandex.ru/watch/92801430" />        
  </a>&nbsp;&nbsp;


Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.

Если вам интересно мое резюме: https://github.com/DEBAGanov


Нормализация: https://support.microsoft.com/ru-ru/help/283878/description-of-the-database-normalization-basics

Заметки: https://docs.google.com/document/d/1QXEv9hnVRFHaPlPMF3CEIaxL8dQrWYx4MI5PLLj14Cc/edit

# Базы данных
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Базы данных](#базы-данных)
  - [Что такое _«база данных»_?](#что-такое-база-данных)
  - [Что такое _«система управления базами данных»_?](#что-такое-система-управления-базами-данных)
  - [Что такое _«реляционная модель данных»_?](#что-такое-реляционная-модель-данных)
  - [Дайте определение терминам _«простой»_, _«составной» (composite)_, _«потенциальный» (candidate)_, _«альтернативный» (alternate)_, _«естественный»_ и _«сурогатный ключ»_.](#дайте-определение-терминам-простой-составной-composite-потенциальный-candidate-альтернативный-alternate-естественный-и-сурогатный-ключ)
  - [Что такое _«первичный ключ» (primary key)_? Каковы критерии его выбора?](#что-такое-первичный-ключ-primary-key-каковы-критерии-его-выбора)
  - [Что такое _«внешний ключ» (foreign key)_?](#что-такое-внешний-ключ-foreign-key)
  - [Что такое _«нормализация»_?](#что-такое-нормализация)
  - [Какие существуют нормальные формы?](#какие-существуют-нормальные-формы)
  - [Что такое _«денормализация»_? Для чего она применяется?](#что-такое-денормализация-для-чего-она-применяется)
  - [Какие существуют типы связей в базе данных? Приведите примеры.](#какие-существуют-типы-связей-в-базе-данных-приведите-примеры)
  - [Что такое _«индексы»_? Для чего их используют? В чём заключаются их преимущества и недостатки?](#что-такое-индексы-для-чего-их-используют-в-чём-заключаются-их-преимущества-и-недостатки)
  - [Какие типы индексов существуют?](#какие-типы-индексов-существуют)
  - [В чем отличие между кластерными и некластерными индексами?](#в-чем-отличие-между-кластерными-и-некластерными-индексами)
  - [Имеет ли смысл индексировать данные, имеющие небольшое количество возможных значений?](#имеет-ли-смысл-индексировать-данные-имеющие-небольшое-количество-возможных-значений)
  - [Когда полное сканирование набора данных выгоднее доступа по индексу?](#когда-полное-сканирование-набора-данных-выгоднее-доступа-по-индексу)
  - [Что такое _«транзакция»_?](#что-такое-транзакция)
  - [Требования к транзакциям.](#требования-к-транзакциям)
  - [Какие существуют уровни изолированности транзакций?](#какие-существуют-уровни-изолированности-транзакций)
  - [Какие проблемы могут возникать при параллельном доступе с использованием транзакций?](#какие-проблемы-могут-возникать-при-параллельном-доступе-с-использованием-транзакций)
  - [Cup теорема](#cup-теорема)
- [Источники](#источники)

## Что такое _«база данных»_?
__База данных__ — организованный и адаптированный для обработки вычислительной системой набор информации.

[к оглавлению](#Базы-данных)

## Что такое _«система управления базами данных»_?
__Система управления базами данных (СУБД)__ - набор средств общего или специального назначения, обеспечивающий создание, доступ к материалам и управление базой данных.

Основные функции СУБД:

+ управление данными
+ журнализация изменений данных
+ резервное копирование и восстановление данных;
+ поддержка языка определения данных и манипулирования ими.

[к оглавлению](#Базы-данных)

## Что такое _«реляционная модель данных»_?
__Реляционная модель данных__ — это логическая модель данных и прикладная теория построения реляционных баз данных. Термин «реляционный» означает, что теория основана на математическом понятии отношение (relation), которая формально определяет свойства различных объектов и их взаимосвязи.

Реляционная модель данных включает в себя следующие компоненты:

+ _Структурный аспект_ — данные представляют собой набор отношений.
+ _Аспект целостности_ — отношения отвечают определенным условиям целостности: уровня домена (типа данных), уровня отношения и уровня базы данных.
+ _Аспект обработки (манипулирования)_ — поддержка операторов манипулирования отношениями (реляционная алгебра, реляционное исчисление).
+ _Нормальная форма_ - свойство отношения в реляционной модели данных, характеризующее его с точки зрения избыточности и определённое как совокупность требований, которым должно удовлетворять отношение.

[к оглавлению](#Базы-данных)

## Дайте определение терминам _«простой»_, _«составной» (composite)_, _«потенциальный» (candidate)_, _«альтернативный» (alternate)_, _«естественный»_ и _«сурогатный ключ»_.
__Простой ключ__ состоит из одного атрибута (поля). __Составной__ - из двух и более.

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

Из множества всех потенциальных ключей набора данных выбирают первичный ключ, все остальные ключи называют __альтернативными__.

__Естественный Ключ__ – набор атрибутов описываемой записью сущности, уникально её идентифицирующий (например, номер паспорта для человека)

__Суррогатный Ключ__ – автоматически сгенерированное поле, никак не связанное с информационным содержанием записи. Обычно в роли СК выступает автоинкрементное поле типа INTEGER.

[к оглавлению](#Базы-данных)

## Что такое _«первичный ключ» (primary key)_? Каковы критерии его выбора?
__Первичный ключ (primary key)__ уникальный идентификатор записи в табице. В реляционной модели данных один из _потенциальных ключей_ отношения, выбранный в качестве основного ключа (ключа по умолчанию).

Если в отношении имеется единственный потенциальный ключ, он является и первичным ключом. Если потенциальных ключей несколько, один из них выбирается в качестве первичного, а другие называют _«альтернативными»_.

В качестве первичного обычно выбирается тот из потенциальных ключей, который наиболее удобен. Поэтому в качестве первичного ключа, как правило, выбирают тот, который имеет наименьший размер (физического хранения) и/или включает наименьшее количество атрибутов. Другой критерий выбора первичного ключа — сохранение его уникальности со временем. Поэтому в качестве первичного ключа стараются выбирать такой потенциальный ключ, который с наибольшей вероятностью никогда не утратит уникальность.

[к оглавлению](#Базы-данных)

## Что такое _«внешний ключ» (foreign key)_?
__Внешний ключ (foreign key)__ — подмножество атрибутов некоторого отношения A, значения которых должны совпадать со значениями некоторого потенциального ключа некоторого отношения B.

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

[к оглавлению](#Базы-данных)

## Что такое _«нормализация»_?
_Нормализация_ - процесс замены исходной схемы другой схемой, в которой наборы данных имеют более простую и логичную структуру.

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

[к оглавлению](#Базы-данных)

## Какие существуют нормальные формы?
__Первая нормальная форма (1NF)__ - Отношение находится в 1NF, если значения всех его атрибутов атомарны (неделимы). 
+ В каждой ячейке таблицы должно находиться только 1 значение.
+ Строки не должны повторяться

__Вторая нормальная форма (2NF)__ - Отношение находится в 2NF, если оно находится в 1NF, и при этом все неключевые атрибуты зависят только от ключа целиком, а не от какой-то его части. Чтобы привести таблицу в 2NF необходимо ее декомпозировать на несколько зависящих друг от друга.
+ Таблица в 1NF.
+ Все атрибуты зависят целиком от primary key,а не от его части.

__Третья нормальная форма (3NF)__ - Отношение находится в 3NF, если оно находится в 2NF и все неключевые атрибуты не зависят друг от друга.
+ Таблица в 2NF. 
+ Все атрибуты зависят только от primary key, но не от других атрибутов.

__Четвёртая нормальная форма (4NF)__ - Отношение находится в 4NF , если оно находится в 3NF и если в нем не содержатся независимые группы атрибутов, между которыми существует отношение «многие-ко-многим».
+ Таблица в 3NF. 
+ Ключевые атрибуты не должны зависеть от неключевых.

__Пятая нормальная форма (5NF)__ - Отношение находится в 5NF, когда каждая нетривиальная зависимость соединения в ней определяется потенциальным ключом (ключами) этого отношения.

__Шестая нормальная форма (6NF)__ - Отношение находится в 6NF, когда она удовлетворяет всем нетривиальным зависимостям соединения, т.е. когда она неприводима, то есть не может быть подвергнута дальнейшей декомпозиции без потерь. Каждая переменная отношения, которая находится в 6NF, также находится и в 5NF. Введена как обобщение пятой нормальной формы для хронологической базы данных.

__Нормальная форма Бойса-Кодда, усиленная 3 нормальная форма (BCNF)__ - Отношение находится в BCNF, когда каждая её нетривиальная и неприводимая слева функциональная зависимость имеет в качестве своего детерминанта некоторый потенциальный ключ.

__Доменно-ключевая нормальная форма (DKNF)__ -  Отношение находится в DKNF, когда каждое наложенное на неё ограничение является логическим следствием ограничений доменов и ограничений ключей, наложенных на данное отношение.

[к оглавлению](#Базы-данных)

## Что такое _«денормализация»_? Для чего она применяется?
__Денормализация базы данных__ — это процесс осознанного приведения базы данных к виду, в котором она не будет соответствовать правилам нормализации. Обычно это необходимо для повышения производительности и скорости извлечения данных, за счет увеличения избыточности данных.

[к оглавлению](#Базы-данных)

## Какие существуют типы связей в базе данных? Приведите примеры.
+ __OneToOne ОдинКОдному__ - любому значению атрибута А соответствует только одно значение атрибута В, и наоборот.

>Каждый университет гарантированно имеет 1-го ректора: _1 университет → 1 ректор_.

+ __OneToMany ОдинКоМногим__ - любому значению атрибута А соответствует 0, 1 или несколько значений атрибута В.

>В каждом университете есть несколько факультетов: _1 университет → много факультетов_.

+ __ManyToOne МногиеКОдному__ - связь многие к одному, обратная связь для OneToMany

>Многие университеты находятся в одном городе.

+ __МногиеКоМногим__ - любому значению атрибута А соответствует 0, 1 или несколько значений атрибута В, и любому значению атрибута В соответствует 0, 1 или несколько значение атрибута А.

>1 профессор может преподавать на нескольких факультетах, в то же время на 1-ом факультете может преподавать несколько профессоров: _Несколько профессоров ↔ Несколько факультетов_.

Каждую из которых можно разделить еще на два вида:
+ Bidirectional (пер. - Двунаправленный) - две связи
+ Unidirectional (пер. - Однонаправленный ) — ссылка на связь устанавливается у всех Entity, то есть в случае OneToOne A-B в Entity A есть ссылка на Entity B, в Entity B есть ссылка на Entity A, Entity A считается владельцем этой связи (это важно для случаев каскадного удаления данных, тогда при удалении A также будет удалено B, но не наоборот).Unidirectional - ссылка на связь устанавливается только с одной стороны, то есть в случае OneToOne A-B только у Entity A будет ссылка на Entity B, у Entity B ссылки на A не будет.

[к оглавлению](#Базы-данных)

## Что такое _«индексы»_? Для чего их используют? В чём заключаются их преимущества и недостатки?
__Индекс (index)__ — объект базы данных (отдельная таблица), создаваемый с целью повышения производительности выборки данных. Как закладка у книги.

Наборы данных могут иметь большое количество записей, которые хранятся в произвольном порядке, и их поиск по заданному критерию путём последовательного просмотра набора данных запись за записью может занимать много времени. Индекс формируется из значений одного или нескольких полей и указателей на соответствующие записи набора данных, - таким образом, достигается значительный прирост скорости выборки из этих данных.

```java
CREATE INDEX имя_индекса ON имя_таблицы;
```

Преимущества

+ ускорение поиска и сортировки по определенному полю или набору полей.
+ обеспечение уникальности данных.

Недостатки 

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

Индексы предпочтительней для:

+ Поля-счетчика, чтобы в том числе избежать и повторения значений в этом поле;
+ Поля, по которому проводится сортировка данных;
+ Полей, по которым часто проводится соединение наборов данных. Поскольку в этом случае данные располагаются в порядке возрастания индекса и соединение происходит значительно быстрее;
+ Поля, которое объявлено первичным ключом (primary key);
+ Поля, в котором данные выбираются из некоторого диапазона. В этом случае как только будет найдена первая запись с нужным значением, все последующие значения будут расположены рядом.
 
Использование индексов нецелесообразно для:

+ Полей, которые редко используются в запросах;
+ Полей, которые содержат всего два или три значения, например: _мужской_,  _женский пол_ или значения _«да»_, _«нет»_.

[к оглавлению](#Базы-данных)

## Какие типы индексов существуют?

__По порядку сортировки__
+ _упорядоченные_ — индексы, в которых элементы упорядочены;
+ _возрастающие_;
+ _убывающие_;
+ _неупорядоченные_ — индексы, в которых элементы неупорядочены.

__По источнику данных__
+ _индексы по представлению (view)_;
+ _индексы по выражениям_.

__По воздействию на источник данных__
+ _кластерный индекс_ - при определении в наборе данных физическое расположение данных перестраивается в соответствии со структурой индекса. Логическая структура набора данных в этом случае представляет собой скорее словарь, чем индекс. Данные в словаре физически упорядочены, например по алфавиту. Кластерные индексы могут дать существенное увеличение производительности поиска данных даже по сравнению с обычными индексами. Увеличение производительности особенно заметно при работе с последовательными данными.
+ _некластерный индекс_ — наиболее типичные представители семейства индексов. В отличие от кластерных, они не перестраивают физическую структуру набора данных, а лишь организуют ссылки на соответствующие записи. Для идентификации нужной записи в наборе данных некластерный индекс организует специальные указатели, включающие в себя: информацию об идентификационном номере файла, в котором хранится запись; идентификационный номер страницы соответствующих данных; номер искомой записи на соответствующей странице; содержимое столбца.

__По структуре__
+ _B*-деревья_;
+ _B+-деревья_;
+ _B-деревья_;
+ _Хэши_.

__По количественному составу__
+ _простой индекс (индекс с одним ключом)_ — строится по одному полю;
+ _составной (многоключевой, композитный) индекс_ — строится по нескольким полям при этом важен порядок их следования;
+ _индекс с включенными столбцами_ — некластеризованный индекс, дополнительно содержащий кроме ключевых столбцов еще и неключевые;
+ _главный индекс (индекс по первичному ключу)_ — это тот индексный ключ, под управлением которого в данный момент находится набор данных. Набор данных не может быть отсортирован по нескольким индексным ключам одновременно. Хотя, если один и тот же набор данных открыт одновременно в нескольких рабочих областях, то у каждой копии набора данных может быть назначен свой главный индекс.

__По характеристике содержимого__
+ _уникальный индекс_ состоит из множества уникальных значений поля;
+ _плотный индекс_ (NoSQL) — индекс, при котором, каждом документе в индексируемой коллекции соответствует запись в индексе, даже если в документе нет индексируемого поля.
+ _разреженный индекс_ (NoSQL) — тот, в котором представлены только те документы, для которых индексируемый ключ имеет какое-то определённое значение (существует).
+ _пространственный индекс_ — оптимизирован для описания географического местоположения. Представляет из себя многоключевой индекс состоящий из широты и долготы.
+ _составной пространственный индекс_ — индекс, включающий в себя кроме широты и долготы ещё какие-либо мета-данные (например теги). Но географические координаты должны стоять на первом месте.
+ _полнотекстовый (инвертированный) индекс_ — словарь, в котором перечислены все слова и указано, в каких местах они встречаются. При наличии такого индекса достаточно осуществить поиск нужных слов в нём и тогда сразу же будет получен список документов, в которых они встречаются.
+ _хэш-индекс_ предполагает хранение не самих значений, а их хэшей, благодаря чему уменьшается размер (а, соответственно, и увеличивается скорость их обработки) индексов из больших полей. Таким образом, при запросах с использованием хэш-индексов, сравниваться будут не искомое со значения поля, а хэш от искомого значения с хэшами полей.
Из-за нелинейнойсти хэш-функций данный индекс нельзя сортировать по значению, что приводит к невозможности использования в сравнениях больше/меньше и «is null». Кроме того, так как хэши не уникальны, то для совпадающих хэшей применяются методы разрешения коллизий.
+ _битовый индекс (bitmap index)_ — метод битовых индексов заключается в создании отдельных битовых карт (последовательностей 0 и 1) для каждого возможного значения столбца, где каждому биту соответствует запись с индексируемым значением, а его значение равное 1 означает, что запись, соответствующая позиции бита содержит индексируемое значение для данного столбца или свойства.
+ _обратный индекс (reverse index)_ — B-tree индекс, но с реверсированным ключом, используемый в основном для монотонно возрастающих значений (например, автоинкрементный идентификатор) в OLTP системах с целью снятия конкуренции за последний листовой блок индекса, т.к. благодаря переворачиванию значения две соседние записи индекса попадают в разные блоки индекса. Он не может использоваться для диапазонного поиска.
+ _функциональный индекс, индекс по вычисляемому полю (function-based index)_ — индекс, ключи которого хранят результат пользовательских функций. Функциональные индексы часто строятся для полей, значения которых проходят предварительную обработку перед сравнением в команде SQL. Например, при сравнении строковых данных без учета регистра символов часто используется функция UPPER. Кроме того, функциональный индекс может помочь реализовать любой другой отсутствующий тип индексов данной СУБД.
+ _первичный индекс_ — уникальный индекс по полю первичного ключа.
+ _вторичный индекс_ — индекс по другим полям (кроме поля первичного ключа).
+ _XML-индекс_ — вырезанное материализованное представление больших двоичных XML-объектов (BLOB) в столбце с типом данных xml.

__По механизму обновления__
+ _полностью перестраиваемый_ — при добавлении элемента заново перестраивается весь индекс.
+ _пополняемый (балансируемый)_ — при добавлении элементов индекс перестраивается частично (например одна из ветви) и периодически балансируется.

__По покрытию индексируемого содержимого__
+ _полностью покрывающий (полный) индекс_ — покрывает всё содержимое индексируемого объекта.
+ _частичный индекс (partial index)_ — это индекс, построенный на части набора данных, удовлетворяющей определенному условию самого индекса. Данный индекс создан для уменьшения размера индекса.
+ _инкрементный (delta) индекс_ — индексируется малая часть данных(дельта), как правило, по истечении определённого времени. Используется при интенсивной записи. Например, полный индекс перестраивается раз в сутки, а дельта-индекс строится каждый час. По сути это частичный индекс по временной метке.
+ _индекс реального времени (real-time index)_ — особый вид инкрементного индекса, характеризующийся высокой скоростью построения. Предназначен для часто меняющихся данных.

__Индексы в кластерных системах__
+ _глобальный индекс_ — индекс по всему содержимому всех сегментов БД (shard).
+ _сегментный индекс_ — глобальный индекс по полю-сегментируемому ключу (shard key). Используется для быстрого определения сегмента, на котором хранятся данные в процессе маршрутизации запроса в кластере БД.
+ _локальный индекс_ —  индекс по содержимому только одного сегмента БД.

[к оглавлению](#Базы-данных)

## В чем отличие между кластерными и некластерными индексами?
Некластерные индексы - данные физически расположены в произвольном порядке, но логически упорядочены согласно индексу. Такой тип индексов подходит для часто изменяемого набора данных.

При кластерном индексировании данные физически упорядочены, что серьезно повышает скорость выборок данных (но только в случае последовательного доступа к данным). Для одного набора данных может быть создан только один кластерный индекс.

[к оглавлению](#Базы-данных)

## Имеет ли смысл индексировать данные, имеющие небольшое количество возможных значений?
Примерное правило, которым можно руководствоваться при создании индекса - если объем информации (в байтах) НЕ удовлетворяющей условию выборки меньше, чем размер индекса (в байтах) по данному условию выборки, то в общем случае оптимизация приведет к замедлению выборки.

[к оглавлению](#Базы-данных)

## Когда полное сканирование набора данных выгоднее доступа по индексу?
Полное сканирование производится многоблочным чтением. Сканирование по индексу - одноблочным. Также, при доступе по индексу сначала идет сканирование самого индекса, а затем чтение блоков из набора данных. Число блоков, которые надо при этом прочитать из набора зависит от фактора кластеризации. Если суммарная стоимость всех необходимых одноблочных чтений больше стоимости полного сканирования многоблочным чтением, то полное сканирование выгоднее и оно выбирается оптимизатором.

Таким образом, полное сканирование выбирается при слабой селективности предикатов зароса и/или слабой кластеризации данных, либо в случае очень маленьких наборов данных.

[к оглавлению](#Базы-данных)

## Что такое _«транзакция»_?
__Транзакция__ - это воздействие на базу данных, переводящее её из одного целостного состояния в другое и выражаемое в изменении данных, хранящихся в базе данных.

[к оглавлению](#Базы-данных)

## Требования к транзакциям.
Требования, для наиболее эфективной и безопасной работы транзакций.

__Атомарность (atomicity)__ гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. 

__Согласованность (consistency)__ требование, подразумевающее, что в результате работы транзакции данные будут допустимыми. Это вопрос не технологии, а бизнес-логики: например, если количество денег на счете не может быть отрицательным, логика транзакции должна проверять, не выйдет ли в результате отрицательных значений.

__Изолированность (isolation)__. Во время выполнения транзакции параллельные транзакции не должны оказывать влияние на её результат.

__Долговечность (durability)__. Независимо от проблем на нижних уровнях изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. Другими словами, если пользователь получил подтверждение от системы, что транзакция выполнена, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.

[к оглавлению](#Базы-данных)

## Какие существуют уровни изолированности транзакций?
В порядке увеличения изолированности транзакций и, соответственно, надёжности работы с данными:

+ __Чтение незавершенных транзакций (read uncommitted)__ — чтение незафиксированных изменений как своей транзакции, так и параллельных транзакций. Если несколько параллельных транзакций пытаются изменять одну и ту же строку таблицы, то в окончательном варианте строка будет иметь значение, определенное всем набором успешно выполненных транзакций. Гарантирует только отсутствие потерянных обновлений.

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

+ __Чтение завершенных транзакций (read committed)__ — На этом уровне обеспечивается защита от чернового, «грязного» чтения, тем не менее, в процессе работы одной транзакции другая может быть успешно завершена и сделанные ею изменения зафиксированы. В итоге первая транзакция будет работать с другим набором данных. По умолчанию в MySql и PostgreSQL

Работает либо через __Блокирование читаемых и изменяемых данных__, т.е. пишущая транзакция блокирует изменяемые данные для читающих транзакций, работающих на уровне read committed или более высоком, до своего завершения, препятствуя, таким образом, «грязному» чтению, а данные, блокируемые читающей транзакцией, освобождаются сразу после завершения операции SELECT (таким образом, ситуация «неповторяющегося чтения» может возникать на данном уровне изоляции). 

Либо __Сохранение нескольких версий параллельно изменяемых строк__, т.е. при каждом изменении строки СУБД создаёт новую версию этой строки, с которой продолжает работать изменившая данные транзакция, в то время как любой другой «читающей» транзакции возвращается последняя зафиксированная версия. Преимущество такого подхода в том, что он обеспечивает бо́льшую скорость, так как предотвращает блокировки. Однако он требует, по сравнению с первым, существенно бо́льшего расхода оперативной памяти, которая тратится на хранение версий строк. Кроме того, при параллельном изменении данных несколькими транзакциями может создаться ситуация, когда несколько параллельных транзакций произведут несогласованные изменения одних и тех же данных (поскольку блокировки отсутствуют, ничто не помешает это сделать). Тогда та транзакция, которая зафиксируется первой, сохранит свои изменения в основной БД, а остальные параллельные транзакции окажется невозможно зафиксировать (так как это приведёт к потере обновления первой транзакции). Единственное, что может в такой ситуации СУБД — это откатить остальные транзакции и выдать сообщение об ошибке «Запись уже изменена».

+ __Повторяемость чтения (repeatable read)__ — Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена.

Блокировки в разделяющем режиме применяются ко всем данным, считываемым любой инструкцией транзакции, и сохраняются до её завершения. Это запрещает другим транзакциям изменять строки, которые были считаны незавершённой транзакцией. Однако другие транзакции могут вставлять новые строки, соответствующие условиям поиска инструкций, содержащихся в текущей транзакции. При повторном запуске инструкции текущей транзакцией будут извлечены новые строки, что приведёт к фантомному чтению. Учитывая то, что разделяющие блокировки сохраняются до завершения транзакции, а не снимаются в конце каждой инструкции, степень параллелизма ниже, чем при уровне изоляции READ COMMITTED. Поэтому пользоваться данным и более высокими уровнями транзакций без необходимости обычно не рекомендуется.  
+ __Упорядочиваемость (serializable)__ — Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует, а они работают последовательно Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения».

Не все СУБД поддерживают все 4 вышеперечисленных уровня изолированности, а некоторые СУБД вводят дополнительные уровни.

[к оглавлению](#Базы-данных)

## Какие проблемы могут возникать при параллельном доступе с использованием транзакций?
При параллельном выполнении транзакций возможны следующие проблемы:

+ __Потерянное обновление (lost update)__ — когда две транзакции записывают разные значения в одну и ту же ячейку, одно из изменений теряется;
+ __«Грязное» чтение (dirty read)__ — когда читаются данные, которые в этот момент изменяются транзакцией, а потом транзакция откатывается и данные исчезают. В MySQl решается Read Uncommitted, в PostgreSQL - не поддерживается вообще  
+ __Неповторяющееся чтение (non-repeatable read)__ — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками меняет или удаляет данные, используемых в критериях выборки первой транзакции, и успешно заканчивается. Из-за этого результаты выборки в первой транзакции будут разными.
+ __Фантомное чтение (phantom reads)__ — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками добавляет новые данные, используемых в критериях выборки первой транзакции, и успешно заканчивается. От неповторяющегося чтения оно отличается тем, что результат повторного обращения к данным изменился не из-за изменения/удаления самих этих данных, а из-за появления новых (фантомных) данных.

[к оглавлению](#Базы-данных)

## Cup теорема
Она гласит, что в распределенной системе можно обеспечить только два свойства из трех: согласованность, доступность и устойчивость к разделению. Помогает понимать, как конкретная распределенная система будет работать и какую систему базы данных (например Postgresql или MySql) лучше выбрать. Однако многими учёными и практиками теорема CAP критикуется за вольность трактовки и даже недостоверность.

__Согласованность данных (consistency)__
Когда во всех узлах в каждый момент времени данные согласованы друг с другом, то есть не противоречат друг другу. Если в одном из узлов в ячейке базы данных есть данные, такие же данные есть на всех остальных узлах.

__Доступность (availability)__
Когда любой запрос может быть обработан системой, вне зависимости от ее состояния.

__Устойчивость к разделению (partition tolerance)__
Когда расщепление системы на несколько изолированных секций не приводит к некорректному отклику от каждой из секций: отвалилась сеть между двумя узлами, но каждый из них может корректно отвечать своим клиентам.

# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/)
+ [tokarchuk.ru](http://tokarchuk.ru/2012/08/indexes-classification/)
+ [Quizful](http://www.quizful.net/interview/sql/)

[Вопросы для собеседования](README.md)
