Не так давно писал цикл постов про нормальные формы. Сегодня хочу еще рассказать про обратную процедуру — денормализацию.

Что такое денормализация? Это намеренное внесение изменений в нормализованную схему бд, после которых она перестает соответствовать правилам НФ.

Для чего это делается? Основная цель — это увеличение производительности ценой увеличения избыточности, возможных коллизий, а также некоторым неудобством составления сложных выборок.  Read more…

Много раз бывает такая ситуация, когда нужно обговорить, как будет выглядеть будущий элемент дизайна, но через аську или скайп рассказывать что вот тут разместится вот это а там вон то совсем не айс. Гораздо удобнее накидать в редакторе наброски, отправить и согласовать их. Но только каждый раз что-то править, потом сохранять, потом отправлять совсем не удобно.
Есть такие сервисы, которые предоставляют возможность сделать тоже самое, но только совместно и онлайн.

Большинство из таких сервисов предоставяют бесплатный пробный доступ на несколько дней, но я искал полностью бесплатный вариант, пускай и не сильно функциональный.
Read more…

Последний пост про нормальные формы, перевод книги PHP 6 and MySQL 5 for Dynamic Web Sites. Предыдущие три вынесены ссылками в конце поста. Read more…

Третий пост, перевод книги PHP 6 and MySQL 5 for Dynamic Web Sites. Предыдущие два:  вводный, 1НФ Read more…

Итак, в предыдущем посте была вводная часть про нормализацию баз данных, ключи и отношения. В этом посте будет рассмотрена первая нормальная форма или 1НФ сокращено. Read more…

Попала в руки одна замечательная книжка — PHP 6 and MySQL 5 for Dynamic Web Sites , за авторством Larry Ulman. В целом, книга расчитана на новичков — середнячков, но затрагиваются и довольно серьёзные вещи, при чем объясняется весьма доходчивым языком.

Задела глава про нормальные формы. Довольно мудрёную тему автор раскрывает в весьма доходчивой манере. На русском издания я не нашел, поэтому перевел эту часть книги. Обьем статьи довольно большой, поэтому я разобью на несколько постов. В этом будет вводная часть.

Вкратце, что такое нормализация. Большинство современных субд разработаны на основе реляционной алгебры, которая появилась раньше самих реляционных субд под авторством некого доктора Кодда. Он же вывел несколько правил, или форм, по упорядочиванию данных и их отношений. Всего таких форм 6 + две вне конкурса, Бойса-Кодда и доменно-ключевая.

На практике редко нормализуют дальше 3-ей нормальной формы. Поподробнее узнать обо всех нормальных формах и теории по ссылкам внизу поста. Read more…

Понадобилось для одной задачи сделать выборку из таблицы А по определенным условиям и вставить ее в таблицу B.
Можно особо не заморачиваться, сделать SELECT  в переменную, потом пройтись циклом по INSERT и все.

Но это не очень красивое решение. Очень запросов много + на переменные память расходуется. Проще использовать вложенные запросы, они же nested queries. Но тут возникает проблемка -  если вставлять  только данные из INSERT, то все ок, но если добавлять еще и какие-нибудь неизменные значения, то выдается Subquery returned more than 1 value.

Чтобы не обьяснять на пальцах — сама таблица B

CREATE TEMPORARY TABLE `B` (
  `status` TINYINT(4) NULL DEFAULT NULL ,
  `pair` TEXT NULL DEFAULT NULL ,
)
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;

Копируем из таблицы A и вставляем в B так

INSERT INTO `B` (`pair`)
            SELECT `pair` FROM `A` ORDER BY RAND() LIMIT 100;

Если поле status имеет неизменное значение, например 123, то просто вот так уже не вставить

INSERT INTO `B` (`status`, `pair`) VALUES (
            (SELECT `pair` FROM `A` ORDER BY RAND() LIMIT 100),
            123);

Не совсем красивое решение нашел

UPDATE `B` SET `status` = '123' WHERE 1=1;

Но хотелось бы в одну строку все заделать. Отпишитесь плиз в коментах, кто знает, как реализовать.

Иногда бывает надо сохранить массив с данными куда-то, чтобы потом его достать и прочитать. Есть две хорошие функции для этого — serialize и unserialize. И все бы ничего, но вот иногда массив не получается десериализовать назад — возвращается предательское bool(false) вместо заветного массивчика.

Проблем может быть две — первая это включенная директива magic_quotes. Лечится примерно так -

(get_magic_quotes_gpc()) ? stripslashes(unserialize($variable)) : unserialize($variable);

За работу кода не отвечаю, но думаю мысль понятна.

Второй вариант, с которым втух я на несколько часов, это переносы строки. Если массив имеет в себе ячейку, в которой несколько строк, то он нифига не сериализуется взад, а выдаст false. Лечится убиванием \r\n

$str = preg_replace("/\n/", "", $str);
$str = preg_replace("/\r/", "", $str);

Упало в ридер несколько записей(раз, двас, трис), как посчитать строчки в си проектах и стало интересно, сколько же строчек я накропал для одного проекта. Оказалось, 5060, не считая js и css всяких.

Сама команда:

find . -type f -name "*.php" -exec wc -l {} +;

Знакомый кинул линк на перловый скриптец, который собирает статистику из конфига и логов и выдает рекомендации по оптимизации бд.
Вот такой вывод:

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.0.51a-24+lenny5-log
[!!] Switch to 64-bit OS - MySQL cannot currently use all of your RAM

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Archive -BDB +Federated -InnoDB -ISAM -NDBCluster 

[--] Data in MyISAM tables: 5M (Tables: 260)
[OK] Total fragmented tables: 0

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 1d 12h 14m 59s (4M q [33.837 qps], 39K conn, TX: 822M, RX: 460M)
[--] Reads / Writes: 30% / 70%
[--] Total buffers: 57.0M global + 50.5M per thread
(400 max threads)
[!!] Allocating > 2GB RAM on 32-bit systems can cause system instability
[!!] Maximum possible memory usage: 19.8G (293%
of installed RAM)
[!!] Slow queries: 10%
(443K/4M)
[OK] Highest usage of available connections: 38%
(152/400)
[OK] Key buffer size / total MyISAM indexes:
15.0M/4.7M
[OK] Key buffer hit rate: 99.1% (9M cached
/ 91K reads)
[OK] Query cache efficiency: 75.5% (2M cached /
2M selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp
sorts / 439K sorts)
[OK] Temporary tables created on disk: 1% (8K
on disk / 444K total)
[OK] Thread cache hit rate: 99% (307 created /
39K connections)
[!!] Table cache hit rate: 0% (5 open /
11K opened)
[OK] Open file limit used: 0%
(11/65K)
[OK] Table locks acquired immediately: 99%
(2M immediate / 2M
locks)

-------- Recommendations -----------------------------------------------------
General recommendations:
    Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    table_cache (> 32562)

Сам скрипт лежит тут: веб, гит

1