Обычно я просто использовал бы SQL / SQLite / Mongo для любой базы данных, но я подумал, что было бы интересно попытаться создать собственную структуру базы данных с плоскими файлами (это всего лишь учебный проект).Само приложение представляет собой музыкальный стример с централизованной библиотекой на сервере.
База данных:
Мое приложение является клиент-серверным, и любые изменения, вносимыесервер синхронизируется со всеми клиентами.Серверы выполняют операции вставки, редактирования и удаления.
Клиенты могут изменять только логическое поле модификатора клиента в записи (значение которого зависит от данного клиента).Другие операции недоступны для клиентов, поэтому никаких синхронизирующих изменений нет.
Операции записи на сервере редки после первоначального построения базы данных, но происходят.Приоритет здесь определенно - операции чтения для клиентов.
Требуется масштабирование до 500 тыс. Треков или до 2 ГБ (2 ^ 31 байт) размера файла базы данных (который когда-либо будет первым).
Что хранится:
- Несколько таблиц, с некоторыми отношениями.Это всего лишь макет, но вы понимаете:
+--------+ +--------+ +-------------------+
| id* | | id* | | id* |
| ARTIST | ------> | ARTIST | | track name |
| | | ALBUM | ------> | ALBUM |
| | | year | | length |
| | | | | filename** |
| | | | | {client modifier} |
+--------+ +--------+ +-------------------+
* unique identifier
** not stored in client version of database
{client modifier} is only on the client version of database
Одна проблема, которую нужно преодолеть, - это как обращаться с отношениями и искать, чтобы минимизировать операции ввода-вывода.
- Все поля имеют переменную длину, кроме идентификатора, года и длины.
Обязательные функции:
- Разрешитьсинхронизировать базу данных со всеми клиентами с минимальными операциями.
Одним из способов решения этой проблемы было бы сохранение даты / времени каждой записи, которая была изменена в последний раз, и предоставление клиенту даты последней синхронизации.Когда клиент подключается к сети, все изменения в той же части синхронизируются с клиентом.Другим способом сделать это было бы иметь отдельную таблицу на сервере, которая перечисляет все операции, которые произошли, и дату, когда они произошли;и синхронизировать аналогичным образом.
- Операции быстрого чтения для клиентов
Поскольку таблицы меньше по размеру, клиент может сохранять таблицы исполнителей, альбомовв памяти, но я собираюсь предположить, что они этого не сделают.
я думал о том, чтобы иметь отдельные файлы для каждой таблицы, и каждый раз клиент открывает каждый файл, чтобы гарантировать, что он может читать каккак можно быстрее ... разве это плохая идея?
Для каждой таблицы, где начинается каждая запись, нужно будет сохранить какой-то индекс.Это может быть достаточно мало для загрузки в память и может быть сохранено в файлах отдельно от фактических таблиц, чтобы избежать проблем.
- Минимизация операций ввода-вывода
Сервер будетсохраните «индекс» базы данных треков в памяти с идентификатором и именем файла, чтобы операции чтения были сведены к минимуму.
Сервер также буферизует операции записи в базу данных, так что если он обнаружит, что много записиОперации будут происходить в короткий промежуток времени, он будет ждать, а затем выполнять пакетную запись.Это возможно, потому что изменения в файловой системе все еще будут происходить, если происходит сбой базы данных, поэтому он может просто перезагрузить все изменения при перезапуске.
- НЕ разреженный файл, чтобы размер файла был минимальным.
Я буду работать на уровне байтов, чтобы уменьшить размер файла.Основной проблемой будет фрагментация при удалении записи.Из-за полей переменной длины вы не можете просто добавить новую запись в этом месте
Я мог бы выполнить фрагментацию файла, когда он достигнет определенного уровня фрагментации (отношение удаленных записей к записям), ноЯ бы предпочел этого избежать, если смогу, так как это будет дорогостоящей операцией для клиентов.
Я бы предпочел также не использовать поля фиксированной длины (поскольку имя файла может быть огромным, например), но они кажутсямне только варианты?
Комментарии:
Так, как мне пойти на это и максимизировать производительность?
Да, я ищу новое изобретение колеса, и да, я знаю, что, вероятно, я не подойду к производительности других баз данных.
Так у кого-нибудь есть мысли / комментарии / идеи?
Спасибо за чтение.