Uygulama geliştiricileri tarafından yapılan yaygın veritabanı geliştirme hataları nelerdir?
Uygulama geliştiricileri tarafından yapılan yaygın veritabanı geliştirme hataları nelerdir?
Yanıtlar:
1. Uygun endeksleri kullanmamak
Bu nispeten kolay bir şey ama yine de her zaman oluyor. Yabancı anahtarlar üzerinde dizinler olmalıdır. Eğer bir alanı bir alan üzerinde kullanıyorsanız WHERE
(muhtemelen) üzerinde bir indeks olmalıdır. Bu tür dizinler genellikle yürütmeniz gereken sorguları temel alan birden çok sütunu kapsamalıdır.
2. Referans bütünlüğünü zorlamamak
Veritabanınız burada değişiklik gösterebilir, ancak veri tabanınız referans bütünlüğünü destekliyorsa - yani tüm yabancı anahtarların var olan bir varlığı göstereceği garanti edilirse - kullanmalısınız.
Bu hatayı MySQL veritabanlarında görmek oldukça yaygındır. MyISAM'ın bunu desteklediğine inanmıyorum. InnoDB yapar. MyISAM kullanan veya InnoDB kullanan ancak yine de kullanmayan kişileri bulacaksınız.
Daha fazla burada:
3. Yedek (teknik) birincil anahtarlar yerine doğal anahtarlar kullanma
Doğal anahtarlar (görünüşte) benzersiz olan dışsal anlamlı verilere dayanan anahtarlardır. Yaygın örnekler arasında ürün kodları, iki harfli durum kodları (ABD), sosyal güvenlik numaraları vb. Sayılabilir. Yedek veya teknik birincil anahtarlar, sistem dışında kesinlikle hiçbir anlamı olmayan anahtarlardır. Yalnızca varlığı tanımlamak için icat edilirler ve genellikle otomatik olarak artan alanlar (SQL Server, MySQL, diğerleri) veya dizilerdir (en önemlisi Oracle).
Bence her zaman yedek anahtar kullanmalısınız. Bu sorun şu sorularda ortaya çıktı:
Bu, üzerinde anlaşmaya varmayacağınız tartışmalı bir konudur. Doğal anahtarların bazı durumlarda iyi olduğunu düşünen bazı insanlar bulabilirsiniz, ancak yedek anahtarların tartışmasız gereksiz olmaktan başka bir eleştiri bulamazsınız. Bana sorarsan bu oldukça küçük bir dezavantaj.
Unutmayın, ülkeler bile var olabilir (örneğin, Yugoslavya).
4. DISTINCT
Çalışması gereken sorular yazma
Bunu sık sık ORM tarafından oluşturulan sorgularda görürsünüz. Hazırda Bekletme'nin günlük çıktısına bakın ve tüm sorguların şununla başladığını göreceksiniz:
SELECT DISTINCT ...
Bu, yinelenen satırları döndürmemenizi ve böylece yinelenen nesneleri elde etmenizi sağlamak için bir kısayoldur. Bazen insanların bunu yaptığını görürsünüz. Çok fazla görürseniz, gerçek bir kırmızı bayrak. Bu DISTINCT
kötü değil veya geçerli uygulamaları yok. (Her iki durumda da) yapar, ancak doğru sorguları yazmak için bir vekil veya bir durma aralığı değildir.
Gönderen ben DISTINCT Nefret Neden :
İşler bir geliştirici, önemli bir sorgu bina tablolar birlikte katılarak ve tüm zaman benim görüşüm ekşi gitmek başlamak Nerede ani o olduğunu fark görünüyor o yinelenen (hatta daha çok) satır ve onun hemen yanıt oluyor gibi ... onun bu "soruna" "çözümü" DISTINCT anahtar kelimesini atmak ve POOF tüm sıkıntılarını ortadan kaldırıyor .
5. Birleştirmeler üzerinde toplama lehine
Veritabanı uygulama geliştiricileri tarafından yapılan bir diğer yaygın hata, birleştirmelerle ne kadar daha pahalı bir toplamanın (yani GROUP BY
madde) karşılaştırılabileceğinin farkına varmamaktır.
Bunun ne kadar yaygın olduğu hakkında bir fikir vermek için, bu konu hakkında birkaç kez burada yazdım ve bunun için çok aşağı indirildim. Örneğin:
Gönderen SQL deyimi - “tarafından ve sahip grubu” vs “katılmak” :
İlk sorgu:
SELECT userid FROM userrole WHERE roleid IN (1, 2, 3) GROUP by userid HAVING COUNT(1) = 3
Sorgu süresi: 0.312 s
İkinci sorgu:
SELECT t1.userid FROM userrole t1 JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2 JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3 AND t1.roleid = 1
Sorgu süresi: 0,016 s
Doğru. Önerdiğim birleştirme sürümü toplu sürümden yirmi kat daha hızlı.
6. Görünümler aracılığıyla karmaşık sorguları basitleştirmemek
Tüm veritabanı satıcıları görünümleri desteklemez, ancak bunu yapanlar için mantıklı bir şekilde kullanılırsa sorguları büyük ölçüde basitleştirebilirler. Örneğin, bir projede CRM için genel bir Parti modeli kullandım . Bu son derece güçlü ve esnek bir modelleme tekniğidir ancak birçok birleşmeye yol açabilir. Bu modelde şunlar vardı:
Misal:
Ted'i işverenine bağlamak için beş tablo birleştirildi. Tüm çalışanların Kişi (organizasyon değil) olduğunu varsayar ve bu yardımcı görünümü sağlarsınız:
CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id
Ve aniden, çok esnek bir veri modelinde istediğiniz verileri çok basit bir şekilde görebilirsiniz.
7. Girişi sterilize etmiyor
Bu çok büyük. Şimdi PHP'yi seviyorum ama ne yaptığınızı bilmiyorsanız saldırılara karşı savunmasız siteler oluşturmak gerçekten çok kolay. Hiçbir şey küçük Bobby Tables'ın hikayesinden daha iyi özetleyemez .
Kullanıcı tarafından URL'ler, form verileri ve çerezler aracılığıyla sağlanan veriler her zaman düşmanca ve dezenfekte edilmiş olarak ele alınmalıdır. Beklediğinizi aldığınızdan emin olun.
8. Hazırlanan ifadeleri kullanmamak
Hazırlanan ifadeler, ekler, güncelleştirmeler ve WHERE
yan tümcelerinde kullanılan verileri eksi bir sorgu derleyip derledikten sonra bunu daha sonra sağladığınız zamandır. Örneğin:
SELECT * FROM users WHERE username = 'bob'
vs
SELECT * FROM users WHERE username = ?
veya
SELECT * FROM users WHERE username = :username
platformunuza bağlı olarak.
Bunu yaparak veritabanlarının dizlerine getirildiğini gördüm. Temel olarak, herhangi bir modern veritabanı yeni bir sorgu ile her karşılaştığında onu derlemek zorundadır. Daha önce gördüğü bir sorgu ile karşılaşırsa, veritabanına derlenmiş sorguyu ve yürütme planını önbelleğe alma fırsatı verirsiniz. Sorguyu çok yaparak veritabanına bunu bulma ve buna göre optimize etme fırsatı vermiş olursunuz (örneğin, derlenmiş sorguyu belleğe sabitleyerek).
Hazırlanan ifadeleri kullanmak, belirli sorguların ne sıklıkta kullanıldığına ilişkin anlamlı istatistikler de verir.
Hazırlanan ifadeler sizi SQL enjeksiyon saldırılarına karşı daha iyi koruyacaktır.
9. Yeterince normalleşmeme
Veritabanı normalizasyonu temel olarak veritabanı tasarımını optimize etme veya verilerinizi tablolar halinde nasıl düzenlediğinizdir.
Sadece bu hafta birisi bir dizi imploded ve bir veritabanındaki tek bir alana eklenmiş bazı kod üzerinde koştu. Bunu normalleştirmek, o dizinin elemanını bir alt tabloda ayrı bir satır olarak ele almak olacaktır (yani bir-çok ilişkisi).
Bu aynı zamanda kullanıcı kimlikleri listesini saklamak için En İyi yöntemde de ortaya çıktı :
Diğer sistemlerde listenin serileştirilmiş bir PHP dizisinde saklandığını gördüm.
Ancak normalleşme eksikliği birçok şekilde ortaya çıkar.
Daha:
10. Çok fazla normalleştirme
Bu, önceki noktaya bir çelişki gibi görünebilir, ancak normalleştirme, birçok şey gibi, bir araçtır. Bu kendi başına bir amaç değil, bir amaçtır. Bence birçok geliştirici bunu unutuyor ve “araçlara” “son” gibi davranmaya başlıyor. Birim testi bunun en iyi örneğidir.
Bir keresinde, müşteriler için büyük bir hiyerarşiye sahip bir sistem üzerinde çalıştım:
Licensee -> Dealer Group -> Company -> Practice -> ...
böylece anlamlı veriler elde edebilmek için yaklaşık 11 masaya katılmak zorunda kaldınız. Çok ileri götürülen normalleşmenin iyi bir örneğiydi.
Daha da önemlisi, dikkatli ve denormalizasyonun büyük performans faydaları olabilir, ancak bunu yaparken gerçekten dikkatli olmalısınız.
Daha:
11. Özel yayların kullanılması
Özel ark, bir tablonun iki veya daha fazla yabancı anahtarla oluşturulduğu yaygın bir hatadır ve bunlardan sadece bir tanesi boş olamaz. Büyük hata. Birincisi, veri bütünlüğünü korumak çok daha zorlaşıyor. Sonuçta, referans bütünlüğünde bile, bu yabancı anahtarların iki veya daha fazlasının ayarlanmasını engelleyecek hiçbir şey yoktur (buna rağmen karmaşık kontrol kısıtlamaları).
Gönderen İlişkisel Veritabanı Tasarım Pratik Rehber :
Mümkün olan her yerde özel ark yapımına karşı şiddetle tavsiye ettik, bunun nedeni kod yazmak ve daha fazla bakım zorluğu yaratmak için garip olabilirler.
12. Sorgularda performans analizi yapmamak
Pragmatizm özellikle veritabanı dünyasında yüce hüküm sürer. İlkeleri bir dogma haline geldikleri noktaya bağlıyorsanız, büyük olasılıkla hata yaptınız. Yukarıdaki toplu sorguların örneğini ele alalım. Toplu sürüm "hoş" görünebilir, ancak performansı sıkıntılıdır. Performans karşılaştırması tartışmayı bitirmişti (ama bitmedi) ama daha da önemlisi: bu tür bilgisiz görüşlerin ilk etapta verilmesi cahil, hatta tehlikeli.
13. UNION ALL ve özellikle UNION yapılarına aşırı güvenme
SQL terimlerindeki bir BİRLİK sadece uyumlu veri kümelerini birleştirir, yani aynı tür ve sütun sayısına sahiptir. Aralarındaki fark, UNION ALL'un basit bir birleştirme olması ve mümkün olan her yerde tercih edilmesi gerektiğidir, oysa bir UNION örtük olarak çiftleri çıkarmak için bir DISTINCT yapacaktır.
DISTINCT gibi sendikaların da yeri var. Geçerli uygulamalar var. Ancak kendinizi, özellikle alt sorgularda çok şey yaparken bulursanız, muhtemelen yanlış bir şey yapıyorsunuzdur. Bu, kötü sorgu oluşturma veya sizi böyle şeyler yapmaya zorlayan kötü tasarlanmış bir veri modeli olabilir.
UNION'lar, özellikle birleştirme veya bağımlı alt sorgularda kullanıldığında, bir veritabanını sakatlayabilir. Mümkün olduğunca onlardan kaçınmaya çalışın.
14. Sorgularda VEYA koşullarını kullanma
Bu zararsız görünebilir. Sonuçta, AND'ler iyi. VEYA çok iyi olmalı mı? Yanlış. Temel olarak bir VE koşulu veri kümesini kısıtlarken bir VEYA koşulu onu büyütür , ancak optimizasyona uygun bir şekilde değil. Özellikle farklı OR koşulları kesişebildiğinde, optimize ediciyi sonuç üzerinde bir DISTINCT operasyonuna etkili bir şekilde zorlamaya zorladığında.
Kötü:
... WHERE a = 2 OR a = 5 OR a = 11
Daha iyi:
... WHERE a IN (2, 5, 11)
Şimdi SQL optimize ediciniz ilk sorguyu etkili bir şekilde ikinciye çevirebilir. Ama olmayabilir. Sadece yapma.
15. Veri modellerini yüksek performanslı çözümlere uyum sağlayacak şekilde tasarlamamak
Bunu ölçmek zor bir nokta. Genellikle etkisi ile gözlenir. Kendinizi nispeten basit görevler için gnarly sorgular yazarken bulursanız veya nispeten basit bilgiler bulmak için sorgular etkili olmazsa, muhtemelen zayıf bir veri modeliniz vardır.
Bazı açılardan bu nokta daha öncekileri özetlemektedir, ancak sorgu optimizasyonu gibi şeyler yapmanın genellikle ilk yapılması gerektiğinde ilk önce yapılması gereken bir uyarıcı masaldır. Her şeyden önce, performansı optimize etmeye çalışmadan önce iyi bir veri modeline sahip olduğunuzdan emin olmalısınız. Knuth'un dediği gibi:
Erken optimizasyon tüm kötülüklerin köküdür
16. Veritabanı İşlemlerinin Yanlış Kullanımı
Belirli bir işlem için tüm veri değişiklikleri atomik olmalıdır. Yani işlem başarılı olursa, tam olarak gerçekleşir. Başarısız olursa veriler değişmeden kalır. - 'Yarı bitmiş' değişiklik olasılığı olmamalıdır.
İdeal olarak, bunu başarmanın en basit yolu, tüm sistem tasarımının tüm veri değişikliklerini tek bir INSERT / UPDATE / DELETE deyimi aracılığıyla desteklemeye çalışmasıdır. Bu durumda, veritabanı motorunuzun otomatik olarak yapması gerektiği için özel bir işlem işlemeye gerek yoktur.
Bununla birlikte, herhangi bir işlem, verileri tutarlı bir durumda tutmak için bir birim olarak birden fazla ifade yapılmasını gerektiriyorsa, uygun İşlem Denetimi gereklidir.
Ayrıca, veritabanı bağlantı katmanınızın ve veritabanı motorunuzun bu bağlamda nasıl etkileşime girdiğine dikkat etmenizi öneririz.
17. 'Kümeye dayalı' paradigmayı anlamamak
SQL dili, belirli türdeki sorunlara uygun belirli bir paradigmayı izler. Çeşitli satıcıya özgü uzantılar buna rağmen, dil Java, C #, Delphi vb.
Bu anlayış eksikliği kendini birkaç şekilde gösterir.
Açık bir sorumluluk bölümü belirleyin ve her sorunu çözmek için uygun aracı kullanmaya çalışın.
Geliştiriciler tarafından yapılan temel veritabanı tasarımı ve programlama hataları
Bencil veritabanı tasarımı ve kullanımı. Geliştiriciler, veriyi diğer paydaşların ihtiyaçlarını dikkate almadan veritabanını genellikle kişisel kalıcı nesne deposu olarak görürler. Bu aynı zamanda uygulama mimarları için de geçerlidir. Kötü veritabanı tasarımı ve veri bütünlüğü, verilerle çalışan üçüncü tarafların işini zorlaştırır ve sistemin yaşam döngüsü maliyetlerini önemli ölçüde artırabilir. Raporlama ve YBS uygulama tasarımında zayıf bir kuzen olma eğilimindedir ve sadece sonradan düşünülerek yapılır.
Denormalize edilmiş verilerin kötüye kullanılması. Denormalize edilmiş verileri abartmak ve uygulama içinde tutmaya çalışmak veri bütünlüğü sorunları için bir reçetedir. Denormalizasyonu idareli kullanın. Bir sorguya birleştirme eklemek istememek, normalleştirme için bir bahane değildir.
SQL yazmaktan korkuyorum. SQL roket bilimi değildir ve aslında işini yapmakta oldukça iyidir. O / R eşleme katmanları, basit ve bu modele iyi uyan sorguların% 95'ini yapmakta oldukça iyidir. Bazen SQL işi yapmanın en iyi yoludur.
Dogmatic 'Saklı Yordam Yok' politikaları. Saklı yordamların kötü olup olmadığına bakılmaksızın, bu tür dogmatik tutumun bir yazılım projesinde yeri yoktur.
Veritabanı tasarımını anlamamak. Normalleştirme senin arkadaşın ve roket bilimi değil. Birleştirme ve kardinalite oldukça basit kavramlardır - eğer veritabanı uygulaması geliştirmeyle ilgileniyorsanız, onları anlamadığınız için hiçbir mazeret yoktur.
Aşırı kullanım ve / veya saklı prosedürlere bağımlılık.
Bazı uygulama geliştiricileri, saklı yordamları orta katman / ön uç kodunun doğrudan uzantısı olarak görür. Bu, Microsoft yığın geliştiricilerinde ortak bir özellik gibi görünüyor (ben birim, ancak büyüdüm) ve karmaşık iş mantığı ve iş akışı işleme gerçekleştiren birçok saklı yordam üretiyor. Bu başka bir yerde daha iyi yapılır.
Saklı yordamlar, bazı gerçek teknik faktörlerin (örneğin performans ve güvenlik) kullanımını gerektirdiğinin kanıtlandığı durumlarda yararlıdır. Örneğin, büyük veri kümelerinin toplanmasını / filtrelenmesini "verilere yakın" tutmak.
Son zamanlarda, iş mantığı ve kurallarının% 70'inin 1400 SQL Server saklı yordamında (kalan kullanıcı arabirimi olay işleyicilerinde) uygulandığı büyük bir Delphi masaüstü uygulamasının korunmasına ve geliştirilmesine yardımcı olmak zorundaydım. Bu, esasen TSQL'e etkili birim testi yapma, kapsülleme eksikliği ve zayıf araçların (Hata ayıklayıcılar, editörler) zorluğu nedeniyle bir kabustu.
Geçmişte bir Java ekibiyle çalışırken çabucak tam tersinin o ortamda bulunduğunu öğrendim. Bir Java Mimarı bana bir keresinde şöyle demişti: "Veritabanı kod değil veri içindir."
Bu günlerde saklı procları hiç dikkate almamanın bir hata olduğunu düşünüyorum, ancak yararlı faydalar sağladıkları durumlarda (varsayılan olarak değil) az miktarda kullanılmalıdırlar (diğer cevaplara bakın).
Bir numaralı sorun mu var? Sadece oyuncak veritabanlarında test ederler. Bu yüzden, veritabanı büyük olduğunda SQL'lerinin taranacağına dair bir fikirleri yoktur ve birisi gelip daha sonra düzeltmek zorundadır (duyabileceğiniz ses dişlerimin taşlanmasıdır).
Dizin kullanmamak.
İlişkili Alt Sorguların Neden Olduğu Düşük Performans
Çoğu zaman ilişkili alt sorgulardan kaçınmak istersiniz. Alt sorgu içinde, dış sorgudan bir sütuna başvuru varsa bir alt sorgu ilişkilendirilir. Bu olduğunda, alt sorgu döndürülen her satır için en az bir kez yürütülür ve ilişkili alt sorguyu içeren koşul uygulandıktan sonra başka koşullar uygulanırsa daha fazla yürütülür.
Anlaşılan örneği ve Oracle sözdizimini affedin, ancak diyelim ki mağaza bir günde son zamanlarda 10.000 ABD dolarından az satış yaptı.
select e.first_name, e.last_name
from employee e
where e.start_date >
(select max(ds.transaction_date)
from daily_sales ds
where ds.store_id = e.store_id and
ds.total < 10000)
Bu örnekteki alt sorgu, store_id tarafından dış sorgu ile ilişkilendirilir ve sisteminizdeki her çalışan için yürütülür. Bu sorgunun optimize edilmesinin bir yolu, alt sorguyu satır içi görünüme taşımaktır.
select e.first_name, e.last_name
from employee e,
(select ds.store_id,
max(s.transaction_date) transaction_date
from daily_sales ds
where ds.total < 10000
group by s.store_id) dsx
where e.store_id = dsx.store_id and
e.start_date > dsx.transaction_date
Bu örnekte, from yan tümcesindeki sorgu artık bir satır içi görünümdür (yine bazı Oracle'a özgü sözdizimi) ve yalnızca bir kez yürütülür. Veri modelinize bağlı olarak, bu sorgu muhtemelen çok daha hızlı yürütülür. Çalışan sayısı arttıkça ilk sorgudan daha iyi performans gösterecektir. Az sayıda çalışan ve çok sayıda mağaza (ve belki de mağazaların çoğunda hiç çalışanı bulunmamışsa) ve daily_sales tablosu store_id'de dizine eklenmişse ilk sorgu aslında daha iyi performans gösterebilir. Bu olası bir senaryo değildir, ancak ilişkili bir sorgunun bir alternatiften daha iyi nasıl performans gösterebileceğini gösterir.
Küçük geliştiricilerin alt sorguları birçok kez ilişkilendirdiklerini gördüm ve genellikle performans üzerinde ciddi bir etkisi oldu. Bununla birlikte, ilişkili bir alt sorguyu kaldırırken , performansı daha da kötüleştirmediğinizden emin olmak için önce ve sonra açıklama planına baktığınızdan emin olun.
"Gerçek" bir veritabanı yerine Access'i kullanma. SQL Express , MySQL ve SQLite gibi çok daha iyi çalışacak ve ölçeklendirilecek çok sayıda küçük ve hatta ücretsiz veritabanı vardır . Uygulamaların genellikle beklenmedik şekillerde ölçeklendirilmesi gerekir.
(Büyük miktarlarda) veri depolamak için Excel'i kullanma.
Binlerce satır tutan ve birden çok çalışma sayfası kullanan şirketler gördüm (önceki Excel sürümlerinde 65535 satır sınırı nedeniyle).
Excel raporlar, veri sunumu ve diğer görevler için çok uygundur, ancak veritabanı olarak ele alınmamalıdır.
Eklemek istiyorum: Yüksek performans kod üzerinde "Zarif" kodu tercih. Veritabanlarına karşı en iyi çalışan kod genellikle uygulama geliştiricisinin gözünde çirkin.
Erken optimizasyon konusunda bu saçmalıklara inanmak. Veritabanları, özgün tasarımdaki ve sonraki geliştirmelerdeki performansı dikkate almalıdır. Performans, veritabanı tasarımının% 50'sidir (% 40 veri bütünlüğü ve son% 10 güvenlik). Gerçek kullanıcılar ve gerçek trafik veritabanına yerleştirildikten sonra aşağıdan yukarıya doğru oluşturulmayan veritabanları kötü performans gösterecektir. Erken optimizasyon, optimizasyon olmadığı anlamına gelmez! Bu, daha kolay bulduğunuz için neredeyse her zaman kötü performans gösterecek bir kod yazmanız gerektiği anlamına gelmez (örneğin, imleçler, başka bir şey başarısız olmadıkça üretim veritabanında asla izin verilmemelidir). Bu, ihtiyacınız olana kadar son performansın biraz sıkılmasına bakmanıza gerek olmadığı anlamına gelir. Veritabanlarında neyin daha iyi performans göstereceği hakkında çok şey bilinir,
Parametreli sorgular kullanılmıyor. SQL Injection'ı durdurmada oldukça kullanışlıdır .
Bu, başka bir cevapta bahsedilen girdi verilerinin sterilize edilmemesinin spesifik bir örneğidir.
Geliştiriciler yuvalanmış select deyimlerini kullandığında veya hatta bir sorgunun "SELECT" bölümündeki bir select deyiminin sonucunu döndürdüğünde nefret ediyorum.
Aslında burada başka bir yerde görmüyorum şaşırdım, belki de göz ardı, @adam benzer bir sorun belirtilmiş olmasına rağmen.
Misal:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
Bu senaryoda, MyTable 10000 satır döndürürse, sonuç, ilk sorgu artı her sonuç satırı için diğer tabloların her birini bir kez sorgulaması gerektiği için sorgunun sadece 20001 sorgusunu çalıştırdığı gibidir.
Geliştiriciler bu çalışmayla sadece birkaç satır veri döndürdükleri ve alt tabloların genellikle çok az miktarda verilere sahip olduğu bir geliştirme ortamında kurtulabilirler, ancak bir üretim ortamında bu tür bir sorgu daha fazla katlanabilir veriler tablolara eklenir.
Daha iyi (mutlaka mükemmel olmayan) bir örnek şöyle olacaktır:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Bu veritabanı en iyileştiriciler ana tablodan her kayıt yeniden sorgulamak yerine, birlikte veri karıştırmak sağlar ve genellikle bu sorunun oluşturulduğu yerde kodu düzeltmek zorunda kaldığımda bulmak, genellikle sorgu hızını% 100 veya aynı anda CPU ve bellek kullanımını azaltır.
SQL tabanlı veritabanları için:
Üretim veritabanındaki bazı sorunları gidermeden yedek almamak.
Saklı yordamlarda depolanan nesnelerde (tablolar, görünümler gibi) DDL komutlarını kullanma.
Depolanmış proc kullanma korkusu veya ORM sorgularını kullanmak için daha verimli / uygun olan yerlerde kullanma korkusu.
ORM sorgunuzun neye dönüştürüldüğünü tam olarak anlatabilecek ve dolayısıyla mantığı doğrulayabilecek ve hatta ORM kullanmadığınızda hata ayıklayabileceğiniz bir veritabanı profillerinin kullanımını yok saymak.
Doğru normalleştirme seviyesini yapmamak . Verilerin çoğaltılmadığından ve verileri gerektiği gibi farklı bir şekilde böldüğünüzden emin olmak istiyorsunuz. Ayrıca , performansı olumsuz etkileyeceği için normalleştirmeyi çok fazla takip etmediğinizden emin olmanız gerekir .
Veritabanına sadece bir depolama mekanizması (örn. Yüceltilmiş koleksiyonlar kütüphanesi) olarak davranılması ve dolayısıyla bunların uygulamalarına tabi tutulması (verileri paylaşan diğer uygulamaları göz ardı ederek)
1 - Gereksiz olarak, burada kullanılan bir dizinin değerinin kullanılmadığı bir değerde bir işlev kullanmak.
Misal:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
onun yerine
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
Ve daha az ölçüde: İhtiyacı olan değerlere fonksiyonel indeksler eklememek ...
2 - Verilerin geçerliliğini sağlamak için kontrol kısıtlamaları eklememek. Kısıtlamalar sorgu optimize edici tarafından kullanılabilir ve GERÇEKTEN değişmezlerinize güvenebileceğinizden emin olmanıza yardımcı olur. Onları kullanmamak için hiçbir neden yok.
3 - Saf tembellik veya zaman baskısı dışında tablolara normalleştirilmemiş sütunlar ekleme. İşler genellikle bu şekilde tasarlanmaz, ancak buna dönüşür. Nihai sonuç, başarısız olmadan, gelecekteki evrimlerdeki kayıp veri bütünlüğünden ısırdığınızda karışıklığı temizlemeye çalışan bir ton çalışmadır.
Bunu düşünün, veri içermeyen bir tabloyu yeniden tasarlamak çok ucuzdur. Bütünlüğü olmayan birkaç milyon kayıt içeren bir tablo ... yeniden tasarlamak o kadar ucuz değil. Böylece, sütun veya tablo oluştururken doğru tasarımı yapmak maça itfa edilir.
4 - kendi başına veritabanı hakkında çok fazla değil, ama gerçekten can sıkıcı. SQL'in kod kalitesine önem vermemek. SQL'inizin metinde ifade edilmesi, mantığı dize işleme algoritmalarının yığınlarında gizlemeyi TAMAM yapmaz. SQL'i, diğer programcı tarafından okunabilecek şekilde metne yazmak mükemmel bir şekilde mümkündür.
Bu daha önce söylendi, ancak: dizinler, dizinler, dizinler . Ben sadece küçük bir profilleme (hangi tabloların çok vurulduğunu görmek için) yaparak ve daha sonra bu tablolara bir dizin ekleyerek düzeltildi kötü performans gösteren kurumsal web uygulamaları birçok durumda gördüm. Bu, SQL yazma bilgisi için bile fazla bir şey gerektirmez ve getirisi çok büyüktür.
Veba gibi veri çoğaltmasından kaçının. Bazı insanlar küçük bir çoğaltmanın zarar görmeyeceğini ve performansı artıracağını savunuyorlar. Hey, DBA'lar bile neler olup bittiğini bilmeyecek kadar soyut olana kadar şemanıza Üçüncü Normal Form'a işkence yapmanız gerektiğini söylemiyorum. Yalnızca bir ad kümesi, posta kodu veya gönderim kodu kopyaladığınızda, kopyaların eninde sonunda birbirleriyle senkronize olmayacağını anlamanız yeterlidir. Olacaktır. Ve sonra haftalık bakım komut dosyasını çalıştırırken kendinizi tekmeliyor olacaksınız.
Ve son olarak: açık, tutarlı, sezgisel bir adlandırma kuralı kullanın. İyi yazılmış bir kod parçasının okunması gerektiği gibi, iyi bir SQL şeması veya sorgusu okunabilir olmalı ve yorum yapmasa bile pratikte ne yaptığını size söylemelidir . Masalarda bakım yapmanız gerektiğinde altı ay içinde kendinize teşekkür edeceksiniz. "SELECT account_number, billing_date FROM national_accounts"
"ACCNTNBR, NTNLACCTS'DEN BILLDAT SEÇ" seçeneğinden çok daha kolaydır.
Yirmi yıl içinde gördüğüm en yaygın hata: önceden planlama yapmak değil. Birçok geliştirici bir veritabanı ve tablolar oluşturur ve ardından uygulamaları geliştirirken tabloları sürekli olarak değiştirir ve genişletir. Sonuç genellikle karışıklık ve verimsizdir ve daha sonra temizlenmesi veya basitleştirilmesi zordur.
a) Dize
içindeki kodlama sorgu değerleri b) Veritabanı sorgu kodunu bir Windows Forms uygulamasındaki "OnButtonPress" eylemine ekleme
İkisini de gördüm.
Bu alanlarda herhangi bir resmi telkin bulunmadığında DBA ve veri modelcisi / tasarımcısı olduklarını düşünmek.
Projelerinin bir DBA gerektirmediğini düşünmek, çünkü bu şeylerin hepsi kolay / önemsizdir.
Veritabanında yapılması gereken iş ile uygulamada yapılması gereken işler arasında doğru bir şekilde ayrım yapmamak.
Yedekleri doğrulamıyor veya yedeklemiyor.
Ham SQL kodlarına gömülüyor.
İşte Scott Walz'un ' Klasik Veritabanı Geliştirme Hataları ve bunları aşmanın beş yolu ' adlı videoya bir bağlantı
Veritabanlarının eşzamanlılık modelini ve bunun gelişimi nasıl etkilediğini anlamamak. Bundan sonra dizinler eklemek ve sorguları değiştirmek kolaydır. Ancak, etkin noktalar, kaynak çekişmesi ve doğru işlem (doğru okuduğunuzun hala geçerli olduğu varsayılarak!) İçin uygun bir şekilde düşünülmeden tasarlanan uygulamalar, daha sonra düzeltmek için veritabanı ve uygulama katmanında önemli değişiklikler gerektirebilir.
Bir DBMS'nin kaputun altında nasıl çalıştığını anlamamak.
Bir debriyajın nasıl çalıştığını anlamadan bir çubuğu düzgün bir şekilde süremezsiniz. Ve sadece sabit diskinizdeki bir dosyaya gerçekten yazdığınızı anlamadan bir Veritabanını nasıl kullanacağınızı anlayamazsınız.
özellikle:
Kümelenmiş Bir Endeksin ne olduğunu biliyor musunuz? Şemanızı tasarlarken bunu düşündünüz mü?
Dizinleri doğru şekilde nasıl kullanacağınızı biliyor musunuz? Bir endeks nasıl yeniden kullanılır? Bir Kaplama Endeksinin ne olduğunu biliyor musunuz?
Harika, dizinleriniz var. Dizininizdeki 1 satır ne kadar büyük? Çok fazla veriniz olduğunda dizin ne kadar büyük olacak? Bu kolayca belleğe sığacak mı? Eğer olmazsa endeks olarak işe yaramaz.
MySQL'de EXPLAIN kullandınız mı? Harika. Şimdi kendinize karşı dürüst olun: Gördüklerinizin yarısını bile anladınız mı? Hayır, muhtemelen söylemedin. Bunu düzeltin.
Sorgu Önbelleğini anlıyor musunuz? Sorguyu erişilemez yapan şeyin ne olduğunu biliyor musunuz?
MyISAM kullanıyor musunuz? Tam metin aramasına ihtiyacınız varsa, MyISAM's zaten saçmalık. Sfenks kullanın. Ardından Inno'ya geçin.