LINUX.ORG.RU

mysqli: Adds support for the improved mySQL libraries

PDO - The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP

я не спец, по получается что это разные вещи

ZuBB ★★★★★
()
Ответ на: комментарий от ZuBB

PDO - унифицированный интерфейс к различным базам данных
mysqli - интерфейс к mysql

Olegymous ★★★
()
Ответ на: комментарий от trashymichael

PDO — тормоз. А для любого приличного ORM пофиг на бэкенд :) Я, вот, до сих пор проверенный mysql использую, вообще…

KRoN73 ★★★★★
()
Ответ на: комментарий от no-dashi

Ты уцепился взглядом в единственное известное тебе - mysql и не заметил слово ORM? Дай угадаю, ты до сих пор SQL-запросы самостоятельно пишешь?

KRoN73 ★★★★★
()
Ответ на: комментарий от no-dashi

Я последний SQL-запрос писал, наверное, года два назад :) Так что - вполне уложить можно.

А когда дело до SQL доходит, то, представь себе, я тоже не ручками контактенацией строк запросы писал. А через тот же свой mysql-драйвер, на котором ORM работает. И который вопросы инъекций тоже все на себя сам берёт.

Последний раз SQL-запрос с ручной контактенацией, дай бог, я лет 5 назад писал. И то под Java :D

KRoN73 ★★★★★
()
Ответ на: lol от anonymous

Угу :)

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous_0

Покажи, пожалуйста, код, который генерирует запрос с inner и left join одновременно.

На высоком уровне я вручную этим не занимаюсь. Уточни конкретнее, что тебя интересует с практической точки зрения.

На низком это будет в духе

$related_news = bors_find_all('aviaport_digest_atom', array(
    'inner_join' => 'rubrics_high_cross ON (news_id=aviaport_digest_atom.id AND high_id=8)',
//  'left_join' => ...
    'create_time>' => time() - 86400*30,
    'order' => '-create_time',
    'limit' => 4,
));

Но это уже не сильно далеко от чистого SQL.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Ну например, есть тарифы и группы клиентов. Некоторые (не все) тарифы можно назначить некоторым группам клиентов. И нужно сделать админку для этого.

Я сделал так: таблица тарифов, групп клиентов и еще одна таблица, где только два столбца (primary key из id группы клиента и тарифа) и строки только для тех сочетаний, какой группе что назначено. Для админки я строю таблицу: по горизонтали тарифы, по вертикали группы клиентов, на пересечении - чекбоксы. Соответсвенно и запрос будет: тарифы cross join группы клиентов left join применимость.

А ты бы как на своей ORM эту задачу реализовал?

anonymous_0
()
Ответ на: комментарий от anonymous_0

>Ну например, есть тарифы и группы клиентов. Некоторые (не все) тарифы можно назначить некоторым группам клиентов. И нужно сделать админку для этого.

Каждая сущность - отдельный объект. Простые связи (1xM) делаются чаще в рамках одного из объектов, множественные или унифицированные - отдельными таблицами, для этого есть специальная сущность связей. У меня много подобных связок :)

Для админки я строю таблицу: по горизонтали тарифы, по вертикали группы клиентов, на пересечении - чекбоксы. Соответсвенно и запрос будет: тарифы cross join группы клиентов left join применимость.


Админка не требует высокой производительности, так что я обычно вообще тупо в коде в циклах все нужные данные вытаскиваю и скармливаю их шаблону. 0,5 сек. вместо 0,05 в случае админки погоды не сделают :) Зато получается универсальный вариант, не привязанный не только к бэкенду, но и даже к структуре объектов. Лишь бы методы проверочные совпадали.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Ну, я так и думал. ORM хорошо справляется с задачами «взял из базы по ид - положил в базу по ид». А если надо чуть посложнее, то начинается: либо в цикле долбить базу запросами, либо писать что-то в стиле

array('AND' => array(
  'id' => 'IN ...'
  'id_group' => 3
)
  'OR' => array(...)
)

и не дай б-же запутаться в скобках или пожелать использовать функции sql.

>Админка не требует высокой производительности, так что я обычно вообще тупо в коде в циклах все нужные данные вытаскиваю и скармливаю их шаблону. 0,5 сек. вместо 0,05 в случае админки погоды не сделают :)

Бугага. Тебе, видимо, не приходилось переписывать админку на plain sql, потому что клиент накидал чуть больше данных, чем в демо-версии, и написанный по всем правилам ORM скрипт перестал пролазить в 30-секундный временнОй лимит. Админка тупо не могла загрузиться то конца (да и хостер начал грозить карами). Я тогда из него выжал 130-кратное ускорение.

anonymous_0
()
Ответ на: комментарий от anonymous_0

>Тебе, видимо, не приходилось переписывать админку на plain sql, потому что клиент накидал чуть больше данных, чем в демо-версии, и написанный по всем правилам ORM скрипт перестал пролазить в 30-секундный временнОй лимит

Нет, не приходилось. Дже с миллионами записей и гиговыми базами админки обычно укладываются в десятые доли секунды :) 30 секунд — это сотни гигов, что ли? Нет, с такими объёмами я не работал, слава Богу :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Какие сотни гигов? Там вся база уложилась бы в мегабайт. Я подробности плохо помню за давностью, но там было что-то вроде 3-хуровневной вложенности объектов с отношением «один ко многим» и на каждом уровне оно автоматом разворачивалось в цикл для каждого объекта. И доразворачивалось до того, что одних запросов было около 1500 плюс обработка всего этого.

anonymous_0
()
Ответ на: комментарий от anonymous_0

Там вся база уложилась бы в мегабайт.

И по 30 секунд в админке?? Что-то тут не так. Мегабайтную базу можно, вообще, целиком загрузить за несколько секунд :)

но там было что-то вроде 3-хуровневной вложенности объектов с отношением «один ко многим»

Боюсь, что это, скорее всего, ошибка в дизайне. Типа, один «вложенный» объект — один запрос. Я обычно в таком случае собираю все нужные ID объектов и делаю один запрос на загрузку массивов.

При чём фреймворк организован так, что можно сперва вообще тупо использовать «ленивую» загрузку связанных объектов (по запросу на объект). Если не хватает производительности — добавляется буквально по 1-2 строчки для предзагрузке этих объектов одним запросом. Скажем, у нас есть массив сообщений форума, $posts. Там есть свойство/метод user_id, возвращающий ID юзера. Загрузка полноценного объекта user — это отдельный запрос. Типа,

{foreach from=$this->posts() item="p"}
<p>Сообщение {$p->title()} написал {$p->user()->title()}</p>
{/foreach}
Тут каждый вызов user() сгенерирует SQL-запрос. Когда дело доходит до оптимизации, мы в контроллере пишем:
function pre_show()
{
    bors_objects_preload($this->posts(), 'user_id', 'forum_user', 'user'); 
    // Массив, ID субэлемента, имя класса, куда записывать результат
    // user() == bors_load('forum_user', $user_id) для каждого $post
}
и у нас одним запросом загрузятся все объекты юзера в массив постов.

Обычно для 99.9% задач такого уровня оптимизации уже хватает даже для основных страниц с высокой загрузкой. Ну а если не хватает (скажем, страница генерится 0,5 сек., а запросов от пользователей по 100 в секунду), то там уже можно и статическое кеширование включить :)

KRoN73 ★★★★★
()

вы здесь упоролись чтоле?! я вам задал прямой вопрос. началось про ОRM Крона и анонимуса который его донимает. кстати Крон посоветуй что нить для развития скила в php и работай с бд, и что кроме вики почитать про орм.

ggrn ★★★★★
() автор топика
Ответ на: комментарий от ggrn

>кстати Крон посоветуй что нить для развития скила

У меня основной источник всех знаний по PHP — это php.net :) В какой-то степени ещё отдельные статьи, результаты того или иного гугления. Систематически PHP никогда не изучал. С БД аналогично. Ну а когда впервые услышал про ORM и MVC (довольно поздно, надо сказать, и в Java), то уже их использовал на практике, не зная, что они так называются ;)

KRoN73 ★★★★★
()

лично у меня вот такой индусокод

class db {
    private $server = '';
    private $user = '';
    private $pass = '';
    private $dbname = '';
    private $pfx = '';
    private $link;
    private $state = 0;
    const state_not_initialized = 0;
    const state_error_connect = 1;
    const state_error_dbselect = 2;
    const state_connected = 3;
    function __construct() {
        $s = $GLOBALS['config']['db'];
        $this->link = @mysql_pconnect($s['server'], $s['user'], $s['pass']);
        if (!$this->link) {
            $this->state = self::state_error_connect;
            return;
        }
        $db_selected = mysql_select_db($s['dbname'], $this->link);
        if (!$db_selected) {
            $this->state = self::state_error_dbselect;
            return;
        }
        $this->state = self::state_connected;
        $this->server = $s['server'];
        $this->user   = $s['user'];
        $this->pass   = $s['pass'];
        $this->dbname = $s['dbname'];
        $this->pfx    = $s['pfx'];
    }
    function __destruct() {
        if (is_resource($this->link)) {
            mysql_close($this->link);
            $this->state = self::state_not_initialized;
        }
    }
    public function __get($name) {
        if ($name != 'link' and isset($this->$name)) {
            return $this->$name;
        }
    }
    public function escape($str) {
        return mysql_real_escape_string($str, $this->link);
    }
    public function query($q, $args = array()) {
        if ($this->state != self::state_connected) {
            return;
        }
        array_walk($args, array($this, 'escape'));
        $query = vsprintf($q, $args);
        $res = mysql_query($query, $this->link);
        if (!$res) {
            return mysql_errno($this->link).": ".mysql_error($this->link);
        }
        if (!is_resource($res)) {
            return $res;
        }
        $r = array();
        while ($row = mysql_fetch_assoc($res)) {
            $r[] = $row;
        }
        mysql_free_result($res);
        return $r;
    }
    public function insert_id() {
        return mysql_insert_id($this->link);
    }
}

//
$db = new db();
var_dump($db->query('select * from %stable where id=%d', array($db->pfx, 13)));
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.