Просмотр полной версии : Прозрачная работа с несколькими базами данных на PHP
PeaceCoder
22.02.2010, 16:16
Тема следующая. Приходилось ли работать с несколькими базами данных на одном сервере ? Если кому и приходилось расскажите какие были проблемы ?
Зачем: Надоели стандартные методы работы с базой. Думаю создать модуль, который будет прозрачен для разработчика, за счет которого можно работать с любой базой данных любого типа в любой момент, указав всего лишь тип (mysql,mssql и т.п.) и название базы данных (его указываешь в настройках баз), а на выходе получить обьект с (договоренными/обще принятыми) методами типа ->query, ->next и т.п. Вся инфа по тому как сделать запрос, генерация ошибок, колво строк и т.п. выполняет сам полученный обьект...
http://ru.wikipedia.org/wiki/PHP_Data_Objects
http://ru.wikipedia.org/wiki/ORM
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->__ - префикс для работы с таблицами модуля.
тем самым модуль прозрачен к сайту полность. все настраивается админом, какой главнй префикс. к какой базе привязан модуль и т.п.
$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 в нем уже будут готовые функции для работы с тем или инным типом базы данных. В твоем же случае я не представляю как это сделать. Ведь синтаксис разных баз разный... и преобразовывать один в другой просто как минимум лишняя трата времени, а во вторых не файл что преобразование будет правильным.
В моем случае не играет роли на каком языке написан запрос.
Мда? То есть в коде проекта будет sql-строка. А если некоторый формат базы не поддерживает синтаксис, используемый в ней? А если мы решили вообще отказаться от sql? ;) Если делать грамотный Storage-wrapper, то от запросов везде, кроме как в классах, реализующих функционал для каждого типа БД, надо бежать как от огня.
В этом случае да, мы просто в конфиге меняем класс, который будет использоватся, и кушам печенье. Иначе мы бегаем, высунув язык, по коду, и меняем ручками запросы, которые ВНЕЗАПНО перестали работать на другой БД.
e1f,
:yes:
PeaceCoder,
Zend и ещё раз Zend. Семое главное это архитектура (идея как всё должно работать). Реализовать сможет любой, у кого есть более или менее прямые руки. Если сейчас архитектуру не додумать то потом уже не исправить, только переделывать.
Сдается мне что уже есть такое - тот же самый PEAR DB packages (с Zendом не работал).
Или не прав ?
sergdev,
всё верно, такого много, но это всё ЧУЖОЙ КОД.
PeaceCoder
23.02.2010, 16:12
e1f,
Да я уже думал об этом, хотелось бы вообще сделать такой класс, которому пишешь стандартизированный запрос, а класс его переделывает под ту или инную базу и его синтаксис.
Планирую ща следующее. изучить стандарт SQL, внести немного своих фич под свою CMS, а класс, как раз таки, стандартный синтаксис будет конверитровать под тот или иной тип базы данных учитывая фичи CMS.
Планирую сделать так что, например, модуль пользователей использует одну базу, а модуль групп другую, причем на разных типах баз.. а подав единый запрос включающий выборку с одной и другой базы, указав всего лишь модули и их таблицы, получить ответ....
свою CMS
Как говорил у нас в Волгограде на семинаре генеральный директор UMI.CMS Сергей Котырев: «Каждый PHP-программист должен написать свою CMS и забросить её». :)
PeaceCoder
23.02.2010, 16:40
Как говорил у нас в Волгограде на семинаре генеральный директор UMI.CMS Сергей Котырев: «Каждый PHP-программист должен написать свою CMS и забросить её
нее. она покруче joomla будет. она гибкая до жути. пиши сайт хоть через левое ухо правой рукой.
PeaceCoder,
Зачем нужно две БД одной CMS? В чём смысл? Так безопаснее? Быстрее? Почему не 5? Сервер железный, пусть работает?
PeaceCoder
23.02.2010, 17:16
Зачем нужно две БД одной CMS? В чём смысл?
ты сталкивался с таким когда модулю надо делать запросы к другой бд от которой зависит текущий результат из нашей бд? вот для этого.
Простой пример. сделано несколько сайтов на разных доменах и базах но с одним сервером..., более банальный пример - сайт альянса в игре. Все сайты кланов хранятся на разных доменах и серверах, но например по "соглашению" можно взять например темы новостей каждого клана и вывести на сайте альянса....
или например, сайт онлайн игры. все ссервера лучше размещать на отдельных серверах и базы соответсвенно... но инфа на главном сайте то должна быть?
Не, мне до такого не додуматься даже. Признаю свою вину, меру, степень, глубину....
ты сталкивался с таким когда модулю надо делать запросы к другой бд от которой зависит текущий результат из нашей бд? вот для этого.
так есть просто две БД или рассматривается вариант перехода с одной БД на другую?
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 - названия модулей.
Такой запрос будет действовать не зависимо от того какие базы юзают каждый из модулей и на каком они синтаксисе. При этом об префиксах можно будет вообще забыть. Они будут генерится автоматом =)
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. что меня больше всего смущает, так это то, что ты придумываешь проблему и начинаешь отстаивать ее актуальность. Нет чтобы просто сказать: "Интересно мне, любопытно или что там еще..." ;)
ты придумываешь проблему и начинаешь отстаивать ее актуальность
это из-за универа, без этого навыка диплом не сделать =)
нее. она покруче joomla будет. она гибкая до жути. пиши сайт хоть через левое ухо правой рукой.
дай автограф. :)
А по сути: кому писать сайт будет гибко - пользователям джумлы что-ли? Они писать умеют?
Joomla не самая гибкая CMS. Если говорить о гибкости, то ей нужно меряться с Drupal.
PeaceCoder
25.02.2010, 21:43
использованный диалект и преобразует в нужный?
именно. преобразует в соответствие с необходимым типом базы.
PeaceCoder, говноидея. Полностью согласен с x-yuri в том, что Вы выдумываете идею ради идеи.
PeaceCoder
26.02.2010, 10:26
PeaceCoder, говноидея.
Вы всем так говорите? Все что делаете не вы все говно? Вы даже не задумались какие возможно появляются...
Вы всем так говорите? Все что делаете не вы все говно? Вы даже не задумались какие возможно появляются...
Чорт, вот все Вы не так понимаете.
Ну, и какие же возможности появляются? Крошево запросов в веб-части како было, тако и осталось, зато они теперь какие-то мутные, и я плохо представляю себе, как написать их.
Далее, мне понадобился запрос, к примеру, с WITH. Mysql его не поддерживает, емнип. Я пишу -- все работает, потому что модули используются не mysql, а oracle, к примеру. Я радостно дописываю запрос и ухожу домой. Потом кто-то меняет в моем запросе только имя модуля, и вуаля -- ничего не пашет. Вот что тут делать пользователю Вашей "системы"? Надо садится, и руками переписывать sql-запросы. Как был каменный век, так и остался.
PeaceCoder
26.02.2010, 11:16
e1f,
Как выражается иногда subzey, я Вам соболезную.Потом кто-то меняет в моем запросе только имя модуля
Угу, ток при установке модуля в нем прописываются требования на использования других модулей и вот такой кто поменяет имя модуля должен и требования поменять. Иначе модуль вы не поставите. Не все так просто.
А причем тут требования на использование модулей? Или Вы имеете в виду, что я не смогу использовать модули Oracle и MySQL в одном запросе? Так толку тогда с такой системы, когда я вроде бы и могу
SELECT * FROM _oracle_db, _mysql_db
а на самом деле нет.
PeaceCoder
26.02.2010, 11:44
А причем тут требования на использование модулей?
Явно видно, что Вы не поняли вообще что я подразумеваю под словом "модуль" в моей цмс, а не в апаче. А то что вы имеете ввиду так это как раз и делает модуль работы с SQL.
модуль работы с SQL.
С каким именно sql? sql, он, знаете ли, разный :)
Ну и вдогонку -- все же, запросы будут формироватся пользователем вашей CMS? Как будет реализован квотинг данных? Забота об этом возлагается на пользователя?
PeaceCoder
26.02.2010, 14:22
запросы будут формироватся пользователем вашей CMS
Да. Будет стандартный синтаксис (шаблоны написания запросов), все остальное - функции не реазлизованные на той или инной БД берет на себя модуль. Например SELECT INTO не везде одиноков, но по стандарту он таков: "SELECT ... INTO ... FROM ......"
Как будет реализован квотинг данных?
А вот над этим я думаю, пытаюсь вообще все на автомат поставить. Потому как задолбало постоянно писать типа
$db->q("SELECT * FROM ... WHERE ...='".sql_escape($data)."'"
Может есть идеи как избавиться от функции ?
Может есть идеи как избавиться от функции ?
От sql_escape? PDO::prepare
Да. Будет стандартный синтаксис
Т.е. запрос будет в виде строки а потом будет парсится регулярками и приводиться к нужному виду?
Если делать грамотный 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
Посмотрите как там сделано
А вот кста, я так и не понял как сформировать запрос с сабзапросом?
А вот кста, я так и не понял как сформировать запрос с сабзапросом?
// Запрос номер 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 рулит
Рулит но не в том направлении в котором буду делать я. На счет сабов так и подумал...
только вот интересно как это происходит конкатенация если на выходе постоянно обьект, а не строка ?
Нужно определить в классе метод __toString() и он будет автоматически вызываться. Беглый осмотр кода кода Zend показал, что так оно и сделано.
class my_class {
function __toString()
{
return 'Вдруг как в сказке скрипнула дверь ;)';
}
}
$my_obj = new my_class();
print $my_obj;
Tim, а Zend вроде говорят очень объемная и массивная вешь. В плане научиться с ним работать. Так это?
Да там оч много всего (библиотеки в несжатом виде 20мб). Я сам далеко не всё знаю. Вот, оцените сами:
http://framework.zend.com/manual/ru/
Да там оч много всего (библиотеки в несжатом виде 20мб). Я сам далеко не всё знаю. Вот, оцените сами:
http://framework.zend.com/manual/ru/
Да посмотрел, спасибо. Впечатляет. Люблю ООП.
Есть же еще какая-то среда разработки Zend, платная вроде. Они как то связаны?
Я вообще сейчас задумал с Drupal разбираться. У нас в городе вроде востребован. Он же тоже как фреймворк. Правда без ООП но с хорошим стилем кодирования.
p.s. плюсик не хочет ставиться, на потом запомню :) .
Я вообще сейчас задумал с Drupal разбираться.
:) Я тоже. Пару недель назад две книги по нему купил. Одна по администрированию, другая чисто по кодингу. До этого с джумлой колупался - не нравится она мне что-то.
Есть же еще какая-то среда разработки Zend, платная вроде.
Zend Studio. М.б. и связаны. Я скрины посмотрел - не впечатлило, к тому же платная. Мне больше Netbeans нравится и Notepad++.
p.s. плюсик не хочет ставиться, на потом запомню
http://javascript.ru/forum/misc/7893-sokhranenie-peremennykh.html#post45967 ;)
Ещё можно так:
-> where('uid = (SELECT delta FROM blocks WHERE bid = 2)')
но это уже совсем быдлокодерство.
не так плох SQL, чтобы его использование считать быдлокодерством ;)
не так плох SQL, чтобы его использование считать быдлокодерством
Если есть уверенность, что это будет работать и в остальных типах БД, тогда SQL не плох.
Недавно слышал, как хвалили http://www.redbeanphp.com/ :)
vBulletin® v3.6.7, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot