MySQL'de Tabloları Bölme. İyi pratik?


14

Mevcut bir proje üzerinde çalışmaya başladım ve önceki geliştirici bir tabloyu aynı şemaları ancak farklı verileri olan 10 ayrı tabloya ayırmıştı.

Tablolar şöyle görünür:

[tableName_0]
[tableName_1]
[tableName_2]
[tableName_3]
[tableName_4]
[tableName_5]
[tableName_6]
[tableName_7]
[tableName_8]
[tableName_9]

Birincil anahtar bir tamsayı idalanıdır. Uygulama, idarama yaparken hangi tabloya erişmek için bir karma algoritma ( mod 10) kullanır . Örneğin id= 10 sonuçlanır [tableName_0].

Birleştirildiğinde, tabloların muhtemelen 100.000 satırı vardır ve büyüme oranı nispeten düşüktür.

Benim sorum şu, bunun uygulanabilir bir çözüm olup olmadığı ya da her durumda iyi bir uygulama olsa bile. Benim teorim, şeyleri UNIONgittikçe kolaylaştıracağı için birleştirmelerini sağlamaktır . Ana dezavantajı tüm uygulama kodunu ve uzun vadede buna değip değmeyeceğini değiştirmektir.

Yanıtlar:


17

Bence herkes bunu çok karmaşık hale getiriyor. Burada kilit nokta:

Birleştirildiğinde, tabloların muhtemelen 100.000 satırı vardır ve büyüme oranı nispeten düşüktür.

Bu bir kek parçası sapa herhangi bir RDBMS için. Tek bir tabloyla gidin, düzgün bir şekilde dizinleyin ve çözülmüş bir sorun olduğunu düşünün.

Çok büyük miktarda veri işlemeye başlayıncaya kadar "ev yapımı" veya başka bir şekilde bölümlemeyi düşünmenize gerek yok - milyarlarca satır ve üstü düşünün.


3

Birleştirme tablolarını kullanabilirsiniz, ancak bunlar 4.x sürümlerinden daha eskidir. Uygulamanız manuel olarak bölümlendiğinde, a) gerçekten eski bir sürüm çalıştırıyorsanız veya b) orijinal geliştirici tablo bölümlerinden haberdar değildi.

Kısacası 5.1+ çalıştırıyorsanız, mysql'in bu bölümlemeyi sizin için yapmasına izin verebilirsiniz. Bkz. Http://dev.mysql.com/doc/refman/5.1/en/partitioning.html 5.5 kullanıyorsanız, bazı farklılıklar bulacağınız için bu dokümanları kontrol etmelisiniz.

Bölümlemenin birçok avantajı vardır. Bununla birlikte, gerçekten eldeki veri kümesine, erişim kalıplarına ve nasıl endeksleneceğine bağlıdır. Ayrıca, aşağıdaki yorumların mysql 5+ bölümleme bağlamında olduğunu unutmayın, eski mysql Birleştirme tabloları DEĞİL; her ne kadar bazen bölümler açısından tartışılsa da.

Bazı örnekler:

  • Sık erişilen arama anahtarına dayalı düz kovalama (veya karma). Eğer hemen hemen her zaman birincil veya başka bir benzersiz anahtar ile arıyorsanız o zaman mysql arama alanı kaç bölüm var bir faktör tarafından kesebilir. Bununla birlikte, bir anahtarla bölümleme yapıp daha sonra başka bir anahtarla sık sık arama yaptığınızda bunun zararlı olabileceğini unutmayın. Bir anahtarla arama yaparsanız veriler tarafından bölümlenmezse, aramalarda DAHA FAZLA arama yapmalıdır (her bölüm için bir tane, b / c açıkçası, verilerin nerede olduğunu bilmiyor)
  • Tarihe göre büyüyen geçici bir kayıt kümeniz olduğunda ve bir önceki ay periyodik olarak budanmış olduğunuzda durumları göz önünde bulundurun. Tarihe göre bölümleme yapıyorsanız, ne kadar büyük olursa olsun, bir tabloyu düşürmek kadar hızlı olan bir bölümü bırakmanız yeterlidir. Böyle bir tabloyu tarihlere göre bulacağınız takdirde, her bir satırın silindiği bir veya daha fazla DELETE sorgusu yayınlamanız gerekirdi. Bunun dezavantajı, mysql'nin bu senaryoda muhasebeleştirdiğiniz maksimum tarihe ulaştığınızda otomatik olarak yeni bölümler oluşturmamasıdır; bölümleri gerektiği gibi eklemek için parçanıza ek bakım komut dosyaları eklemeniz gerekir.
  • Myisam kontrolleri ve kurtarma işlemleri kullanıyorsanız çok daha hızlıdır. 100G'lik bir myisam tablosu düşünün. Çökmüş bir tabloyu kurtarmak istiyorsanız, en az 100G yedek disk alanına ihtiyacınız olacaktır. Eşit büyüklükte 10 farklı parçaya bölünmüşse, sadece 10G alana ihtiyacınız var (ve hızlı kurtarma için daha az key_sort_buffer bellek); ancak her bölüm için bir yineleme yapmanız gerekir.

Özetle, bölümleme tablolarının genel yaklaşımı birçok fayda sağlayabilir. Ancak, erişim kalıplarına ve tam olarak ne kadar bölüştüğünüze bakmadan körü körüne uygulanacak sihirli bir mermi değildir .

İstenen bölümlendirmenin uygulamaya çok özel olduğu ve mantığın uygulama katmanında oturması için daha uygun olduğu durumları hayal edebiliyorum. Bununla birlikte, düz modül 10 açıklamanız göz önüne alındığında, bu böyle bir durum gibi görünmemektedir.

DÜZENLE

Açıklamamı yazarken tablonuzun 100 bin satır olduğunu belirtmişsiniz. Tablonuzun tüm şeması ve ortalama satır uzunluğu ile kesin olarak söylemek zor, ancak genel olarak mütevazı donanım için bile orta büyüklükte geliyor. Aynı zamanda, şu anda veya öngörülebilir gelecekte sorunlara neden olmazsa, zaman harcamayın ve değiştirerek risk getirmeyin.


3

Önceki geliştiricinin sizin için yaptığı, kendi bölümleme karması uygulamalarını oluşturuyor. MySQL tam anlamıyla bu yerel MySQL 5.1 destekler:

http://dev.mysql.com/doc/refman/5.1/en/partitioning-hash.html

Ben iyi bir neden düşünemiyorum bu yüzden yerel sürüm güvenmek yerine kendi bölümleme karma uygulamak [1]. Şema değişikliklerinin yapılması bir kabus olacaktır.

Ayrıca nadiren bölümleme karma (yerel uygulama) öneririz. Ben bir kerede (ki MySQL yapmayacak) bölümleri her biri paralel arama için kullanmak yararlı olacağını düşünüyorum. Birden fazla bölümde arama yapmanız gerekiyorsa, tanımladığınız şema genellikle daha yavaş olacaktır.

[1] Ancak, diğer bölümleme türlerinin bazıları için kendi bölümlemenizi yuvarlamanız mantıklı olabilir. MySQL, bölüm anahtarınızı birincil anahtarınızın ve tüm benzersiz dizinlerin bir parçası yapmaya zorlar.


2

Soruya yanıt olarak:

bunun uygulanabilir bir çözüm olup olmadığıdır

IMHO, Bu gereksiz bir ek yük gibi görünüyor. Açıklamasında açıklanmayan başka bilgiler olmadığı sürece tek bir tabloyu düzgün bir şekilde dizinleyebilir ve bölümleyebilirsiniz.

Soruya yanıt olarak:

... her durumda iyi bir uygulama ise

IMHO, dikey parçalama bağlama göre anlamlı olabilir. Bunu gördüğümde, genellikle bir tür günlük biçimindedir. Bunu web sunucusu günlükleri için kullandığımızı ve aya göre bölümlemek istediğimizi varsayalım. Her gün mevcut bir tabloyu değiştirmek yerine, her gün yeni bir tablo oluşturabilir ve bu tabloya satır kaydedebiliriz.

Örneğin, bir web günlüğü tablosu aşağıdaki gibi olabilir:

datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
uri VARCHAR(1024),
host VARCHAR(255),
user_agent VARCHAR(255),
etc...

Çözümünüz weblog veritabanında gerektiği gibi tablolar oluşturur:

weblogs.20120301
weblogs.20120302
weblogs.20120303

vb.

Bu şekilde veriler korunabilir ve aranabilir kalır. Ekstraksiyon normal periyodik bir süreç haline gelir. Sürekli işlemler, eski verilerdeki işlemler tarafından kilitlenmez.

Sunduğunuz senaryoda yine de bir yapıya hapsedildiniz, neden bu amaç için optimize edilmiş tek bir tablo kullanmıyorsunuz? Satırların algoritma tabanlı depolaması kabataslak ve hataya açık görünüyor.


0

Bir sorgu çok büyük verileri hedefliyorsa, verilerin sorgu koşullarına göre bölünmesi performansta kayda değer bir iyileşme sağlayacaktır. Ancak gördüğünüz gibi, bu tür bölünmeler bazı programlama sorunlarını gündeme getiriyor.

Yani soru şudur: Bu bölünme performansa değer mi yoksa performansa zarar verir mi?

Birden çok satırı birden çok tablo üzerinde kilitlemeniz gereken bir işleminiz varsa ve üzerinde sorunlar varsa (örneğin, kilitlenme veya işlem zaman aşımı), bunları tek bir tabloda birleştirmek ve sorunları onarmak için SQL'i yeniden yazmak isteyebilirsiniz.

Tabloyu bölüp bölmemeyi düşündüğümde, performans kazanma ve programlama karmaşıklığı arasındaki dengeyi düşünürdüm.

Sizin durumunuzda, mevcut kodun değiştirilmesi kodun bakımını kolaylaştırmak için uzun vadeli bir çözüm olabilir. Meta-programlama denemeyi öneririm. Örneğin, dinamik olarak SQL oluşturmak için StringTemplate kullanma . Mevcut kodun değiştirilmesi çok zorsa meta-programlama motorundan SQL üretmeyi seviyorum.


0

Dosyaları tabloda depolamanız gerektiğinde, bu metodolojiyi kullanmak dışa aktarmaya, onarmaya ve geri yüklemeye yardımcı olur.

Ben 10 tablolarda bölümlenmiş> 30 Gb tablolar var. Bu tabloların sadece ID - BLOB vardır ve benim için tutmak kolaydır. Ve INISODB arabelleğini kaydetmek için MyISAM kullanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.