<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://www.wikicshse.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_2%2Fsimpledb</id>
	<title>Базы данных 2/simpledb - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://www.wikicshse.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_2%2Fsimpledb"/>
	<link rel="alternate" type="text/html" href="https://www.wikicshse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_2/simpledb&amp;action=history"/>
	<updated>2026-06-06T12:15:52Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://www.wikicshse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_2/simpledb&amp;diff=1989&amp;oldid=prev</id>
		<title>imported&gt;Ivsavin: Migrated current public revision from wiki.cs.hse.ru</title>
		<link rel="alternate" type="text/html" href="https://www.wikicshse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_2/simpledb&amp;diff=1989&amp;oldid=prev"/>
		<updated>2017-03-21T06:30:05Z</updated>

		<summary type="html">&lt;p&gt;Migrated current public revision from wiki.cs.hse.ru&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=== Задания ===&lt;br /&gt;
&lt;br /&gt;
====Задание 1====&lt;br /&gt;
&lt;br /&gt;
* В СУБД есть чтение доступных таблиц (схем) при старте сервера.&lt;br /&gt;
* При выполнении запроса создается (на данном шаге можно не парсить запрос, а забить предустановленные значения) QueryPlan с операцией чтения из таблицы. QueryPlan содержит операцию full_scan.&lt;br /&gt;
* BufferManager, получив QueryPlan, начинает считывать поблочно из файла с данными и формировать список кортежей для результата.&lt;br /&gt;
&lt;br /&gt;
Замечания:&lt;br /&gt;
&lt;br /&gt;
* В QueryResult атрибут schema указан как список, но на самом деле в результате выполнения запроса нужно иметь только одну схему.&lt;br /&gt;
* Для перехода к следующему блоку можно также использовать и смещение в текущем файле данных.&lt;br /&gt;
* Так как схема отношения уже определена, дополнительно не нужно хранить ее в блоках или картежах данных. Минимально достаточные данные в блоке: указатель/смещение на следующий блок, внутренняя таблица смещения кортежей, кортежи. В кортежах только данные. Для данных переменной длины (VARCHAR) допустимо использовать любой из методов хранения: указание в первом байте размера поля или указание управляющего символа в конце записи.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Задание до 14 февраля.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Если есть вопросы, то пишите на почту преподавателю: acccko@gmail.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Для сдачи задания используйте форму: https://goo.gl/forms/81yE6BcY7tZP3wVm2 &amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
====Задание 2====&lt;br /&gt;
* Реализовать вставку кортежей (формирование страниц) и запись страниц на диск. Для операции добавления нового кортежа достаточно считать в память последний страницу отношения (или реализовать поиск достаточного свободного места в страницах), добавить в него кортеж и записать страницу на диск.&lt;br /&gt;
* Реализовать поддержку В-дерева: операции добавление, удаление, поиск по дереву.&lt;br /&gt;
* Реализовать поддержку некластерного индекса (кластерного опционально)&lt;br /&gt;
&lt;br /&gt;
Замечания:&lt;br /&gt;
* Для вставки достаточно брать случайные данные, не парсить запрос. Например, исходя из того, встречается ли в запросе слово insert или select, выполнять операции добавления или выборки.&lt;br /&gt;
* Количество ссылок в узле/листе дерева определяется исходя из размера страницы на диске.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Информацию об индексах можно хранить в отдельном файле или файлах.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Задание до 1 марта.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Для сдачи задания используйте форму: https://goo.gl/forms/gWhAi0fkObLA1uov2&lt;br /&gt;
&lt;br /&gt;
====Задание 3====&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Парсинг запроса, составление плана. Возможно, будет пропущено.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
====Задание 4====&lt;br /&gt;
&lt;br /&gt;
Добавить менеджера транзакций, журнал и менеджера восстановления. Реализация поддержки транзакций.&lt;br /&gt;
&lt;br /&gt;
* Запись журнала в режиме undo/redo для списка запросов, обозначенных как одна транзакция&lt;br /&gt;
* Алгоритм восстановления по журналу&lt;br /&gt;
&lt;br /&gt;
Пояснения:&lt;br /&gt;
* Для обозначения транзакции нужно передать в BufferManager последовательно запросы: BEGIN, UPDATE ..., UPDATE ..., COMMIT. Можно использовать предустановленные результаты разбора запросов (не парсить). &lt;br /&gt;
* BufferManager прежде чем совершить запрос, должен обратиться к TransactionManager и передать ему запрос и идентификатор клиента (можно использовать номер треда). В свою очередь TransactionManager, получив команду BEGIN, должен зафиксировать начало транзакции и затем обрабатывать все последующие операции. Как только TransactionManager успешно выполнит свою работу с запросов, BufferManager может выполнять свои действия (саму операцию). Как только BufferManager выполнил операцию, он обращается к TransactionManager, чтобы тот мог завершить действия по логированию операции.&lt;br /&gt;
* Лог транзакций можно вести в текстовом виде, указывая простые команды типа START transaction_id, WRITE disk_address_to_field old_value new_value, COMMIT transaction_id&lt;br /&gt;
* Во время запуска сервера должна быть возможность указать, что этот запуск в режиме восстановления. При этом RecoverManager должен считать журнал и выполнить операции согласно алгоритму восстановления.&lt;br /&gt;
&lt;br /&gt;
Замечания:&lt;br /&gt;
* Механизм контрольных точек можно не реализовывать&lt;br /&gt;
* Файл журнала можно хранить там же где данные, например, в файле transactions.log&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Задание до 14 марта&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Для сдачи задания используйте форму: https://docs.google.com/forms/d/e/1FAIpQLSek7ffoAvyeErRCXFkong4dvpqKbV4OLJ8KkgJ1inePig2fGw/viewform?usp=sf_link&lt;br /&gt;
&lt;br /&gt;
====Задание 5====&lt;br /&gt;
&lt;br /&gt;
Параллельная обработка запросов.&lt;br /&gt;
&lt;br /&gt;
* Реализовать планировщик выполнения операций с блокированием: обработку транзакций перед отправкой к BufferManager для исполнения, таблицу блокировок с очередью из операций.&lt;br /&gt;
&lt;br /&gt;
Пояснения:&lt;br /&gt;
* Нужно добавить SchedulePlanner, получающий операции транзакций от TransactionManager, переформировывающий расписание операций, и отправляющий его в BufferManager. SchedulePlanner также должен использовать таблицу блокировок и очередь транзакций для блокировки конкретных элементов данных (кортежей или отношений).&lt;br /&gt;
* Используйте типы блокировок: shared, exclusive, update и сооветствующую матрицу возможностей блокировки.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Задание до 24 марта&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Для сдачи задания используйте форму: https://docs.google.com/forms/d/e/1FAIpQLSfEayeVldmsxDjk2NlSU7DaicnlSnJWWhj8LBE0ZpbAa0y3Nw/viewform?usp=sf_link&lt;br /&gt;
&lt;br /&gt;
=== Описание ===&lt;br /&gt;
&lt;br /&gt;
Описание пока что может отличаться от реального кода (какие-то взаимодействия еще не дописаны), но концепция скорее всего менять не будет.&lt;br /&gt;
&lt;br /&gt;
Есть Server (SocketServer), который может принять и обработать запрос (RequestHandler), затем отправить клиенту ответ.&lt;br /&gt;
Запрос предварительно парсится на: управляюдище команды, DDL, DML.&lt;br /&gt;
&lt;br /&gt;
Если управляющая команда, то запрос уходит в ControlManager (там можно завершить соединение с клиентом exit)&lt;br /&gt;
&lt;br /&gt;
Если DDL, то запрос отправляется в SchemaManager (там можно запросить список отношений с колонками и индексами, а в будущем создавать и удалять их).&lt;br /&gt;
&lt;br /&gt;
Если запрос DML, то отправляется в QueryManager, который парсит запрос (с помощью QueryParser) и возвращает QueryPlan (список операций, типы операций и отношения, над которыми нужно их делать). Пример операции: table1, full_scan, condition.&lt;br /&gt;
Результат работы QueryParser QueryManager отправляет в BufferManager, в котором происходят все операции. Если BufferManager нужны данные, которых нет в оперативной памяти, он используя SchemaManager отправляет запросы в DiskManager, который возвращает блоки с диска. Получив блоки (и записи в них) в BufferManager, тот считывает записи оттуда с помощью Row и отправляет наверх к QueryParser, тот в свою очередь отправляет результаты назад к CommandManager, который интерпретирует их и выводит в виде строки пользователю.&lt;br /&gt;
&lt;br /&gt;
При старте Server говорит SchemaManager, чтобы тот запустил свою инициализацию, по умолчанию это значит попросит BufferManager записать в оперативную мапять доступные схемы из файлов.&lt;br /&gt;
&lt;br /&gt;
SchemaManager работает с Schema, который состоит из Column, у которых есть название, тип и размер.&lt;br /&gt;
&lt;br /&gt;
=== Код ===&lt;br /&gt;
&lt;br /&gt;
* Стартовый код расположен в git-репозитории: https://bitbucket.org/qs/simpledb&lt;br /&gt;
&lt;br /&gt;
=== Описание взаимодействия ===&lt;br /&gt;
&lt;br /&gt;
На данном этапе нужно реализовать подгрузку схемы отношения и взаимодействие менеджера памяти с диском.&lt;br /&gt;
&lt;br /&gt;
Предлагается использовать следующую структуру файловой системы:&lt;br /&gt;
&lt;br /&gt;
    Корень базы&lt;br /&gt;
      --- table.data - файл со страницами с данными&lt;br /&gt;
      --- table.meta - файл со схемой отношения&lt;br /&gt;
&lt;br /&gt;
Формат схемы отношений&lt;br /&gt;
&lt;br /&gt;
Можно ограничиться читабельным форматом, например, перечислить через точку с запятой имя поля, тип и размер (если он есть):&lt;br /&gt;
&lt;br /&gt;
    id;int&lt;br /&gt;
    name;varchar;10&lt;br /&gt;
    dt;datetime&lt;br /&gt;
&lt;br /&gt;
Можно также хранить тип в виде числа объявленного в Const.&lt;br /&gt;
&lt;br /&gt;
Для данного задания точкой входа является BufferManager.executeQuery, который принимает queryPlan - список из операций (Операция определяется как отношение, тип операции (на данном этапе это full_scan) и предикат).&lt;br /&gt;
&lt;br /&gt;
Адресацию в таблице трансляции в BufferManager можно сделать относительно просто воспринимаемой: в качестве ключа в bufferTable нужно указать имя файла данных и смешение относительно начала файла, например: &lt;br /&gt;
&lt;br /&gt;
    table1.data:32&lt;br /&gt;
&lt;br /&gt;
executeQuery запрашивает у SchemaManager файл с данными. Так как нужно выполнить операцию full_scan, то первоначальный адрес страницы, которую нужно загрузить в память будет table1.data:0, нужно проверить, загружена ли она в таблицу трансляции, и если нет, то с помощью DiskManager считать ее.&lt;br /&gt;
&lt;br /&gt;
Также нужно, чтобы у страницы (Page) была ссылка на следующую страницу.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. BufferManager должен использовать свое адресное пространство при загрузке данных с диска (строить таблицу трансляции). Физический адрес - путь к файлу и смещение для перехода к нужному блоку.&lt;br /&gt;
&lt;br /&gt;
2. Добавить команду добавления записей в таблицу. При этом расположение записей на блоке должно быть оптимальным для схемы.&lt;br /&gt;
&lt;br /&gt;
Как только блок заполнен, его нужно сохранить на диск. Если блок изменен, то через несколько операций (или по таймеру) он также долже быть сохранен на диск.&lt;br /&gt;
&lt;br /&gt;
Блок должен относиться к одному отношению. В блоке должны быть: ссылка на схему отношения, ссылка на следующий блок, бит переполнения (используется, если запись не поместилась в блок целиком)&lt;br /&gt;
&lt;br /&gt;
Схема отношения должна содержать адрес файла, в котором находятся блоки с записями.&lt;/div&gt;</summary>
		<author><name>imported&gt;Ivsavin</name></author>
	</entry>
</feed>