Bugün, Yapılandırılmış Sorgu Dili, ürünler arasında özel uzantılara sahip olmakla birlikte ilişkisel veritabanlarındaki verileri işlemek ve sorgulamak için standart bir araçtır. SQL'in kolaylığı ve her yerde bulunması, birçok "NoSQL" veya Hadoop gibi ilişkisel olmayan veri depolarının yaratıcılarını SQL alt kümelerini benimsemeye veya kendi SQL benzeri sorgu dillerini oluşturmaya bile yönlendirdi.
Ancak SQL, ilişkisel veritabanları için her zaman "evrensel" dil değildi. Başından beri (1980 dolaylarında), SQL ona karşı belirli grevler yaptı. O zamanlar ben de dahil olmak üzere birçok araştırmacı ve geliştirici, SQL'in ek yükünün bir üretim veritabanında pratik olmasını engelleyeceğini düşünüyordu.
Açıkça yanıldık. Ancak çoğu hala, SQL'in tüm kolaylığı ve erişilebilirliği için, çalışma zamanı performansında zorlanan fiyatın genellikle çok yüksek olduğuna inanıyor.
SQL geçmişi
SQL olmadan önce, veritabanları sıkı, gezinme programlama arayüzlerine sahipti ve tipik olarak CODASYL veri modeli adı verilen bir ağ şeması etrafında tasarlanıyordu. CODASYL (Veri Sistemleri Dilleri Komitesi), COBOL programlama dilinden (1959'dan başlayarak) ve veritabanı dili uzantılarından (10 yıl sonra başlayarak) sorumlu olan bir konsorsiyumdu.
Bir CODASYL veritabanına göre programladığınızda, bire çok ilişkileri ifade eden kümeler arasında kayıtlara gidiyordunuz. Daha eski hiyerarşik veritabanları yalnızca bir kaydın bir kümeye ait olmasına izin verir. Ağ veritabanları, bir kaydın birden çok kümeye ait olmasına izin verir.
CS 101'e kayıtlı öğrencileri listelemek istediğinizi varsayalım. Öncelikle sette isme göre bulursunuz
"CS 101", bunu
Coursessetin sahibi veya ebeveyni olarak
Enrolleesayarlarsınız, setin ilk üyesini (
ffm) bulursunuz
Enrollees, ki bu bir
Studentkayıt ve liste o. Sonra bir döngüye girersiniz: Sonraki üyeyi bulun (
fnm) ve listeleyin. Ne zaman
fnmbaşarısız, sen döngü çıkmak istiyorum.
Bu, veritabanı programcısı için çok fazla çalışma gibi görünebilir, ancak yürütme zamanında çok verimli oldu. Berkeley ve Ingres'teki California Üniversitesi'nden Michael Stonebraker gibi uzmanlar, IDMS gibi bir CODASYL veritabanında bu tür bir sorgu yapmanın, SQL kullanan ilişkisel bir veritabanındaki aynı sorguya göre yaklaşık olarak CPU zamanının yarısını ve belleğin yarısından daha azını aldığını belirtti. .
Karşılaştırma için, CS 101'deki tüm öğrencileri döndürmek için eşdeğer SQL sorgusu şöyle bir şey olacaktır:
Kurslar, kayıtlı kişiler, öğrenciler WHERE course.name'DEN öğrenci.adı seçin
Bu sözdizimi, aşağıda açıklayacağım gibi ilişkisel bir iç birleşim (aslında ikisi) anlamına gelir ve birleşimler için kullanılan alanlar gibi bazı önemli ayrıntıları dışarıda bırakır.
İlişkisel veritabanları ve SQL
Yürütme hızı ve bellek kullanımında neden iki kat iyileştirmeden vazgeçiyorsunuz? İki büyük neden vardı: geliştirme kolaylığı ve taşınabilirlik. 1980'de performans ve bellek gereksinimlerine kıyasla ikisinin de önemli olduğunu düşünmemiştim, ancak bilgisayar donanımı geliştikçe ve daha ucuz hale geldikçe, insanlar yürütme hızı ve bellekle ilgilenmeyi bıraktı ve geliştirme maliyeti hakkında daha fazla endişelendi.
Başka bir deyişle, Moore Yasası, CODASYL veritabanlarını ilişkisel veritabanları lehine öldürdü. Olduğu gibi, geliştirme süresindeki iyileşme önemliydi, ancak SQL taşınabilirliği boş bir hayal olarak ortaya çıktı.
İlişkisel model ve SQL nereden geldi? EF “Ted” Codd, 1960'larda ilişkisel model teorisini geliştiren ve 1970 yılında yayınlayan IBM San Jose Araştırma Laboratuvarı'nda bir bilgisayar bilimcisiydi. IBM, gelirlerini korumak için ilişkisel bir veritabanını uygulamakta yavaştı. CODASYL veritabanı IMS / DB. IBM nihayet System R projesini başlattığında, geliştirme ekibi (Don Chamberlin ve Ray Boyce) Codd bünyesinde değildi ve Codd'un 1971 Alpha ilişkisel dili makalesini kendi dilleri SEQUEL'i (Structured English Query Language) tasarlamak için görmezden geldiler. 1979'da, IBM ürününü piyasaya sürmeden önce, Larry Ellison dili Oracle veritabanına dahil etti (spesifikasyonu olarak IBM'in lansman öncesi SEQUEL yayınlarını kullanarak). SEQUEL, uluslararası bir ticari marka ihlalinden kaçınmak için kısa sürede SQL oldu.
"SQL için atan tom-tomlar" (Michael Stonebraker'in ifadesiyle) yalnızca Oracle ve IBM'den değil, aynı zamanda müşterilerden de geliyordu. CODASYL veritabanı tasarımcılarını ve programcılarını işe almak veya eğitmek kolay değildi, bu yüzden SEQUEL (ve SQL) çok daha çekici görünüyordu. 1980'lerin sonlarında SQL o kadar çekiciydi ki, birçok veritabanı satıcısı, ilişkisel veritabanlarının ilişkisel olması için sıfırdan tasarlanması gerektiğini düşünen Codd'un büyük dehşetine rağmen, esasen CODASYL veritabanlarının üzerine bir SQL sorgu işlemcisi yerleştirdi.
Codd tarafından tasarlandığı şekliyle saf bir ilişkisel veritabanı, birinci dereceden yüklem mantığıyla tutarlı bir şekilde ilişkiler içinde gruplandırılmış gruplar üzerine inşa edilmiştir. Gerçek dünyadaki ilişkisel veritabanlarında alanlar, kısıtlamalar ve tetikleyiciler içeren tablolar bulunur ve tablolar yabancı anahtarlarla ilişkilendirilir. SQL, döndürülecek verileri bildirmek için kullanılır ve bir SQL sorgu işlemcisi ve sorgu iyileştirici, SQL bildirimini veritabanı motoru tarafından yürütülen bir sorgu planına dönüştürür.
SQL, şemaları tanımlamak için bir alt dil, veri tanımlama dili (DDL) ve verileri değiştirmek için bir alt dil, veri işleme dili (DML) içerir. Bunların her ikisinin de erken CODASYL spesifikasyonlarında kökleri vardır. SQL'deki üçüncü alt dil,
SELECTifade ve ilişkisel birleştirmeler yoluyla sorguları bildirir .
SQL
SELECTifadesi
Bu
SELECTifade, sorgu iyileştiricisine hangi verilerin döndürüleceğini, hangi tablolara bakılacağını, hangi ilişkilerin izleneceğini ve döndürülen verilere hangi sıranın uygulanacağını söyler. Sorgu iyileştirici, belirli veritabanı dizin ipuçlarını desteklemediği sürece, kaba kuvvet tablosu taramalarından kaçınmak ve iyi sorgu performansı elde etmek için hangi dizinlerin kullanılacağını kendi başına bulmalıdır.
İlişkisel veritabanı tasarım sanatının bir kısmı, dizinlerin mantıklı kullanımına dayanır. Sık bir sorgu için bir dizini atlarsanız, yoğun okuma yükleri altında tüm veritabanı yavaşlayabilir. Çok fazla dizininiz varsa, yoğun yazma ve güncelleme yükleri altında tüm veritabanı yavaşlayabilir.
Bir diğer önemli sanat, her tablo için iyi, benzersiz bir birincil anahtar seçmektir. Yalnızca birincil anahtarın ortak sorgular üzerindeki etkisini değil, aynı zamanda başka bir tabloda yabancı anahtar olarak göründüğünde birleşimlerde nasıl oynayacağını ve verilerin referans konumunu nasıl etkileyeceğini de düşünmeniz gerekir.
Yatay parçalama adı verilen birincil anahtarın değerine bağlı olarak farklı birimlere bölünmüş veritabanı tablolarının gelişmiş durumunda, birincil anahtarın parçalamayı nasıl etkileyeceğini de düşünmeniz gerekir. İpucu: Tablonun ciltler arasında eşit olarak dağıtılmasını istiyorsunuz, bu da tarih damgalarını veya ardışık tam sayıları birincil anahtar olarak kullanmak istemediğinizi gösterir.
İfadenin tartışılması
SELECTbasit başlayabilir, ancak hızla kafa karıştırıcı hale gelebilir. Düşünmek:
MÜŞTERİLERDEN SEÇ *;
Basit, değil mi?
CustomersTablonun tüm alanlarını ve tüm satırlarını sorar . Ancak,
Customerstablonun yüz milyon satırı ve yüz alanı olduğunu ve alanlardan birinin yorumlar için büyük bir metin alanı olduğunu varsayalım . Her satır ortalama 1 kilobayt veri içeriyorsa, saniyede 10 megabitlik bir ağ bağlantısı üzerinden tüm bu veriyi çekmek ne kadar sürer?
Belki de tel üzerinden ne kadar göndereceğinizi azaltmalısınız. Düşünmek:
Müşterilerden EN İYİ 100 şirketAdı, lastSaleDate, lastSaleAmount, totalSalesAmount SEÇİN
NEREDE eyalet VE şehir
LastSaleDate DESCENDING TARAFINDAN SİPARİŞ;
Şimdi çok daha az veriyi aşağı çekeceksiniz. Veritabanından size yalnızca dört alan vermesini, yalnızca Cleveland'daki şirketleri dikkate almanızı ve size en son satışı yapan 100 şirketi vermesini istediniz. Ancak bunu veritabanı sunucusunda en verimli şekilde yapmak için,
Customerstablonun cümle
state+cityiçin
WHEREbir indeks
lastSaleDateve
ORDER BYve
TOP 100cümlecikleri için bir on indeksine ihtiyacı vardır .
Bu arada,
TOP 100SQL Server ve SQL Azure için geçerlidir, ancak MySQL veya Oracle için geçerli değildir. MySQL'de cümleden
LIMIT 100sonra kullanırsınız
WHERE. Oracle'da, cümlenin bir
ROWNUMparçası olarak bir sınır kullanırsınız
WHERE, yani
WHERE... AND ROWNUM <=100. Ne yazık ki, ANSI / ISO SQL standartları (ve 1986'dan 2016'ya kadar uzanan dokuz tanesi var), her veritabanının kendi tescilli cümlecikleri ve özelliklerini tanıttığı kadar ileri gidiyor.
SQL birleşimleri
Şimdiye kadar,
SELECTtek tablolar için sözdizimini tanımladım . Cümleleri açıklamadan önce
JOIN, yabancı anahtarları ve tablolar arasındaki ilişkileri anlamanız gerekir. Bunu DDL'deki örneklerle, SQL Server sözdizimini kullanarak açıklayacağım.
Bunun kısa versiyonu oldukça basit. İlişkilerde kullanmak istediğiniz her tablonun birincil anahtar kısıtlaması olmalıdır; bu, tek bir alan veya bir ifade tarafından tanımlanan alanların birleşimi olabilir. Örneğin:
TABLO OLUŞTURMA Kişiler (
PersonID int NULL PRIMARY ANAHTAR,
KişiAdı karakter (80),
...
İlişkilendirilmesi
Personsgereken her tablo ,
Personsbirincil anahtara karşılık gelen bir alana sahip olmalı ve ilişkisel bütünlüğü korumak için bu alanın bir yabancı anahtar kısıtlamasına sahip olması gerekir. Örneğin:
TABLO Siparişleri OLUŞTURMA (
OrderID int NULL PRIMARY ANAHTAR DEĞİL,
...
PersonID int YABANCI ANAHTAR REFERANSLAR Kişiler (PersonID)
);
Her iki ifadenin de
CONSTRAINTanahtar kelimeyi kullanan daha uzun sürümleri vardır , bu da kısıtlamayı adlandırmanıza izin verir. Çoğu veritabanı tasarım aracının ürettiği şey budur.
Birincil anahtarlar her zaman dizine alınır ve benzersizdir (alan değerleri çoğaltılamaz). Diğer alanlar isteğe bağlı olarak indekslenebilir. Yazma ve güncellemelerden kaynaklanan potansiyel ek yükler nedeniyle her zaman olmasa da, her zaman olmasa da, yabancı anahtar alanları ve içinde
WHEREve
ORDER BYyan tümcelerinde görünen alanlar için dizin oluşturmak genellikle yararlıdır .
John Doe tarafından verilen tüm siparişleri döndüren bir sorguyu nasıl yazarsınız?
Kişilerden Kişi Adı, Sipariş Kimliği SEÇİN
Persons.PersonID ÜZERİNDE INNER JOIN Emirleri = Orders.PersonID
WHERE PersonName;
Aslında, dört türü vardır
JOIN:
INNER,
OUTER,
LEFT, ve
RIGHT.
INNER JOINVarsayılan (sözcüğünü atlayabilirsiniz olan
INNER) ve sadece her iki tabloda eşleşen değerler içeren satırları içeren biri. Kişileri sipariş alıp almadıklarını listelemek istiyorsanız
LEFT JOIN, örneğin:
Kişilerden Kişi Adı, Sipariş Kimliği SEÇİN
Persons.PersonID = Orders.PersonID ÜZERİNDE SOL BİRLEŞTİRME Emirleri
Kişi adına göre sipariş;
İfadeler kullanan veya veri türlerini zorlayan ikiden fazla tabloyu birleştiren sorgular yapmaya başladığınızda, sözdizimi ilk başta biraz belirsizleşebilir. Neyse ki, genellikle tabloları ve alanları şema diyagramından bir sorgu diyagramına sürükleyip bırakarak sizin için doğru SQL sorguları oluşturabilen veritabanı geliştirme araçları vardır.
SQL saklı yordamları
Bazen
SELECTifadenin açıklayıcı niteliği sizi gitmek istediğiniz yere götürmez. Çoğu veritabanında saklı yordam adı verilen bir tesis bulunur; ne yazık ki bu, neredeyse tüm veritabanlarının ANSI / ISO SQL standartlarına özel uzantıları kullandığı bir alandır.
SQL Server'da, saklı yordamlar (veya depolanan işlemler) için ilk lehçe Transact-SQL, yani T-SQL idi; Oracle'da PL-SQL idi. Her iki veritabanı da C #, Java ve R gibi saklı yordamlar için ek diller eklemiştir. Basit bir T-SQL saklı yordamı, bir
SELECTifadenin yalnızca parametreleştirilmiş bir sürümü olabilir . Avantajları kullanım kolaylığı ve verimliliktir. Saklanan prosedürler, her yürütüldüklerinde değil, kaydedildiklerinde optimize edilir.
Daha karmaşık bir T-SQL saklı yordamı, birden çok SQL deyimi, girdi ve çıktı parametreleri, yerel değişkenler,
BEGIN...ENDbloklar,
IF...THEN...ELSEkoşullar, imleçler (bir kümenin satır satır işleme), ifadeler, geçici tablolar ve diğer tüm yordamsal sözdizimi. Açıktır ki, saklı yordam dili C #, Java veya R ise, bu yordamsal dillerin işlevlerini ve sözdizimini kullanacaksınız. Diğer bir deyişle, SQL için motivasyonun standartlaştırılmış bildirimsel sorgular kullanmak olmasına rağmen, gerçek dünyada çok sayıda veritabanına özgü yordamsal sunucu programlaması görüyorsunuz.
Bu bizi CODASYL veritabanı programlamasının kötü eski günlerine geri götürmez (imleçler yaklaşsa da), ancak SQL ifadelerinin standartlaştırılması gerektiği ve performans endişelerinin veritabanı sorgu iyileştiricisine bırakılması gerektiği fikirlerinden geri döner. . Sonunda, performansın ikiye katlanması genellikle masada bırakılamayacak kadar fazladır.
SQL öğrenin
Aşağıda listelenen siteler SQL öğrenmenize veya çeşitli SQL lehçelerinin tuhaflıklarını keşfetmenize yardımcı olabilir.