
Ветка экспериментальная. Исходники
Далее примеры.
Немного о самой БД
Tarantool — это распределенное key/value хранилище.
Необходимо отметить, что Tarantool — это хранилище данных, а не система кеширования типа memcache. Все данные находятся в памяти и при необходимости сохраняются в файлах (снапах).
Данное хранилище, в отличие от традиционного memcached & redis хранилища имеет дополнительные возможности:
- наложение дополнительных индексов на данные
- индексы могут быть составными
- индексы могут иметь тип TREE или HASH
- осуществление выборок по одному или нескольким индексам
- изъятие данных частями (аналог LIMIT/OFFSET)
Tarantool оперирует данными, которые объединены в неймспейсы (namespace). Неймспейс — это аналог таблицы в MySQL. В системе организована цифровая нумерация неймспейсов (0, 1, 2, 3 ...).
На каждый неймспейс накладывается индекс. Индексы могут накладываться на числовое (int32 или int64) или символьное поле. Как упоминалось выше: индексы могут быть двух типов: HASH & TREE.
Так же как с неймспейсами, в системе определена цифровая нумерация индексов.
Все индексы прописываются в конфиге. Конфиг более менее человеко воспринимаем. Ниже в примерах будет использоваться следующий конфиг:
namespace[0].enabled = 1
namespace[0].index[0].type = "HASH"
namespace[0].index[0].unique = 1
namespace[0].index[0].key_field[0].fieldno = 0
namespace[0].index[0].key_field[0].type = "NUM"
namespace[0].index[1].type = "TREE"
namespace[0].index[1].unique = 0
namespace[0].index[1].key_field[0].fieldno = 1
namespace[0].index[1].key_field[0].type = "STR"
namespace[0].index[2].type = "TREE"
namespace[0].index[2].unique = 0
namespace[0].index[2].key_field[0].fieldno = 1
namespace[0].index[2].key_field[0].type = "STR"
namespace[0].index[2].key_field[1].fieldno = 2
namespace[0].index[2].key_field[1].type = "STR"
namespace[0].index[3].type = "HASH"
namespace[0].index[3].unique = 0
namespace[0].index[3].key_field[0].fieldno = 3
namespace[0].index[3].key_field[0].type = "NUM"
Пояснение:
используется один неймспейс, namespace=0
Первый индекс=0, является всегда первичным. Тип индекса HASH, наложен на числовое поле=0.
Второй индекс=1, тип TREE, накладывается на поле=1, тип строка.
Третий индекс =2, составной, накладывается на поля 1 и 2
Четвертый индекс=3 — накладывается на числовое поле 3
Инсталляция
1) качаем исходники:
** git clone git@github.com:akalend/tarantool.git
возможен переход в master https://github.com/mailru/tarantool.git
2) cd connector/php
3) phpize
4) ./configure
5) sudo make install
6) в php.ini в секции extension вставляем строку:
extension=tarantool.so
Конструктор
// constructor(host,port);
$tnt = new Tarantool($host,$port);
Конструктор задает параметры соединения, Но само соединение происходит при первом обращении к данным.
Параметры $host, $port необязательные. Но умолчанию $host=127.0.0.1, $port =33013. Также в Tarantool имеется вторичный порт 33014, настроен только на чтение.
Вставка
Tarantool — оперирует порциями данных, именуемых кортежами.
В математике корте́ж — последовательность конечного числа элементовВ РНР — корте́ж представлен как массив.
В некоторых языках программирования (например Python или Lisp), кортеж — особый тип структуры данных
©Wikipedia
$tuple = array(1, 'x','abd', 1023 );
$res = $tnt->insert(0,$tuple);
var_dump($res);
Нулевой элемент массива вставится в нулевое поле данных.
Количество элементов массива может быть больше, чем кол-во индексных полей, Но в этом случае, выборка по этим полям будет невозможна. Если элемент уже существует, то он заменится на новый.
Результат true/false — результат выполнения операции INSERT
Выборка
выборка, аналогично интерфейсам РСУБД, осуществляется в два этапа: 1) оператор выбора рекордсета SELECT и 2) итерирование по выборки строк, в нашем случае кортежей/tuple
ниже пример:
/**
* Tarantool::select
*
* @param number namespace
* @param number index No
* @param mixed key
* @param optional limit default all
* @param optional offset default 0
*
* @return count of tuples
*/
$count = $tnt->select(0,0,1); // namespace,index, key
var_dump($count);
$res = $tnt->getTuple();
var_dump($res);
Приведенный пример выбирает данные из namespace=0, index=0, key=1. Результат метода Select — кол-во выбранных кортежей. Выборка производится по первичному ключу. В данном случае — будет выбран один кортеж методом getTuple()
Если мы должны выбрать несколько элементов данных, то необходимо организовать цикл:
echo "some tuple select by fielNo[1] = 'x'\n";
$count = $tnt->select(0,1,'x'); // namespace,index, key
while( ($res = $tnt->getTuple()) != false){
var_dump($res);
}
Если нужно выбрать по двум критериям, например аналог SQL оператора: SELECT * FROM t WHERE f1='msk' AND f2='realty', то необходимо использовать составной индекс. В нашем примере — это index=2. Смотрим конфиг.
echo "some tuple select by index = 2 (fielNo[1] = 'spb' and fielNo[2] = 'realry')\n";
$count = $tnt->select(0,2,array('spb', 'realty')); // namespace,index, key
while( ($res = $tnt->getTuple()) != false){
var_dump($res);
}
Пример выборки по числовому полю(индекс=3)
echo "some tuple select by index = 3 (fielNo[3] = 1025)\n";
$res = $tnt->select(0,3,1025); // namespace,index, key
var_dump($res);
while( ($res = $tnt->getTuple()) != false){
var_dump($res);
}
Если нужно организовать выборку частями, то предусмотрены параметры LIMIT/OFFSET (аналочигные в MySQL). Ниже пример выборки 5-ти кортежей, начиная с 10-го в рекордсете.
echo "some tuple select by index = 3 (fielNo[3] = 1025) NEXT 5 (offset=10, limit=5)\n";
$tnt->select(0,3,1025,5,10); // namespace,index, key, limit, offset
while( ($res = $tnt->getTuple()) != false){
var_dump($res);
}
Изменение данных
В настоящий момент реализовано только два метода изменения данных: inc — увеличение данных, update — замена данных. Оба метода работают только по первичому индексу, т.е в качестве ключа используется только первичный индекс.
Рассмотрим более простой метод inc(). Данный метод увеличивает (по умолчанию на 1) поле типа NUM. На других типах полей возникнут ошибки.
/**Если хотим уменьшить на 1, то используем:
* Tarantool::inc
*
* @param namespace
* @param primary key
* @param field No for increment
* @param optional incremental data default +1
*
* @return bool result
*/
// increment
$tnt->inc(0,1,3);
$tnt->select(0,0,1);
$tuple = $tnt->getTuple();
var_dump($tuple);
$tnt->inc(0,1,3,-1);
Метод UPDATE отличается от INSERT тем, что UPDATE изменяет только необходимые нам поля данных, не трогая остальные. Метод INSERT — осуществляет, при наличие уже имеющихся данных первичного индекса все поля кортежа. Ближе к
/**Второй параметр — это ключ выбора, третий параметр — это ассоциативный массив данных, которые необходимо заменить. Ключами массива являются числовые индексы, соответствующие номерам полей, которые необходимо заменить, на данные, которые соответствуют данным ключам.
* Tarantool::update
*
* @param namespace
* @param primary key
* @param array of new data:
* array( fieldNo => newValue, ... )
*
* @return bool result
*/
$res = $tnt->update(0,1,array(2=>'y'));
echo "update tuple res=$res\n";
Ограничения
пока реализовано только использование int32 индексов. int64 не реализовано.
не реализованы операции UPDATE/AND UPDATE/XOR
Надеюсь, что данный модуль будет полезен не только моему проекту. О замеченных багах прошу отписываться в личку, либо на страницу проекта.