Yıldız şeması veri ambarındaki dinamik alanlar için EAV'ye alternatif


13

API istekleri günlüğünü depolamak için büyük bir veri deposunda dinamik alanları ve değerleri desteklemem gerekiyor, kullanıcı durumum tüm API istekleri sorgu dizesini saklamalı ve gelecekte onlara karşı sorgulama yapabilmem (yani yalnızca depolama, bu yüzden onlar için damla kullanamam)

Örneğin http://example.com/?action=test&foo=abc&bar=def...

Tüm field => valueeşlemeleri saklamam gerekiyor (action => test), (foo => abc), (bar => def)ve alan çok dinamik olduğu için bulduğum tek çözüm Entity-Attribute-Value kullanmak, ancak insanlar bunun çok kötü bir tasarım olduğunu söylüyorlar.

Öyleyse yukarıdaki kullanım durumumu düşünün, EAV için uygun bir alternatif ne olurdu?

KAV kullanarak mevcut şemam

  1. Tablo requests
    (id, timestamp, uri)
    örn.(1, 149382220, '/')

  2. Tablo params
    (request_id, key, value)
    örn.(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')

Herhangi bir öneri?

Güncelleme: Depoyu AWS RedShift'te çalıştırıyoruz


2
Bir dev veritabanında önerdiğiniz şeyi denemede sorun nedir? Ayrıca, SQL Server hakkında mı konuşuyorsunuz? Sql etiketi oldukça geniştir.
Max Vernon


1
Hangi DBMS'yi kullanıyorsunuz? Bazı oldukça iyi metin indeksleme yetenekleri var, bu yüzden istekleri saklamak için bir "uzun metin" alanı kullanarak ekarte olmaz. Bunu söyledikten sonra, önerdiğiniz modeli kullanırken bir sorunum olmazdı. EAV katı bir anlamda olsa da, sadece bu çok özel amaç için kullanılmaktadır. Yine, bunu söyledikten sonra, ne tür sorgular yapabilmeniz gerekir? Sizin için işe yarayıp yaramadığını görmek için bu sorguları bu modele yazmayı deneyin.
Colin 't Hart

1
Hangi RDBMS'yi kullanıyorsunuz? SQLyeterince spesifik değil. Sizden iki kez istendi. Ben üçüncü.
Erwin Brandstetter

2
RedShift PostgreSQL tabanlı olduğu için, hstoreveya jsonveri tiplerini (veya jsonb9.4'e " yükseldiklerinde " / / kullandıklarında) kullanmaya çalışacağım .
Colin 't Hart

Yanıtlar:


11

Üç çözüm düşünebilirim - EAV, XML ve Seyrek Sütunlar. İkincisi satıcıya özgüdür ve sizin için yararlı olmayabilir.

Hangi yöntemi seçerseniz seçin, orijinal istek verilerini ham biçimde, bir tabloda veya düz bir dosyada saklamayı düşünebilirsiniz. Verileri depolamanın yeni yollarını denemeyi kolaylaştıracak, isteklerinizi ayrıştırma yönteminizle ilgili bir hata bulursanız verileri yeniden yüklemenize olanak tanıyacak ve toplu işlem veya "büyük veri" kullanarak API isteklerini ayrıştırma fırsatları sunacak veri ambarınızın verilerle verimli bir şekilde başa çıkamayacağını tespit ederseniz

EAV ile ilgili hususlar

EAV / KVS, yukarıda açıkladığınız gibi, muhtemelen en basit uygulama olacaktır.

Ne yazık ki çok pahalı olacak - yaygın olarak kullanılan anahtarlar üzerinde her türlü verimli sorguları almak için anahtar sütununda çok parçalanmış olabilecek dizinlere ihtiyacınız olacak. Belirli anahtarları sorgulamak çok pahalıya mal olacaktır.

Değer verdiğiniz anahtarları veya değerleri sorgulamak için EAV mağazanızı materyal görünümleriyle (birçok satıcı bunu destekler) destekleyerek dizin oluşturma veya dizin tarama maliyetini düşürebilirsiniz.

XML

Çoğu kurumsal veritabanı sistemi, doğrulama, dizin oluşturma ve gelişmiş sorgulama da dahil olmak üzere çok olgun XML işleme sunar.

API isteğini veritabanına XML olarak yüklemek, istek başına bir grup sağlar; bu, mantıksal olarak, bir EAV tablosunda bilinmeyen sayıda satıra sahip olmaktan biraz daha lezzetli olabilir.

Bunun etkili olup olmadığı, RDBMS satıcınıza ve uygulamanıza çok bağlıdır.

En büyük dezavantajı, bu, orijinal isteğin dize manipülasyonundan daha karmaşık olan verileri yönetmenin tek yolu olmasıdır!

Seyrek Sütunlar / geleneksel tablolar

Verilerinizi, anahtar başına bir sütun olacak şekilde geleneksel bir tablo yapısına yükleyebilirsiniz.

SQL Server'ın Seyrek Sütunlar özelliği, bir EAV mağazasına mükemmel bir alternatiftir. Seyrek Sütunlara sahip bir tablo, 30.000 sütuna kadar olabilmesi dışında, normal sütunlarla aynı şekilde davranır ve seyrek sütunlardaki NULL değerleri tabloda boşluk kullanmaz.

Bunları Filtrelenmiş Dizinlerle (başka bir SQL Server'a özgü özellik) birleştirmek, birkaç belirli sütun ve / veya değeri sık sık sorguluyorsanız, EAV deposuna son derece verimli bir alternatif sağlayabilir.

Diğer satıcılarla geleneksel bir tablo kullanmak uygun olabilir - IBM, tablo başına 700'den fazla sütunu ve yaklaşık 1000 Oracle'ı destekler ve sıkıştırma veya Oracle'ın sondaki boş değerlere muamele gibi özellikler, API verilerinizi oldukça verimli bir şekilde depolayabileceğiniz anlamına gelebilir.

Bu yaklaşımın bariz dezavantajı, API'nize yeni anahtarlar ekledikçe, şemanızı buna göre ayarlamanız gerektiğidir.


2
PostgreSQL'de XML'i önermiyorum ama ya hstoreda json. Gelecekte 9.4 jsonbbenim tavsiyem olacaktır.
Colin 't Hart

Bu yanıtı artıları eksileri ve her açıklama ile gerçekten seviyorum. Çok bilgilendirici - kesinlikle Seyrek Sütunlar bilgi için teşekkür ederiz. Seyrek sütun yaklaşımını kullanan bir EAV örneği istiyorum.
StixO

9

EAV kötü bir tasarım değildir, sadece makul miktarda öngörü gerektiren ve veri miktarı arttıkça performans sorunları ile işlenebilen bir tasarımdır. Sisteminiz için iyi çalışabilir.

Sorgu dizelerini saklamak için bir sistem tasarladığımda, hangi alanlarla ilgileneceğimi önceden bilmiyordum . Sorgu dizesini serileştirilmiş ikili biçimde depolamak için bir tablo oluşturdum ve sorguyu ayırmamı sağlayan bir sistem oluşturdum İlgilendiğim parçaları öğrendikten sonra bileşen parçalarına dizildi. Oradan bir dizi tablo oluşturdum; sorgu dizesinde yaygın olarak bulunan veri kümeleri için birer tane.

Örneğin, sonunda yönlendirici verileri için bir tablo, hedef istek verileri için bir tablo ve girdikleri arama sorgusu gibi kullanıcıyla ilgili öğeler için bir tablo vardı.

Gelecekte bu blob ayrı bölme yeteneği sağlarken, tüm sorgu dizesini tek bir tabloda bir blob olarak saklamak için yeteneği buldum, benim ihtiyaçlarını çok iyi karşıladı.


1
Hem soruda hem de cevapta İkili Uzun OBject BLOBanlamına gelen terim kullanılır . İkili verilerden değil karakter hakkında konuştuğumuz için PostgreSQL'de bir (Character Long OBject) veya bir şey kullanmayı tercih ederim . CLOBtext
Colin 't Hart

2
Tüm oturum nesnesini serileştirdiğim ve her şeyi veritabanında sakladığım için ikili bir alan kullandım.
Max Vernon
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.