Вход

Просмотр полной версии : Прозрачная работа с несколькими базами данных на PHP


PeaceCoder
22.02.2010, 16:16
Тема следующая. Приходилось ли работать с несколькими базами данных на одном сервере ? Если кому и приходилось расскажите какие были проблемы ?
Зачем: Надоели стандартные методы работы с базой. Думаю создать модуль, который будет прозрачен для разработчика, за счет которого можно работать с любой базой данных любого типа в любой момент, указав всего лишь тип (mysql,mssql и т.п.) и название базы данных (его указываешь в настройках баз), а на выходе получить обьект с (договоренными/обще принятыми) методами типа ->query, ->next и т.п. Вся инфа по тому как сделать запрос, генерация ошибок, колво строк и т.п. выполняет сам полученный обьект...

Kolyaj
22.02.2010, 18:55
http://ru.wikipedia.org/wiki/PHP_Data_Objects
http://ru.wikipedia.org/wiki/ORM

Tim
22.02.2010, 19:04
http://framework.zend.com/manual/ru/zend.db.html
Советую почитать перед началом - можно подчерпнуть много полезных идей. Сам ни чего такого ещё не делал, но планирую. Вообще идея хорошая ибо для добавления поддержки очередного СУБД нужно править только один класс, да и объекты как-то симпатичнее кучи переменных в глобальном пространстве.

PeaceCoder
22.02.2010, 20:12
СУБД нужно править только один класс
в моем случае ничего даже править не надо. в setup файле надо будет указать тип базы необходимые интсал запросы и идентификатор в модуле.
А в самом модуле будет так:
$db = F_SQL::dbo('Название модуля','идентификатор базы')
$db->q("SELECT * FROM {$db->__}название таблицы");
echo $db->count; //количество полученных строк запроса
while ($r = $db->next()){
...
}

...

где $db->__ - префикс для работы с таблицами модуля.
тем самым модуль прозрачен к сайту полность. все настраивается админом, какой главнй префикс. к какой базе привязан модуль и т.п.

e1f
22.02.2010, 20:56
$db->q("SELECT * FROM {$db->__}название таблицы");
Вот и первый плохой подход.
При подобном проектировании, конечная цель -- вообще избавиться от sql везде, кроме как непосредственно в классах, реализующих каждый database engine. Правильно как-то так:
$db->get_object_list($type, $tbl_name, $fields, $filter, $offset, $count);

PeaceCoder
23.02.2010, 01:14
Правильно как-то так:
и как этим методом ты предлагаешь гибкость выборки ? Твой метод как раз плох. Ты пытаешься исключить вообще запросы, прибегая к жесточайшим методам. Это не то, на что я нацелен.
В моем случае не играет роли на каком языке написан запрос. При создании обьекта $db в нем уже будут готовые функции для работы с тем или инным типом базы данных. В твоем же случае я не представляю как это сделать. Ведь синтаксис разных баз разный... и преобразовывать один в другой просто как минимум лишняя трата времени, а во вторых не файл что преобразование будет правильным.

e1f
23.02.2010, 10:09
В моем случае не играет роли на каком языке написан запрос.
Мда? То есть в коде проекта будет sql-строка. А если некоторый формат базы не поддерживает синтаксис, используемый в ней? А если мы решили вообще отказаться от sql? ;) Если делать грамотный Storage-wrapper, то от запросов везде, кроме как в классах, реализующих функционал для каждого типа БД, надо бежать как от огня.
В этом случае да, мы просто в конфиге меняем класс, который будет использоватся, и кушам печенье. Иначе мы бегаем, высунув язык, по коду, и меняем ручками запросы, которые ВНЕЗАПНО перестали работать на другой БД.

Tim
23.02.2010, 10:38
e1f,
:yes:

PeaceCoder,
Zend и ещё раз Zend. Семое главное это архитектура (идея как всё должно работать). Реализовать сможет любой, у кого есть более или менее прямые руки. Если сейчас архитектуру не додумать то потом уже не исправить, только переделывать.

sergdev
23.02.2010, 11:09
Сдается мне что уже есть такое - тот же самый PEAR DB packages (с Zendом не работал).
Или не прав ?

Tim
23.02.2010, 14:04
sergdev,
всё верно, такого много, но это всё ЧУЖОЙ КОД.

PeaceCoder
23.02.2010, 16:12
e1f,
Да я уже думал об этом, хотелось бы вообще сделать такой класс, которому пишешь стандартизированный запрос, а класс его переделывает под ту или инную базу и его синтаксис.
Планирую ща следующее. изучить стандарт SQL, внести немного своих фич под свою CMS, а класс, как раз таки, стандартный синтаксис будет конверитровать под тот или иной тип базы данных учитывая фичи CMS.

Планирую сделать так что, например, модуль пользователей использует одну базу, а модуль групп другую, причем на разных типах баз.. а подав единый запрос включающий выборку с одной и другой базы, указав всего лишь модули и их таблицы, получить ответ....

Octane
23.02.2010, 16:26
свою CMS
Как говорил у нас в Волгограде на семинаре генеральный директор UMI.CMS Сергей Котырев: «Каждый PHP-программист должен написать свою CMS и забросить её». :)

PeaceCoder
23.02.2010, 16:40
Как говорил у нас в Волгограде на семинаре генеральный директор UMI.CMS Сергей Котырев: «Каждый PHP-программист должен написать свою CMS и забросить её
нее. она покруче joomla будет. она гибкая до жути. пиши сайт хоть через левое ухо правой рукой.

Tim
23.02.2010, 17:00
PeaceCoder,
Зачем нужно две БД одной CMS? В чём смысл? Так безопаснее? Быстрее? Почему не 5? Сервер железный, пусть работает?

PeaceCoder
23.02.2010, 17:16
Зачем нужно две БД одной CMS? В чём смысл?
ты сталкивался с таким когда модулю надо делать запросы к другой бд от которой зависит текущий результат из нашей бд? вот для этого.

Простой пример. сделано несколько сайтов на разных доменах и базах но с одним сервером..., более банальный пример - сайт альянса в игре. Все сайты кланов хранятся на разных доменах и серверах, но например по "соглашению" можно взять например темы новостей каждого клана и вывести на сайте альянса....
или например, сайт онлайн игры. все ссервера лучше размещать на отдельных серверах и базы соответсвенно... но инфа на главном сайте то должна быть?

Tim
23.02.2010, 17:36
Не, мне до такого не додуматься даже. Признаю свою вину, меру, степень, глубину....

x-yuri
24.02.2010, 23:45
ты сталкивался с таким когда модулю надо делать запросы к другой бд от которой зависит текущий результат из нашей бд? вот для этого.
так есть просто две БД или рассматривается вариант перехода с одной БД на другую?

PeaceCoder
25.02.2010, 01:32
так есть просто две БД или рассматривается вариант перехода с одной БД на другую?
то что я описал две. а вообще уже реализовываю кросс-бд запросы. независимо от синтаксиса можно будет делать запросы разных модулей
Пример: есть модуль пользователей с таблицей users, групп с таблицей groups и форум с таблицами topics, forums

Можно будет делать такой запрос
$db->q("SELECT T.*,G.Color,U.Nick
FROM M_FORUM.topics AS T, M_GROUPS.groups AS G, M_USERS.users AS U
WHERE G.UserID=U.id AND T.UserID=U.id");
где M_FORUM, M_GROUPS и M_USERS - названия модулей.
Такой запрос будет действовать не зависимо от того какие базы юзают каждый из модулей и на каком они синтаксисе. При этом об префиксах можно будет вообще забыть. Они будут генерится автоматом =)

x-yuri
25.02.2010, 14:36
PeaceCoder в своем стиле... т.е. твоя библиотека автоматически определяет использованный диалект и преобразует в нужный? Или она определяет свой, православный?

p.s. пару сообщений, правда про (http://phpclub.ru/talk/showthread.php?postid=843576#post843576) orm (http://phpclub.ru/talk/showthread.php?postid=632652#post632652)

p.p.s. что меня больше всего смущает, так это то, что ты придумываешь проблему и начинаешь отстаивать ее актуальность. Нет чтобы просто сказать: "Интересно мне, любопытно или что там еще..." ;)

Tim
25.02.2010, 15:35
ты придумываешь проблему и начинаешь отстаивать ее актуальность
это из-за универа, без этого навыка диплом не сделать =)

micscr
25.02.2010, 17:35
нее. она покруче joomla будет. она гибкая до жути. пиши сайт хоть через левое ухо правой рукой.
дай автограф. :)

А по сути: кому писать сайт будет гибко - пользователям джумлы что-ли? Они писать умеют?

Tim
25.02.2010, 18:39
Joomla не самая гибкая CMS. Если говорить о гибкости, то ей нужно меряться с Drupal.

PeaceCoder
25.02.2010, 21:43
использованный диалект и преобразует в нужный?
именно. преобразует в соответствие с необходимым типом базы.

e1f
26.02.2010, 02:53
PeaceCoder, говноидея. Полностью согласен с x-yuri в том, что Вы выдумываете идею ради идеи.

PeaceCoder
26.02.2010, 10:26
PeaceCoder, говноидея.
Вы всем так говорите? Все что делаете не вы все говно? Вы даже не задумались какие возможно появляются...

e1f
26.02.2010, 10:42
Вы всем так говорите? Все что делаете не вы все говно? Вы даже не задумались какие возможно появляются...

Чорт, вот все Вы не так понимаете.
Ну, и какие же возможности появляются? Крошево запросов в веб-части како было, тако и осталось, зато они теперь какие-то мутные, и я плохо представляю себе, как написать их.
Далее, мне понадобился запрос, к примеру, с WITH. Mysql его не поддерживает, емнип. Я пишу -- все работает, потому что модули используются не mysql, а oracle, к примеру. Я радостно дописываю запрос и ухожу домой. Потом кто-то меняет в моем запросе только имя модуля, и вуаля -- ничего не пашет. Вот что тут делать пользователю Вашей "системы"? Надо садится, и руками переписывать sql-запросы. Как был каменный век, так и остался.

PeaceCoder
26.02.2010, 11:16
e1f,
Как выражается иногда subzey, я Вам соболезную.Потом кто-то меняет в моем запросе только имя модуля
Угу, ток при установке модуля в нем прописываются требования на использования других модулей и вот такой кто поменяет имя модуля должен и требования поменять. Иначе модуль вы не поставите. Не все так просто.

e1f
26.02.2010, 11:25
А причем тут требования на использование модулей? Или Вы имеете в виду, что я не смогу использовать модули Oracle и MySQL в одном запросе? Так толку тогда с такой системы, когда я вроде бы и могу
SELECT * FROM _oracle_db, _mysql_db

а на самом деле нет.

PeaceCoder
26.02.2010, 11:44
А причем тут требования на использование модулей?
Явно видно, что Вы не поняли вообще что я подразумеваю под словом "модуль" в моей цмс, а не в апаче. А то что вы имеете ввиду так это как раз и делает модуль работы с SQL.

e1f
26.02.2010, 13:07
модуль работы с SQL.

С каким именно sql? sql, он, знаете ли, разный :)
Ну и вдогонку -- все же, запросы будут формироватся пользователем вашей CMS? Как будет реализован квотинг данных? Забота об этом возлагается на пользователя?

PeaceCoder
26.02.2010, 14:22
запросы будут формироватся пользователем вашей CMS
Да. Будет стандартный синтаксис (шаблоны написания запросов), все остальное - функции не реазлизованные на той или инной БД берет на себя модуль. Например SELECT INTO не везде одиноков, но по стандарту он таков: "SELECT ... INTO ... FROM ......"
Как будет реализован квотинг данных?
А вот над этим я думаю, пытаюсь вообще все на автомат поставить. Потому как задолбало постоянно писать типа
$db->q("SELECT * FROM ... WHERE ...='".sql_escape($data)."'"

Может есть идеи как избавиться от функции ?

Kolyaj
26.02.2010, 14:26
Может есть идеи как избавиться от функции ?
От sql_escape? PDO::prepare

e1f
26.02.2010, 15:05
bind_param

Tim
26.02.2010, 16:00
Да. Будет стандартный синтаксис
Т.е. запрос будет в виде строки а потом будет парсится регулярками и приводиться к нужному виду?

Если делать грамотный Storage-wrapper, то от запросов везде, кроме как в классах, реализующих функционал для каждого типа БД, надо бежать как от огня.
Человек дело говорит! PeaceCoder зря вы мой призыв обратить внимание на Zend не услышали. Посмотрите как там сделано:


$params = array(
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'drupal'
);

// Инициализация адаптера с указанием нужного диалекта
$db = Zend_Db::factory('Pdo_Mysql', $params);

// Выполнение запроса
$result = $db->fetchAll(
$db -> select()
-> from('users')
-> order('uid')
-> limit(15)
);

PeaceCoder
26.02.2010, 16:14
От sql_escape?
Идейка понравилась, думал что-то в этом роде но не думал что это будет удобно...

PeaceCoder
26.02.2010, 17:52
зря вы мой призыв обратить внимание на Zend не услышали
услышал. пока размышляю что будет лучше. то как построены зенд запросы и хорошо и плохо. хорошо - мы в нутри класса имеем четкую структуру запроса, плохо такое формирование уменьшает кпд программиста, т.к. постоянно повторятся array(name=>adwd,...) утомляет

PeaceCoder
26.02.2010, 18:34
Посмотрите как там сделано
А вот кста, я так и не понял как сформировать запрос с сабзапросом?

Tim
27.02.2010, 00:41
А вот кста, я так и не понял как сформировать запрос с сабзапросом?


// Запрос номер 1 (вложенный)
$query1 = $db -> select()
-> from('blocks', 'delta')
-> where('bid = 2');

// Запрос номер 2
$query2 = $db -> select()
-> from('users')
-> where('uid = ?' , $query1)
-> limit(2);

// Посмотрим как выглядит строка запроса
print $query2->assemble();

/* Вот она:
SELECT users.* FROM users WHERE (uid = (SELECT blocks.delta FROM blocks WHERE (bid = 2))) LIMIT 2
*/

// Теперь выполним этот запрос
$result = $db->fetchAll($query2);

// Распечатаем массив результатов
print_r($result);


Теперь обратим внимание на строку:

-> where('uid = ?' , $query1)

Запрос 1 будет подставлен вместо знака вопроса. В принципе, можно использовать и конкатенацию, но тогда добавлять скобки придётся руками.

-> where('uid = (' . $query1 . ')' )


Ещё можно так:

-> where('uid = (SELECT delta FROM blocks WHERE bid = 2)')

но это уже совсем быдлокодерство.

P.S.: Сдавайтесь PeaceCoder ;) Zend рулит. Хотя, конечно есть и минусы: они перестраховщики большие - много линних проверок и перепроверок.

PeaceCoder
27.02.2010, 01:41
Запрос 1 будет подставлен вместо знака вопроса. В принципе, можно использовать и конкатенацию,
только вот интересно как это происходит конкатенация если на выходе постоянно обьект, а не строка ? Или в пхп принцип -> иной return не влияет на эту команду ?
Сдавайтесь PeaceCoder Zend рулит
Рулит но не в том направлении в котором буду делать я. На счет сабов так и подумал...

Tim
27.02.2010, 02:46
только вот интересно как это происходит конкатенация если на выходе постоянно обьект, а не строка ?

Нужно определить в классе метод __toString() и он будет автоматически вызываться. Беглый осмотр кода кода Zend показал, что так оно и сделано.

class my_class {

function __toString()
{
return 'Вдруг как в сказке скрипнула дверь ;)';
}
}

$my_obj = new my_class();

print $my_obj;

micscr
27.02.2010, 09:37
Tim, а Zend вроде говорят очень объемная и массивная вешь. В плане научиться с ним работать. Так это?

Tim
27.02.2010, 11:19
Да там оч много всего (библиотеки в несжатом виде 20мб). Я сам далеко не всё знаю. Вот, оцените сами:
http://framework.zend.com/manual/ru/

micscr
27.02.2010, 11:43
Да там оч много всего (библиотеки в несжатом виде 20мб). Я сам далеко не всё знаю. Вот, оцените сами:
http://framework.zend.com/manual/ru/
Да посмотрел, спасибо. Впечатляет. Люблю ООП.
Есть же еще какая-то среда разработки Zend, платная вроде. Они как то связаны?

Я вообще сейчас задумал с Drupal разбираться. У нас в городе вроде востребован. Он же тоже как фреймворк. Правда без ООП но с хорошим стилем кодирования.

p.s. плюсик не хочет ставиться, на потом запомню :) .

Tim
27.02.2010, 11:57
Я вообще сейчас задумал с Drupal разбираться.
:) Я тоже. Пару недель назад две книги по нему купил. Одна по администрированию, другая чисто по кодингу. До этого с джумлой колупался - не нравится она мне что-то.

Есть же еще какая-то среда разработки Zend, платная вроде.
Zend Studio. М.б. и связаны. Я скрины посмотрел - не впечатлило, к тому же платная. Мне больше Netbeans нравится и Notepad++.

p.s. плюсик не хочет ставиться, на потом запомню
http://javascript.ru/forum/misc/7893-sokhranenie-peremennykh.html#post45967 ;)

x-yuri
27.02.2010, 16:04
Ещё можно так:
->   where('uid = (SELECT delta FROM blocks WHERE bid = 2)')
но это уже совсем быдлокодерство.
не так плох SQL, чтобы его использование считать быдлокодерством ;)

Tim
27.02.2010, 19:21
не так плох SQL, чтобы его использование считать быдлокодерством
Если есть уверенность, что это будет работать и в остальных типах БД, тогда SQL не плох.

Octane
27.02.2010, 19:41
Недавно слышал, как хвалили http://www.redbeanphp.com/ :)