Mysql bellek tablosu (Mysql Memory Table )

Bu tablo Memory (RAM-bellek üzerinde tutulan) depolama motorudur (ENGINE = MEMORY). Indexlerini varsayılan Hash olarak (karma yapı) tutar. Bu da onları, çok hızlı ve geçici tablo çözümlerinde çok başarılı yapar.

Tablo bilgileri yine de hard diskte, .frm dosyasıyla tutulur, ama mysql server kapatılıp açıldığında (ya da bir şekilde kapandığında) içindeki bilgiler tamamen yok olur. Tablonun yapısı silinmez, yeniden create etmeye gerek yoktur.

Aşağıdaki tabloda test adlı bir memory tablosu oluşturuyoruz. Daha sonra İçindeki verileri , log_table adlı bir tablodan istediğimiz sütunlarını istediğimiz şekilde çekip dolduruyoruz. Daha sonra geçici tabloda, ip sütununu COUNT ile saydırıp, down sütununu AVG ile ortalamasını alıp döndürüyoruz. İşimiz bittikten sonra da, test memory tablosunu siliyoruz.

mysql> CREATE TABLE test ENGINE=MEMORY
    ->     SELECT ip,SUM(downloads) AS down
    ->     FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;

* Mysql memory tabloları için ramde veriler küçük bloklar halinde tutulur, ve remde yer açma işini dinamik olarak mysql kendi yapar. Bizim yer açmamıza vb gerek yoktur.

* Memory tablosu, hem hash hem de btree şeklinde indexleri destekler. (Bu indexler hakkında detaylı bilgiyi MYSQL Indexes konusu altında aramanız gerekmektedir, indexler başlı başına önemli bir konudur çünkü) )

Aşağıda 2 farklı indexin kullanım oluşturulma biçimi bulunmaktadır.

CREATE TABLE test
    (id INT, INDEX USING HASH (id))
    ENGINE = MEMORY;
CREATE TABLE test
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;

* Hash index kullanıp da index kullandığınız sütunda çok fazla aynı bilgi varsa, burada insert komutlarınız yavaşlayabilir. Bu durumda Btree indexi kullanmanız işinizi görebilir deniyor, ama Btree de yapısal olarak hash indexlerinden 5-6 kat daha yavaş olduğu biliniyor. Bu sebeple de, küçük bir optimizasyon ile işleminizi halledeiblirsiniz.

Memory tabloları sabit uzunluklu satır depolama formatında çalışır. VARCHAR gibi değişken uzunluğu tipleri sabit bir uzunluk ile depolanır.

Memory tabloları BLOB veya TEXT tipinde kolonlar içeremez. Bu durum zaten düşünüldüğünde memory tablosu kullanma mantığına da aykırıdır.

Memory tablolarının maximum boyutu, max_heap_table_size sistem değişkeni ile belirlenmiştir, bu da varsayılan olarak 16MB tır. Daha büyük veya küçük istendiğinde bu sistem değişkeni düzenlenerek yapılabilir.

mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)

mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)

mysql tablo kopyalama (mysql copy table)

Bir çok zaman veritabanı üzerinde bir işlem yapacağımızda, mevcut verileri yedekleme ihtiyacı duyuyoruz. (Şu anda da böyle bir şeye ihtiyaç duymuştuk)

Basit seviyeli bir şey olmasına rağmen insanın aklına basit çözüm gelemeyebiliyor. Bizim de aklımıza farklı metodlar geldi, sonra googledan en basit çözümü bulduk.

Aşağıdaki komut ile bir tabloyu başka bir tabloya kopyala-yapıştır yapmış oluyorsunuz.

CREATE TABLE yeni_tablo SELECT * FROM eski_tablo

Tabi içinde milyonlarca veri varsa, sürekli bu işlemi yapmanızı tavsiye edemeyeceğim. Yine de yedekleme hayat kurtarır diyorum.

ÖNEMLİ NOT Bu kopyalanan tabloda, ne primary key, ne index, ne unique key, hiç bir şey kopyalanmamış olduyor. Bu sebeple bu yöntemi sadece hızlı yedekleme amaçlı kullanmanızı tavsiye ederim.

mysql join insert

Denormalizasyon yaptığım bir tablodaki longtext veri alanı olan sütunu ayrı bir tablo halinde sunmak istiyorum. Bu noktada, eski verilerin yeni yerine bir patch işlemi yapmadan taşımasını düşünmek adına, INSERT işlemini JOIN yaparak yapmak geldi aklıma. Bu konuda araştırdığıma göre;

Mysql de update, select ve delete query’lerinde yapılabilen JOIN ederek işlem yapma olayı , INSERT komutu ile çalışmamakta.

Yani sonuçta join edecek verisi yok ki içinde, ona göre işlem yapsın.

Bu noktada çözümü farklı bir yoldan bulmamız gerekti. ilk önce ilgili veri alanlarını select edip, yeni tablomuza  insert etmemiz gerekiyordu. Yaptık.

ÇÖZÜM

Yine mysql tarfında olayı çözebildik.
INSERT INTO tableNew (col1, col2)
SELECT tbl1.col1, tbl2.col2
FROM tbl1 LEFT OUTER JOIN tbl2 ON (tableNew.someColumn = tbl1.someColumn)

tabi on duplucate key kontrolü de isteğe göre yapılabilir.