2.1 NoSQL teriminin ortaya çıkışı

Son zamanlarda, "NoSQL" terimi çok moda ve popüler hale geldi, bu işaret altında her türlü yazılım çözümü aktif olarak geliştirilmekte ve tanıtılmaktadır. NoSQL, büyük miktarda veri, doğrusal ölçeklenebilirlik, kümeler, hata toleransı, ilişkisizlik ile eşanlamlı hale geldi. Ancak, NoSQL depolamanın ne olduğu, terimin nasıl ortaya çıktığı ve hangi ortak özelliklere sahip oldukları konusunda çok az kişi net bir anlayışa sahiptir. Bu boşluğu doldurmaya çalışalım.

Terimin en ilginç yanı, ilk olarak 90'lı yılların sonlarında kullanılmasına rağmen, ancak 2009'un ortalarında şu anki kullanıldığı şekliyle gerçek anlam kazanmasıdır. Carlo Strozzi tarafından oluşturulan, tüm verileri ASCII dosyaları olarak depolayan ve verilere erişmek için SQL yerine kabuk betikleri kullanan kaynak veritabanı. Mevcut haliyle "NoSQL" ile ilgisi yoktu.

Haziran 2009'da Johan Oskarsson, BT depolama ve işleme pazarındaki yeni trendleri tartışmak için San Francisco'da bir toplantı düzenledi. Toplantının ana itici gücü, BigTable ve Dynamo gibi yeni açık kaynaklı ürünlerdi. Bir toplantı için parlak bir işaret için, Twitter hashtag'ine tam olarak uyan geniş ve özlü bir terim bulmak gerekiyordu. Bu terimlerden biri RackSpace'ten Eric Evans tarafından önerildi - "NoSQL". Terim yalnızca bir toplantı için planlandı ve derin bir anlam yükü yoktu, ancak öyle oldu ki küresel ağ boyunca viral bir reklam gibi yayıldı ve BT endüstrisinde tüm yönün fiili adı oldu. Bu arada konferansta Voldemort (Amazon Dynamo klonu), Cassandra, Hbase (Google BigTable'ın analogları), Hypertable, CouchDB, MongoDB konuştu.

"NoSQL" teriminin tamamen kendiliğinden ortaya çıktığını ve arkasında genel kabul görmüş bir tanımın veya bilimsel bir kurumun olmadığını bir kez daha vurgulamakta fayda var. Bu ad daha çok ilişkisel veritabanlarından uzak BT geliştirme vektörünü karakterize eder. No SQL'in doğrudan tanımının destekçileri olmasına rağmen, Yalnızca SQL Değil anlamına gelir. Pramod Sadalaj ve Martin Fowler, son kitapları "NoSQL Distilled"da NoSQL dünyası hakkındaki bilgileri gruplandırmaya ve sistematik hale getirmeye çalıştı.

2.2 NoSQL veritabanlarının temel özellikleri

Pek çok heterojen sistem artık NoSQL etiketi altında gizlendiğinden (belki de en eksiksiz liste http://nosql-database.org/ adresinde bulunabilir), tüm NoSQL için birkaç ortak özellik vardır. Birçok özellik sadece belirli NoSQL veritabanlarına özgüdür, listelerken buna mutlaka değineceğim.

1. SQL kullanılmaz

ANSI SQL DML'yi kastediyorum, çünkü birçok veritabanı iyi bilinen favori sözdizimine benzer sorgu dillerini kullanmaya çalışıyor, ancak hiç kimse onu tam olarak uygulamayı başaramadı ve başarılı olması pek olası değil. Her ne kadar örneğin hadup'ta ( http://www.drawntoscalehq.com/ ve http://www.hadapt.com/ ) SQL'i uygulamaya çalıştığına dair söylentiler olmasına rağmen .

2. Yapılandırılmamış (şemasız)

Bunun anlamı, NoSQL veritabanlarında, ilişkisel veritabanlarının aksine, veri yapısının düzenlenmemesidir (veya programlama dilleriyle analojiler çizersek zayıf bir şekilde yazılır) - önce yapıyı bildirimsel olarak değiştirmeden ayrı bir satıra veya belgeye keyfi bir alan ekleyebilirsiniz. tüm tablonun. Bu nedenle, veri modelini değiştirmeye ihtiyaç varsa, bu durumda yapılacak tek yeterli işlem, değişikliği uygulama koduna yansıtmaktır.

Örneğin, MongoDB'de bir alanı yeniden adlandırırken:

BasicDBObject order = new BasicDBObject();
order.put("date", orderDate); // this field was a long time ago
order.put("totalSum", total); // before we just used "sum"

Uygulama mantığını değiştirirsek, okurken de yeni bir alan bekleriz. Ancak bir veri şemasının olmaması nedeniyle, halihazırda var olan diğer Order nesnelerinde totalSum alanı eksik. Bu durumda, daha fazla eylem için iki seçenek vardır.

Birincisi, tüm belgeleri taramak ve bu alanı mevcut tüm belgelerde güncellemektir. Veri hacmi nedeniyle, bu işlem herhangi bir kilit olmadan gerçekleşir (tabloyu yeniden adlandır sütununu değiştir komutuyla karşılaştırılabilir), bu nedenle güncelleme sırasında mevcut veriler diğer işlemler tarafından okunabilir. Bu nedenle, ikinci seçenek - uygulama kodunun kontrol edilmesi - kaçınılmazdır:

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble("sum"); // This is the old model
if (totalSum  == null)
totalSum = order.getDouble("totalSum"); // This is the updated model

Ve zaten yeniden kayıt yaptığımızda, bu alanı veritabanına yeni bir formatta yazacağız.

Bir şemanın olmamasının hoş bir sonucu, seyrek verilerle çalışmanın verimliliğidir. Bir belgede date_published alanı varsa ve ikincisinde yoksa, ikincisi için boş date_published alanı oluşturulmaz. Bu, prensip olarak mantıklıdır, ancak daha az belirgin bir örnek, tanıdık tablo / sütun kavramlarını kullanan sütun ailesi NoSQL veritabanlarıdır. Bununla birlikte, bir şema olmaması nedeniyle, sütunlar bildirimsel olarak bildirilmez ve bir kullanıcının veritabanı oturumu sırasında değiştirilebilir/eklenebilir. Bu, özellikle listelerin uygulanması için dinamik sütunların kullanılmasına izin verir.

Yapılandırılmamış şemanın dezavantajları vardır - veri modelini değiştirirken uygulama kodunda yukarıda belirtilen ek yüke ek olarak - tabandan her türlü kısıtlamanın olmaması (null değil, benzersiz, kontrol kısıtlaması vb.), artı orada paralel olarak farklı projelerin veritabanıyla çalışırken yapı verilerini anlama ve kontrol etmede ek zorluklardır (veritabanının yanında sözlük yoktur). Bununla birlikte, hızla değişen modern dünyada, bu tür bir esneklik hala bir avantajdır. Bir örnek, beş yıl önce tweet ile birlikte yalnızca küçük bir ek bilgi depolayan (zaman, Twitter tanıtıcısı ve birkaç bayt daha fazla meta bilgi) ancak şimdi mesajın kendisine ek olarak birkaç tane daha depolayan Twitter'dır. kilobaytlarca meta veri veritabanında saklanır.

(Bundan sonra ağırlıklı olarak anahtar-değer, belge ve sütun ailesi veritabanlarından bahsediyoruz, grafik veritabanları bu özelliklere sahip olmayabilir)

2.3. Verilerin kümeler (agregalar) biçiminde temsili

Normalleştirme amacıyla uygulamanın mantıksal ticari varlığını çeşitli fiziksel tablolarda depolayan ilişkisel modelin aksine, NoSQL depoları bu varlıklar üzerinde bütünsel nesneler olarak çalışır:

Bu örnek, standart bir e-ticaret kavramsal ilişkisel modeli olan "Sipariş - Sipariş Öğeleri - Ödemeler - Ürün" için toplamaları gösterir. Her iki durumda da, sipariş konumlarla tek bir mantıksal nesnede birleştirilirken, her konum ürüne bir bağlantı ve ürüne ait bazı öznitelikleri, örneğin adı depolar (bu tür bir normalleştirme, alınırken bir ürün nesnesi talep etmemek için gereklidir). bir düzen - dağıtılmış sistemlerin ana kuralı, nesneler arasındaki "birleşmelerdir"). Bir grupta ödemeler siparişle birleştirilir ve nesnenin ayrılmaz bir parçasıdır, diğerinde ise ayrı bir nesneye yerleştirilir. Bu, NoSQL veritabanlarında bir veri yapısı tasarlamanın ana kuralını gösterir - uygulamanın gereksinimlerine uymalı ve en sık yapılan istekler için mümkün olduğunca optimize edilmelidir.

Birçoğu, sorgular kümelerin yapısına uymadığında, veriler üzerinde rasgele sorgular denerken, büyük, genellikle denormalize edilmiş nesnelerle çalışmanın çok sayıda sorunla dolu olduğuna dikkat çekerek itiraz edecektir. Siparişleri, sipariş satır öğeleri ve ödemelerle birlikte kullanırsak (uygulama böyle çalışır), ancak işletme bizden geçen ay belirli bir ürünün kaç biriminin satıldığını saymamızı isterse ne olur? Bu durumda, OrderItem tablosunu taramak yerine (ilişkisel bir model söz konusu olduğunda), bu bilgilere çok fazla ihtiyacımız olmayacak olsa da, NoSQL deposundaki tüm siparişleri almak zorunda kalacağız. Ne yazık ki bu, dağıtılmış bir sistemde yapılması gereken bir uzlaşmadır: geleneksel tek sunuculu bir sistemdeki gibi verileri normalleştiremeyiz,

Her iki yaklaşımın artılarını ve eksilerini bir tabloda gruplandırmaya çalıştım: