При разработке web приложений, часто возникает потребность в хранении определённых настроек или временных данных. Обычно, для этого используются или файлы, или базы данных. Если это база данных, то хранить в базе таблицу с одной строкой, как чаще всего это бывает, не очень удачный вариант. Для этого чаще используются config файлы определенных форматов (*.php, *.ini, *.xml, *.json).

JSON база данных


В данном посте я хочу рассказать об использовании json файлов как базы данных. Использование именно формата json удобно тем, что информация в данном формате — это Javascript массивы и объекты, к которым легко можно получить доступ с клиентской части web приложения.
Любая база данных включает в себя набор функций для записи, чтения, обновления и удаления данных из таблиц. В данном случае это будет класс с набором методов для управления базой.

$jdb  = new Jsondb($path);

 

  • $path — путь от корня до папки, в которой будут храниться файлы. По умолчанию $path = $_SERVER[«DOCUMENT_ROOT»].'/jdb/'.

 

Управление базой данных


Ниже представлен набор методов и примеров их использования.

Create
Создание таблицы.

$jdb->create($table, $keys);

 

  • $keys — массив ключей таблицы и их характеристик. Поддерживается auto_increment и default.


Пример:

$keys = Array(
	'id'=>Array('auto_increment'),
	'title'=>Array('default'=>'habrahabr'), 
	'posts', 
            'userId'
);
$jdb->create('habr', $keys);


Select
Выборка данных из таблицы.

$jdb->select($select, $table, $rules);

 

  • $select — массив или строка, содержащие ключи для выборки.
  • $table — название таблицы из которой будет происходить выборка данных.
  • $rules — массив, содержащий параметры where, order и limit.


Пример:

$rules = Array(
		'where'=>Array(
				'id'=>Array(1,2,3,4,6,7,10),
				'name'=>'habr'
			),
		'order'=>Array('id','desc'),
		'limit'=>5
	);
$jdb->select('*','habr',$rules);
$rules = Array(
		'order'=>Array('rand()'),
		'limit'=>Array(10,4)
	);
$select = Array('id','title','userId'); # все равно, что $select ='id,title, userId';
$jdb->select($select, 'habr', $rules);


Insert
Вставка данных в таблицу.

$fdb->Insert($table, $data);

 

  • $data — ассоциативный массив данных для вставки в таблицу.


Пример:

$data = Array('title'=>'new title', 'userId'=>6431);
$jdb->insert('habr', $data);


Update
Обновление данных в таблице.

$jdb->update($table, $data, $where);

 

  • $table — название таблицы.
  • $data — ассоциативный массив с данными для обновления.
  • $where — ассоциативный массив с данными для выбора нужной записи для обновления.


Пример:

$data = Array('title'=>'updated title');
$where = Array('title'=>'new title', 'userId'=>6431);
$jdb->update('habr', $data, $where);


Delete
Удаление записей из таблицы.

$jdb->delete($table, $where);

 

  • $table — название таблицы.
  • $where — ассоциативный массив данных для выборки нужной записи для удаления.


Пример:

$where = Array('userId'=>6431);
$jdb->delete('habr', $where);


Drop
Удаление таблицы.

$jdb->drop($table);

 

  • $table — название таблицы.


Пример:

$jdb->drop('habr');


Alter
Добавление и удаление ключей из таблицы.

$jdb->alter($table, $todo, $keys);

 

  • $table — название таблицы.
  • $todo — выполняемое действие. Может быть add или drop.
  • $keys — строка или ассоциативный массив данных для удаления или добавления ключей.


Пример:

$jdb->alter('habr', 'drop', 'title','userId');

$keys = Array(
	            'postTitle'=>Array(
			'default'=>'habrapost'
		)
);
$jdb->alter('habr', 'add', $keys);
$keys = Array('acc','userId'); # все равно, что $keys = 'acc, userId';
$jdb->alter('habr', 'add', $keys);


Truncate
Полностью очистить таблицу.

$jdb->truncate($table);

 

  • $table — название таблицы.


Exists
Проверяет существование таблицы.

$jdb->exists($table);

 

  • $table — название таблицы.

 

Определение ошибок в запросах


Все перечисленные методы возвращают результат запроса, если он был удачен, и false если нет. Метод "status" позволяет узнать статус предыдущего запроса.

$jdb->status($flag);

 

  • $flag — по умолчанию false. Если установлено true, то будет возвращено текстовое сообщение с ошибкой вместо статус-кода.


Пример:

$jdb->create('users',Array('id'=>Array('auto_increment'),'name'));
$jdb->create('users',Array('id','name'));
echo $jdb->status();
echo $jdb->status(true);
/*
 *	101
 *	Table already exists;
 */
$jdb->select('phone', 'users');
echo $jdb->status();
echo $jdb->status(true);
/*
 *	202
 *	Try ro select an unexisting keys from table "users";
 */


Список статус-кодов:

  • 0 — All ok.
  • 101 — Table already exists.
  • 102 — Table doent exist.
  • 103 — Unkonw property.
  • 201 — Key already exist.
  • 202 — Keys doesnt exsit.

 

Вспомогательные методы


Last_insert_id
Часто бывает, что нужно узнать id добавленной записи в базу данных. Для этого нужно воспользоваться методом last_insert_id.

$jdb->last_insert_id();


Пример:

$jdb->insert('users', Array('name'=>'username'));
echo $jdb->last_insert_id();


Exist
Проверяет существование таблицы. Возвращает true или false;
Пример:

$jdb->exist('user');


Так же для удобства есть возможность использовать sql синтаксис для выполнения запросов. Для этого используется другой класс.

Jsonsql::request('select * from `users`', $path);

 

  • $path — путь от корня до папки, в которой хранятся файлы. По умолчанию $path = $_SERVER[«DOCUMENT_ROOT»].'/jdb/'.



Так как в php есть возможность создавать функции и классы с одним именем, то можно применить следующую конструкцию:

function Jsonsql($string, $path = false){
	return Jsonsql::request($string, $path);	
}


Пример:

Jsonsql('create table `new` (id auto_increment, title default "untitled", text)');
Jsonsql('select `name`,`title` from `habr` where `id` in(1,34,5,9,4,100) order by rand()', '/jdb/test/');

 

Дополнительные запросы


Узнать статус запроса:

Jsonsql('status');         		#вернет сообщение о статусе запроса
Jsonsql('status code');  	#вернет статус код запроса


Узнать id добавленной записи в базу данных:

Jsonsql('last_insert_id');


Узнать существует таблица или нет:

Jsonsql('table exists `users`');

 

Сравнение Jsondb с MySql


Конечно, тут и сравнивать то нечего, базы данных для того и созданы, чтобы хранить данные и быстро получать к ним доступ. Но все же интересно.
Для сравнивания быстродействия и количества используемой памяти, был выполнен ряд тестов для методов insert, update и select.

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

Используемая память:

  • Jsondb — 525.67 Kb.
  • MySQL — 421.16 Kb.


Видно, что быстродействие Jsondb очень сильно зависит от количества записей в таблице.

Update
Было выполнено обновление 100 записей в базе данных.

  • Jsondb — 0.03223 сек., 626.66 Kb.
  • MySQL — 0.01991 сек., 470.84 Kb.



Select
Была выполнена выборка всех записей из базы данных.

  • Jsondb — 0.00313 сек., 626.66 Kb.
  • MySQL — 0.00391 сек., 387.69 Kb.



И выборка данных из базы с условиями where, order и limit.

  • Jsondb — 0.02123 сек., 626.66 Kb.
  • MySQL — 0.03991 сек., 387.69 Kb.


Из всего этого следует, что быстродействие такой системы хранения данных, особенно при использовании методов update и insert, очень сильно зависит от количества записей в одной таблице. Выборка данных из таблиц происходит достаточно быстро. Использование такого метода хранения информации хорошо подходит для хранения различных настроек приложений и временных данных. Как было сказано выше, в этом так же есть большой плюс из-за того, что к любой информации, хранимой в данном виде, можно получить доступ с клиентской части приложения. Если подробнее, то например с помощью JQuery метода $.getJSON.

Вот ссылка, по которой можно скачать исходники и примеры.