База по базам данных. Для всех интересующихся

72ef27ba53dd3112191c98d23ef82068.jpg
  • Что такое база данных

  • Реляционные и нереляционные базы данных

  • SQL

  • Транзакций

  • ACID

  • Уровни изоляций

  • Индексы

  • NoSql

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

Что такое база данных

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

Помимо хранения база данных так же предоставляет возможности по добавлению, изменению, удалению и получению данных, разные СУБД подходят к этим операциям по разному, но если говорить глобально то у нас есть два основных типа, это реляционные и нереляционные базы данных, предлагаю поговорить о них по подробнее

Реляционные и нереляционные базы данных

Как я уже сказал, глобально все базы данных делятся на два типа это реляционные и нереляционные, разберем каждый из этих типов более подробно:

Реляционные:

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

  • Лучше подходят для хранения упорядоченных текстовых данных

  • Вторая особенность это язык SQL, каждая реляционная СУБД работает через посредством этого языка, он является декларативным языком программирования который и позволяет нам совершать наши операций с данными

  • Каждая реляционная база данных поддерживает такую вещь как индексы, к ним мы вернемся позже, а пока лишь скажу что они нужны для ускорения поиска

  • ACID, это акроним который говорит нам о том как нам стоит подходить к проектированию нашей бд

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

Нереляционные:

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

  • Так же язык запросов, у каждой нереляционки он может быть свой и нет единого стандарта, плюс нереляционки не всегда, но зачастую не поддерживают операций объединения, например Cassandra

  • Подходят для хранения данных в любом виде, а так же лучше работают с неупорядоченными данными

SQL

SQL — это язык запросов, применяемый в реляционных СУБД, с его помощью можно полностью манипулировать вашей базой данных, по своей сути sql это декларативный язык программирования и как и с любым другим ЯП, есть профессионалы, которые занимаются разработкой на нем.

Основные команды SQL:

CREATE — используется для создания чего либо, будь-то базы данных, или таблицы

UPDATE — используется для изменения каких-либо данных

DELETE — применяем для удаления

INSERT — служит для ставки данных

SELECT — Данная команда служит для поиска данных внутри нашей бд

Помимо данных команд SQL так же поддерживает операций объединения, такие как join, причем у нас есть несколько типов join-ов, сейчас рассмотрим их чуть более внимательно

  • inner join — выводит из таблиц только те данные которые подходят условию (в PostgreSQL который на данный момент является самой популярной реляционной субд, является дефолтным, а следовательно если не будет явно указан тип join в условий, то будет применен именно он)

  • left join — второй по популярности join который выводит результаты которые соответствуют условиям и все данные из левой таблицы

  • right join — по сути работает как left join только как понятно из названия, берет все данные из правой таблицы

  • outer join — выводит все данные из левой и правой таблиц

  • cross join — наверное самый не очевидный и мало используемый join, суть в том что он создает таблицу с декартовым произведением двух таблиц со всеми возможными вариантами, поэтому если в итоговой таблице должно быть 3 записи, то он вернет 12, если 5 то 25

Транзакций

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

BEGIN;
UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice'; SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Wally'; COMMIT;

В данном примере мы видим, что любая транзакция начинается с команды BEGIN, после чего идут стандартные sql операций, а в конце идет команда COMMIT . Идея заключается в том что если во время выполнения данных команд произойдет какая-то ошибка, то все предыдущие изменения не сохранятся

Так же есть возможность откатить транзакцию командой ROLLBACK

ACID

ACID — это акроним, каждая буква которого говорит нам, каким именно способом нам надо подходить к построению нашей БД. Каждая буква несет определенное правило, соблюдение которого является в наше время обязательным для построения надежной базы

A — атомарность, говорит о том что все транзакций в бд должны быть атомарны, то есть не должны зависеть друг от друга

C — консистентность, данные внутри нашей базы должны быть консистентны, то есть не должно быть такого что сохранилась только часть наших данных, скажем у нас есть 3 колонки внутри таблицы, пользователь решил зарегистрироваться, но что-то произошло и в результате сохранилось только ID и имя, но не сохранилась почта, для этого как раз мы и должны применять транзакций

I — изолированность, все операций внутри нашей бд должны выполнятся изолированно, одна операция никак не должна задевать другую, для этого мы применяем уровни изоляций

D — надежность, означает что если пользователь получил подтверждение об успешном выполнении какой-то операций, то эта операция 100% должна быть выполнена

Уровни изоляции

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

  1. Uncommited read — первый уровень изоляции, который позволяет читать любые данные из бд, его главная проблема в том что сразу после чтения данных, может завершится какая-то транзакция и следовательно, пользователь получит не актуальные данные. Именно этот уровень изоляции не поддерживается в postgres в документаций это явно указано и даже если пользователь попытается явно его выполнить, postgres это проигнорирует и автоматически выполнит следующий уровень

  2. Commited read — данный уровень изоляции отличается от первого тем что читает только те данные по которым были закомичены транзакций, в целом он уже в большинстве случаев позволяет избежать проблемы грязного чтения, однако транзакция всегда может быть откачена

  3. Repeateble read — В отличий от первых двух, как следует из названия читает данные два раза, позволяет избежать проблемы грязного чтения, однако не может обезопасить нас от фантомного чтения, это когда транзакция в ходе выполнения выбирает несколько строк по одним и тем же критериям, но при этом приходит к разному результату

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

Индексы

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

Существует несколько основных типов индексов, первый из которых это B-tree

B-Tree — это сбалансированное дерево, самый популярный на данный момент индекс, у которого логарифмическая скорость поиска, а так же он поддерживает операций неравенства, однако важно помнить что индекс работает хорошо до первого неравенства в условий, после чего начинается поиск через стандартный sequesn scan или же перебор, так же является дефолтным в postgres и если при созданий индекса явно не указать какой индекс мы хотим использовать, то автоматически создастся именно он

Скорость у данного индекса достигается как раз за счет хорошей балансировки дерева, из-за чего на каждом уровне этого дерева у нас отрезается достаточно большая часть данных, из-за чего конечная скорость поиска становится O (log^n). Однако важно помнить, что у искомых данных должна быть высокая селективность, другими словами чем больше уникальных данных для поиска в условий тем быстрее и лучше будут работать индексы, а если мы скажем будем делать поиск по полю у которого значение может быть либо 0 либо 1, то в таких случаях наша база может даже деградировать по скорости, так-как ей придется опрашивать не только саму таблицу, но и индекс, далее важно помнить следующее, чем меньше данных будет возвращаться в конечном итоге тем лучше покажет себя индекс, поэтому если ваша бд должна возвращать скажем 1 мл записей, скорее всего индексы вам не помогут.

Следующий индекс который мы разберем это Hash, в отличий от b-tree он является колоночным индексом и поддерживает только операцию равенства, однако в ряде случаев за счет того что поиск по хэшу у нас является в лучшем случае O (1) , а в худшем O (n), может на определенных условиях показывать себя лучше чем b-tree, однако перед его использованием необходимо все взвесить, ибо накосячить с ним гораздо легче

Далее идут специализированные индексы, такие как GiST, GIN и SP-GiST, не будем на них подробно останавливаться, так-как эти индексы являются достаточно редкими и люди которые их используют, хорошо понимают как работают деревья, графы и тд

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

NoSql

Все это время мы говорил про классические реляционные базы данных, однако в конце хочется пару слов так же сказать и о нереляционках.

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

Самыми популярными NoSql базами на данный момент являются:

  • MongoDB — хранит данные в bson формате, по своей сути напоминает json, однако позволяет хранить данные в date формате, а так же бинарные файлы

  • Redis — самая популярная бд используемая для кэша, хранит данные в оперативной памяти, за счет чего обеспечивает быстрый доступ к данным, но потерять из нее данные гораздо легче чем из обычной базы

  • Clickhouse — разработана Яндексом и служит для хранения информации о действиях пользователя на сайте

  • Cassandra — используется для хранения больших данных, за счет высокой скорости и легкости масштабирования

Итог

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

Habrahabr.ru прочитано 1548 раз