Monthly Archives: Июль 2013

Создание урезанной копии базы данных MySQL

Очень часто встречается ситуация, когда нужно иметь копию реальной базы данных на своем компьютере. Например, для тестирования программы на реальных данных, для поиска ошибок или просто иметь более-менее заполненные данными таблицы и т.д. Если в базе хранятся файлы, и они интенсивно добавляются в базу, то размер такой базы может быть очень большим. Чтобы сделать копию такой базы нужно время, свободное место, также затруднительно скачать такую базу удаленно через интернет. Как выход можно сделать урезанную копию — выгружать только таблицы, в которых не храняться файлы. При условии, конечно, что на данные таблиц не ссылаются другие таблицы.

Классический резервную копию делают следующей командой:

mysqldump -uroot -p your_database > dump.sql

Где -p — опция позволяет вводить пароль в скрытом виде,
your_database — название выгружаемой в дамп базы данных.

Также можно после наименования базы данных указать названия таблицы через пробел, которые должны быть выгружены, остальные таблицы не будет выгружены:

mysqldump -uroot -p your_database table1 table2 table3 > dump.sql

В данном случае, из базы данных your_database будут выгружены таблицы (со структурой и данными): table1, table2 и table3. Остальные таблицы не будет выгружены, даже структура.

Для начала получим список всех таблиц в базе данных:

SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = 'your_database'

Где information_schema.tables — системная таблица, содержащая информацию о таблицах,
your_database — название вашей базы данных

Полученные данные имеют вид стобца, нам же нужны список названий с пробелом в качестве разделителя.
Для этого выполните следующий запрос:

SELECT TABLE_NAME INTO OUTFILE 'c:\\tables.txt' 
LINES TERMINATED BY ' '
FROM information_schema.tables 
WHERE TABLE_SCHEMA = 'your_database'

Данный запрос позволяет выгрузить данные в файл c:\tables.txt. Из-за экранирования вместо разделителя пути «\» нужно использовать «\\» (Для linux-систем разделителем является слэш «/», который не экранируется, т.е. путь может быть выглядеть следующим образом /tmp/tables.txt. )
Причем, если файл c:\tables.txt уже существует выйдет ошибка «Error: File ‘c:\tables.txt’ already exists». Нужно удалить этот файл или переименовать название файла для выгрузки и выполнить запрос заново.
Строка LINES TERMINATED BY ‘ ‘ говорит о том, что разделитель строк теперь пробел. Это позволяет значения из столбца записать в виде строки.

Теперь полученный список названий таблиц через пробел можно подставить в запрос:

mysqldump -uroot -p your_database таблицы_через_пробел > dump.sql

Но нам нужны ведь не все таблицы, поэтому вы можете из запроса удалить ненужные таблицы.

Теперь о том, как найти таблицы, которые будем игнорировать. Отсеивать будем по размеру и наименованию таблиц.
Для начала выведем список таблиц, отсортированный по размеру таблиц, используем всё ту же таблицу information_schema.tables.

SELECT
    table_name,    
    ROUND(data_length/1024/1024,2) AS total_size_mb,
    table_rows
FROM
    information_schema.tables
WHERE
    table_schema='your_database'
ORDER BY total_size_mb desc

Где table_name — название таблицы,
total_size_mb — размер таблицы в мегабайтах,
table_rows — кол-во записей в таблице
Пример выполнения запроса:
sizes
Я не буду выгружать таблицы, которые занимают более 10 мегабайт и в названии которых присутствует слово «ATTACH». В таблицах ATTACH храняться файлы, поэтому они занимают много места.
Следующий запрос позволяет получить список таблиц, которые не будем выгружать.

SELECT
    table_name,    
    ROUND(data_length/1024/1024,2) AS total_size_mb,
    table_rows
FROM
    information_schema.tables
WHERE
    table_schema='your_database' AND ROUND(data_length/1024/1024,2) > 10 AND TABLE_NAME LIKE '%attach%'
ORDER BY total_size_mb desc

Так как, скорее всего, список исключаемых таблиц будет невелик. Можно исключить их вручную, так будет даже нагляднее. Итоговый запрос с учетом исключения ненужных таблиц будет выглядеть следующим образом:

SELECT TABLE_NAME INTO OUTFILE 'c:\\tables.txt' 
LINES TERMINATED BY ' '
FROM information_schema.tables 
WHERE TABLE_SCHEMA = 'your_database' AND TABLE_NAME NOT IN ('ignore_table_1','ignore_table_2','ignore_table_3')

Данный запрос выведет названия таблиц через пробел в файл, но не будет исключенных таблиц: ignore_table_1, ignore_table_2 и ignore_table_3.

Остается подставить полученный список таблиц в команду резервного копирования:

mysqldump -uroot -p your_database таблицы_через_пробел > dump.sql

В данным случае, это позволило получить урезанную резервную копию на 7 гигабайт меньше оригинальной.

p.s. Есть один минус — при восстановлении резервной копии нужно создать таблицы, которые мы проигнорировали. В моем проекте это не проблема, т.к. используется ORM(Object-relational mapping), который сам восстановит недостающие таблицы.
Также будьте внимательны при выполнении запросов в различных sql-клиентах. Например, Squirrel SQL Client по умолчанию выведет в файл первый 100 названий таблиц, поэтому нужно снять флаг Limit rows.

GPS KZ Автобусы

Приложение можно скачать с Google Play: https://play.google.com/store/apps/details?id=kz.naik.bus

Приложение показывает текущее положение автобусов в следующих городах: Астана, Костанай, Семей, Талдыкорган, Темиртау, Уральск и Щучинск.

При первом запуске приложения будет предложено выбрать город:
01 выбор города

Откроется карта выбранного города. Для выбора необходимого маршрута нажмите на кнопке с автобусом:
02 вид главного окна

Откроется список маршрутов:
03 выбор маршрута

После выбора маршрута, на карте отобразиться линия маршрута и автобусы в виде круга с номером и стрелкой, указывающей направление движения:
04 маршрут и автобусы

p.s. По мере появления новых возможностей в приложении статья будет обновляться

Шаблоны для построения интерфейса на Seam Framework 2.2.0 с использоватеним RichFaces 3.3.3

template.xhtml — шаблон, который будут использовать другие страницы

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:a="http://richfaces.org/a4j"
      xmlns:s="http://jboss.com/products/seam/taglib">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>#{interface['system.name']}</title>
    <link rel="shortcut icon" href="#{facesContext.externalContext.requestContextPath}/img/favicon.ico" type="image/x-icon"/>
    <link href="#{facesContext.externalContext.requestContextPath}/css/theme.css" rel="stylesheet" type="text/css"/>
    <ui:insert name="scripts"/>
</head>
<body>
 
<noscript style="text-align: center; font-size:9pt; color:red;">
    <div>
        <br/>
        <strong>Для корректной работы необходим браузер с поддержкой JavaScript</strong>
    </div>
</noscript>
 
<TABLE width="100%" cellpadding="0" cellspacing="0">
    <ui:insert name="body"/>
</TABLE>
 
</body>
</html>

Страница, использующая шаблон

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:s="http://jboss.com/products/seam/taglib"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:rich="http://richfaces.org/rich"
                xmlns:a="http://richfaces.org/a4j"
                template="../layout/template.xhtml">
    <ui:define name="body">
        <rich:panel>
            <f:facet name="header">#{interface['page.name']}</f:facet>
            <h:messages globalOnly="true" styleClass="message"/>
            <h:form>
 
            </h:form>
        </rich:panel>
    </ui:define>
</ui:composition>

Вывод таблицы

<rich:dataTable id="tableList"
	rowKeyVar="rowIndex" var="req"
	value="#{workManager.foundRequestList}">
 
</rich:dataTable>

Вывод таблицы постранично

<rich:datascroller align="center" for="tableList" maxPages="10"
				   page="#{workManager.dataTableScrollerBean.currentPage}"
				   style="width:100%;" fastStep="5" fastControls="auto"
				   renderIfSinglePage="false">
	<f:facet name="first">
		<h:outputText value="#{interface['first.page']}"/>
	</f:facet>
	<f:facet name="last">
		<h:outputText value="#{interface['last.page']}"/>
	</f:facet>
	<f:facet name="previous">
		<h:outputText value="#{interface['previous.page']}"/>
	</f:facet>
	<f:facet name="next">
		<h:outputText value="#{interface['next.page']}"/>
	</f:facet>
	<f:facet name="fastrewind">
		<h:outputText value="-5"/>
	</f:facet>
	<f:facet name="fastforward">
		<h:outputText value="+5"/>
	</f:facet>
</rich:datascroller>
 
<rich:dataTable id="tableList"
	rowKeyVar="rowIndex" var="req" rows="10"
	value="#{workManager.foundRequestList}">
 
</rich:dataTable>

Вывод сообщения о том, что в таблице нет записей

<s:div rendered="#{empty workManager.foundRequestList}"
	   styleClass="nodata">
	<h:outputText value="#{interface['list.is.empty']}"/>
</s:div>

Как заполнять иммиграционную карточку пограничного агентства Великобритании

В самолете перед посадкой вам раздадут иммиграционные карточки, которые вы должны самостоятельно заполнить (желательно взять с собой в салон самолета ручку). Одну карточку я испортил, и мне дали новую, поэтому она сохранилась:
Посадочная карта
Ниже я приведу пример заполнения карточки:

Текст

Перевод

Пример

UK Border Agency

Пограничное агентство Великобритании

Landing card

Иммиграционная карточка

Please complete clearly in English and BLOCK CAPITALS

Пожалуйста, заполните чисто на английском и ЗАГЛАВНЫМИ ПЕЧАТНЫМИ БУКВАМИ

Family name

Фамилия

SERIKOV

First name(s)

Имя

SERIK

Sex

Пол

M

M (Male)

Мужской

F (Female)

Женский

Date of birth

Дата рождения

31 12 1985

DD MM YYYY

ДД ММ ГГГГ

Town and country of birth

Город и страна рождения

ALMATY, KAZAKHSTAN

Nationality

Национальность

KAZAKH

Contact address in the UK (in full)

Контактный адрес в Великобритании (полностью)

SHAFTES GRAND LONDON HYDE PARK 4*, 78-82 WESTBOURNE TERRACE, PADDINGTON, LONDON, W2 6QA +44(0) 2072624521

Passport no.

Номер паспорта

N06575855

Place of issue

Место выдачи

MINISTRY OF JUSTICE

Length of stay in the UK

Продолжительность пребывания в Великобритании

8 DAYS

Port of last departure

Точка последнего отправления *

ALMATY

Arrival flight/train number

Номер рейса/поезда прибытия

KC 901

Signature

Подпись

Ваша подпись

If you break UK laws you could face imprisonment and removal

Если вы нарушите законы Великобритании вам может грозить тюремное заключение и высылка

For official use

Для служебного пользования

*
Точка последнего отправления — Например, если вы летите из Алматы в Лондон с пересадкой в Москве, то точка последнего отправления — Москва. Если у вас прямой рейс из Алматы в Лондон, то точка последнего отправления Алматы.

Оборотную сторону карточки заполнять не нужно, она заполняется иммиграционным офицером.
CAM00220

Текст

Перевод

For official use

Для служебного пользования

Immigration Officer’s notes

Пометки иммиграционного офицера

Visa/leave to enter expiry date (if applicable)

Истечение срока действия визы/разрешения на въезд (если применимо)

Landing conditions and arrival date

Условия и дата прибытия

В зале иммиграционного контроля вам нужно будет предъявить заполненную иммиграционную карточку, паспорт и пройти процедуру проверки отпечатков пальцев. Процедура сверки отпечатков происходит путем приложения пальцев к сканеру.

В Лондоне очень интересный способ обслуживания очереди. Так как очень много прибывающих, работают несколько офицеров. Также есть человек, который следит за тем, кто из офицеров освободился. Освободившийся офицер поднимает руку — это очень понравилось. Также понравились слова: «Добро пожаловать, сэр», когда мы прошли иммиграционный контроль. Меня в первый раз в жизни назвали сэром 🙂