Etiketleri bir veritabanında depolamanın en etkili yolu nedir?


138

Ben bir stackoverflow kullanır benzer web sitemde bir etiketleme sistemi uyguluyorum, benim sorum - arama ve filtre böylece böylece depolamak için en etkili yolu nedir?

Benim fikrim şudur:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Bu çok yavaş mı? Daha iyi bir yol var mı?


2
Daha önce sorulan sorular: stackoverflow.com/questions/20856/…
DrBloodmoney

1
2016 itibarıyla Solr veya Elasticsearch kullanın
Charles L.

Yanıtlar:


189

Bir öğede çok sayıda etiket olacaktır. Ve bir etiket birçok öğeye ait olacak. Bu bana, çoktan çoğa engelin üstesinden gelmek için muhtemelen bir aracı masaya ihtiyacınız olacağını ima ediyor.

Gibi bir şey:

Tablo: Öğeler
Sütunlar: Item_ID, Item_Title, İçerik

Tablo: Etiketler
Sütunlar: Tag_ID, Tag_Title

Tablo: Items_Tags
Sütunları: Item_ID, Tag_ID

Web uygulamanız delicesine popüler ve yolda denormalize ihtiyacı olabilir, ama suları çok erken çamurlu anlamsız.



tagGroup gibi bir şey varsa, nasıl işlenir örneğin etiketler kategoriler halinde gruplandırılır örneğin: Programlama dilleri: c #, vb, pearl. İşletim Sistemi: windows7, dos, linux etc
Thunder

4
@Thunder: bir etiketin yalnızca bir kategoriye ait olabileceğini varsayarsak, category_id ve category_name öğelerinden oluşan bir TagCategory tablosu oluştururdum. Oradan, Etiketler tablosuna bir category_id alanı eklemek ve bu bir katılmak gerçekleştirmek.
Simon Scarfe

114

Veritabanı şemalarını etiketleme hakkında Philipp Keller'in blog gönderilerini okumalısınız. O hem bir kaç çalışır ve onun sonuçlarını rapor eder yaygın sorguları inşa kolaylığı açısından ve performans açısından . Etiket sayısı, etiketli öğe sayısı ve öğe başına etiket sayısı tüm faktörlerdi. Görevler 2005 yılından; O zamandan beri herhangi bir güncellemenin farkında değilim.


19
Bence bu en iyi cevap. Diğer cevapların çoğu gibi varsayımlardan ziyade gerçek testlere ve araştırmalara dayanmaktadır.
Cristian Vrabie

4
Yanıttaki bağlantılar işe yaramıyor gibi görünüyor. Vtidter.blogspot.be/2014/02/database-schema-for-tags.html
Christophe Herreman

8

Aslında, etiketler tablosunun normalleştirilmesinin ölçeğe bağlı olarak daha iyi bir yol olabileceğine inanıyorum.

Bu şekilde, etiketler tablosunda tagid, itemid, tagname bulunur.

Yinelenen tagnames alırsınız, ancak belirli öğeler için çok daha fazla etiket ekleme / kaldırma / düzenleme yapar. Yeni bir etiket oluşturmanız, eskisinin tahsisini kaldırmanız ve yeni bir etiket tahsis etmeniz gerekmez, sadece tagname'i düzenlersiniz.

Bir etiket listesi görüntülemek için DISTINCT veya GROUP BY kullanın ve elbette bir etiketin kaç kez kolayca kullanıldığını sayabilirsiniz.


4

Biraz standart olmayan şeyler kullanmak sakıncası yoksa, Postgres sürüm 9.4 ve üstü JSON metin dizisi türünde bir kayıt saklama seçeneğine sahiptir.

Şemanız:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Daha fazla bilgi için Josh Berkus'un bu mükemmel yayınına bakın: http://www.databasesoup.com/2015/01/tag-all-things.html

Performans için ayrıntılı olarak karşılaştırıldığında daha çeşitli seçenekler vardır ve yukarıda önerilen seçenek genel olarak en iyisidir.


2

Etiketler ve öğeler arasında çoktan çoğa ilişkilere sahip olduğumuzdan, etiketler <=> öğe ilişkilendirmelerini depolamak için aracı üçüncü tablo kullanmanızı öneririm, yani bir öğe birden çok etiketle ilişkilendirilebilir ve bir etiket birden çok öğe ile ilişkilendirilebilir. HTH, Valf.


1

Bir soruda verdiğiniz verilere dayanarak yavaşlık hakkında gerçekten konuşamazsınız. Ve bu gelişim aşamasında performans hakkında çok fazla endişelenmeniz gerektiğini düşünmüyorum. Buna erken optimizasyon denir .

Ancak, Etiketler tablosuna Tag_ID sütununu eklemenizi öneririm. Her tablonun bir kimlik sütunu olması genellikle iyi bir uygulamadır.


1

Alan bir sorun olacaksa, etiketin metnini saklamak için 3. tablo Etiketleri'ne (Tag_Id, Başlık) sahip olun ve ardından Etiketler tablonuzu (Tag_Id, Item_Id) olarak değiştirin. Bu iki değer de benzersiz bir bileşik birincil anahtar sağlamalıdır.


0

Öğeler "Kimlik" alanına sahip olmalı ve Etiketler "Kimlik" alanına sahip olmalıdır (Birincil Anahtar, Kümelenmiş).

Sonra ItemID / TagID ara tablo yapmak ve " Perfect Index " koymak .

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.