Показаны сообщения с ярлыком mysql. Показать все сообщения
Показаны сообщения с ярлыком mysql. Показать все сообщения
четверг, 28 марта 2024 г.
CDC репликация средствами Debezium и Kafka Connect
Метки:
bigdata,
debezium,
kafka,
kafka connect,
mysql
Настрока CDC репликации данных между реляционной бд MySql и Kafka
понедельник, 28 апреля 2014 г.
Две заметки о Bitrix
Метки:
bitrix,
CCatalogProduct,
CCatalogStoreProduct,
iblock,
mysql,
php,
SetBasePrice
1. Для создания сложных форм на bitrix я использую кастомный компонент в котором вытаскиваю все данные о инфоблоке с помощью такого запроса:
Запрос берет информацию о полях и свойствах инфоблока. Если поле ссылочное, то функцию можно вызывать рекурсивно.
2. Особенность создания товарных предложений через код.
Создали мы товарное предложение через код:
Задали цену:
Заполнили остатки:
Вроде все. Но товар не покупается, хотя все атрибуты присутствуют.
Чтобы все заработало, нужно еще раз добавить (именно добавить, а не обновить) предложение, но другой функцией:
function getIblockProps($id) { global $DB; $sql = "SELECT b.id, b.code, b.name, ----- p.id as pid, p.code as pcode, p.name as pname, p.SORT psort, UPPER(CASE WHEN p.USER_TYPE IS NOT NULL THEN p.USER_TYPE WHEN p.PROPERTY_TYPE = 'S' AND p.ROW_COUNT > 1 THEN 'T' ELSE p.PROPERTY_TYPE END) as ptype, CASE WHEN p.MULTIPLE = 'Y' THEN 1 END as pmultiple, CASE WHEN p.MULTIPLE = 'Y' THEN p.MULTIPLE_CNT END pmultiple_cnt, CASE WHEN p.LINK_IBLOCK_ID > 0 THEN p.LINK_IBLOCK_ID END as piblock, CASE WHEN p.IS_REQUIRED = 'Y' THEN p.IS_REQUIRED END preq, p.HINT as phint, ----- e.ID as eid, e.VALUE as evalue, e.DEF as edef, e.SORT as esort FROM b_iblock b , b_iblock_property p LEFT JOIN b_iblock_property_enum e ON(e.property_id = p.id) WHERE b.id = %u AND b.id = p.IBLOCK_ID AND p.ACTIVE = 'Y' ORDER BY p.sort,e.SORT"; $rs = $DB->Query( sprintf( $sql, intval($id) ) ); $rows = array(); while ($row = $rs->Fetch()) { $rows[] = $row; } return $rows; }
Запрос берет информацию о полях и свойствах инфоблока. Если поле ссылочное, то функцию можно вызывать рекурсивно.
2. Особенность создания товарных предложений через код.
Создали мы товарное предложение через код:
$el = new CIBlockElement; $id = $el->Add($arFields);
Задали цену:
CPrice::SetBasePrice( $id, $arFields['PRICE'], "RUB", 1);
Заполнили остатки:
$arFields = Array( "PRODUCT_ID" => $id, "STORE_ID" => 1, "AMOUNT" => $v['Количество'], ); CCatalogStoreProduct::Add($arFields);
Вроде все. Но товар не покупается, хотя все атрибуты присутствуют.
Чтобы все заработало, нужно еще раз добавить (именно добавить, а не обновить) предложение, но другой функцией:
$arFields = array('ID'=>$id, 'PRICE_TYPE' => 'S', 'QUANTITY' => floatval($f['Количество'])); CCatalogProduct::Add($arFields);
суббота, 1 декабря 2012 г.
Советы по оптимизации SQL запросов
Поделюсь опытом, который получил за несколько лет оптимизации sql запросов. Большая часть советов касается субд ORACLE.
Если кому статья покажется слишком очевидной, то считайте это заметкой чисто для себя, чтобы не забыть.
Другие статьи по оптимизации SQL
1. Ни каких подзапросов, только JOIN
Как я уже писал ранее, если выборка 1 к 1 или надо что-то просуммировать, то ни каких подзапросов, только join.
Стоит заметить, что в большинстве случаев оптимизатор сможет развернуть подзапрос в join, но это может случиться не всегда.
2. Выбор IN или EXISTS ?
На самом деле это сложный выбор и правильное решение можно получить только опытным путем.
Я дам только несколько советов:
* Если в основной выборке много строк, а в подзапросе мало, то ваш выбор IN. Т.к. в этом случае запрос в in выполнится один раз и сразу ограничит большую основную таблицу.
* Если в подзапросе сложный запрос, а в основной выборке относительно мало строк, то ваш выбор EXISTS. В этом случае сложный запрос выполнится не так часто.
* Если и там и там сложно, то это повод изменить логику на джойны.
3. Не забывайте про индексы
Совет для совсем новичков: вешайте индексы на столбцы по которым джойните таблицы.
4. По возможности не используйте OR.
Проведите тесты, возможно UNION выглядит не так элегантно, за то запрос может выполнится значительно быстрей. Причина в том, что в случае OR индексы почти не используются в join.
5. По возможности не используйте WITH в oracle.
Значительно облегчает жизнь, если запрос в with необходимо использовать несколько раз ( с хинтом materialize ) в основной выборке или если число строк в подзапросе не значительно.
Во всех других случаях необходимо использовать прямые подзапросы в from или взаранее подготовленную таблицу с нужными индексами и данными из WITH.
Причина плохой работы WITH в том, что при его джойне не используются ни какие индексы и если данных в нем много, то все встанет. Вторая причина в том, что оптимизатору сложно определить сколько данных нам вернет with и оптимизатор не может построить правильный план запроса.
В большинстве случаев WITH без +materialize все равно будет развернут в основной запрос.
6. Не делайте километровых запросов
Часто в web обратная проблема - это много мелких запросов в цикле и их советуют объединить в один большой. Но тут есть свои ограничения, если у вас запрос множество раз обернутый в from, то внутреннюю(ие) части надо вынести в отдельную выборку, заполнить временную таблицу, навесить индексы, а потом использовать ее в основной выборке. Скорость работы будет значительно выше (в первую очередь из-за сложности построения оптимального плана на большом числе сочетаний таблиц)
7. Используйте KEEP взамен корреляционных подзапросов.
В ORACLE есть очень полезные аналитические функции, которые упростят ваши запросы. Один из них - это KEEP.
KEEP позволит сделать вам сортировку или группировку основной выборки без дополнительно запроса.
Пример: отобрать контрагента для номенклатуры, который раньше остальных был к ней подвязан. У одной номенклатуры может быть несколько поставщиков.
Но не злоупотребляйте большим числом аналитических функций, особенно если они имеют разные сортировки. Каждая разная сортировка - это новое сканирование окна.
8. Гуляние по выборке вверх-вниз
Менее популярная функция, но не менее полезная. Позволяет смещать текущую строку выборки на N элементов вверх или вниз. Бывает полезно, если необходимо сравнить показатели рядом стоящих строк.
Следующий пример отбирает продажи департаментов отсортированных по дате. К основной выборке добавляются столбцы со следующим и предыдущим значением выручки. Второй параметр - это на сколько строк сместиться, третьи - параметр по-умолчанию, если данные соседа не нашлись.
9. Direct Path Read
Установка этой настройки (настройкой или параллельным запросом) - чтение данных напрямую в PGA, минуя буферный кэш. Что укоряет последующие этапы запроса, т.к. не используется UNDO и защелки совместного доступа.
10. Direct IO
Использование прямой записи/чтения с диска без использования буфера файловой системы (файловая система конкретно для СУБД).
* В случае чтения преимущество в использовании буферного кэша БД, замен кэша ФС (кэш бд лучше заточен на работу с sql)
* В случае записи, прямая запись гарантирует, что данные не потеряются в буфере ФС в случае выключения электричества (для redolog всегда использует fsync, в не зависимости от типа ФС)
11. Оптимизация параллельных запросов
12. Оценка стоимости запроса и построение правильного плана
13. Оптимизация работы секционированных таблиц
14. Индексный поиск
15. Оптимизация запросов вставки
16. Ускорение pl/sql циклов
17. И другое...
Если кому статья покажется слишком очевидной, то считайте это заметкой чисто для себя, чтобы не забыть.
Другие статьи по оптимизации SQL
1. Ни каких подзапросов, только JOIN
Как я уже писал ранее, если выборка 1 к 1 или надо что-то просуммировать, то ни каких подзапросов, только join.
Стоит заметить, что в большинстве случаев оптимизатор сможет развернуть подзапрос в join, но это может случиться не всегда.
2. Выбор IN или EXISTS ?
На самом деле это сложный выбор и правильное решение можно получить только опытным путем.
Я дам только несколько советов:
* Если в основной выборке много строк, а в подзапросе мало, то ваш выбор IN. Т.к. в этом случае запрос в in выполнится один раз и сразу ограничит большую основную таблицу.
* Если в подзапросе сложный запрос, а в основной выборке относительно мало строк, то ваш выбор EXISTS. В этом случае сложный запрос выполнится не так часто.
* Если и там и там сложно, то это повод изменить логику на джойны.
3. Не забывайте про индексы
Совет для совсем новичков: вешайте индексы на столбцы по которым джойните таблицы.
4. По возможности не используйте OR.
Проведите тесты, возможно UNION выглядит не так элегантно, за то запрос может выполнится значительно быстрей. Причина в том, что в случае OR индексы почти не используются в join.
5. По возможности не используйте WITH в oracle.
Значительно облегчает жизнь, если запрос в with необходимо использовать несколько раз ( с хинтом materialize ) в основной выборке или если число строк в подзапросе не значительно.
Во всех других случаях необходимо использовать прямые подзапросы в from или взаранее подготовленную таблицу с нужными индексами и данными из WITH.
Причина плохой работы WITH в том, что при его джойне не используются ни какие индексы и если данных в нем много, то все встанет. Вторая причина в том, что оптимизатору сложно определить сколько данных нам вернет with и оптимизатор не может построить правильный план запроса.
В большинстве случаев WITH без +materialize все равно будет развернут в основной запрос.
6. Не делайте километровых запросов
Часто в web обратная проблема - это много мелких запросов в цикле и их советуют объединить в один большой. Но тут есть свои ограничения, если у вас запрос множество раз обернутый в from, то внутреннюю(ие) части надо вынести в отдельную выборку, заполнить временную таблицу, навесить индексы, а потом использовать ее в основной выборке. Скорость работы будет значительно выше (в первую очередь из-за сложности построения оптимального плана на большом числе сочетаний таблиц)
7. Используйте KEEP взамен корреляционных подзапросов.
В ORACLE есть очень полезные аналитические функции, которые упростят ваши запросы. Один из них - это KEEP.
KEEP позволит сделать вам сортировку или группировку основной выборки без дополнительно запроса.
Пример: отобрать контрагента для номенклатуры, который раньше остальных был к ней подвязан. У одной номенклатуры может быть несколько поставщиков.
SELECT n.ID, MIN(c.ID) KEEP (DENSE_RANK FIRST ORDER BY c.date ASC) as cnt_id FROM nmcl n, cnt c WHERE n.cnt_id = c.id GROUP BY n.IDПри обычном бы подходе пришлось бы делать корреляционный подзапрос для каждой номенклатуры с выбором минимальной даты.
Но не злоупотребляйте большим числом аналитических функций, особенно если они имеют разные сортировки. Каждая разная сортировка - это новое сканирование окна.
8. Гуляние по выборке вверх-вниз
Менее популярная функция, но не менее полезная. Позволяет смещать текущую строку выборки на N элементов вверх или вниз. Бывает полезно, если необходимо сравнить показатели рядом стоящих строк.
Следующий пример отбирает продажи департаментов отсортированных по дате. К основной выборке добавляются столбцы со следующим и предыдущим значением выручки. Второй параметр - это на сколько строк сместиться, третьи - параметр по-умолчанию, если данные соседа не нашлись.
SELECT deptno, empno, sal, LEAD(sal, 1, 0) OVER (PARTITION BY dept ORDER BY date) NEXT_LOWER_SAL, LAG(sal, 1, 0) OVER (PARTITION BY dept ORDER BY date) PREV_HIGHER_SAL FROM emp; ORDER BY deptno, date DESC;При обычном подходе бы пришлось это делать через логику приложения.
9. Direct Path Read
Установка этой настройки (настройкой или параллельным запросом) - чтение данных напрямую в PGA, минуя буферный кэш. Что укоряет последующие этапы запроса, т.к. не используется UNDO и защелки совместного доступа.
10. Direct IO
Использование прямой записи/чтения с диска без использования буфера файловой системы (файловая система конкретно для СУБД).
* В случае чтения преимущество в использовании буферного кэша БД, замен кэша ФС (кэш бд лучше заточен на работу с sql)
* В случае записи, прямая запись гарантирует, что данные не потеряются в буфере ФС в случае выключения электричества (для redolog всегда использует fsync, в не зависимости от типа ФС)
11. Оптимизация параллельных запросов
12. Оценка стоимости запроса и построение правильного плана
13. Оптимизация работы секционированных таблиц
14. Индексный поиск
15. Оптимизация запросов вставки
16. Ускорение pl/sql циклов
17. И другое...
суббота, 7 ноября 2009 г.
Модуль связи PunBB 1.3 и Drupal 6
Модуль связи PunBB и Drupal
Изменения:
1. Переработка модуля для версии Drupal 6
2. Усложнение авторизации и регистрации форума punbb привело к изменению модуля.
Напомню еще раз характеристики:
Только через Drupal. Рекомендую на пунбб вообще отключить регистрацию.
1. Единая регистрация
2. Единая авторизация
3. Единый выход
4. Единая смена учетных данных (В данной версии: почта, временная зона и пароль)
5. Анонс нодов на форуме
Доступ внутри node к информации о топике:
Дата разработки: ноябрь 2009
Основное место обсуждения
Скачать архив (Размер файла: 8КБ)
Изменения:
1. Переработка модуля для версии Drupal 6
2. Усложнение авторизации и регистрации форума punbb привело к изменению модуля.
Напомню еще раз характеристики:
Только через Drupal. Рекомендую на пунбб вообще отключить регистрацию.
1. Единая регистрация
2. Единая авторизация
3. Единый выход
4. Единая смена учетных данных (В данной версии: почта, временная зона и пароль)
5. Анонс нодов на форуме
Доступ внутри node к информации о топике:
$node['punbb'] == array('id', //ид топика 'subject', //тема топика 'posted', //автор топика 'url'); //url до топика на форуме
Дата разработки: ноябрь 2009
Основное место обсуждения
Скачать архив (Размер файла: 8КБ)
четверг, 29 октября 2009 г.
Продажа контента за SMS
Метки:
оплата,
платный доступ,
смс,
технология,
drupal,
mysql,
php,
sms
Сейчас очень распространенным стала оплата услуг и товаров через СМС. Но не многие знают как это все организовано.
Я бы хотел рассказать об одном из простых способов.
Рассмотрим пример оплаты и прокомментируем каждый этап исходным кодом на PHP.
0. Размещению на сайте оплаты через смс предшествует заключение договора с компанией предоставляющей эти услуги.
1. Пользователь заходит на страничку, где ему предлагается скачать приложение, предварительно отослав смс с текстом на указанный номер.
Реализация: Выводится статичные текст с текстом и телефоном, который предоставила на предыдущем этапе организация
2. Клиент отправляет СМС. Ему приходит ответная с уникальным кодом на доступ
Реализация: Сервер смс компании, получает сообщение с нужным тектом на номер. Генерируется событие, вызывающее произвольную (настраиваемую) страницу на нашем сайте. На это странице мы произвольны сделать, что угодно.
Генерируем код, и записываем в БД:
На данном этапе код еще не привязан ни к одному материалу и его можно активировать на любом.
3. Клиент получил код, вводит его, чтобы получить доступ к материалу
Реализация: Сервер сайт получает код, проверяет его наличие в БД. Если код верный, то в БД вносятся данные о файле к которому был получен доступ, также для защиты от передачи кода третьим лицам в бд заносится ip адрес клиента и ставится кука.
Файл может быть скачан не сразу, а по частям. В этом случае пользователю дается несколько часов на скачку файла: в бд заносим также время первого обращения к файлу.
После этого пользователю файл стримится прямо в браузер с утановкой необходимых хеадреов, чтобы у клиента не было прямого доступа к файлу (Об этом можно почитать отдельно, я пользуюсь стандартными функциями Drupal)
4. Клиент повторно обращается к этому же файлу.
Реализация: При повторном обращении к файлу, снова проверять код не обязательно. Необходимо сверить лишь куки и ip пользователя, а также id файла к которому идет обращение.
5. Если пользователь пытается обратится к другому файлу с этим же кодом, то это ему не удастся, т.к. он не пройдет проверку по id файла.
6. Код был передан третьим лицам. Пользователь не пройдет проверку по ip и куке.
Примерный код для предыдущих пунктов можно видеть в листинге: (php/Drupal, точка входа функция sms_pay_file_download)
Я бы хотел рассказать об одном из простых способов.
Рассмотрим пример оплаты и прокомментируем каждый этап исходным кодом на PHP.
0. Размещению на сайте оплаты через смс предшествует заключение договора с компанией предоставляющей эти услуги.
1. Пользователь заходит на страничку, где ему предлагается скачать приложение, предварительно отослав смс с текстом на указанный номер.
Реализация: Выводится статичные текст с текстом и телефоном, который предоставила на предыдущем этапе организация
2. Клиент отправляет СМС. Ему приходит ответная с уникальным кодом на доступ
Реализация: Сервер смс компании, получает сообщение с нужным тектом на номер. Генерируется событие, вызывающее произвольную (настраиваемую) страницу на нашем сайте. На это странице мы произвольны сделать, что угодно.
Генерируем код, и записываем в БД:
function getCOde() { $code = sprintf("%06x", rand(1000000, 10000000)); //рандомное число, преобразованное в hex //проверяем на повторения $res = db_query("SELECT COUNT(*) AS cnt FROM {sms_pay} WHERE code = '%s'", $code); $codes = db_fetch_array($res); if($codes['cnt'] > 0) { getCode(); //генерируем еще раз } db_query("INSERT INTO {sms_pay} (code) VALUES('%s')", rand(), $code); //записываем код в БД return $code; }Сгенерированный код, вываливается через echo в браузер, а сервер весь сгенерированый текст отправляет в виде смс обратно клиенту.
На данном этапе код еще не привязан ни к одному материалу и его можно активировать на любом.
3. Клиент получил код, вводит его, чтобы получить доступ к материалу
Реализация: Сервер сайт получает код, проверяет его наличие в БД. Если код верный, то в БД вносятся данные о файле к которому был получен доступ, также для защиты от передачи кода третьим лицам в бд заносится ip адрес клиента и ставится кука.
Файл может быть скачан не сразу, а по частям. В этом случае пользователю дается несколько часов на скачку файла: в бд заносим также время первого обращения к файлу.
После этого пользователю файл стримится прямо в браузер с утановкой необходимых хеадреов, чтобы у клиента не было прямого доступа к файлу (Об этом можно почитать отдельно, я пользуюсь стандартными функциями Drupal)
4. Клиент повторно обращается к этому же файлу.
Реализация: При повторном обращении к файлу, снова проверять код не обязательно. Необходимо сверить лишь куки и ip пользователя, а также id файла к которому идет обращение.
5. Если пользователь пытается обратится к другому файлу с этим же кодом, то это ему не удастся, т.к. он не пройдет проверку по id файла.
6. Код был передан третьим лицам. Пользователь не пройдет проверку по ip и куке.
Примерный код для предыдущих пунктов можно видеть в листинге: (php/Drupal, точка входа функция sms_pay_file_download)
суббота, 22 августа 2009 г.
Конструктор тестов с экпортом
Конструктор тестов/опросов/голосовании с возожностью экспорта на стороние сайты (самих тестов и статистики)
Характеристики: php, mysql, ajax, jsonp, jquery
Дата разработки: март-май 2009
Скачать архив (Размер файла: 59 КБ)
Характеристики: php, mysql, ajax, jsonp, jquery
Дата разработки: март-май 2009
Скачать архив (Размер файла: 59 КБ)
SimplePDO
Класс расширяющий и упрощающий работу с PDO
Синтаксис:
Дата разработки: июль 2008
Скачать архив (Размер файла: 4КБ)
Синтаксис:
$r = $sp->query("insert into ?_url_alias(src, dst) VALUES(%s, %s)", "tst", "test"); echo $sp->query("update ?_url_alias set dst = %s where pid = %u", "tst1", $r); print_r($sp->selectCol("{?_url_alias} select * from ?_url_alias")); print_r($sp->selectRow("{?_url_alias} select * from ?_url_alias where pid = %u and dst = %s", 1, "news")); print_r($sp->select("select * from ?_url_alias"));Возможности: плэйсхолдеры, кэширование, перфиксы таблиц, выборка таблиц/строк/ячеек/столбцов
Дата разработки: июль 2008
Скачать архив (Размер файла: 4КБ)
Модуль связи PunBB и Drupal
Модуль связи PunBB и Drupal
Только через Drupal. Рекомендую на пунбб вообще отключить регистрацию.
1. Единая регистрация
2. Единая авторизация
3. Единый выход
4. Единая смена учетных данных (В данной версии: почта, временная зона и пароль)
5. Анонс нодов на форуме
Дата разработки: февраль - апрель 2008
Основное место обсуждения
Скачать архив (Размер файла: 8КБ)
Только через Drupal. Рекомендую на пунбб вообще отключить регистрацию.
1. Единая регистрация
2. Единая авторизация
3. Единый выход
4. Единая смена учетных данных (В данной версии: почта, временная зона и пароль)
5. Анонс нодов на форуме
Дата разработки: февраль - апрель 2008
Основное место обсуждения
Скачать архив (Размер файла: 8КБ)
WikiMedia
Wiki движок
Особенность от обычного wiki: возможность создания виджетов (программ написанных на внутреннем языке движка (подмножестве PHP)), с целью автоматизации процессов внутри сайта
Основные виджеты: вставка аудио/видео, сжатие картинок, преобразование ссылок (виджеты можно создавать самому)
Характеристики: php/mysql/mod_rewrite
Дата разработки: октябрь-декабрь 2007
Скачать архив (размер файла: 3221КБ, внутри есть полное описание проекта)
Особенность от обычного wiki: возможность создания виджетов (программ написанных на внутреннем языке движка (подмножестве PHP)), с целью автоматизации процессов внутри сайта
Основные виджеты: вставка аудио/видео, сжатие картинок, преобразование ссылок (виджеты можно создавать самому)
Характеристики: php/mysql/mod_rewrite
Дата разработки: октябрь-декабрь 2007
Скачать архив (размер файла: 3221КБ, внутри есть полное описание проекта)
PHP-CRAFT
Портальная система для создания сайтов:
Харктеристики: PHP/MYSQL/MOD_REWRITE/модульность/блочность/смена тем/wysiwig
Дата создания: 2004-2006 года
Скачать файл (Размер архива: 1043КБ)
Харктеристики: PHP/MYSQL/MOD_REWRITE/модульность/блочность/смена тем/wysiwig
Дата создания: 2004-2006 года
Скачать файл (Размер архива: 1043КБ)
Подписаться на:
Сообщения (Atom)