Neden SQL ANSI-92 standardı ANSI-89'a göre daha iyi benimsenmiyor?


107

Çalıştığım her şirkette, insanların hala ANSI-89 standardında SQL sorgularını yazdığını gördüm:

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

ANSI-92 standardı yerine:

select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id

Bunun gibi son derece basit bir sorgu için, okunabilirlikte büyük bir fark yoktur, ancak büyük sorgular için, katılma ölçütlerimin tabloyu listeleyerek gruplandırılmasının, katılmamda nerede sorun yaşayabileceğimi görmeyi çok daha kolay hale getirdiğini görüyorum ve tüm filtrelememi WHERE yan tümcemde tutalım. Dış birleşimlerin Oracle'daki (+) sözdiziminden çok daha sezgisel olduğunu düşündüğümden bahsetmiyorum bile.

İnsanlara ANSI-92'yi anlatmaya çalışırken, ANSI-92'yi ANSI-89'a göre kullanmanın somut performans avantajları var mı? Kendi başıma denerdim, ancak burada sahip olduğumuz Oracle kurulumları EXPLAIN PLAN'ı kullanmamıza izin vermiyor - insanların kodlarını optimize etmeye çalışmasını istemezsiniz, değil mi?


7
SQL-92 birleştirme gösteriminin birincil bir avantajı, LEFT OUTER JOIN ve türevlerini yazmanın standart ve nispeten mantıklı bir yolu olmasıdır. Her DBMS'nin kendi varyant sözdizimi vardı (genellikle kötü; aslında, bence istisnasız gösterimler kötüydü) ve genellikle biraz farklı anlamlara sahipti. SQL-92 bunu düzeltti ve yeni gösterim yalnızca bu gerekçelerle kullanılmaya değer. Bir kez alıştığınızda daha net olduğunu düşünüyorum. Alışmak biraz zaman alır, ancak zor değildir ve bir kez dönüştürüldükten sonra geri dönüş yoktur.
Jonathan Leffler

anlambilim, şemantizm, anti-shemantics!
Sam


Çok daha güncel ve anlaşılır yeni bir cevap ekledim, buradaki cevaplarda diğer yanlış anlamaların üzerinde netlik var stackoverflow.com/a/47720615/124486
Evan Carroll

Yanıtlar:


77

Peter Gulutzan ve Trudy Pelzer'in, test ettikleri altı veya sekiz RDBMS markasından "SQL Performans Ayarı" na göre, SQL-92 tarzı birleşimlere kıyasla SQL-89'un optimizasyonu veya performansında hiçbir fark yoktu. Çoğu RDBMS motorunun, sorguyu optimize etmeden veya yürütmeden önce sözdizimini dahili bir temsile dönüştürdüğü varsayılabilir, böylece insan tarafından okunabilir sözdizimi hiçbir fark yaratmaz.

Ayrıca SQL-92 sözdizimini de geliştirmeye çalışıyorum. Onaylandıktan on altı yıl sonra, insanların onu kullanmaya başlama zamanı geldi! Ve artık tüm SQL veritabanı markaları bunu destekliyor, bu nedenle standart olmayan (+)Oracle sözdizimini veya *=Microsoft / Sybase sözdizimini kullanmaya devam etmek için hiçbir neden yok .

SQL-89 alışkanlığının geliştirici topluluğunu kırmanın neden bu kadar zor olduğuna gelince, yalnızca kitaplardan, dergi makalelerinden, veya başka bir kod tabanı ve bu insanlar yeni sözdizimini soyut olarak öğrenmezler. Bazı insanlar kalıp eşleştiriyor ve bazıları ezbere öğreniyor.

Yavaş yavaş, SQL-92 sözdizimini eskiye göre daha sık kullanan insanlar görüyorum. 1994'ten beri çevrimiçi olarak SQL sorularını yanıtlıyorum.


6
Tamamen katılıyorum. SQL'lerini 15 yıl önce veya daha uzun süre önce öğrenen (benim yaptığım gibi) ve ilk başladığından beri hiçbir yenilik hakkında hiçbir şey bilmeyen birçok SQL kodlayıcıyla çalışıyorum. Ayrıca öğrenmekle de ilgilenmezler.
Tony Andrews

8
Katılıyorum, ancak eski ANSI-89 Join sözdiziminin yanlış sonuçlar ürettiği iyi belgelenmiş senaryolar olduğunu da ekleyin ... özellikle birleşmenin "dış" tarafından Join ile ilgili olmayan sütunlarda koşullu filtreleme koşulları olduğunda dış Joins.
Charles Bretana

1
MS SQL'in belirli iç kısımlarını bilmiyorum, ancak bu, SQL-92 sözdiziminin değerli olduğuna dair iyi bir anekdot kanıtıdır. Benim için çalışıyor!
Bill Karwin

2
Masif mi? Lütfen çalışmanızı gönderin. En iyi iddiam, elma ile elma karşılaştırması olmamasıdır, ancak "oh evet öyle" diye yanıt vermeyin Sadece yeniden üretebileceğimiz bir test senaryosu, sürüm, yama seviyesi vb.

2
Ayrıca, "anekdot niteliğinde" kanıtlar zaten bilimsel bir ölçü değil. Her zaman bir tuz tanesi ile alınır.
Bill Karwin

16

Peki ANSI092 standardı oldukça kötü sözdizimi içerir. Doğal Birleştirmeler birdir ve KULLANIM Maddesi başka bir maddedir. IMHO, bir tabloya bir sütun eklenmesi kodu kırmamalı, ancak bir DOĞAL BİRLEŞTİRME çok korkunç bir şekilde kırılır. Kırmanın "en iyi" yolu derleme hatasıdır. Örneğin * bir yere SEÇ bile, bir sütunun eklenmesi olabilirderleme başarısız. Başarısız olmanın bir sonraki en iyi yolu çalışma zamanı hatasıdır. Daha kötüdür çünkü kullanıcılarınız görebilir, ancak yine de size bir şeyi bozduğunuza dair güzel bir uyarı verir. ANSI92 kullanır ve NATURAL birleştirmelerle sorgular yazarsanız, derleme zamanında bozulmaz ve çalışma zamanında kırılmaz, sorgu aniden yanlış sonuçlar vermeye başlar. Bu tür böcekler sinsidir. Raporlar yanlış gidiyor, potansiyel olarak mali açıklama yanlış.

NATURAL Joins'e aşina olmayanlar için. Her iki tabloda da bulunan her sütun adında iki tabloyu birleştirirler. 4 sütunlu bir anahtarınız olduğunda ve yazmaktan bıktığınızda gerçekten harika. Sorun, Tablo1'in DESCRIPTION adında önceden var olan bir sütuna sahip olması ve Table2'ye, oh bilmiyorum, mmm, DESCRIPTION gibi zararsız bir şey adında yeni bir sütun eklediğinizde ortaya çıkar ve şimdi iki tabloyu bir VARCHAR2'de birleştiriyorsunuz. (1000) serbest biçimli alan.

USING cümlesi, yukarıda açıklanan soruna ek olarak tam bir belirsizliğe yol açabilir. Başka bir SO gönderisinde , birisi bu ANSI-92 SQL'i gösterdi ve onu okumak için yardım istedi.

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

Bu tamamen belirsizdir. Hem Şirketler hem de kullanıcı tablolarına bir Kullanıcı Kimliği sütunu koydum ve herhangi bir şikayet yok. Şirketlerdeki Kullanıcı Kimliği sütunu, bu satırı değiştiren son kişinin kimliğiyse ne olur?

Ciddiyim, böyle bir belirsizliğin neden gerekli olduğunu kimse açıklayabilir mi? Neden doğrudan standarda dahil edilmiştir?

Bence Bill, kodlama yoluyla kopyalayıp yapıştıran geniş bir geliştirici tabanı olduğu konusunda haklı. Aslında, ANSI-92 söz konusu olduğunda bir tür olduğumu kabul edebilirim. Şimdiye kadar gördüğüm her örnek, birden çok birleşimin parantez içine yerleştirildiğini gösteriyordu. Dürüstlük, en iyi ihtimalle sql'deki tabloları seçmeyi zorlaştırıyor. Ancak daha sonra bir SQL92 evangilisti, bunun aslında bir birleştirme emrini zorlayacağını açıkladı. JESUS ​​... Gördüğüm tüm bu Kopyalama yapıştırıcıları artık bir birleştirme emrini zorluyor - bu, zamanın% 95'ini optimize edenlere, özellikle de bir kopya / pastaya bırakan bir iş .

Tomalak dediğinde doğru anladı,

insanlar sadece orada olduğu için yeni sözdizimine geçmiyor

Bana bir şey vermeli ve ben bir tersini görmüyorum. Ve bir tersi varsa, negatifler göz ardı edilemeyecek kadar büyük bir albatrostur.


3
ON kullanma eğilimindeyim çünkü KULLANMA veya NATURAL JOIN'den daha az belirsiz. Parantezlere gelince, Microsoft Access'te "SQL" öğrenen kişiler, bunları atlarsanız Access sızlandığı için bunu kullanır. (SQL'in etrafındaki alıntılar parmak tırnak işaretleri olmalıdır.)
Powerlord

1
Öksürük KULLANIM cümlesi nedir? ;-) Ben SQL sunucu kısmından geliyorum, bu yüzden bu benim radarımda değil. R. Bemrose'un dediği gibi, ON cümlesi var, gayet iyi çalışıyor, sözdizimsel olarak ifade edemediğim bir birleşimle beni asla bırakmıyor. Bazı yazımları kaydetmek için DB tasarımımı sorgu sözdizimine uyarlamaya gerek yok.
Tomalak

3
Verilerinizi NATURAL JOIN veya uygun olduğunda KULLANMAK için yeterince iyi bilmiyorsanız, muhtemelen bunun için SQL yazmamalısınız. Cehalet için -1.
Rob

4
IMHO, doğal birleşimler ile aynı çantaya düşüyor SELECT *(sonra müşterinin saha düzenine bağlı olduğunu bulmak) - Biraz özensiz hissettiriyor
Temel

2
Doğal birleştirmelerle tanımladığınız sorun, standartta değil, veritabanı tasarımınızla ilgili bir sorundur. verilerinizin farkında olmanız ve sütun adları için standartlar belirlemeniz gerekir.
Travis

14

Akla birkaç neden geliyor:

  • insanlar bunu alışkanlıktan yapıyor
  • insanlar tembeldir ve daha az yazı yazmayı gerektirdikleri için "eski tarz" katılımları tercih ederler
  • yeni başlayanlar genellikle SQL-92 birleştirme sözdizimi etrafında kafalarını sarmada sorun yaşarlar
  • insanlar sadece orada olduğu için yeni sözdizimine geçmiyor
  • insanlar, yeni sözdiziminin (eğer onu böyle adlandırmak istiyorsanız) sağladığı faydaların farkında değildir, öncelikle bir dış birleştirme yapmadan önce bir tabloyu filtrelemenizi sağlar ve tüm sahip olduğunuz WHERE cümlesi olduğunda ondan sonra değil.

Kendi adıma, tüm birleştirmelerimi SQL-92 sözdiziminde yapıyorum ve mümkün olan yerde kodu dönüştürüyorum. Bunu yapmanın daha temiz, daha okunaklı ve güçlü yolu. Ancak, sorgu sonucunu değiştirmemekle birlikte daha fazla yazma çalışması açısından onları incittiğini düşündüğünde, yeni stili kullanmaya ikna etmek zordur.


3
Pek çok insan için SQL'e bakmak onlara zarar verir. Herhangi bir çalışma kodunu değiştirmek, özellikle kodlayıcı gözlerini kaçırırken bir hata ortaya çıkma riski taşır. :-)
Bill Karwin

Hm ... bana göre karmaşık düzenli ifadelere bakmanın bile zararı yok. SQL bana zarar veremez. ;-)
Tomalak

"Yeni başlayanlar sık ​​sık sorun yaşar ..." İşte bu bir satış noktası

2
Nedense bunun "profesyonel" mi yoksa "kontrra" mı olduğundan emin değilim ... Belki de ironi detektörüm bozulmuştur.
Tomalak

10

Yukarıdaki NATURAL JOIN ve USING gönderisine yanıt olarak.

NEDEN bunları kullanma ihtiyacını görürdünüz - bunlar ANSI-89'da mevcut değildi ve ANSI-92 için sadece kısayol olarak görebildiğim gibi eklenmişlerdi.

Bir birleşimi asla şansa bırakmazdım ve her zaman tabloyu / diğer adı ve kimliği belirtirdim.

Benim için gitmenin tek yolu ANSI-92. Daha ayrıntılıdır ve sözdizimi ANSI-89 takipçileri tarafından beğenilmez, ancak JOIN'lerinizi FİLTRELEMENİZDEN düzgün bir şekilde ayırır.


NATURAL JOIN'leri bir kısayol olarak görmüyorum, ancak bir İlişkisel DB içinde Nesne Yönelimli DB programlamasına bir Segway.
Armand

5

Öncelikle SQL Server'da dış birleştirme sözdiziminin (* =) her zaman doğru sonuçları vermediğini söyleyeyim. Bunu bir dış birleşim olarak değil, bir çapraz birleşim olarak yorumladığı zamanlar vardır. Yani onu kullanmayı bırakmak için iyi bir neden var. Ve bu dış birleştirme sözdizimi, kullanımdan kaldırılmış bir özelliktir ve SQL Server 2008'den sonraki SQL Server sürümünde olmayacaktır. İç birleştirmeleri yine de yapabileceksiniz ama neden birileri bunu yapmak ister? Belirsizdir ve bakımı çok daha zordur. Birleştirmenin bir parçası ve gerçekte sadece nerede cümlesinin ne olduğunu kolayca bilemezsiniz.

Eski sözdizimini kullanmamanız gerektiğine inanmamın bir nedeni, birleştirmeleri anlamanın ve yaptıkları ve yapmadıklarının SQL kodu yazacak olan herkes için kritik bir adım olmasıdır. Birleşimleri iyice anlamadan herhangi bir SQL kodu yazmamalısınız. Bunları iyi anlarsanız, muhtemelen ANSI-92 sözdiziminin daha net ve bakımının daha kolay olduğu sonucuna varacaksınız. Eski sözdizimi yerine ANSI-92 sözdizimini kullanmayan bir SQL uzmanıyla hiç tanışmadım.

Eski kodu kullananlarla tanıştığım veya uğraştığım çoğu kişi, birleşmeleri gerçekten anlamıyor ve bu nedenle veritabanını sorgularken başım belaya giriyor. Bu benim kişisel deneyimim, bu yüzden her zaman doğru olduğunu söylemiyorum. Ancak bir veri uzmanı olarak, inanmamak için yıllar boyunca bu çöpü çok fazla düzeltmek zorunda kaldım.


1
Tanıştığıma memnun oldum. İlkiniz olduğum için mutluyum.

4

Okulda ANSI-89 öğretildi ve birkaç yıl endüstride çalıştım. Sonra 8 yıl boyunca muhteşem DBMS dünyasından ayrıldım. Ama sonra geri döndüm ve bu yeni ANSI 92 meselesi öğretiliyordu. Join On sözdizimini öğrendim ve şimdi aslında SQL öğretiyorum ve yeni JOIN ON sözdizimini öneriyorum.

Ancak gördüğüm dezavantaj, ilişkili alt sorgular, ANSI 92 birleşimlerinin ışığında mantıklı görünmüyor. Birleştirme bilgisi WHERE'ye eklendiğinde ve ilişkili alt sorgular WHERE'da "birleştirildiğinde" hepsi doğru ve tutarlı görünüyordu. ANSI 92 tablosunda birleştirme ölçütleri WHERE'de değildir ve alt sorgu "birleştirme" ise sözdizimi tutarsız görünüyor. Öte yandan, bu tutarsızlığı "düzeltmeye" çalışmak muhtemelen durumu daha da kötüleştirecektir.


Öte yandan, performans domuzları oldukları için, ilişkili alt sorgular yazmamalısınız. Sorgunuza bir imleç koymak gibidirler. Ugh.
HLGEM

3

Cevabı kesin olarak bilmiyorum .. bu dinsel bir savaş (Mac-Pc veya diğerlerinden daha az dereceli)

Bir tahmin, Oracle'ın (ve belki diğer satıcıların da) ANSI-92 standardını (sanırım Oracle v9'da olduğunu düşünüyorum) ve bu nedenle DBA'lar / Db Developers yakın zamana kadar, Hâlâ bu sürümleri kullanıyorlardı (veya kodun bu sürümleri kullanan sunucular arasında taşınabilir olmasını istiyorlardı, eski standarda bağlı kalmaları gerekiyordu ...

Gerçekten utanç verici, çünkü yeni birleştirme sözdizimi çok daha okunabilir ve eski sözdizimi birkaç iyi belgelenmiş senaryoda yanlış (yanlış) sonuçlar veriyor.

  • Spesifik olarak, birleştirmenin "dış" tarafındaki tablodan Join ile ilgili olmayan sütunlarda koşullu filtreleme tahminleri olduğunda dış Joins.

Evet, Oracle 9i; 2001'de piyasaya sürüldü. Partiye biraz geç kaldı!

1
MS SQL INNER JOIN, LEFT JOIN1996 yılına kadar olmasa da 1995'te eklendi . MySQL en azından 1999'da piyasaya sürülen 3.23'ten beri destekledi; PostgreSQL en az 7.2'den beri, 2002'de piyasaya sürüldü. Sıradan bir Google araştırması bana Teradata için cevap vermiyor.

Evet, 1991'de Oracle'ın üstünlüğünü kanıtlayan kınama buydu: "Sol" ve "Sağ" sözdizimini kullanan MS erişimi gibi veritabanı sistemleri ANSI standart SQL değildi. Böyle bir SQL göndermek, diğer insanların sana alay etmeleri için bir fırsattı. Şimdi twitter ve facebook gibi.
david

2

Atalet ve pratiklik.

ANSI-92 SQL, dokunarak yazma gibidir. Teorik bir şekilde, bir gün her şeyi daha iyi hale getirebilir, ama şimdi dört parmağımla tuşlara çok daha hızlı bakarak yazabiliyorum. Bir ödeme olacağına dair hiçbir garanti olmadan, ileriye gitmek için geriye gitmem gerekecekti.

SQL yazmak işimin yaklaşık% 10'u. ANSI-89 SQL'in çözemediği bir sorunu çözmek için ANSI-92 SQL'e ihtiyacım olursa, onu kullanacağım. (Aslında onu Access'te kullanıyorum.) Her zaman kullanmak mevcut sorunlarımı çok daha hızlı çözmeme yardımcı olacaksa, onu özümsemek için zaman harcardım. Ancak sözdizimini hiç düşünmeden ANSI-89 SQL'i kırbaçlayabilirim. Sorunları çözmek için para alıyorum - SQL sözdizimi hakkında düşünmek zamanımı ve işverenimin parasını boşa harcıyor.

Bir gün genç Grasshopper, ANSI-92 SQL sözdizimi kullanımınızı, SQL3 (veya her neyse) kullanmanız gerektiğini söyleyen gençlere karşı savunacaksınız. Ve sonra anlayacaksın. :-)


2
Burada açıklanan yaklaşım, önleyici bakım fikrinden kaçınarak, "kırıldığında düzelt" düşünce ekolüne benziyor. Sorunları çözmek için para alıyorsunuz, evet, ancak şirketinize daha fazla değer sağlamak için de para alıyorsunuz. Sizin durumunuzda ANSI-89 kısa vadede daha fazla değer sağlar, ancak uzun vadede ANSI-92'ye zaman ayırmamak daha pahalı bir seçenek olacaktır.
Travis

Her zaman yaptığınız şeye bağlı kalmak, gittiğinizde kodunuzu korumak zorunda olan zavallı adam için bir maliyetle gelir. Bu, ayın tadına geçmeniz gerektiği anlamına gelmez, ancak en iyi uygulamaları benimsemek neredeyse her zaman sürdürülebilirlikte karşılığını verir.

Excel'e geçmeyeceğim (fareye üç tıklama veya daha azıyla her şeyi yapabilirsiniz), çünkü ihtiyacım olan binlerce Lotus 123 komutunu ezberledim ve bunları rahatlıkla kullanıyorum! Hah!
Charles Bretana

2

Başlangıçta SQL Server 6.5 için yazılmış ve SQL 92 birleştirme sözdizimini desteklemeyen bir sorgu vardı, yani

select foo.baz
from foo
  left outer join bar
  on foo.a = bar.a

bunun yerine şu şekilde yazılmıştır:

select foo.baz
from foo, bar
where foo.a *= bar.a

Sorgu bir süredir ortalıktaydı ve ilgili veriler, sorgunun çok yavaş çalışmasına neden olacak şekilde birikmişti, tamamlanması yaklaşık 90 saniye. Bu sorun ortaya çıktığında, SQL Server 7'ye yükseltmiştik.

Dizinler ve diğer Paskalya yumurtaları ile uğraştıktan sonra, birleştirme sözdizimini SQL 92 uyumlu olacak şekilde değiştirdim. Sorgu süresi 3 saniyeye düştü.

Geçiş yapmak için iyi bir neden var.

Dan reposted burada .


1

Her iki sözdizimini anlayacak kadar SQL bilerek ortalama bir geliştiricinin bakış açısından cevap verebilirim, ancak yine de ihtiyacım olan her seferinde insert sözdizimini tam olarak araştırıyorum ... :-P (Bütün gün SQL yapmam sadece zaman zaman bazı sorunları düzeltir.)

Aslında, ilk biçimi daha sezgisel buluyorum, iki tablo arasında görünürde bir hiyerarşi oluşturmuyorum. SQL'i muhtemelen eski kitaplarla, ilk formu göstererek öğrendiğim gerçeği muhtemelen yardımcı olmuyor ... ;-)
Ve Google'da bir sql seçme aramasında bulduğum ilk referans (benim için çoğunlukla Fransızca cevaplar veriyor ... ) önce eski formu gösterir (sonra ikincisini açıklar).

Sadece "neden" sorusuyla ilgili bazı ipuçları veriyorum ... ^ _ ^ Konuyla ilgili iyi, modern bir kitap (DB agnostik) okumalıyım. Birinin önerileri varsa ...


1

Tüm okullar adına konuşamam ama üniversitemde kursumuzun SQL modülünü yaparken ANSI-92 öğretmediler, ANSI-89 öğrettiler - eski bir VAX sisteminde! Sorgu tasarımcısını kullanarak bazı sorgular oluşturup ardından SQL kodunu araştırıp Access'te araştırmaya başlayana kadar ANSI-92'ye maruz kalmadım. Birleşmeleri nasıl tamamladığını ya da sözdiziminin etkilerini bilmediğimi fark ederek daha derine inmeye başladım, böylece anlayabileyim.

Mevcut belgelerin pek çok durumda tam olarak sezgisel olmadığı ve insanların bildiklerine sadık kaldıkları ve çoğu durumda işlerini yapmak için ihtiyaç duyduklarından fazlasını öğrenmeye çalışmadıkları göz önüne alındığında, bu evlat edinmenin neden bu kadar uzun sürdüğünü anlamak kolay.

Elbette, kurcalamayı ve anlamayı seven teknik evanjelistler var ve "daha yeni" ilkeleri benimseyen ve geri kalanını dönüştürmeye çalışan türler olma eğilimindedir.

İşin garibi, bana öyle geliyor ki birçok programcı okuldan çıkıyor ve ilerlemeyi bırakıyor; Bu onlara öğretildiği için, bu şekilde yapıldığını düşünüyorum. Okulun size sadece temel bilgileri öğretmek ve gerisini kendiniz öğrenmeniz için yeterli anlayış sağlamak amacıyla yapıldığını ve gerçekten bilinmesi gereken şeylerin yüzeyini zar zor çizdiğinizi fark edene kadar gözlerinizi kırpmayın; şimdi bu yola devam etmek senin işin.

Tabii ki, bu sadece deneyimlerime dayanan fikrim.


Sadece programcılar değil. Pek çok alanda, insanları kariyerlerine yerleştikten sonra yeniden eğitmeye ikna etmek zordur. Her alanda aynı oranda istisnai bireyler olduğunu varsayıyorum elbette.
Bill Karwin

2
Birini başarılı bir şeyden fayda sağlamayan farklı bir şeye geçmeye ikna etmek zordur. Evin .net tarafımız 1.0'dan 3.5'e ve aradaki her adımda SIFIR cajoling ile değişti. Her yeni sürüm daha iyiydi. Aynısını burada söyleyemem.

1

1) OUTER JOIN yazmanın standart yolu, * = veya (+) =

2) DOĞAL BİRLEŞİM

3) Veritabanı motoruna bağlı olarak, ANSI-92 trendlerinin daha optimal olması.

4) Manuel optimizasyon:

Diyelim ki bir sonraki sözdizimimiz var (ANSI-89):

(1)select * from TABLE_OFFICES to,BIG_TABLE_USERS btu
where to.iduser=tbu.iduser and to.idoffice=1

Şu şekilde yazılabilir:

(2)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser
where to.idoffice=1

Ama aynı zamanda:

(3)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser and to.idoffice=1

Hepsi (1), (2), (3) aynı sonucu döndürür, ancak farklı şekilde optimize edilirler, veritabanı motoruna bağlıdır, ancak çoğu yapar:

  • (1) optimizasyona karar veri tabanı motoruna bağlıdır.
  • (2) her iki tabloyu birleştirir ve sonra ofis başına filtreyi yapar.
  • (3) idoffice kullanarak BIG_TABLE_USERS'ı filtreler ve ardından her iki tabloyu birleştirir.

5) Daha uzun sorgular daha az karmaşıktır.


1

İnsanların yaşlı ve genç programcılar, kursiyerler ve yeni mezunlarla olan pratik deneyimlerime dayanarak ANSI-89'u kullanmasının nedenleri:

  • SQL'i gördükleri mevcut koddan (kitaplar yerine) öğrenirler ve ANSI-89'u koddan öğrenirler.
  • ANSI-89, çünkü daha az yazıyor
  • Bunu düşünmezler ve bir veya başka bir tarz kullanırlar ve ikisinden hangisinin yeni veya eski kabul edildiğini bile bilmiyorlar ve umursamıyorlar.
  • Kodun aynı zamanda, kodu koruyan bir sonraki programcı ile bir iletişim olduğu fikri mevcut değildir. Bilgisayarla konuştuklarını ve bilgisayarın umrunda olmadığını düşünüyorlar.
  • "Temiz kodlama" sanatı bilinmiyor
  • Özellikle programlama dili ve SQL bilgisi o kadar zayıftır ki, başka yerlerde bulduklarını kopyalayıp birbirine yapıştırırlar
  • Kişisel tercih

Kişisel olarak ANSI-92'yi tercih ediyorum ve ANSI-89 sözdiziminde gördüğüm her sorguyu bazen sadece elimdeki SQL İfadesini daha iyi anlamak için değiştiriyorum. Ancak birlikte çalıştığım insanların çoğunun birçok masada birleştirme yazacak kadar yetenekli olmadığını fark ettim. Ellerinden geldiğince iyi kodlarlar ve bir SQL ifadesiyle ilk karşılaştıklarında ezberlediklerini kullanırlar.


1

İşte SQL-89 ve SQL-92'yi karşılaştıran ve diğer yanıtlardaki bazı yanlış anlamaları gideren birkaç nokta.

  1. NATURAL JOINSkorkunç bir fikir. Örtükler ve tablo hakkında meta bilgi gerektiriyorlar. SQL-92 ile ilgili hiçbir şey onların kullanımını gerektirmez, bu yüzden onları görmezden gelin . Bu tartışma ile alakalı değiller.
  2. USING harika bir fikir, iki etkisi var:
    1. Bir equijoin'den sonuç kümesinde yalnızca bir sütun üretir.
    2. Sağlam ve mantıklı bir kongre uygular. SQL-89'da idher iki tabloya da sütun yazan insanlar vardı . Tabloları birleştirdikten sonra, bu belirsiz hale gelir ve açık bir örtüşme gerektirir. Dahası, idbirleşimdeki bilgiler neredeyse kesinlikle farklı verilere sahipti. Eğer şirkete kişiyi katılırsanız, şimdi takma birine sahip idüzere person_idbir ve idkarşı company_idiki belirsiz sütunları üretecektir katılmak onsuz. Tablonun vekil anahtarı için küresel olarak benzersiz bir tanımlayıcı kullanmak, standartların ödüllendirdiği bir konudur USING.
  3. SQL-89 sözdizimi örtüktür CROSS JOIN. A CROSS JOINseti küçültmez, dolaylı olarak büyütür. bununla FROM T1,T2aynıdır FROM T1 CROSS JOIN T2, genellikle istediğiniz gibi olmayan bir Kartezyen birleştirme üretir. Uzak bir WHEREkoşula indirgemek için seçiciliğe sahip olmak, tasarım sırasında hata yapma olasılığınızın daha yüksek olduğu anlamına gelir.
  4. SQL-89 ,ve SQL-92 açık JOINURL'lerin farklı önceliği vardır. JOINdaha yüksek bir önceliğe sahiptir. Daha da kötüsü, MySQL gibi bazı veritabanları bunu çok uzun süre yanlış anladı. . Bu yüzden iki stili karıştırmak kötü bir fikir ve bugün çok daha popüler olan stil SQL-92 stili.

1) İlişkisel modeli incelerseniz, takdir edersiniz ki, harika bir fikre katılmanız doğal değildir, ihtiyacınız olan tek katılım türüdür. 2) Bkz. 1, yani gerekli değil. 3) Sözdizimine bakılmaksızın (ve her ikisi de SQL-92 sözdizimidir), ilişkisel operatör üründür (çarpma), yani gerçekte bir birleştirme değildir (Kartezyen birleştirme 'bir şey değildir). 4. Bkz. 1 ie gerekli değil.
birgün

0

Oracle, ANSI-92'yi hiç iyi uygulamaz. Birkaç sorun yaşadım, en azından Oracle Apps'taki veri tabloları çok iyi sütunlarla donatılmış olduğundan. Birleşimlerinizdeki sütun sayısı yaklaşık 1050 sütunu aşarsa (bu, Uygulamalarda yapılması çok kolaydır), o zaman kesinlikle mantıklı olmayan bu sahte hatayı alırsınız:

ORA-01445: cannot select ROWID from a join view without a key-preserved table.

Eski stil birleştirme sözdizimini kullanmak için sorguyu yeniden yazmak sorunu ortadan kaldırır, bu da ANSI-92 birleşimlerinin uygulanmasında doğrudan suçun parmağını işaret ediyor gibi görünüyor.

Bu problemle karşılaşana kadar, eski tarz sözdizimiyle yapmak çok kolay olan kazara çapraz birleştirme olasılığını azaltmanın faydalarından dolayı ASNI-92'nin kararlı bir destekçisiydim.

Ancak şimdi bunda ısrar etmeyi çok daha zor buluyorum. Oracle'ın kötü uygulamasına işaret ediyorlar ve "Kendi yöntemimizle yapacağız, teşekkürler" diyorlar.


1
Cross Join yapmak kolay olabilir, aynı zamanda kendiliğinden olmayan bir şeydir ve kesinlikle belirsiz değildir. Herhangi bir düzgün SQL geliştiricisi bunu fark edebilir. Ama KULLANIM ve DOĞAL BİRLEŞME, size seslenen ve küçük teknenizi ıstırap ve sefalet kayaları üzerinde parçalayan baştan çıkarıcılardır.

1
Demek istediğim, iki tabloyu bir araya getiren where cümlesini atlayarak yanlışlıkla çapraz birleştirme oluşturmak daha kolaydı. ANSI-92'de çapraz birleştirme kasıtlı olmalıdır. Ama NATURAL JOIN'in iğrenç bir şey olduğuna katılıyorum. :)
Jonathan

Demek istediğini anladım. Ama birdenbire böyle olmuyor. Sorgunuzda hata ayıklarken sorunu fark eder ve düzeltirsiniz. Sorgunun kendisinde hiçbir değişiklik yapmadan doğal birleştirme kullanırsanız, bir tablo değişikliği nedeniyle değişebilir.

0

Yeni bir SQL standardı, önceki standarttan, yani 'uyumluluğun prangaları' olan her şeyi miras alır. Bu nedenle, 'eski' / 'virgülle ayrılmış' / 'niteliksiz' birleştirme stili mükemmel bir şekilde geçerli SQL-92 sistemidir.

Şimdi, SQL-92'lerin NATURAL JOINihtiyacınız olan tek birleştirme olduğunu iddia ediyorum . Örneğin, inner joinyinelenen sütunlar oluşturmadığı için daha üstün olduğunu savunuyorum - SELECTyan tümcelerde sütunları netleştirmek için artık aralık değişkeni yok ! Ancak her kalbi ve zihni değiştirmeyi bekleyemem, bu yüzden kişisel olarak eski birleştirme stilleri olduğunu düşündüğüm şeyi benimsemeye devam edecek kodlayıcılarla çalışmam gerekiyor (ve hatta aralık değişkenlerini 'takma adlar' olarak adlandırabilirler!). Bu, ekip çalışmasının doğasıdır ve boşlukta faaliyet göstermez.

SQL dilinin eleştirilerinden biri, aynı sonucun bir dizi semantik olarak eşdeğer sözdizimi kullanılarak elde edilebileceğidir (bazıları ilişkisel cebir kullanarak, bazıları ilişkisel hesabı kullanarak), burada 'en iyi' olanı seçmenin basitçe kişisel stile geldiği . Bu yüzden 'eski tarz' katılımlarda olduğum kadar rahatım INNER. Bunları yeniden yazmak için zaman ayırıp ayırmayacağım NATURAL, içeriğe bağlıdır.

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.