Поиск по композитным ключам в MySQL

Предикат IN в MySQL позволяет проверять не только вхождение значения одного поля в список, но и вхождения значений нескольких полей одновременно:

SELECT * 
  FROM foo
 WHERE (bar, baz) IN ((1, 2), (3, 4), (5, 6));

Это может быть особенно полезно, когда первичный ключ — композитный.

Точек не хватает

Решил поизучать классификаторы. Взял ОК 029-2014. Смотрю, а там нумерация какая-то странная:

10.41.3 Производство хлопкового линта
10.41.4 Производство жмыха и муки тонкого и грубого помола из семян или плодов масличных культур
10.41.5 Производство рафинированных растительных масел и их фракций
10.41.51 Производство рафинированного соевого масла и его фракций
10.41.52 Производство рафинированного арахисового масла и его фракций
10.41.53 Производство рафинированного оливкового масла и его фракций
10.41.54 Производство рафинированного подсолнечного масла и его фракций
10.41.55 Производство рафинированного хлопкового масла и его фракций
10.41.56 Производство рафинированного рапсового, сурепного, горчичного масел и их фракций
10.41.57 Производство рафинированного пальмового масла и его фракций
10.41.58 Производство рафинированного кокосового масла и его фракций
10.41.59 Производство прочих рафинированных растительных масел и их фракций
10.41.6 Производство гидрогенизированных и переэтерифицированных животных и растительных жиров и масел и их фракций

Так сразу и не поймешь, что точек не хватает (чтобы отделить группу от подгруппы). И так по всему документу. Замечательный документ.

А все почему? А потому что вот такая нотация используется:

XX класс
XX.X подкласс
XX.XX группа
XX.XX.X подгруппа
XX.XX.XX вид

И то, что казалось подгруппой, на самом деле подгруппа + вид.

О-хо-хо.

Новости научно-технического прогресса

Как вам словосочетание «разрабатывать кнопку»?

МОСКВА, 10 дек — РИА Новости, Алина Гайнуллина. Крупнейшая в мире соцсеть Facebook разрабатывает кнопку Sympathise («Сочувствую») — аналог кнопки «Мне нравится» для событий, с которыми подобное отношение несовместимо — однако точных планов запуска функции пока нет, пишет Би-би-си.

Проблемы нормализации баз данных

1. В Ленинградской области более 300 сельскохозяйственных предприятий. Названия 11 из них включают в себя словосочетание «Сельскохозяйственное предприятие» или аббревиатуру:

Андреевское, Бекон, Восход, Климово, Кузнечное, Матросово, Пашозерское, Петродвор, Салма, Смена, Сяглицы

Ещё одно предприятие — «Лосево» — выделилось, назвавшись не СП «Лосево», а СХП «Лосево».

2. Ещё в Ленинградской области есть Сельскохозяйственный производственный кооператив «Коопхоз «Нива»». Коопхоз — это вид сельскохозяйственного производственного кооператива. Просто удивительно, как они обошлись без ООО или ЗАО в названии.

Вот он, тот самый ад перфекциониста.

Один запрос на обновление вместо нескольких в MySQL

Один запрос к базе данных вместо нескольких — это хорошо. Поэтому рано или поздно возникает вопрос, как оптимизировать простыню запросов, подобную этой:

UPDATE forms SET stem='биогенн', suffix='ый' WHERE id = 123480;
UPDATE forms SET stem='биогенн', suffix='ого' WHERE id = 123481;
UPDATE forms SET stem='биогенн', suffix='ому' WHERE id = 123482;
UPDATE forms SET stem='биогенн', suffix='ого' WHERE id = 123483;
UPDATE forms SET stem='биогенн', suffix='ый' WHERE id = 123484;
UPDATE forms SET stem='биогенн', suffix='ым' WHERE id = 123485;
UPDATE forms SET stem='биогенн', suffix='ом' WHERE id = 123486;
UPDATE forms SET stem='биогенн', suffix='ая' WHERE id = 123487;
UPDATE forms SET stem='биогенн', suffix='ой' WHERE id = 123488;
UPDATE forms SET stem='биогенн', suffix='ой' WHERE id = 123489;
UPDATE forms SET stem='биогенн', suffix='ую' WHERE id = 123490;
UPDATE forms SET stem='биогенн', suffix='ой' WHERE id = 123491;
UPDATE forms SET stem='биогенн', suffix='ою' WHERE id = 123492;
UPDATE forms SET stem='биогенн', suffix='ой' WHERE id = 123493;
UPDATE forms SET stem='биогенн', suffix='ое' WHERE id = 123494;
UPDATE forms SET stem='биогенн', suffix='ого' WHERE id = 123495;
UPDATE forms SET stem='биогенн', suffix='ому' WHERE id = 123496;
UPDATE forms SET stem='биогенн', suffix='ое' WHERE id = 123497;
UPDATE forms SET stem='биогенн', suffix='ым' WHERE id = 123498;
UPDATE forms SET stem='биогенн', suffix='ом' WHERE id = 123499;
UPDATE forms SET stem='биогенн', suffix='ые' WHERE id = 123500;
UPDATE forms SET stem='биогенн', suffix='ых' WHERE id = 123501;
UPDATE forms SET stem='биогенн', suffix='ым' WHERE id = 123502;
UPDATE forms SET stem='биогенн', suffix='ые' WHERE id = 123503;
UPDATE forms SET stem='биогенн', suffix='ых' WHERE id = 123504;
UPDATE forms SET stem='биогенн', suffix='ыми' WHERE id = 123505;
UPDATE forms SET stem='биогенн', suffix='ых' WHERE id = 123506;

Запросы однотипные, обновляем значение полей stem и suffix. Id — первичный ключ. Конечно, в рабочей базе поля stem быть не должно: очевидная избыточность данных, но нам оно нужно для демонстрации. Чисто в учебно-педагогических целях.

Теперь используем MySQL-функцию INSERT … ON DUPLICATE KEY UPDATE, которая по своему функционалу эквивалента оракловому UPSERT — вставляет несуществующие и обновляет существующие строки в таблице в рамках одного (!) запроса.

INSERT INTO forms(id,stem,suffix) 
     VALUES (123480,'биогенн','ый'),
            (123481,'биогенн','ого'),
            (123482,'биогенн','ому'),
            (123483,'биогенн','ого'),
            (123484,'биогенн','ый'),
            (123485,'биогенн','ым'),
            (123486,'биогенн','ом'),
            (123487,'биогенн','ая'),
            (123488,'биогенн','ой'),
            (123489,'биогенн','ой'),
            (123490,'биогенн','ую'),
            (123491,'биогенн','ой'),
            (123492,'биогенн','ою'),
            (123493,'биогенн','ой'),
            (123494,'биогенн','ое'),
            (123495,'биогенн','ого'),
            (123496,'биогенн','ому'),
            (123497,'биогенн','ое'),
            (123498,'биогенн','ым'),
            (123499,'биогенн','ом'),
            (123500,'биогенн','ые'),
            (123501,'биогенн','ых'),
            (123502,'биогенн','ым'),
            (123503,'биогенн','ые'),
            (123504,'биогенн','ых'),
            (123505,'биогенн','ыми'),
            (123506,'биогенн','ых') 
ON DUPLICATE KEY UPDATE stem=VALUES(stem), suffix=VALUES(suffix);

В итоге имеем 1 запрос вместо 27 запросов, приведенных выше.

Аналоги в некоторых других СУБД + SQL:2008 стандарт.

Партиционирование по списку в MySQL

Партиционирование (секционирование) данных — это реально крутая штука при больших объемах данных. Вот рабочий пример. Допустим, у нас есть два списка: грамматические категории и словоформы. Первому списку соответствует таблица grammar, второму — forms. В таблицах 65 и 4058805 записей соответственно. Отношение между таблицами — многие-ко-многим, роль вспомогательной таблицы выполняет таблица morphology. В ней 23044224 записей. Её-то мы и будем партиционировать.

Продолжить чтение →

Сортировка записей с учетом регистра в MS Access

В Microsoft Access записи сортируются по возрастанию или по убыванию без учета регистра. Однако при сортировке по кодам ASCII прописные и строчные буквы различаются, что и позволяет выполнять сортировку с учетом регистра. При помощи небольшого трюка можно обойтись и без VBA.

В конструкторе запросов создаем новое поле и пишем в нем:

code: Asc(Left([table]![field];1))

Вспомогательное поле должно стоять в конструкторе запросов ДО сортируемого поля — тогда при сортировке данные будут отсортированы в первую очередь по нему:

Объяснение процесса. table, field — это название таблицы и поля, данные в которых нужно отсортировать. Функция Left() используется для получения первого символа в поле, по которому мы сортируем данные. Функция Asc() возвращает ASCII-код для первого символа. code: — название вспомогательного поля.

Кодировка сайта определяется неправильно

Все страницы в UNIX-формате, кодировка UTF-8 без BOM, <meta http-equiv=»content-type» content=»text/html;charset=utf-8″> прописан, а браузеры упорно определяют кодировку как win-1251.

В проекте есть всего одна страница входа — index.php в корне:

<?php
include_once("controller/Controller.php");

$controller = new Controller();
$controller->invoke();

Решение проблемы — отдать заголовок:

header("Content-Type: text/html;charset=utf-8");

Добавляем перед include_once…

Недопустимый знак в полном имени xml

Если при импорте xml-файла выдается сообщение типа «Не удается открыть файл из-за ошибок его содержимого. Сведения: Недопустимый знак в полном имени.» — откройте этот файл в обычном блокноте и поищите два или более символов <  подряд (<< или <<<) замените их на одинарный < и файл откроется без проблем.