Pull to refresh

Движок СУБД на PHP

Reading time4 min
Views3.3K
Здравствуйте, уважаемые читатели. Моя СУБД не является портом никакой из существующих СУБД на PHP (в отличие от C#-SQLITE, к примеру), а является уникальной разработкой. Основным отличием от существующих движков, вроде TxtSQL, является поддержка индексов. Если используется только PRIMARY INDEX, скорость вставки на моём ноутбуке достигает 5000/сек. Для PHP, как мне кажется, это вполне неплохо.

Зачем?


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

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

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

Что из себя представляет


На данном этапе ядро базы находится на ранней стадии разработки, и из той версии, которую я здесь представлю, даже не убраны некоторые куски отладочного кода. Их, конечно, можно убрать и использовать СУБД уже прямо сейчас, но я бы хотел акцентировать ваше внимание не на этом. Если вам не терпится посмотреть ядро «в бою», у меня есть демо:

База данных форума forum.dklab.ru, импортированная в самодельный форум

Изначально форум использовал MySQL, но он был модифицирован для работы с ядром моей СУБД (этот процесс занял не очень много времени, буквально несколько часов). В базе данных forum.dklab.ru находится порядка 150 000 сообщений, база с сообщениями занимает порядка 60 Мб (я могу выслать исходники желающим).

Текущие возможности БД


На данный момент база поддерживает AUTO_INCREMENT поля, которые одновременно являются PRIMARY INDEX, а также аналоги индексов INDEX и UNIQUE в MySQL. Имеется поддержка нескольких индексированных полей. Поддержки составных индексов на данный момент нет, и пока что не планируется. Также, для индексирования доступны лишь числовые поля (INT).

Синтаксис метода, который используется для выборки строк, на данный момент предусматривает выборку лишь по одному условию вида «имя_поля оператор значение», где оператором может быть одно из следующего: " > < = IN". Индексы используются для запросов вида «имя_поля = значение», и только для них. Для PRIMARY INDEX также есть оптимизация по выборке с использованием оператора IN (это полный аналог того же самого в MySQL).

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

Технические подробности


Для PRIMARY INDEX (и одновременно AUTO_INCREMENT поля) используется отдельный файл, в котором записываются смещения в таблице с данными, причём по очень простому принципу: в позиции id*4 (4 = sizeof(int)) записывается то самое смещение. Это работает очень быстро.

Для UNIQUE индексов используется Б-дерево. На данный момент его реализация не блещет производительностью, но тем не менее использование настоящего Б-дерева позволяет делать минимальное количество обращений к файловой системе ( ~log(КОЛ-ВО ЗАПИСЕЙ) / log(70) ), а соответственно — хранение произвольных значений в большом количестве без потери производительности при добавлении новых записей.

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

Все смещения в файлах 32-битные, что накладывает ограничение в 2 Гб как для файла с базой, так и для индексов. Все индексы хранятся в файлах, так что индексы требуется «прогревать» перед использованием — для unix выполните

cat *.idx *.btr *.pri > /dev/null

перед тем, как запускать БД из нового места. Это занесет индексы в кэш ОС, что существенно повысит быстродействие базы.

Использование



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

$db = new YNDb('my_data');

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

$db->create('test_table', array('id' => 'INT', 'name' => 'TINYTEXT'), array('AUTO_INCREMENT' => 'id') );

Вставка не может быть проще:

for($i = 0; $i < 100; $i++)
{
$db->insert('test_table', array('name' => 'value'.$i));
}


Выборка значений имеет самый сложный синтаксис, но зато позволяет отсортировать результат, применить limit'ы, и т.д. Вот один из примеров:

$results = $db->select('test_table', array('cond' => 'id > 30', 'limit' => '30,50', 'order' => array('name', SORT_ASC) ) );

* This source code was highlighted with Source Code Highlighter
.


Где скачать?


Проект размещен на Google Code:

code.google.com/p/yndb

Там представлено краткое описание проекта, документация, и пара примеров использования СУБД, в том числе и «YNDbAdmin» — скрипт в 300 строк кода, который даёт базовый функционал по работе с базой.

Жду ваших комментариев :)!
Tags:
Hubs:
Total votes 193: ↑164 and ↓29+135
Comments186

Articles