2016-03-24 17 views
0

Laravel framework'ü kullanılarak oluşturulmuş bir uygulamam var. Özelliklerinden biri, tablolar arasında polimorfik ilişkiler oluşturma yeteneğidir. Bunu ilgili tablonun kimliğini ve ilgili tablo modelinin tam nitelikli sınıf adını saklayarak yapar. Tahmin edebileceğiniz gibi, bazı girişler model adlarına ve sınıf adlarına bağlı olarak oldukça uzun olabilir.MySQL değişken depolama alanı

Benim senaryoda, 4 tablom var. Polimorfik olan baz masa A. Tablolar B, C ve D değillerdir.

böyle olmayan polimorfik tablo modelleri için sınıf adları: masanın A den

LongNamespace\SubNamespace\Something\B 
LongNamespace\SubNamespace\Something\C 
LongNamespace\SubNamespace\Something\D 

Sonuçlar şöyle olacaktır: kayıt başına

id | relation_id | relation_type 
-------------------------------- 
1 | 1   | LongNamespace\SubNamespace\Something\B 
2 | 2   | LongNamespace\SubNamespace\Something\C 
3 | 5   | LongNamespace\SubNamespace\Something\D 
4 | 12   | LongNamespace\SubNamespace\Something\D 
5 | 3   | LongNamespace\SubNamespace\Something\B 
6 | 6   | LongNamespace\SubNamespace\Something\C 

... etc (around 50,000 rows) ... 

38 ile bayt olan çoğu tekrarlanır, katma veri, benim sorum, relation_type sütun deposuna her bir relation_type sütun deposuna ayrı ayrı bellekte (indekslerle ne olduğunu varsadığımı varsayalım) bir indeks ekleyecek veya onları bir ENUM gibi gruplayacak mı? Toplam depolama alanı, relation_type numaralı 3 benzersiz girişten oluşuyordu. Bunlar, dahili olarak, bir çeşit hash tablosuyla ilişkilendiriliyor, ergo tasarrufu, n * 38 baytlık alan değerinde.

cevap

0

Dizin, tüm dizinlenmiş sütunların tüm metinlerini ve (InnoDB örneğinde) tüm PRIMARY KEY sütunlarının tüm metinlerini içerir. Yani 38 * n byte 'boşa'.

Eğer
ENUM(`LongNamespace\SubNamespace\Something\B`, 
    `LongNamespace\SubNamespace\Something\C`, 
    `LongNamespace\SubNamespace\Something\D`, 
    ...) 

o zaman sadece 1 veya 2 bayt alacağını, henüz çok bu 39 bayt dizeleri gibi hareket olması relation_type ilan edin.

gerçekten büyük bir anlaşma var, tabii ki, başka bir tablo ekleyin bakım problemleri, diğer yandan vb

, 38 * 50 K = ~ 2MB "küçük" olduğunu ve değil.

Hayır, bir dizin RAM'de saklanmaz. Ancak, RAM'de "önbelleğe alınmış", blokla engellenir. Yani dizin (veya tablo) gerçekten büyük olsaydı, önbellekte (RAM) kalmayan şeyler nedeniyle ekstra I/O olurdu. Ama yavaş yavaş da olsa "işe" devam ederdi.