Сделав за свою карьеру не один десяток сайтов, пришел к одному выводу. И вывод это такой: чем лучше написан backend, тем проще писать frontend. И это не просто слова, а вполне реальный факт, который я вынес за почти 5 лет работы.
В последнее время средние и большие проекты в нашей организации пишутся двумя программистами. Вот примерный ход работы над каким-либо бизнес порталом или большим сайтом для не коммерческой организации (сразу оговорюсь, что backend я тоже пишу, но несколько реже, это зависит не от меня):
- Мой сотрудник по тех. заданию пишет backend.
- Я в это время верстаю страницы из готовых psd дизайнов.
- Как только созданы таблицы в базе данных, и определена логика, я начинаю заполнять html шаблоны данными из базы данных.
- и т.д.
И вот тут начинается самое интересное. Так как я надеюсь, что логика backend выполнена на высшем уровне, я и не делаю очевидных проверок в скриптах на frontend. Кто-то конечно скажет, что проверки делать обязательно везде и всегда, но мне из опыта известно совсем другое. Как правило хостинги последнее время начинают урезать количество запросов в секунду к серверу БД. И я считаю это правильным, так как существуют вполне себе известные cms, которые не заботятся об этом факторе и у них на главной странице запросов к БД больше 30-40, хотя если все пересмотреть и подумать хорошенько, и воспользоваться join или выборкой из нескольких страниц, то это число можно сократить как минимум вдвое. Также очень важно спроектировать изначально правильно структуру таблиц и связи между ними, учитывая преимущества реляционных БД, или преимущества NoSQL БД.
Ниже я буду приводить те примеры, которые видел сам и от которых хочу предостеречь вас. Так же хочу заметить, что эти примеры будут приводиться на php, mysql, но на самом деле не важно каким языком программирования и БД вы будете пользоваться. Главное здесь логика, взаимосвязь между логическими еденицами.
Пример 1
Исходные данные:
таблица БД “keywords” содердит ключевые слова для неких статей и других контентных страниц. Вот ее структура
id | name |
1 | Hello |
2 | Code |
3 | Site |
таблица БД “articles” тут все понятно, содержит поля типичные для статей. Я приведу лишь необходимую для примера структуру таблицы
id | title | content | active | keywords |
1 | test 1 | test content 1 | 1 | 1,3 |
2 | test 2 | test content 2 | 1 | 2,3 |
как видите в поле keywords таблицы article записываются id кейвордов из таблицы keywords через запятую
Кто скажет сколько запросов нужно выполнить чтобы сделать поиск по кейвордам и вывести только те статьи, которые содержат найденные кейворды.
Тут и думать не нужно, первый запрос выведет все кейворды удовлетворяющие условию поиска из таблицы keywords, с помощью php мы сформируем массив $arrayKeywords из id, например “1,3″ и потом сделаем запрос к таблице articles, где в where используем такое условие articles.keywords REGEXP “[[:<:]]$str[[:>:]] OR … (это условие через “OR” нужно повторить ровно столько раз сколько элементов в массиве $arrayKeywords), где $str это одно id из массива arrayKeywords. Как видите запрос может получиться очень и очень длинным.
Основная задача, избежать лишнего запроса и соответственно ненужность php скрипта формировавшего строку айдишек и уменьшить длину основного запроса.
Первое что нужно сделать - это создать еще одну таблицу “article_keyword” (название может быть любым), в ней будет всего два поля
id_article | id_keyword |
2 | 2 |
2 | 3 |
Думаю что тут все понятно, id_article – это id статьи, id_keyword – это id кейворда. Поле keywords в таблице articles уже не нужно.
Теперь я напишу sql запрос который выдаст только те статьи, в которых присутствуют найденные кейворды
SELECT DISTINCT article.id, article.title, article.content FROM keywords, article_keyword, articles WHERE keywords.name LIKE ‘hel%’ AND article_keyword.id_keyword = keywords.id AND articles.id = article_keyword.id_article
Пример 2
Часто встречается такая проблема: при редактировании какого-либо материала в backend – е, если поле имеет редактор типа TinyMCE или FCKEditor и в поле что-то пописать, а потом все стереть, то остается либо <br /> , либо , либо еще какой-то html тег . Если даже ничего в поле не вставлять, все равно там будет один из этих тегов. Как правило его так и записывают в базу. Ну конечно если это поле не обязательное к заполнению. А потом начинаются трудности. При выводе во frontend функция trim не приносит нам никакой помощи, так как пробел этот является html мнемоникой. И если нам нужно сделать проверку, выводить тег, обрамляющий текст из редактора, только в том случае, если это поле пустое, то такая проверка тоже не прокатит if( strlen($value)>0 ), так как $value содержит html мнемонику(и). В данном случае, если не брать во внимание backend, то для решения данной проблемы нужно писать регулярные выражения. Вроде бы ничего страшного.
Правильное решение данного вопроса:
Нужно в админке (backend) перед сохранением в БД данных этого поля, сделать такую проверку :
if(strlen(preg_replace(‘/^ /i’, ”,trim(strip_tags($value))))>0){
записывать в базу значение переменной
}else {
запись в базу пустого значения
}
Теперь самое важное – оценим пользу в случает проверки в backend – е.
Материал в админке редактируется как правило редко, точнее на него тратят время при создании, потом еще пару часиков на поправление всяких недочетов в словах или оформлении. То есть можно предположить, что проверка которую я привел для админки будет отработана в среднем раз 100 в год, 5 материалов – 500 в год. А теперь посмотрим на frontend (клиентская часть). Если предположить, что на сайте 5 статей с нашим полем и каждую посещают минимум 3 человека в день, то за год выходит в среднем 5500 проверок. Ну думаю дальше объяснять не нужно. 99% проверок над данными нужно делать в админке – это факт.
Пример 3
Этот пример непосредственно касается SQL. Часто так бывает, что программисты хорошо знают язык программирования, но не достаточно полно владеют языком запросов SQL .
Не один сайт не обходиться без включения или выключения какого-то материала в определенный момент времени. Часто поле отвечающее за эту фунцию называют “active” и значение оно может принимать либо 0 (деактивировано), либо 1 (активировано). В админке, как правило, в списке этих материалов есть кнопочка рядом с этим материалом, нажимая на которую мы либо активируем деактивированный материал, либо наоборот. Вот как делает большинство знакомых мне программистов: они посылают на сервер ajax запрос и двумя SQL запросами меняют значение поля “active”. Первым запросом узнают текущее значение поля данной записи, и в зависимости от значения, записывают в поле либо 0, либо 1. Вот пример кода:
$select = mysql_query(‘SELECT `active` FROM `articles` WHERE id=1′);
$result = mysql_fetch_array($select);
if($result ['active']== 0){
mysql_query(‘UPDATE `articles` SET active = 1 where id=1′); // записываем в поле 1, то есть активируем запись
} else {
mysql_query(‘UPDATE `articles` SET active = 0 where id=1′); // записываем в поле 0, то есть деактивируем запись
}
Здесь как минимум две лишние операции, первая – это “$select = mysql_query(‘SELECT `active` FROM `articles` WHERE id=1′);” , вторая – “if($result == 0)” . Весь выше приведенный код можно уместить в одну строку запроса. Вот она, берите и пользуйтесь на здоровье :
UPDATE `articles` SET active = IF(active = 1, 0, 1) where …
Но и это еще не все глупости, которые, обычно, делают некоторые молодые (а может и со стажем тоже) программисты. Вот пример как делать не нужно :
если в списке материалов в админке, мы выбрали несколько материалов, отметив чекбоксы, а потом передали на сервер список id этих материалов и на сервере получили из строки $stringId, например 1,2,3,4,5,6, массив $arrayId то не нужно в цикле делать вот так :
foreach($arrayId AS $k => $v){
$select = mysql_query(“SELECT `active` FROM `articles` WHERE id=’$v’”);
$result = mysql_fetch_array($select);
if($result ['active']== 0){
mysql_query(“UPDATE `articles` SET active = 1 where id=’$v’”); // записываем в поле 1, то есть активируем запись
} else {
mysql_query(“UPDATE `articles` SET active = 0 where id=’$v’”); // записываем в поле 0, то есть деактивируем запись
}
}
это я показал маразм вообще, но не удивляйтесь, примерно 30% программистов так и пишут, если им никто не скажет что так не правильно.
Далее идет тоже не правильный подход, хотя уже запросов к базе будет вдвое меньше.
foreach($arrayId AS $k => $v){
mysql_query(“UPDATE `articles` SET active = IF(active = 1, 0, 1) where id=’$v’”);
}
Вот правильный вариант, ну возможно не самый самый правильный, но более правильного я не знаю. Ну уж извините …
mysql_query(“UPDATE `articles` SET active = IF(active = 1, 0, 1) where id IN ($stringId)”);
Ясное дело что все переменные, которые участвуют в sql запросах нужно проверять, чтобы не оставлять лазейки для злоумышленников
Продолжение здесь Frontend vs Backend, часть 2
Использование DISTINCT плохой тон видимо оптимизация вас не волнует совсем.
Может быть. Можете дать решение данной проблемы со своей стороны, если можно с примером кода.
Вообще, статья немного убога
Для кого убога???
Мде… Жаль, очень жаль… Естественно, что сожалею о тех пользователях, а точнее новичках в этой области, которые прочитают эту статью и, не дай Бог, примут её, как руководство к действию. Ощущение, что Женечка Попов или его последователи не устают “плодиться” подобно компьютерному вирусу. Больше и добавить нечего.
Я если и ждал критики, то хотя бы конструктивной. А вы я гляжу просто болтун и пустомеля. Иначе и не скажешь…