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 Условия и дата прибытия
В зале иммиграционного контроля вам нужно будет предъявить заполненную иммиграционную карточку, паспорт и пройти процедуру проверки отпечатков пальцев. Процедура сверки отпечатков происходит путем приложения пальцев к сканеру. В Лондоне очень интересный способ обслуживания очереди. Так как очень много прибывающих, работают несколько офицеров. Также есть человек, который следит за тем, кто из офицеров освободился. Освободившийся офицер поднимает руку - это очень понравилось. Также понравились слова: "Добро пожаловать, сэр", когда мы прошли иммиграционный контроль. Меня в первый раз в жизни назвали сэром 🙂