Skip to main content

Теория

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

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

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

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

Введение

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

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

В первой колонке указывался номер записи, в последующих - сами данные. В базах данных эта колонка, однозначно определяющая запись(строку таблицы), называется id(identification number) - идентификационный номер. Правда, в современном программировании id может быть вообще любыми уникальными данными. Чаще всего вместо числа в id используется просто строка. Id ещё называется ключом. Столбцы таблицы называются полями, а строки – записями.

Табличный способ хранения данных называется SQL(Structured Query Language) - язык структурированных запросов. Самое распространённое решение - это Postgresql.

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

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

Связывание таблиц

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

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

Результаты
idфамилияИмяОценка
0ИвановСергей4
1СидоровПавел4
2ПетровАлександр5

По такой таблице можно всегда определить, какая оценка у того или иного ученика.

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

Здесь нам как раз пригодится id. Ведь у каждой записи он уникален. Тогда можно переделать нашу таблицу следующим образом:

Результаты
idфамилияИмяid работы
0ИвановСергей6
1СидоровПавел7
2ПетровАлександр9

Ответы учеников поместим в другую таблицу.

Работы
idЗадание 1Задание 2Задание 3Оценка
610qwerty202
711qwerty201
911qwerty202

в поле id работы я специально указал другие значения, чтобы не путать их с id результата. Хотя в реальных базах при добавлении поле id заполняется автоматически первым свободным значением после последнего заданного. Соответственно, если бы мы в пустую базу данных добавили записи, то их id были бы 0, 1, 2 и т.д.

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

Работы
idЗадание 1Задание 2Задание 3Оценка
610qwerty2024
711qwerty2014
911qwerty2025

Отношение между результатами и соответствующими работами называется Один ко многим(OneToMany).

После выставления оценок мы можем по этим двум таблицам определить, какую оценку получил тот или иной ученик

Результаты
idфамилияИмяid работы
0ИвановСергей6
1СидоровПавел7
2ПетровАлександр9

Например, если мы хотим узнать, какую оценку получил Павел Сидоров, нам необходимо в его записи найти id работы, он равен 7 и в таблице работ найти запись с соответствующим id:

idЗадание 1Задание 2Задание 3Оценка
711qwerty2025

Оценка равна 5.

Расширим задачу. Предположим, что каждый ученик может сдавать несколько работ, а оценку надо выставить по лучшему результату. Можно было бы искать все записи с заданными именем и фамилией, но это - неоптимальное решение. Тем более, если данных об ученике будет больше, то тогда мы будем хранить много дублирующейся информации.
Такое отношение между результатами и соответствующими работами называется Многие ко многим(ManyToMany).

Лучше перестроить логику базы данных так, чтобы в таблице результатов указывался не ученик, а id его записи в таблице учеников. Id учеников я тоже задам не 0, 1, 2, а 10, 11, 12. Это сделано для того, чтобы избежать путаницы.

Переделаем таблицы:

Ученики
idфамилияИмяКласс
10ИвановСергей11
11СидоровПавел11
12ПетровАлександр10

В таблицу учеников я добавил поле класс.

Таблица результатов теперь будет выглядеть

Результаты
idid ученикаid работы
0106
1117
2129
31010

Я добавил в таблицу результатов ещё одну запись. Она добавлен

Работы
idЗадание 1Задание 2Задание 3Оценка
610qwerty2024
711qwerty2024
911qwerty2025
1011qwerty2025

Теперь попробуем по трём таблицам: результаты, оценки, ученики вывести фамилии всех учеников, которые получили оценку 5 по лучшему результату.

В таблице работ пятёрка стоит в записях с id=9 и id=10.

В таблице результатов работе с id=9 соответствует запись

idid ученикаid работы
2129

По ней мы можем узнать id ученика и в таблице учеников найти нужного нам. Его id равен 12, это - Петров Александр

В таблице результатов работе с id=10 соответствует запись

idid ученикаid работы
31010

id ученика тоже равен 10, он принадлежит Иванову Сергею.

Диаграммы

Иногда связи показывают с помощью диаграмм

xor

В рассматриваемых нами в таблицах языков и городов хранятся коды(id) страны, также в таблице городов содержится код(id) столицы.

Хотя такое проектирование баз считается порочным, потому что зависимость получается циклической, тем не менее, в ЕГЭ вы легко можете встретить построения такого рода.

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

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