Глава 7. Работа с базой данных

[10 ноября 2016 г.]    Российская сборка Magento 2.49.12
Magento 2: модули и услуги
#1 Надежда А
  • Иконка
  • Группа: Администратор
  • Сообщений: 50
  • Регистрация: 12.12.2010

29.03.2011 00:48

В этой главе мы рассмотрим:

  • Ресурсы и соединения с базой данных

  • Magento репликацию баз данных с помощью мастер-Slave установки

  • Использование метода Синглтон в Magento

  • Ремонт базы данных Magento

  • Работу с EAV дизайном Magento



Введение

Magento использует MySQL для своей базы данных и использует продвинутый инструмент для моделирования данных под названием EAV (Entity-Attribute-Value). База данных MySQL стала самой популярной в мире СУБД с открытым исходным кодом из-за его последовательно высокой производительности, высокой надежности и простоты использования. MySQL Cluster получил широкое распространение для спектра телекоммуникаций, Интернета и требовательных корпоративных приложений операторского класса доступности, с высокой транзакционной пропускной способностью, и низкой латентностью.
В этой главе мы рассмотрим некоторые интересные рецепты, которые связаны с лучшими практиками в целях обеспечения следующих пунктов:
  • Высокая доступность (High-availability)

  • Проведенное на сайте время/ время простоя (Uptime/Downtime)

  • Уровень доступности (Level of availability)

  • Единая точка отказа (Single point of failure (SPOF))

  • Восстановление / преодоление отказа

  • Кластер



Ресурсы и соединения с базой данных
Ресурс в Magento используется для управления базами данных. Ресурсы определены в глобальном XML теге любого файла config.xml. Для создания нового соединения с базой данных мы должны добавить файл XML, такой как app/etc/config.xml файл. Каждый ресурс имеет имя. Имена соединения – это, как правило, образца module_read, module_write или module_setup. В этот рецепт мы будем играть с ресурсом и создавать новое подключение к базе данных, которое будет работать на любой базе данных, которую мы указываем.


Подготовка

Откройте Magento проект в вашем редакторе кода.


Как это сделать...

1. Мы будем печатать данные на странице изображения товара с целью развития. Давайте откроем view.phtml файл из папки app/design/frontend/YOUR_INTERFACE/YOUR_THEME/template/catalog/product/.
2. Добавьте следующий фрагмент кода в верхнюю часть view.phtml:
<?php
$singleton = Mage::getSingleton('catalog/session’);
echo '<pre>’;
var_export($singleton->debug());
echo '</pre>’;
?>

3. Посетите любую страницу сведений о товаре, чтобы увидеть результаты в вашем браузере.
4. Давайте протестируем метод Синглтон (Singleton method) в этом фрагменте кода:
<?php
$resource = Mage::getSingleton('core/resource’);
$conn = $resource->getConnection('core_read’);
$results = $conn->query('SELECT * FROM admin_user’)->fetchAll();
echo '<pre>’;
var_export($results);
echo '</pre>’;
?>

5. Запустите этот код, посетив любую страницу деталей товара. Вы должны увидеть страницу, похожую на эту:

Прикрепленное изображение: 1.png

6. Давайте создадим новый ресурс и используем его для подключения к любой базе данных. Замените предыдущий фрагмент кода на следующий блок кода:
<?php
$conf = array(
'host’ => 'localhost’,
'username’ => 'root’,
'password’ => 'Owy! My password!!’,
'dbname’ => 'wordpress’ // you can any database name here
);
$_resource = Mage::getSingleton('core/resource’);
//Creating new connection to new server and new database
$_conn = $_resource->createConnection('customConnection’,
'pdo_mysql’, $conf);
$results = $_conn->query('SELECT * FROM wp_posts’)->fetchAll();
echo '<pre>’;
print_r($results);
echo '</pre>’;
?>

7. Таким образом, мы можем подключить внешнюю базу данных и выполнить запрос, используя ресурс Magento. Мы подключили внешнюю базу данных WordPress и взяли wp_posts таблицу. Чтобы увидеть ее в действии, посетите страницу деталей товара, такую как: http://magento.local...tebook-pc.html.
8. Вот еще одна реализация (implementation) с фильтром для SKU:
$collection_of_products = Mage::getModel('catalog/product’)-
>getCollection();
//another neat thing about collections is you can pass them into
the count //function. More PHP5 powered goodness
echo "Our collection now has " . count($collection_of_products) .
' item(s)’;
$collection_of_products->addFieldToFilter('sku’, 'mycomputer’);
echo '<pre>’;
var_export($collection_of_products->getFirstItem()->getData());
echo '</pre>’;

9. Надеюсь, это помогает!


Как это работает...

Magento активно использует Singleton шаблон (модель) дизайна для обработки соединения с базой данных. Singleton является полезным шаблоном дизайна для допуска только одного экземпляра вашего класса. Цель Singleton – это контроль создания объекта, ограничивая количество к одному, но с учетом гибкости, чтобы создать больше объектов, если ситуация изменится. Поскольку существует только один Singleton экземпляр, любой области экземпляра Singleton будет происходить только один раз в классе, как и статические поля.


Magento репликация базы данных с помощью Master Slave установки

Magento имеет замечательную функцию в борьбе (for coping) со средством репликации базы данных (database replicating facility). Репликация может быть использована во многих случаях для создания эффективных и масштабируемых, высокодоступных решений. Существуют различные методы для настройки репликации, и точный метод для использования зависит от того, как вы настраиваете репликацию, и от того, есть ли у вас уже данные в вашей основной базе данных.
В этом рецепте мы будем использовать некоторые общие задачи, которые являются общими для всех установок репликации для выполнения Мастер Slave установки для нашего магазина Magento. Преимуществом этой установки является то, что Magento может выдать read запросы любому из подчиненных серверов, сохраняя все write запросы для базы данных. База данных традиционно сложная составляющая для масштабирования по горизонтали, так что репликация – удачный компромисс.


Подготовка

Давайте решим и получим два MySQL сервера готовыми, чтобы сделать репликацию успешно. Соберите информацию, такую как имя хоста, IP-адрес, имя пользователя и пароль.


Как это сделать...

Настройка мастера:

1. Откройте файл my.cnf из каталога /etc/mysql (если вы находитесь на дистрибутиве основе Debian, например, Ubuntu). Если вы используете инструмент третьего выпуска, как XAMPP, то это будет my.ini файл, расположенный в каталоге xampp/bin.
2. Найдите следующий код и прокомментируйте его, добавив # перед ним. Мы должны видеть его следующим образом. Это позволит другим сетям иметь доступ к серверу MySQL. Мы будем использовать его из подчиненного компонента (from the slave).
#bind-address = 127.0.0.1
3. Вставьте следующий фрагмент кода под [mysqld] раздел; вы можете изменить параметры, как вы установите их:
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
binlog_do_db = magentodb
4. Перезагрузите ваш сервер MySQL. Если это дистрибутив на Debian основе, то команда:
sudo /etc/init.d/mysql restart
5. Войдите в вашу MYSQL консоль с корневым пользователем:
sudo mysql -u root -p
6. Когда вы будете в ней, введите следующие команды в оболочку MySQL (MYSQL shell):
GRANT ALL PRIVILEGES ON `magentodb` . * TO 'slave_user’@’%’ WITH
GRANT OPTION IDENTIFIED BY 'slave_password’;
FLUSH PRIVILEGES;
QUIT;

7. Войдите снова в вашу MYSQL оболочку с корневой привилегией. Выпустите эти команды и проверьте состояние нашего Master:
USE magentodb;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

8. Вы должны увидеть результат, подобный этому:

Прикрепленное изображение: 2.png

9. Храните эту информацию в безопасном месте, т.к. мы будем использовать ее в нашей Slave установке.
10. Выполните следующую команду в оболочке MYSQL для снятия блокировки на таблицы, как мы подали заявку на предыдущем шаге:
UNLOCK TABLES;
quit;

11. Нет такого шага для Master установки. Вы сделали!

Настройка Slave:
1. Войдите в ваш Slave сервер с корневой привилегией, как:
mysql -u root –p
2. Создайте новую базу данных с именем magentodb и импортируйте точную схему экспортируемую из базы данных.
3. Откройте my.cnf или my.ini файл из /etc/mysql или xampp/mysql/bin папки. Вложите следующий код в [mysqld] раздел. Измените его в соответствии с вашей собственной серверной информацией:
[mysqld]
server-id = 2
master-host = 192.168.3.12
master-user = slave_user
master-password = slave_password
master-connect-retry = 60
replicate-do-db = magentodb
4. Сейчас перезапустите свой MYSQL сервер:
/etc/init.d/mysql restart
5. Войдите в свою оболочку Slave MYSQL сервера:
mysql -u root -p
6. Теперь введите следующую команду в вашей MySQL оболочке. Используйте master log файл и master log позицию, как вы, наверное, видели это во время настройки Master сервера.
CHANGE MASTER TO MASTER_HOST=’192.168.3.12’, MASTER_USER=’slave_
user’, MASTER_PASSWORD=’slave_password’, MASTER_LOG_FILE=’mysqlbin.
000001’, MASTER_LOG_POS=88;

7. Теперь запустите Slave (подчиненный) сервер:
START SLAVE;
8. Проверьте Slave статус:
SHOW SLAVE STATUS \G
9. Это должно выглядеть следующим образом:

Прикрепленное изображение: 3.png

На данный момент вы можете изменить вашу MySQL репликацию путем изменения Master базы данных и просмотра, изменяется ли она автоматически в базе данных Slave или нет. Любые изменения в базе данных мастер должен также применяться изменения в базе данных Slave (почти) режиме реального времени!
10. После того как вы получили функционирование MySQL репликации, настройка Magento на использование нескольких серверов баз данных является относительно простой задачей. Только файл, который вы должны, - это app/etc/local.xml. Как вы можете видеть, Есть два настроенных соединения с базой данных, одно называется default_setup и другой - default_read. Соединение default_setup будет использоваться для всех запросов на основе написания (write-based), и соединение default_read будет использоваться для всех запросов на основе чтения (read-based).
11. Вот мое app/etc/local.xml, DIY (Do It Yourself):
<resources>
<db>
<table_prefix><![CDATA[]]></table_prefix>
</db>
<default_setup>
<connection>
<host><![CDATA[master.localhost.com]]></host>
<username><![CDATA[master_user]]></username>
<password><![CDATA[owey!mypassword!!]]></password>
<dbname><![CDATA[magentodb]]></dbname>
<active>1</active>
</connection>
</default_setup>
<default_read>
<connection>
<host><![CDATA[slave.localhost.com]]></host>
<username><![CDATA[slave_user]]></username>
<password><![CDATA[slave_password]]></password>
<dbname><![CDATA[magentodb]]></dbname>
<active>1</active>
</connection>
</default_read>
</resources>

12. Это все для этого рецепта. Вы можете протестировать его сейчас!


Как это работает...

На мастере репликации вы должны включить двоичную регистрацию и создать уникальный идентификатор сервера. Если это еще не сделано, эта часть Master установки требует перезагрузки сервера.
Бинарная регистрация (Binary logging ) должна быть включена на мастере, так как бинарная запись (binary log ) является основанием для направления изменения данных от Master к его Slaves (подчиненные). Если бинарный лог не включен, репликация будет невозможна.
Чтобы настроить репликацию на Slave, необходимо определить текущие координаты Master в пределах его бинарной записи (binary log). Вам понадобится эта информация, так что, когда подчиненный (Slave) начинает процесс репликации, он может начать обработку событий из бинарного журнала (binary log ) в нужной точке.
Если вы можете зайти так далеко, то Magento будет делать все остальное. Вам не нужно беспокоиться о том, как это происходит там!


Использование метода Синглтон в Magento

Magento использует популярный Синглтон дизайн-шаблон для обработки соединения базы данных с ее ресурсными моделями. Он использует PDO Adapter (Varien_Db_Adapter_Pdo_Mysql) объект, который является только подклассом Zend_Db_Adapter_Pdo_Mysql из Zend Framework. В этот рецепте мы будем запускать пользовательский запрос SQL к базе данных Magento с помощью метода Синглтон.


Подготовка

Запустите ваш IDE и откройте проект Magento, с которым мы будем работать. Теперь откройте файл Mage.php из app/ каталога. Ищите метод getSingleton в файле Mage.php. В моем случае он находится на строке № 435. Я показываю вам метод здесь для вашего удобства.
/**
* Retrieve model object singleton
*
* @param string $modelClass
* @param array $arguments
* @return Mage_Core_Model_Abstract
*/
public static function getSingleton($modelClass=’’, array
$arguments=array())
{
$registryKey = '_singleton/’.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, self::getModel($modelClass,
$arguments));
}
return self::registry($registryKey);
}

Посмотрите внимательно на заголовок функции (phpdoc) и обратите внимание на параметры функции в скобке. Это метод, который мы будет вызывать для запуска пользовательского (клиентского) SQL запроса.


Как это сделать…

1. Мы будем печатать данные на странице просмотра товара в целях развития. Давайте откроем view.phtml файл из папки app/design/frontend/YOUR_INTERFACE/YOUR_THEME/template/catalog/product/
2. Добавим следующий фрагмент кода в верхней части view.phtml:
$w = Mage::getSingleton('core/resource’)->getConnection('core_
write’);
$result = $w->query('select `entity_id` from `catalog_product_
entity`’);
if (!$result) {
return false;
}
$row = $result->fetch(PDO::FETCH_ASSOC);
if (!$row) {
return false;
}
echo '<pre>’;
var_export($row);
echo '</pre>’;

3. Посетите любую страницу сведений о товаре, чтобы увидеть результаты в вашем браузере.


Как это работает...

Мы использовали ресурс соединения родной базы данных Magento, который является ядром / ресурсом с core_write привилегией. Мы можем использовать наши собственные ресурсы или другие привилегии, такие как default_read и т.д.


Ремонт базы данных Magento

В некоторых случаях мы можем столкнуться с проблемой с базой данных при работе с CMS Magento. Существует довольно простое решение, чтобы вернуть базу данных Magento в его свежую версию, если у нас есть резервная копия нашей базы данных Magento. В этом рецепте мы будем делать ремонт поврежденной базы данных из свежей резервной копии с помощью Magento инструмента ремонта базы данных.


Подотовка

Magento инструмент ремонта базы данных доступен в разделе загрузки Magento бесплатно. Вы можете скачать его отсюда: http://www.magentoco...e.com/download.
Найдите слово Database Repair Tool, выберите свой формат и загрузите копию.


Как это сделать…

1. Загрузите архив Magento инструмента ремонта базы данных со страницы загрузки http://www.magentoco...e.com/download.
2. Распакуйте архив.
3. Положите magento-db-repair-tool-1.0.php в вашу webroot папку на вашем сервере. Вы не должны ложить его в Magento.
4. Сделайте резервную копию существующей базы данных, чтобы иметь возможность восстановить ее, если что-нибудь пойдет не так.
5. Допустим, у нас есть две базы данных. Одна называется magento_fresh и другая - magento_corrupted.
6. Укажите ваш браузер на место, куда вы вставили magento-db-repairtool-1.0.php. Вы должны увидеть страницу что-то вроде следующего скриншота. Введите учетные данные, как я сделал:

Прикрепленное изображение: 4.png

7. После отправки этой формы вы увидите подробный отчет о процессе восстановления.
8. Проверьте ваш поврежденный Magento сайт прямо сейчас.


Как это работает...

Database Repair Tool сравнивает две базы данных (reference и target), и обновляет целевую базу данных (target database), поэтому она имеет такую же структуру, как и справочная база данных (reference database), выполняя следующие действия:
Добавляет отсутствующие таблицы, или выполняет их ремонт, чтобы иметь тот же тип двигателя и кодировки
Добавляет отсутствующие поля или выполняет их ремонт
Удаляет противоречивые данные из таблиц, которые нарушили ссылки внешнего ключа (foreign key references)
Добавляет отсутствующие внешние ключи и индексы


Работа с EAV дизайна в Magento

Magento использует EAV для обеспечения вертикального моделирования данных, а не традиционного горизонтального моделирования. В EAV дизайне мы можем добавить неограниченное число столбцов, этолучшая его часть. Но это за счет ухудшения производительности запросов и потери бизнес-логики, которая хранилась в реляционной схеме базы данных.
EAV дизайн Magento работает с его ресурсами, объектами (entities), объектами-атрибутами и их значениями. Кроме объектов Magento по умолчанию мы можем добавить новую. В Magento популярный шаблон проектирования Active Record используется для обеспечения эффективности при работе с большим набором данных для серьезных бизнес-приложений.
Объекты позволяют вам загружать и сохранять сложные отношения к и из базы данных. Но большую часть времени, когда мы думаем о запросах к базе данных, мы хотим написать SELECT заявление, котрое дает нам результат с несколькими строками. лица моделей не будет в состоянии сделать это. Объектные модели предназначены для загрузки одного пункта, или записи за раз.
Только нахождение в состоянии отношения с одной записью за раз означает, что мы должны знать первичное значение ID записи, чтобы загрузить ее. Но что произойдет, если мы хотим выбрать все записи из базы данных, соответствующие определенным критериям? Как правило, простое SELECT заявление с предложением WHERE будет работать. Но все не так просто, когда дело с объектами (entities). Не все данные, которые составляют сущность (entity) «живут» в одной таблице, поэтому мы должны объединить несколько таблиц. Чтобы решить эту проблему, мы будем использовать здесь getCollection () Magento модели и addAttributeToFilter ().


Как это сделать…

1. Мы будем печатать данные на странице просмотра товара в целях развития. Позволим нам открыть view.phtml файл из папки the app/design/frontend/YOUR_INTERFACE/YOUR_THEME/template/catalog/product/.
2. Добавите следующий фрагмент кода в верхнюю часть view.phtml:
$products = Mage::getModel('catalog/product’)->getCollection();
$products->addAttributeToFilter('entity_id’, array('in’=>
array(163,164,165) ));
$products->load();
echo '<pre>’;
foreach($products as $product) {
var_export($product->getData());
}
echo '</pre>’;
?>

3. Посетите любую страницу сведений о товаре, чтобы увидеть результаты в вашем браузере. Вот скриншот:

Прикрепленное изображение: 5.png

4. Вот еще один пример для лучшего понимания:
<?php
$products = Mage::getModel('catalog/product’)->getCollection();
$products->addAttributeToFilter('sku’, 'uni-hoodie-medium’);
$products->load();
echo '<pre>’;
foreach($products as $product) {
var_export($product->getData());
}
echo '</pre>’;
?>

5. Надеюсь, это помогает!


Как это работает...

Мы использовали модель товара из каталога и для коллекции захвата товара путем сцепления getCollection () метода. Затем мы добавили фильтр для конкретного товарного листинга. Мы можем использовать некоторые другие типы атрибутов и параметров. Вот PHPDoc, который обрабатывает параметры addFilterAtributes обычного порядка:

/**
* Build SQL statement for condition
*
* If $condition integer or string - exact value will be filtered
*
* If $condition is array is - one of the following structures is
expected:
* - array("from"=>$fromValue, "to"=>$toValue)
* - array("like"=>$likeValue)
* - array("neq"=>$notEqualValue)
* - array("in"=>array($inValues))
* - array("nin"=>array($notInValues))
*
* If non matched - sequential array is expected and OR
conditions
* will be built using above mentioned structure
*
* @param string $fieldName
* @param integer|string|array $condition
* @return string
*/


Поделиться темой: