
Быстрый поиск
Введите фрагмент названия статьи для поиска

Подсветка синтаксиса MySQL-запросов
07.04.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
При выводе диагностики в своих рабочих проектах я использую вот такую функцию для подсветки синтаксиса MySQL-запросов. Она преобразует текст запроса, делая все служебные слова языка заглавными буквами и подсвечивает их цветом, а также выделяет различными цветами числовые значения и скобки. Такая подсветка позволяет сразу же увидеть синтаксические ошибки, да и вообще повышает наглядность сообщений при отладке скриптов.Code (PHP) : Убрать нумерацию
- //-------------------------------------------------------------------
- // Функция подсветки синтаксиса MySQL-запроса
- // (C) ManHunter / PCL
- // http://www.manhunter.ru
- //-------------------------------------------------------------------
- function mysql_debug($query) {
- $tmp=htmlspecialchars($query);
- $tmp=str_replace("\r",'',$tmp);
- $tmp=trim(str_replace("\n","\r\n",$tmp))."\r\n";
- $quote_list_text=array();
- $quote_list_symbols=array();
- $k=0;
- $quotes=Array();
- // Обработать экранированные кавычки
- preg_match_all("/\\\'|\\\"/is", $tmp, $quotes);
- array_unique($quotes);
- if (count($quotes)) {
- foreach($quotes[0] as $i) {
- $k++;
- $quote_list_symbols[$k]=$i;
- $tmp=str_replace($i, '<symbol'.$k.'>', $tmp);
- }
- }
- $matches=Array(
- "/("|'|`)(.*?)(\\1)/is", // текст в кавычках
- "/\/\*.*?\*\//s", // текст комментария
- "/ \-\-.*\x0D\x0A/", // текст ' --' комментария
- "/ #.*\x0D\x0A/", // текст ' #' комментария
- );
- // Обработать текст
- foreach($matches as $match) {
- // Обработать текст
- $found=array();
- preg_match_all($match, $tmp, $found);
- $quotes=(array)$found[0];
- array_unique($quotes);
- if (count($quotes)) {
- foreach($quotes as $i) {
- $k++;
- $quote_list_text[$k]=$i;
- $tmp=str_replace($i, '<text'.$k.'>', $tmp);
- }
- }
- }
- // Служебные слова MySQL
- $keywords=Array(
- "avg", "as", "auto_increment", "and", "analyze", "alter",
- "asc", "all", "after", "add", "action", "against",
- "aes_encrypt", "aes_decrypt", "ascii", "abs", "acos",
- "asin", "atan", "authors", "between", "btree", "backup",
- "by", "binary", "before", "binlog", "benchmark", "blob",
- "bigint", "bit_count", "bit_or", "bit_and", "bin",
- "bit_length", "both", "create", "count", "comment",
- "check", "char", "concat", "cipher", "changed", "column",
- "columns", "change", "constraint", "cascade", "checksum",
- "cross", "close", "concurrent", "commit", "curdate",
- "current_date", "curtime", "current_time",
- "current_timestamp", "cast", "convert", "connection_id",
- "coalesce", "case", "conv", "concat_ws", "char_length",
- "character_length", "ceiling", "cos", "cot", "crc32",
- "compress", "delete", "drop", "default", "distinct",
- "decimal", "date", "describe", "data", "desc",
- "dayofmonth", "date_add", "database", "databases",
- "double", "duplicate", "disable", "datetime", "dumpfile",
- "distinctrow", "delayed", "dayofweek", "dayofyear",
- "dayname", "day_minute", "date_format", "date_sub",
- "decode", "des_encrypt", "des_decrypt", "degrees",
- "decompress", "dec", "engine", "explain", "enum",
- "escaped", "execute", "extended", "errors", "exists",
- "enable", "enclosed", "extract", "encrypt", "encode",
- "elt", "export_set", "escape", "exp", "end", "from",
- "float", "flush", "fields", "file", "for", "fast", "full",
- "fulltext", "first", "foreign", "force", "from_days",
- "from_unixtime", "format", "found_rows", "floor", "field",
- "find_in_set", "group", "grant", "grants", "global",
- "get_lock", "greatest", "having", "high_priority",
- "handler", "hour", "hex", "insert", "into", "inner",
- "int", "ifnull", "if", "isnull", "in", "infile", "is",
- "interval", "ignore", "identified", "index", "issuer",
- "integer", "is_free_lock", "inet_ntoa", "inet_aton",
- "instr", "join", "kill", "key", "keys", "left", "load",
- "local", "limit", "like", "lock", "lpad", "last_insert_id",
- "logs", "length", "longblob", "longtext", "last", "lines",
- "low_priority", "locate", "ltrim", "leading", "lcase",
- "lower", "load_file", "ln", "log", "least", "month", "mod",
- "max", "min", "mediumint", "medium", "master", "modify",
- "mediumblob", "mediumtext", "match", "mode", "monthname",
- "mid", "minute", "master_pos_wait", "make_set", "null",
- "not", "now", "none", "new", "numeric", "no", "natural",
- "next", "nullif", "national", "nchar", "on", "or",
- "optimize", "order", "optionally", "option", "outfile",
- "open", "offset", "outer", "old_password", "ord", "oct",
- "octet_length", "primary", "password", "privileges",
- "process", "processlist", "purge", "partial", "procedure",
- "prev", "period_add", "period_diff", "position", "pow",
- "power", "pi", "quick", "quarter", "quote", "right",
- "repair", "restore", "reset", "regexp", "references",
- "replace", "revoke", "reload", "require", "replication",
- "read", "rand", "rename", "real", "restrict",
- "release_lock", "rpad", "rtrim", "repeat", "reverse",
- "rlike", "round", "radians", "rollup", "select", "sum",
- "set", "show", "substring", "smallint", "super", "subject",
- "status", "slave", "session", "start", "share",
- "straight_join", "sql_small_result", "sql_big_result",
- "sql_buffer_result", "sql_cache", "sql_no_cache",
- "sql_calc_found_rows", "second", "sysdate", "sec_to_time",
- "system_user", "session_user", "substring_index", "std",
- "stddev", "soundex", "space", "strcmp", "sign", "sqrt",
- "sin", "straight", "sleep", "text", "truncate", "table",
- "tinyint", "tables", "to_days", "temporary", "terminated",
- "to", "types", "time", "timestamp", "tinytext",
- "tinyblob", "transaction", "time_format", "time_to_sec",
- "trim", "trailing", "tan", "then", "update", "union",
- "using", "unsigned", "unlock", "usage", "use_frm",
- "unix_timestamp", "unique", "use", "user", "ucase",
- "upper", "uuid", "values", "varchar", "variables",
- "version", "variance", "varying", "where", "with",
- "warnings", "write", "weekday", "week", "when", "xor",
- "year", "yearweek", "year_month", "zerofill");
- $replace=Array();
- foreach($keywords as $keyword) {
- $replace[]='/\b'.$keyword.'\b/ie';
- }
- // Выделить служебные слова в тексте запроса
- $tmp=preg_replace($replace,
- '"<b style=\"color:#0000FF\">".strtoupper("$0")."</b>"',$tmp);
- // Выделить числовые значения в тексте запроса
- $tmp=preg_replace('/\b([\.0-9]+)\b/',
- '<b style="color:#008000">\1</b>',$tmp);
- // Выделить скобки в тексте запроса
- $tmp=preg_replace('/([\(\)])/',
- '<b style="color:#FF0000">\1</b>',$tmp);
- // Вернуть обратно строки в кавычках
- if (count($quote_list_text)) {
- $quote_list_text=array_reverse($quote_list_text, true);
- foreach($quote_list_text as $k=>$i) {
- $tmp=str_replace('<text'.$k.'>',
- '<span style="color:#777;">'.$i.'</span>', $tmp);
- }
- }
- // Вернуть обратно экранированные символы
- if (count($quote_list_symbols)) {
- $quote_list_symbols=array_reverse($quote_list_symbols, true);
- foreach($quote_list_symbols as $k=>$i) {
- $tmp=str_replace('<symbol'.$k.'>', $i, $tmp);
- }
- }
- // Вернуть подсвеченный текст запроса
- // Если не надо расставлять переносы, то уберите nl2br
- return nl2br(trim($tmp));
- }
Читать статью целиком »
Просмотров: 4613 | Комментариев: 7

Релевантный поиск по базе MySQL
04.11.2011 | Категория: Web-мастеру и не только | Автор: ManHunter

Релевантный поиск по базе MySQL
Я уже писал о возможностях поиска с учетом морфологии, а теперь обещанная статья о релевантном поиске по базе MySQL. Как разъясняют словари, релевантность - в поисковых системах - мера соответствия результатов поиска задаче поставленной в запросе. То есть чем ближе найденный результат соответствует искомому, тем выше в результатах поиска он должен находиться. Применительно к выборке из базы, в строках результата релевантность должна быть представлена неким числовым значением, по которому эта выборка должна быть отсортирована.
Начнем с теории. Если мы ищем строку из нескольких слов среди нескольких текстов, то наибольшей релевантностью обладает текст, в котором встречается вся эта строка целиком и точно в том виде, как ее задали к поиску. Затем идут тексты, где есть все слова из искомой фразы, но расположенные не по порядку. После них идут тексты, где встречаются только отдельные слова, и, чем меньше слов из фразы, тем ниже релевантность. К тому же слова из заголовка текста должны иметь поисковый вес больше, чем такие же слова из текста.
Читать статью целиком »
Просмотров: 18365 | Комментариев: 13

Как сделать свой сервис коротких ссылок
02.06.2011 | Категория: Web-мастеру и не только | Автор: ManHunter
С ростом популярности социальных сетей типа Twitter, где длина сообщения ограничена, возникла необходимость в специальных сервисах для сокращения длинных ссылок. В результате появилось много сайтов, где вы можете ввести длинную ссылку и вместо нее получить короткую. При переходе по такой ссылке вы сперва попадаете на сайт-редиректор, а уже с него выполняется автоматический переход на нужную ссылку. Я даже встречал такие сокращенные ссылки в печатных изданиях, а не только в интернете. Ничего сложного в реализации такого сервиса нет, и сейчас мы сделаем что-нибудь подобное.Начинается все с покупки короткого доменного имени. Все красивые имена уже разобраны или захвачены киберсквоттерами, но кое-что еще можно найти. В конце концов, рядовому пользователю нет особой разницы, по красивой ссылке идти или по некрасивой, главное чтобы она помещалась в его сообщение. Хорошо, домен у нас есть, едем дальше.
А дальше нам надо продумать структуру базы данных, в которой будут храниться короткие ссылки и их соответствия. Поскольку мы делаем сейчас самый простейший сервис, то пусть структура базы будет такой:
CREATE TABLE IF NOT EXISTS `redirector_links` (
`link_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'ID ссылки в базе',
`link_hash` VARCHAR(32) COMMENT 'Хэш ссылки',
`link_url` TEXT COMMENT 'Адрес ссылки',
PRIMARY KEY (`link_id`),
KEY `link_hash` (`link_hash`)
) ENGINE=MyISAM
Хэш ссылки нужен для того, чтобы не создавать в базе дубли для повторяющихся ссылок. В принципе, сюда же можно добавить счетчик для сбора статистики переходов, добавить принадлежность к какому-нибудь владельцу и т.п. Все зависит от поставленных задач.
Читать статью целиком »
Просмотров: 29595 | Комментариев: 24

Выбор случайной строки из таблицы MySQL
20.04.2011 | Категория: Web-мастеру и не только | Автор: ManHunter
Одна из часто встречающихся задач при создании сайтов - выборка случайной строки из таблицы MySQL. Это может быть случайный баннер в ротации, какая-нибудь "фраза дня" или афоризм, промо-блок на главной странице и т.п. Применений масса. Я решил на практике протестировать несколько вариантов решения этой задачи. Исходные данные: база MySQL, таблица типа MyISAM проиндексирована по полю id, количество записей около 500000, поле id обозначено как PRIMARY KEY, в нумерации есть "дырки" из-за удаленных строк.Переходим к тестированию. Традиционное решение сводится к такому запросу:
SELECT * FROM `table` ORDER BY RAND() LIMIT 1
Код на PHP для тестирования:
Code (PHP) : Убрать нумерацию
- // Тест №1
- $query="SELECT * FROM `table` ORDER BY RAND() LIMIT 1";
- $sql_result=mysql_query($query);
- $row=mysql_fetch_array($sql_result);
- mysql_free_result($sql_result);
Читать статью целиком »
Просмотров: 14108 | Комментариев: 9

Ошибка MySQL "Got error 28 from storage engine"
20.05.2010 | Категория: Web-мастеру и не только | Автор: ManHunter
Прихожу на работу, а у меня уже телефон разрывается от звонков. Рабочий сайт компании лежит с загадочной ошибкой MySQL "Got error 28 from storage engine", причем не весь, а выборочно местами и только на некоторых запросах. В официальной документации по MySQL ничего внятного не нашел, но после небольшого расследования и поиска в разных интернетах выяснилось, что такая ошибка возникает из-за нехватки свободного места на диске. На небольших запросах оставшегося места хватало для работы MySQL и возвращался какой-то результат, а на более ресурсоемких появлялась указанная ошибка. Позвонил админам, добавили места, почистили мусор, проблема сразу же решилась. Вот такая загогулина. Может кому-нибудь пригодится.
Просмотров: 14417 | Комментариев: 11
