Ruby / DBI Eğitimi
Bu bölüm size Ruby kullanarak bir veritabanına nasıl erişeceğinizi öğretir. Yakut DBI modülü Perl DBI modülü benzer Ruby komut dosyaları için bir veritabanı bağımsız arayüz sağlar.
DBI, Ruby için Veritabanından Bağımsız Arayüz anlamına gelir; bu, DBI'nın Ruby kodu ile temeldeki veritabanı arasında bir soyutlama katmanı sağladığı ve veritabanı uygulamalarını gerçekten kolayca değiştirmenize izin verdiği anlamına gelir. Kullanılan gerçek veritabanından bağımsız olarak tutarlı bir veritabanı arabirimi sağlayan bir dizi yöntemi, değişkeni ve kuralı tanımlar.
DBI aşağıdakilerle arayüz oluşturabilir -
- ADO (ActiveX Veri Nesneleri)
- DB2
- Frontbase
- mSQL
- MySQL
- ODBC
- Oracle
- OCI8 (Oracle)
- PostgreSQL
- Proxy/Server
- SQLite
- SQLRelay
DBI Uygulamasının Mimarisi
DBI, arka uçta bulunan herhangi bir veritabanından bağımsızdır. Oracle, MySQL veya Informix vb. İle çalışıyor olsanız da DBI kullanabilirsiniz. Bu, aşağıdaki mimari diyagramdan anlaşılır.
Ruby DBI için genel mimari iki katman kullanır -
Veritabanı arabirimi (DBI) katmanı. Bu katman veritabanından bağımsızdır ve iletişim kurduğunuz veritabanı sunucusunun türüne bakılmaksızın aynı şekilde kullanılan bir dizi ortak erişim yöntemi sağlar.
Veritabanı sürücüsü (DBD) katmanı. Bu katman veritabanına bağlıdır; farklı sürücüler, farklı veritabanı motorlarına erişim sağlar. MySQL için bir sürücü, PostgreSQL için bir sürücü, InterBase için bir sürücü, Oracle için bir sürücü ve diğerleri vardır. Her sürücü, DBI katmanından gelen istekleri yorumlar ve bunları belirli bir veritabanı sunucusu türüne uygun isteklerle eşler.
Önkoşullar
MySQL veritabanlarına erişmek için Ruby komut dosyaları yazmak istiyorsanız, Ruby MySQL modülünün kurulu olması gerekir.
Bu modül, yukarıda açıklandığı gibi bir DBD görevi görür ve şu adresten indirilebilir: https://www.tmtm.org/en/mysql/ruby/
Ruby / DBI Edinme ve Yükleme
Ruby DBI modülünü aşağıdaki konumdan indirip kurabilirsiniz -
https://imgur.com/NFEuWe4/embed
Bu kuruluma başlamadan önce, root ayrıcalığına sahip olduğunuzdan emin olun. Şimdi, aşağıda verilen adımları izleyin -
Aşama 1
$ tar zxf dbi-0.2.0.tar.gz
Adım 2
Dbi -0.2.0 dağıtım dizinine gidin ve bu dizindeki setup.rb komut dosyasını kullanarak yapılandırın . En genel konfigürasyon komutu, config argümanını takip eden hiçbir argüman olmaksızın buna benzer. Bu komut, dağıtımı varsayılan olarak tüm sürücüleri yükleyecek şekilde yapılandırır.
$ ruby setup.rb config
Daha spesifik olmak gerekirse, dağıtımın kullanmak istediğiniz belirli bölümlerini listeleyen bir --with seçeneği sağlayın. Örneğin, yalnızca ana DBI modülünü ve MySQL DBD düzeyi sürücüyü yapılandırmak için aşağıdaki komutu çalıştırın -
$ ruby setup.rb config --with = dbi,dbd_mysql
Aşama 3
Son adım, sürücüyü oluşturmak ve aşağıdaki komutları kullanarak kurmaktır -
$ ruby setup.rb setup
$ ruby setup.rb install
Veritabanı Bağlantısı
MySQL veritabanıyla çalışacağımızı varsayarsak, bir veritabanına bağlanmadan önce aşağıdakilerden emin olun -
Bir TESTDB veritabanı oluşturdunuz.
TESTDB'de EMPLOYEE oluşturdunuz.
Bu tablo FIRST_NAME, LAST_NAME, AGE, SEX ve INCOME alanlarına sahip.
"Testuser" kullanıcı kimliği ve "test123" şifresi TESTDB'ye erişmek için ayarlanmıştır.
Ruby Module DBI, makinenize düzgün bir şekilde kurulmuş.
MySQL Temellerini anlamak için MySQL eğitiminden geçtiniz.
Aşağıda MySQL veritabanı "TESTDB" ile bağlantı kurma örneği verilmiştir
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
# get server version string and display it
row = dbh.select_one("SELECT VERSION()")
puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# disconnect from server
dbh.disconnect if dbh
end
Bu betiği çalıştırırken, Linux makinemizde aşağıdaki sonucu verir.
Server version: 5.0.45
Veri kaynağıyla bir bağlantı kurulursa, bir Veritabanı Tutacağı döndürülür ve dbh aksi takdirde daha fazla kullanım için dbhnil değerine ayarlanır ve e.err ve e :: errstr , sırasıyla hata kodu ve bir hata dizesi döndürür.
Son olarak, çıkmadan önce veritabanı bağlantısının kapatıldığından ve kaynakların serbest bırakıldığından emin olun.
INSERT İşlemi
Kayıtlarınızı bir veritabanı tablosunda oluşturmak istediğinizde INSERT işlemi gereklidir.
Bir veritabanı bağlantısı kurulduktan sonra, kullanarak veritabanı tablolarına tablo veya kayıt oluşturmaya hazırız. do yöntem veya prepare ve execute yöntem.
Do İfadesini Kullanma
Satır döndürmeyen ifadeler, doveritabanı işleme yöntemi. Bu yöntem bir ifade dizesi bağımsız değişkeni alır ve ifadeden etkilenen satırların sayısını döndürür.
dbh.do("DROP TABLE IF EXISTS EMPLOYEE")
dbh.do("CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )" );
Benzer şekilde, EMPLOYEE tablosunda bir kayıt oluşturmak için SQL INSERT deyimini çalıştırabilirsiniz .
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
dbh.do( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)" )
puts "Record has been created"
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end
Hazırla ve yürüt özelliğini kullanma
SQL deyimini Ruby kodu aracılığıyla yürütmek için DBI sınıfının hazırlama ve yürütme yöntemlerini kullanabilirsiniz .
Kayıt oluşturma aşağıdaki adımları gerçekleştirir -
INSERT deyimiyle SQL deyiminin hazırlanması. Bu, kullanılarak yapılacaktır.prepare yöntem.
Veritabanından tüm sonuçları seçmek için SQL sorgusunun yürütülmesi. Bu, kullanılarak yapılacaktır.execute yöntem.
Serbest bırakma İfadesi tutamacı. Bu kullanılarak yapılacaktırfinish API
Her şey yolunda giderse, o zaman commit bu işlem yoksa yapabilirsin rollback tam işlem.
Bu iki yöntemi kullanmak için sözdizimi aşağıdadır -
sth = dbh.prepare(statement)
sth.execute
... zero or more SQL operations ...
sth.finish
Bu iki yöntem geçmek için kullanılabilir bindSQL ifadelerine değerler. Girilecek değerlerin önceden verilmediği bir durum olabilir. Böyle bir durumda bağlanma değerleri kullanılır. Bir soru işareti (?) gerçek değerler yerine kullanılır ve ardından gerçek değerler execute () API üzerinden geçirilir.
EMPLOYEE tablosunda iki kayıt oluşturmak için örnek aşağıdadır -
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
VALUES (?, ?, ?, ?, ?)" )
sth.execute('John', 'Poul', 25, 'M', 2300)
sth.execute('Zara', 'Ali', 17, 'F', 1000)
sth.finish
dbh.commit
puts "Record has been created"
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end
Bir seferde birden fazla INSERT varsa, o zaman önce bir ifade hazırlamak ve sonra bunu bir döngü içinde birden çok kez yürütmek, döngü boyunca her seferinde çağırmaktan daha etkilidir.
OKUMA İşlemi
Herhangi bir veritabanı üzerinde READ İşlemi, veritabanından bazı yararlı bilgileri almak anlamına gelir.
Veritabanı bağlantımız kurulduktan sonra, bu veritabanına bir sorgulama yapmaya hazırız. İkisini de kullanabilirizdo yöntem veya prepare ve execute bir veritabanı tablosundan değerleri getirme yöntemleri.
Kayıt getirme aşağıdaki adımları gerçekleştirir -
SQL sorgusunun gerekli koşullara göre hazırlanması. Bu, kullanılarak yapılacaktır.prepare yöntem.
Veritabanından tüm sonuçları seçmek için SQL sorgusunun yürütülmesi. Bu, kullanılarak yapılacaktır.execute yöntem.
Tüm sonuçları tek tek almak ve bu sonuçları yazdırmak. Bu, kullanılarak yapılacaktır.fetch yöntem.
Serbest bırakma İfadesi tutamacı. Bu, kullanılarak yapılacaktır.finish yöntem.
1000'den fazla maaşı olan EMPLOYEE tablosundaki tüm kayıtları sorgulama prosedürü aşağıdadır.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE INCOME > ?")
sth.execute(1000)
sth.fetch do |row|
printf "First Name: %s, Last Name : %s\n", row[0], row[1]
printf "Age: %d, Sex : %s\n", row[2], row[3]
printf "Salary :%d \n\n", row[4]
end
sth.finish
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# disconnect from server
dbh.disconnect if dbh
end
Bu, aşağıdaki sonucu verecektir -
First Name: Mac, Last Name : Mohan
Age: 20, Sex : M
Salary :2000
First Name: John, Last Name : Poul
Age: 25, Sex : M
Salary :2300
Veritabanından kayıt almak için daha fazla kısa yol yöntemi vardır. Eğer ilgileniyorsanız , Sonucu Getirme bölümüne gidin, aksi takdirde sonraki bölüme geçin.
Güncelleme İşlemi
GÜNCELLEME Herhangi bir veritabanı üzerinde işlem, veritabanında zaten mevcut olan bir veya daha fazla kaydı güncellemek anlamına gelir. Aşağıda, SEX olan tüm kayıtları 'M' olarak güncelleme prosedürü yer almaktadır. Burada tüm erkeklerin YAŞ'ını bir yıl artıracağız. Bu üç adım atacak -
SQL sorgusunun gerekli koşullara göre hazırlanması. Bu, kullanılarak yapılacaktır.prepare yöntem.
Veritabanından tüm sonuçları seçmek için SQL sorgusunun yürütülmesi. Bu, kullanılarak yapılacaktır.execute yöntem.
Serbest bırakma İfadesi tutamacı. Bu, kullanılarak yapılacaktır.finish yöntem.
Her şey yolunda giderse o zaman commit bu işlem yoksa yapabilirsin rollback tam işlem.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = ?")
sth.execute('M')
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end
DELETE İşlemi
Veritabanınızdan bazı kayıtları silmek istediğinizde DELETE işlemi gereklidir. Aşağıda, AGE'nin 20'den fazla olduğu ÇALIŞAN'dan tüm kayıtları silme prosedürü verilmiştir. Bu işlem aşağıdaki adımları gerçekleştirecektir.
SQL sorgusunun gerekli koşullara göre hazırlanması. Bu, kullanılarak yapılacaktır.prepare yöntem.
Veritabanından gerekli kayıtları silmek için SQL sorgusunun yürütülmesi. Bu, kullanılarak yapılacaktır.execute yöntem.
Serbest bırakma İfadesi tutamacı. Bu, kullanılarak yapılacaktır.finish yöntem.
Her şey yolunda giderse o zaman commit bu işlem yoksa yapabilirsin rollback tam işlem.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("DELETE FROM EMPLOYEE WHERE AGE > ?")
sth.execute(20)
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end
İşlem Yapmak
İşlemler, veri tutarlılığını sağlayan bir mekanizmadır. İşlemler aşağıdaki dört özelliğe sahip olmalıdır -
Atomicity - Ya bir işlem tamamlanır ya da hiçbir şey olmaz.
Consistency - Bir işlem tutarlı bir durumda başlamalı ve sistemi tutarlı bir durumda bırakmalıdır.
Isolation - Bir işlemin ara sonuçları, mevcut işlemin dışında görünmez.
Durability - Bir işlem yapıldığında, sistem arızasından sonra bile etkiler kalıcıdır.
DBI birine iki yöntem sağlar işlemek veya geri alma işlem. İşlemleri uygulamak için kullanılabilecek işlem adında bir yöntem daha vardır . İşlemleri uygulamak için iki basit yaklaşım vardır -
Yaklaşım I
İlk yaklaşım , işlemi açıkça taahhüt etmek veya iptal etmek için DBI'nın kesinleştirme ve geri alma yöntemlerini kullanır -
dbh['AutoCommit'] = false # Set auto commit to false.
begin
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
dbh.commit
rescue
puts "transaction failed"
dbh.rollback
end
dbh['AutoCommit'] = true
Yaklaşım II
İkinci yaklaşım işlem yöntemini kullanır . Bu daha basittir, çünkü işlemi oluşturan ifadeleri içeren bir kod bloğu alır. İşlem yöntemi, daha sonra başlatır, blok yürütür işlemek veya geri alma bloğu başarılı veya başarısız olmasına bağlı olarak, otomatik olarak -
dbh['AutoCommit'] = false # Set auto commit to false.
dbh.transaction do |dbh|
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true
COMMIT İşlemi
Commit, değişiklikleri sonlandırmak için veri tabanına yeşil sinyal veren ve bu işlemden sonra hiçbir değişiklik geri alınamayan işlemdir.
İşte aranacak basit bir örnek commit yöntem.
dbh.commit
GERİ DÖNME İşlemi
Değişikliklerden bir veya daha fazlasından memnun değilseniz ve bu değişiklikleri tamamen geri almak istiyorsanız, o zaman rollback yöntem.
İşte aranacak basit bir örnek rollback yöntem.
dbh.rollback
Veritabanının Bağlantısını Kesme
Veritabanı bağlantısını kesmek için bağlantı kesme API'sini kullanın.
dbh.disconnect
Bir veritabanına bağlantı, kullanıcı tarafından bağlantı kesme yöntemiyle kapatılırsa, bekleyen tüm işlemler DBI tarafından geri alınır. Ancak, herhangi bir DBI uygulama detayına bağlı olmak yerine, uygulamanız kesin olarak commit veya geri alma çağrısı yapmaktan daha iyi olacaktır.
Hataları Yönetme
Birçok hata kaynağı var. Birkaç örnek, yürütülen bir SQL deyimindeki sözdizimi hatası, bir bağlantı hatası veya önceden iptal edilmiş veya bitmiş bir ifade tutamacı için getirme yönteminin çağrılmasıdır.
Bir DBI yöntemi başarısız olursa, DBI bir istisna oluşturur. DBI yöntemleri birkaç istisna türünden herhangi birini ortaya çıkarabilir, ancak en önemli iki istisna sınıfı DBI :: InterfaceError ve DBI :: DatabaseError'dır .
Bu sınıfların istisna nesneleri , hata numarasını, açıklayıcı bir hata dizesini ve standart bir hata kodunu temsil eden err , errstr ve state adlı üç niteliğe sahiptir . Nitelikler aşağıda açıklanmıştır -
err- DBD tarafından desteklenmiyorsa, oluşan hatanın tamsayı temsilini veya nil döndürür. Oracle DBD, örneğin ORA-XXXX hata mesajının sayısal bölümünü döndürür .
errstr - Oluşan hatanın dize gösterimini döndürür.
state- Oluşan hatanın SQLSTATE kodunu döndürür. SQLSTATE beş karakter uzunluğunda bir dizedir. Çoğu DBD bunu desteklemez ve bunun yerine sıfır döndürür.
Örneklerin çoğunda yukarıdaki kodu gördünüz -
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end
Komut dosyanızın yürütülürken ne yaptığı hakkında hata ayıklama bilgisi almak için izlemeyi etkinleştirebilirsiniz. Bunu yapmak için, öncelikle dbi / iz modülü yüklemek ve daha sonra çağırmalıdır iz yöntemi olduğunu kontrolleri iz modu ve çıkış hedef -
require "dbi/trace"
..............
trace(mode, destination)
Mod değeri 0 (kapalı), 1, 2 veya 3 olabilir ve hedef bir GÇ nesnesi olmalıdır. Varsayılan değerler sırasıyla 2 ve STDERR'dir.
Yöntemlerle Kod Blokları
Tutamaç oluşturan bazı yöntemler vardır. Bu yöntemler bir kod bloğu ile çağrılabilir. Yöntemlerle birlikte kod bloğunu kullanmanın avantajı, kod bloğuna bir parametre olarak tutamacı sağlaması ve blok sona erdiğinde tutamacı otomatik olarak temizlemesidir. Kavramı anlamak için birkaç örnek var.
DBI.connect- Bu yöntem bir veritabanı tanıtıcısı oluşturur ve veritabanının bağlantısını kesmek için bloğun sonunda bağlantıyı kesmenin çağrılması önerilir .
dbh.prepare- Bu yöntem bir ifade tutamacı oluşturur ve bloğun sonunda bitirilmesi önerilir . Blok içinde, ifadeyi yürütmek için yürütme yöntemini çağırmalısınız .
dbh.execute- Bu yöntem benzerdir, ancak blok içinde çalıştırmayı çağırmamız gerekmez. İfade tutamacı otomatik olarak yürütülür.
örnek 1
DBI.connect bir kod bloğu alabilir, veritabanı tutamacını ona iletebilir ve aşağıdaki gibi bloğun sonundaki tutamacı otomatik olarak keser.
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") do |dbh|
Örnek 2
dbh.prepare bir kod bloğu alabilir, ifade tutamacını ona aktarır ve çağrılar otomatik olarak bloğun sonunda aşağıdaki gibi bitirilir.
dbh.prepare("SHOW DATABASES") do |sth|
sth.execute
puts "Databases: " + sth.fetch_all.join(", ")
end
Örnek 3
dbh.execute bir kod bloğu alabilir, ifade tutamacını ona iletebilir ve çağrılar otomatik olarak bloğun sonunda aşağıdaki şekilde biter -
dbh.execute("SHOW DATABASES") do |sth|
puts "Databases: " + sth.fetch_all.join(", ")
end
DBI işlem yöntemi ayrıca yukarıda açıklanan bir kod bloğunu alır.
Sürücüye Özgü İşlevler ve Nitelikler
DBI, veritabanı sürücülerinin , herhangi bir Tutamaç nesnesinin func yöntemi aracılığıyla kullanıcı tarafından çağrılabilen, veritabanına özgü ek işlevler sağlamasına izin verir .
Sürücüye özgü öznitelikler desteklenir ve aşağıdakiler kullanılarak ayarlanabilir veya alınabilir: []= veya [] yöntemler.
Sr.No. | Fonksiyonlar ve Açıklama |
---|---|
1 | dbh.func(:createdb, db_name) Yeni bir veritabanı oluşturur. |
2 | dbh.func(:dropdb, db_name) Bir veritabanı bırakır. |
3 | dbh.func(:reload) Yeniden yükleme işlemi gerçekleştirir. |
4 | dbh.func(:shutdown) Sunucuyu kapatır. |
5 | dbh.func(:insert_id) => Fixnum Bir bağlantı için en son AUTO_INCREMENT değerini döndürür. |
6 | dbh.func(:client_info) => String MySQL istemci bilgilerini sürüm açısından döndürür. |
7 | dbh.func(:client_version) => Fixnum Müşteri bilgilerini sürüm açısından döndürür. Bu şuna benzer: client_info, ancak sting yerine bir fixnum döndürür. |
8 | dbh.func(:host_info) => String Ana bilgisayar bilgilerini döndürür. |
9 | dbh.func(:proto_info) => Fixnum İletişim için kullanılan protokolü döndürür. |
10 | dbh.func(:server_info) => String MySQL sunucu bilgilerini sürüm açısından döndürür. |
11 | dbh.func(:stat) => String Veritabanının mevcut durumunu döndürür. |
12 | dbh.func(:thread_id) => Fixnum Mevcut iş parçacığı kimliğini döndürür. |
Misal
#!/usr/bin/ruby
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
puts dbh.func(:client_info)
puts dbh.func(:client_version)
puts dbh.func(:host_info)
puts dbh.func(:proto_info)
puts dbh.func(:server_info)
puts dbh.func(:thread_id)
puts dbh.func(:stat)
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
dbh.disconnect if dbh
end
Bu, aşağıdaki sonucu verecektir -
5.0.45
50045
Localhost via UNIX socket
10
5.0.45
150621
Uptime: 384981 Threads: 1 Questions: 1101078 Slow queries: 4 \
Opens: 324 Flush tables: 1 Open tables: 64 \
Queries per second avg: 2.860