четверг, 10 сентября 2009 г.

Немного о контроле версий.

Всегда у меня была проблема с хранением разрабатываемых проектов. Точнее проблемы-то никакой и не было. Есть задача: имеется несколько рабочих мест - домашний десктоп, ноутбук, и рабочий компьютер. Есть флэшка, на которой хранятся разработки. На каждом рабочем месте я мог доработать любой из своих проектов. Казалось бы - работай сразу с флэшки и будет тебе счастье, однако счастья не было. Бывали моменты, когда нужно было просмотреть внесенные изменения, или откатить уже сделанные. При работе напрямую приходится делать копии проекта для доработок, при этом становится уже практически невозможно отследить сделанные изменения. Я использовал вариант хранения, когда после каждой доработки проекта, я создавал архив с названием, содержащим имя проекта и дату в формате ггггммдд. Такой формат даты позволял сортировать данные файлы по старшинству и вроде был порядок. Всегда можно было посмотреть состояние проекта на какую либо дату.
Однако, по какому-то наитию, я наткнулся на систему котроля версий SubVersion. Эта система захватила меня целиком и полностью. Я создал репозитории для всех своих проектов на флешке, все рабочие места оборудовал клиентом TortoiseSVN (Очень удобный клиент, интегрируется в среду Windows, содержит инструменты для просмотра изменений). Все эти продукты имеют подробную документацию на русском языке. Кстати говоря, при установке клиента TortoiseSVN, не требуется наличия SubVersion, она включена в установку. Однако, я так и не смог выполнять команды администрирования SubVersion с командной строки.
Дальше меня захватила идея - поднять дистанционный репозиторий, доступный по интернету. Немного "плясок с бубном" и это получилось. (О том, как это происходило, следует написать отдельный пост). Надо сказать, что в дальнейшем я планирую все свои проекты перевести на дистанционный сервер, а еще вызревает идея создания SubVersion хостинга.
Возможно, эта задача не по силам одному программисту, поэтому если кто-то считает целесообразным открытие подобного сервиса, прошу обращаться в асю 66двенадцать11, или на почту odmin@odmin.name

вторник, 8 сентября 2009 г.

Пара граблей в MySQL, на которые часто любят наступать при разработке CMS

Неоднократно сталкиваюсь с такими ситуациями, что CMS рассчитаные на широкий круг вебмастеров и включающие в себя ненужную кучу дополнительных возможностей, начинают тормозить при количестве статей более 1000.
Конкретные примеры организации баз данных показывают, что либо у разработчиков нет понимания процессов, либо просто, как это часто бывает, модернизация и расширение функциональности делается непродумано и наспех.
В результате таких спешек появляются таблицы, содержащие текстовые поля, информация в которых неоднократно дублируется. Например, таблица статистики показа банеров.


CREATE TABLE `test`.`baner_stat` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`url` VARCHAR(255) NOT NULL DEFAULT '',
`baner_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
)
ENGINE = InnoDB;

Очевидно, что поле url в данной таблице используется для идентификации страницы, на которой был показан банер. Например будет 10000 показов банера на странице /the_most_popular_chapter/very_delicious_page_in_most_popular_chapter.html
Тогда url этой страницы будет записан 10000 раз в это поле.
При создании отчетов по статистике, с группировкой по странице просмотра, такой запрос будет выполнятся крайне долго. Однако, если вы хотите еще более ухудшить ситуацию, тогда следует создать индекс по полю url.
При каждом просмотре банера, при такой организации хранения данных, будет создаваться команда на вставку строки, следовательно будет происходить построение индекса и вставка замедлится в разы. Очевидно, это плохая идея.
В данном случае есть несколько вариантов решения. Если нас интересуют только просмотры и гибкая сатистика нам не нужна, то следует добавить в эту таблицу целочисленное поле счетчика просмотров. Тогда нам будет необходимо сделать два запроса к базе - 1-й нахождение ID строки по URL (здесь целесообразно использовать индекс), если мы нашли ID, то делаем UPDATE данной таблицы, увеличивая счетчик просмотров на единицу, в противном случае - вставляем новую строку с новым URL.
2-й вариант сводится к разнесению данных на две таблицы - словарную и регистрационную. На мой взгляд, данный вариант более красивый и логичный. Словарная талица:


CREATE TABLE `test`.`baner_url` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`url` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`),
INDEX `Index`(`url`)
)
ENGINE = InnoDB;


и таблица регистрации просмотров:


CREATE TABLE `test`.`baner_stat` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`url_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
`baner_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
)
ENGINE = InnoDB;


Далее, регистрация просмотра банера сопровождается хитрым запросом:


INSERT INTO `test`.`baner_stat` (`url_id`, `baner_id`)
SELECT `id`, константа_id_банера FROM baner_url b
WHERE url='константа_URL_страницы'


Потом, в коде PHP, следует проверить количество вставленных строк (для этого есть оператор mysql_affected_rows), а если вдруг оно равно нулю, то вам следует обновить словарь:


INSERT INTO `test`.`baner_url` (`url`) VALUES ('константа_URL_страницы')


и повторить первый запрос. Таким образом, до заполнения словаря, у нас будет использоваться 3 запроса к базе, но по мере того, как все страницы, существующие на нашем сайте, будут занесены в таблицу, у нас останется 1 запрос для регистрации просмотра банера.
Такая схема должна применяться во многих вещах, например в таблице статей (категория, тип) или коментариев.

Во второй части статьи будет рассмотрена частая ошибка организации счетчика просмотров статей.

понедельник, 7 сентября 2009 г.

Почти год молчания

Вспоминается один бородатый анекдот, когда сорвался один добрый человек со скалы, и как-то умудрился уцепиться за выступ. Висит, значит, внизу - скалы, пальцы уже соскальзывают, и, вдруг, перед глазами появляется маленький мужичек в красной шапочке. И говорит - Я Кудесник, ты прыгай, тебе ничего не будет. Ну ладно, решает мужик, закрывает глаза, отцепляется и летит вниз. Естественно разбивается вдребезги. Маленький мужичок смотрит вниз с сожалением - мдаа.. хреновый из меня кудесник.
Однако, каким бы я не был хреновым "кудесником", хочется исправиться, да и написать есть о чем. Вкратце.
1. Возродил сайт krewedko.ru, давно хотел поэкспериментировать с почтовыми алиасами и оценить перспективы данного рынка. Судя по текущему положению вещей - перспективы не радужные.
2. Открыл сайт, посвященный CMS Krewedko, на коем в данный момент выложена рабочая версия и немного документации.
3. Выиграл пятничный конкурс у Master-X

Было немало неплохих вариантов, но меня просто взорвало от истории про маркетинг: "Применили маркетинг не по назначению". Автору в аську или скайп за призом.

Участвовал не для приза, просто по приколу :)