Evet bu korkunç bir fikir.
Gitmek yerine:
SELECT Deal.Name, DealCategory.Name
FROM Deal
INNER JOIN
DealCategories ON Deal.DealID = DealCategories.DealID
INNER JOIN
DealCategory ON DealCategories.DealCategoryID = DealCategory.DealCategoryID
WHERE Deal.DealID = 1234
Şimdi gitmelisin:
SELECT Deal.ID, Deal.Name, DealCategories
FROM Deal
WHERE Deal.DealID = 1234
Ardından, virgül listesini bireysel numaralara bölmek için uygulama kodunuzda bir şeyler yapmanız ve ardından veritabanını ayrı olarak sorgulamanız gerekir:
SELECT DealCategory.Name
FROM DealCategory
WHERE DealCategory.DealCategoryID IN (<<that list from before>>)
Bu tasarım antipattern, ilişkisel modellemenin tam olarak yanlış anlaşılmasından kaynaklanmaktadır (Tablolardan korkmak zorunda değilsiniz. Tablolar arkadaşlarınızdır. Bunları kullanın) veya tuhaf bir şekilde yanlış yönlendirilmiş bir inancı virgülle ayrılmış bir listeye alıp bölmek daha hızlı Uygulama kodunda bir link tablosu eklemek olduğundan ( asla değil ). Üçüncü seçenek, yabancı anahtarlar ayarlayabilmeleri için SQL ile yeteri kadar güvenilmez / yetkin olmalarıdır, ancak bu durumda, ilişkisel bir modelin tasarımı ile ilgisi olmamalıdır.
SQL Antipatterns ( Karwin , 2010), bu antipattern'e ('Jaywalking' adını verdiği) 15-23. Sayfaların tamamını vermektedir. Ayrıca, yazar SO'da benzer bir soru yayınlamıştır . Not ettiği anahtar noktalar (bu örneğe uygulandığı gibi):
- Belirli bir kategorideki tüm anlaşmaları sorgulamak oldukça karmaşıktır (bu sorunu çözmenin en kolay yolu düzenli bir ifadedir, ancak düzenli bir ifade kendi başına bir sorundur).
- Yabancı anahtar ilişkileri olmadan referans bütünlüğünü uygulayamazsınız. DealCategory silmek nr. # 26, sonra, uygulama kodunuzda, # 26 kategorisine referansları aramak için her bir anlaşmayı gözden geçirmeli ve silmelisiniz. Bu, veri katmanında ele alınması gereken bir şeydir ve uygulamanızda ele almak zorunda kalmak çok kötü bir şeydir .
- Agrega sorgular (
COUNT
, SUM
vb), yine, 'neredeyse imkansız' to 'karmaşık' değişir. Geliştiricilerinize, bu kategorideki fırsatların sayısının yer aldığı, size tüm kategorilerin listesini nasıl alabileceklerini sorun. Düzgün bir tasarıma sahip, dört satır SQL.
- Güncellemeler çok daha zorlaşıyor (yani beş kategoride yapılan bir anlaşmanız var, ancak ikisini kaldırmak ve üç tane daha eklemek istiyorsunuz). Bu, uygun bir tasarıma sahip üç SQL hattıdır.
- Sonunda
VARCHAR
liste uzunluğu sınırlamaları ile karşılaşacaksınız. 4000 karakterden fazla virgülle ayrılmış bir listeniz olsa da, canavarın cehennem kadar yavaş olacağına dair bir ihtimal var.
- Bir listeyi veritabanından çıkarmak, bölmek ve ardından başka bir sorgu için veritabanına geri dönmek, aslında bir sorgudan daha yavaştır.
TLDR: Temelde kusurlu bir tasarım, iyi ölçeklenmeyecek, en basit sorgulara bile ek bir karmaşıklık getirecek ve kullanıma hazır hale getirmesini yavaşlatacak.