Veritabanı yapısı Önerileri Gerekli

8 Cevap php

Im şu anda bir ürün kataloğu içeren bir site üzerinde çalışan. Bunu yapmak için en iyi nasıl tavsiye için arıyorum ben veritabanı tasarımı biraz yeni duyuyorum. Ben "çok çok" veya anlamak yüzden ilişkisel veritabanı tasarımı ile tanıdık vb (üniversitede iyi bir db sınıf aldı) "için bir çok". İşte bir öğe olarak kategorize olabilir ne bir örnek:

Propeller -> aircraft -> wood -> brand -> product.

Bunun yerine ben bugüne kadar ne yazmaya çalışıyorum, sadece ben phpmyadmin tasarımcı özelliği yaratılan bu görüntünün hızlı bir göz atın.

alt text

Ben kategori "odun" da pervane altında kullanılan olacağını fark kadar Şimdi, bu, ince ve züppe görünüyordu -> sürat teknesi -> (ahşap). Bu "ağaç" Ben farklı bir ebeveyn altında kullanmak istediğiniz her zaman yeniden zorunda olacağı anlamına gelecektir. Bu dünyanın sonu değil, ama ben bu konuda gitmek için daha iyi bir yolu olup olmadığını bilmek istiyordu.

Ayrıca, onun ihtiyaçları değiştikçe kadar müşteri kendi katalog organize mümkün olduğunca dinamik bu şeyi tutmaya çalışıyorum.

* Düzenleme. Sadece bir "etiket" tablosu oluşturma hakkında düşünüyordum. Bu yüzden pek çok ürün için 1 tag "odun" veya "metal" veya "50Inch" atayabilirsiniz. Ben hala ana kategoriler için bir ebeveynlik türü şey devam edecek, ancak bu şekilde kategoriler çok derin gitmek ve tekrarı orada olmaz olmazdı.

8 Cevap

First, the user interface: kullanıcı olarak ben hate bir strictly hierarchical şekilde düzenlenen bir katalogda bir ürün aramak için. Ben bir "egzotik" bir ürün, en azından benim için (sadece bir kategorize olduğunu keşfetmek için "umut verici" kategoriler keşfetmek zaman harcamak bana ve bu kuvvet nedir alt-alt-alt-alt ... kategori hatırlıyorum asla ) garip bir yol.

Ne Kevin Peno göstermektedir iyi sitesi ve faceted browsing . As Marcia Bates, After the Dot-Bomb: Getting Web Information Retrieval Right This Time in yazdığı ".. faceted classification is to hierarchical classification as relational databases are to hierarchical databases. .." olarak bilinir .

Özünde, yönlü arama kullanıcıların tercih ne olursa olsun "faset" den başlayarak katalog arama ve onları arama boyunca diğer yönü seçerek bilgileri filtrelemek izin verir. Etiket sistemleri genellikle nasıl tasavvur edildiğini aksine, hiçbir hiyerarşik bu yönleriyle bazı organize engeller, unutmayın.

Hızla yönlü arama tüm hakkında ne olduğunu anlamak için vardır some demos to explore at The Flamenco Search Interface Project - Search Interfaces that Flow.

(Anladığım kadarıyla) Second, the application logic: ne Manitra önermektedir de iyi bir tavsiyedir, yani ayıran nodes ve links bir ağaç / grafiğin farklı ilişkiler. O transitive closure of a directed acyclic graph (DAG) (ulaşabilirlik ilişki) olarak bilinir (ancak, çok daha iyi bir sezgisel adıdır) "ata masa" dediği. Manitra dediği gibi performans ötesinde, bu, büyük ölçüde sorguları basitleştirmek.

Güncellemeleri gerçek zamanlı ve artan, bir toplu iş tarafından periyodik değil böylece But Ben, böyle "ata masada" (geçişli kapanma) için view öneririz. Orada SQL kodu (ama belirli DBMSes biraz adapte olması gerektiğini düşünüyorum) I query language for graph sets: data modeling question benim cevap belirtilen gazetelerde. (. - PostScript PS) Özellikle, Maintaining Transitive Closure of Graphs in SQL bakmak.

Products-Categories relationship

Manitra ilk nokta da, vurgu değer.

Ne söylediğini ürünler ve kategoriler arasında çok-çok ilişkisi var olmasıdır. Yani: Her ürün bir veya daha fazla kategoride olabilir ve her kategoride sıfır veya daha fazla ürün olabilir.

Ilişki değişkenler (relvars) Ürünler ve Kategoriler verilen bu ilişki ile bir relvar PC olarak en az P # niteliklerini ve ilgili ürün ve kategorileri ile bir yabancı anahtar ilişkileri C #, yani ürün ve kategori numaraları (Identifier), örneğin, temsil edilebilir sayılar.

Bu kategoriler 'hiyerarşileri yönetimi tamamlayıcıdır. Tabii ki, bu sadece bir tasarım eskiz.

On faceted browsing in SQL

"Yönlü tarama" uygulamak için yararlı bir kavram relational division, ya da, hatta, relational comparisons (bağlantılı sayfanın altına bakınız). Yani Bir kullanıcı (faset navigasyon) bir (tabii ki, kategoriler aksi seçerek, not Tüm dışlayan tahmin ediliyor gibi kategorilerde sadece ürün elde seçilen kategorilerde (artan) listesinde PC (Ürün Kategorileri) bölünmesi iki kategori tek) sıfır ürünler elde edecektir.

SQL tabanlı VTYS genellikle bu operatörleri (bölünme ve karşılaştırmalar) eksikliği, bu yüzden ben / bunları tartışmak uygulayan bazı ilginç yazılara aşağıda veriyoruz:

ve böylece ...

Ben burada ayrıntılarına girmeyeceğim ama kategoriler hiyerarşileri ve faset tarama arasındaki etkileşim özel bir bakıma ihtiyacı vardır.

A digression on "flatness"

Ben kısaca Pras, Managing Hierarchical Data in MySQL ile bağlantılı makale baktı, ama ben girişte bu birkaç satır sonra okuma durdu:

Introduction

Most users at one time or another have dealt with hierarchical data in a SQL database and no doubt learned that the management of hierarchical data is not what a relational database is intended for. The tables of a relational database are not hierarchical (like XML), but are simply a flat list. Hierarchical data has a parent-child relationship that is not naturally represented in a relational database table. ...

Bu 8 koordinatları (üçüz) tarafından tespit edilecek, demek P1 (x1, y1, z1: ​​ilişkilerin düzlüğüne bu ısrarı just nonsense, bir three dimensional Cartesian coordinate system bir küp hayal olduğunu anlamak için ), P2 (x2, y2, z2), ..., P8 (x8, y8, z8) [onlar gerçekten bir küp temsil ettiğini, bu nedenle burada bu koordinatlara kısıtlamaları ile ilgili değildir].

Şimdi, biz bir ilişki değişken içine koordinatları (puan) bu seti koyacağız ve biz bu değişkeni isim olacak Points. Yapacaklarımız aşağıda bir tablo olarak Points ve represent ilişki değeri:

Points|  x |  y |  z |
=======+====+====+====+
       | x1 | y1 | z1 |
       +----+----+----+
       | x2 | y2 | z2 |
       +----+----+----+
       | .. | .. | .. |
       | .. | .. | .. |
       +----+----+----+
       | x8 | y8 | z8 |
       +----+----+----+

Bu küp bir sekmeli şekilde temsil sadece eyleminde tarafından "dümdüz" ediliyor mu? Bir ilişki (değer) onun tablo temsili olarak aynı şey midir?

N ilişki niteliklerin sayısı ("sütun") bir n-boyutlu ayrık uzayda puan setleri değerleri gibi bir ilişki değişken varsayar. Bu ne anlama geliyor, bir n-boyutlu ayrık alanı için, "düz" olması? Sadece saçma, ben yukarıda yazdığım gibi.

Beni yanlış anlamayın, bu SQL bir kötü tasarlanmış bir dil olduğunu ve SQL tabanlı DBMSes huyların ve eksiklikleri dolu olduğu kesinlikle doğrudur (NULL, fazlalık, ...), özellikle kötü olanlar, DBMS-olarak- aptal-mağaza tipi (hiçbir başvuru kısıtlamaları, hiçbir bütünlüğü kısıtlar, ...). Ama tersine, ilişkisel veri modeli sınırlamaları hayaller ile ilgisi var daha onlar ondan çevirmek ve kötü sonuçtur.

Özellikle, ilişkisel veri modeli, bunu anlamak kez, yukarıda bahsettiğim yayınlanan makalelere referanslar ayrıntılı olarak, hangi yapı, hatta hiyerarşileri ve grafikleri temsil hiçbir sorun teşkil etmektedir. Hatta SQL can, daha iyi bir şey eksik, eksiklikleri geçiştirmeye eğer.

On the "The Nested Set Model"

I that article geri kalanını yağsız ve ben böyle mantıksal tasarımı ile özellikle etkilendim değilim: iki farklı oluşumları, nodes ve links geçinip önerir, içine bir ilişkisi ve bu muhtemelen beceriksizlik neden olur. Ama ben daha iyice olduğunu tasarımını analiz eğimli değilim, üzgünüm.


EDIT: Stephan Eggermont ki "The flat list model is a problem. It is an abstraction of the implementation that makes performance difficult to achieve. ...", aşağıda yorumlarda, itiraz etti.

Şimdi, benim açımdan, tam, yani:

  1. Bu "Düz liste model" olan bir fantasy: Bir yatıyordu sırf tablolar ("düz listeler") olarak ilişkileri ilişkileri "düz listeler" (bir "nesne" ve olduğu anlamına gelmez (temsil) onun temsilleri) aynı şey değildir;
  2. mantıksal bir temsilidir (ilişki) ve fiziksel depolama detayları (yatay veya dikey ayrıştırma, sıkıştırma, indeksler (sağlamalarının, b + ağaç, r-ağacı, ...), kümeleme, bölümleme vb) farklıdır; ilişkisel veri modeli noktalarından biri (RDM) (kullanıcı ve DBMSes bir gerçeklenimcileri hem avantajları ile) "fiziksel" modeli mantıksal ayrılabilmesi için;
  3. performans (EGGERMONT sözleri, logical-physical confusion klasik bir örneğidir) fiziksel depolama ayrıntıları (uygulama) ve not mantıksal gösterimi arasında doğrudan bir sonucudur.

RDM model, herhangi bir şekilde uygulamaları kısıtlama yoktur; tek tek uygun görmek gibi dizilerini ve ilişkileri uygulamak için ücretsizdir. İlişkileri not necessarily dosya ve küpe bir dosya vardır not necessarily kayıtları vardır. Böyle yazışmalar bir aptal direct-image implementation olduğunu.

Ne yazık ki SQL tabanlı VTYS uygulamaları are, çok sık, aptal direkt görüntü uygulamaları ve çeşitli senaryolar kötü performansını acı - OLAP / ETL ürün var bu eksikliklerini gidermek için.

Bu yavaş yavaş değişiyor. Sonunda bu temel tuzaktan kaçınmak ticari ve özgür yazılım / açık kaynak uygulamaları vardır:

/ Tabii ki, gelin bir "optimal" fiziksel depolama tasarımı var olmalıdır not olduğunu, ama ne olursa olsun fiziksel depolama tasarım declarative language ilişkisel cebir dayalı güzel tarafından abstracted edilebilir taşı (- "prolog to SQL converter" sorusuna cevabım görmek örneğin Prolog gibi) bir mantık programlama dili üzerinde daha doğrudan veya (ve SQL bir bad örnektir). İyi bir DBMS veri erişim istatistikleri (ve / veya kullanıcı ipuçları) dayalı, on-the-fly fiziksel depolama tasarımını değiştirmek gerekir.

Son olarak, EGGERMONT en açıklamada deyimi "The relational model is getting squeeezed between the cloud and prevayler." başka saçmalık ama ben burada bir çürütme veremem, bu yorum çok uzun zaten.

Eğer veritabanında hiyerarşik bir kategori modelini oluşturmadan önce, sorunları ve çözüm (iç içe setlerini kullanarak) açıklamaktadır this article bakabilirsiniz.

Çok iyi ölçek değildir, basit bir parent_category_id kullanarak, özetlemek ve ölçülebilir SQL sorguları yazma zor bir zaman olacak. Sorunun cevabı diğer setleri iç içe olduğu setleri gibi pek çok-çok kategori modeli görselleştirmek yapmak iç içe setleri kullanmaktır.

Eğer kategorilerde birden çok ana kategoriye sahip olmak istiyorsanız, o zaman sadece ilişki "birçok one" yerine bir ilişkinin bir "çok çok" bulunuyor. Kategori ve kendisi arasında bir köprü masa koymak gerekir.

Ancak, ben bu ne istediğiniz şüpheliyim. Ben kategorisinde arıyorum varsa Aircraft > Wood sonra Boating > Wood öğeleri görmek istemem. Onlar farklı öğeleri içerdiğinden iki Wood kategorisi vardır.

My suggestions

  • Bir ürünün birçok hiyerarşi düğüm görüntülenebilir böylece Ürün ve Kategori arasında çok-çok ilişkisi koymak (ebay kullanılan, sourceforge ...)
  • kategori hiyerarşi tutmak

Performance on the category hierarchy

Lütfen kategori hiyerarşisi derinliği ise, o zaman bir "Atalar" tablosu oluşturabilir. Bu tablo bir toplu çalışma ile elde edilecek ve irade içerir:

  • ChildID (bir kategori id)
  • AncestorId (kendi üst, büyük ebeveyn ... tüm ataları kategorinin id)

Bu demektir ki 3 kategori varsa: 1-Pervane> 2-uçak> 3-wood

Sonra Ata tablo içerecektir:

ChildId  AncestorId
1        2
1        3
2        3

Bu Category1 tüm çocukları var demektir, sadece 1 sorgu gerekir ve iç içe sorgu yapmak zorunda değilsiniz. Bu arada bu size kategori hiyerarşisinin derinliği ne olursa olsun değil çalışmak istiyorum.

Bu tabloya sayesinde, sadece 1 (onun çocuk ile) bir kategoriye karşı sorgu katılmak gerekir.

Eğer Atası tablo oluşturmak konusunda yardıma ihtiyacınız varsa, sadece bana bildirin.

Before you create a hierarchical category model in your database, take a look at this article which explains the problems and the solution (using nested sets).

To summarize, using a simple parent_category_id doesn't scale very well and you'll have a hard time writing performant SQL queries. The answer is to use nested sets which make you visualize your many-to-many category model as sets which are nested inside other sets.

Bu "birden fazla kategori" fikir "etiketleme" nasıl çalıştığını temelde olduğuna işaret değer olmalıdır. "Etiketleme" in, herhangi bir ürün birçok kategorileri için izin, istisna ile. Herhangi bir ürün birçok kategoride olması izin vererek, allow the customer tam yeteneği to start**ing **where they believe they need to start kendi arama filtre. Bu "turbojet motor" (veya ne olursa olsun) daha sonra, "uçaklar", sonra da "odun" tıklayarak olabilir. Ya da Wood ile arama başlatmak ve aynı sonucu alabilir.

Bu size büyük esneklik sağlar, ve customer will enjoy a better UX , yet still allow you to maintain the hierarchy structure. So, while the quoted answer suggests letting categories be M:N to categories, my suggestion is to allow products to have M:N categories instead. olacak

Tüm sonuç tüm çoğunlukla aynı olan, categories will have a natural hierarchy, but Bu will lend ile even greater flexibility.

Ben de bu iki katı bir hiyerarşi engellemez dikkat etmelisiniz. Sen çok kolayca (örn. sadece ilk sayfada kategoriler "arabalar", "uçaklar" ve "tekne" gösteren) Gerekli kod hiyerarşisini uygulamak olabilir. Sadece uzun vadede daha iyi yapmak olabilir, iş mantığı için "strctness" hareket eder.

EDIT: I just realized that you vaguly mentioned this in your answer. I actually didn't notice it, but I think this is along the lines you would want to do instead. Otherwise you are mixing two hierarchy systems into your program without much benefit.

Ben daha önce yaptım. Ben (ürünleri çok-çok ilişkisi tablo) etiketleme ile başlayan öneririz. Size etiketleri (ağaç, ya da iç içe setleri, ya da ne olursa olsun) sizin ürünlere çok daha kolay üstünde bir hiyerarşi ilişki kurabilirsiniz. Etiketleme nispeten serbest biçimli olduğundan, bu da size, insanların doğal olarak kategorize ve daha sonra belirli beklenen davranışları codify izin yeteneği verir.

Örneğin, 2009-Kasım-Special gibi özel etiketleri vardı. Bu gibi herhangi bir ürünün o ay için ön sayfasında özel olarak göstermek için uygun oldu. Yani biz sadece mevcut etiket sistemini kullanılan ön sayfaya dönen özel işlemek için özel bir sistem inşa etmek yoktu. Daha sonra bu vb tüketicilerin, gelenler etiketlerini gizlemek için geliştirilmiş olabilir

Eğer karşılamak için daha fazla esneklik veren bir etiketleme sistemi içinde yeniden dağıtımın karmaşık veritabanı zorluklar veya EAV, tüm kabuslar olmaksızın nispeten karmaşık bir sınıflandırma ve drilldowns yapmak için izin vermek için Nike: style: ahşap MFG Benzer şekilde, sizin gibi etiketleme önekleri kullanabilirsiniz kullanıcı beklentileri. Kullanıcıların veritabanı ve iş sahibi sandığınız gibi size farklı şekillerde ürünlerini gezinmek için bekliyor olabilir unutmayın. Etiketleme sistemini kullanarak size envanter veya satış takibi veya başka bir şey ödün vermeden alışveriş arabirimini etkinleştirmek yardımcı olabilir.

Ben kategori "odun" da pervane altında kullanılan olacağını fark kadar Şimdi, bu, ince ve züppe görünüyordu -> sürat teknesi -> (ahşap). Bu "ağaç" Ben farklı bir ebeveyn altında kullanmak istediğiniz her zaman yeniden zorunda olacağı anlamına gelecektir. Bu dünyanın sonu değil, ama ben bu konuda gitmek için daha iyi bir yolu olup olmadığını bilmek istiyordu.

Ne ahşap yapı bir uçak var, ama pervane, karbon fiber, fiberglas, metal, grafit olabilir eğer?

Ben malzemelerin bir tablo tanımlamak ve öğeleri bir tabloda yabancı anahtar başvuru kullanmak istiyorum. Birden fazla maddi destek isterseniz (IE: ... Metal yeniden donatı veya vidalar var diyorlar), o zaman bir corrollary / arama / xref tablo gerekir ediyorum.

MATERIALS_TYPE_CODE table

  • MATERIALS_TYPE_CODE pk
  • MATERIALS_TYPE_CODE_DESC

PRODUCTS table

  • PRODUCT_ID, pk
  • MATERIALS_TYPE_CODE fk IF tek bir malzeme hiç ilişkilidir

PRODUCT_MATERIALS_XREF table

  • PRODUCT_ID, pk
  • MATERIALS_TYPE_CODE pk

Ben de tek bir corrollary / arama / xref tablosunu kullanarak başka ürünler ilgili olacaktır. Bir ürün birden fazla donatıldı ürün ile ilgili olabilir:

KITTED_PRODUCTS table

  • PARENT_PRODUCT_ID, fk
  • CHILD_PRODUCT_ID, fk

Çocuk başka soemthing ebeveyn olabilir çünkü ... ve bir hiyerarşik ilişkiyi desteklemektedir.

Kolayca http://cakeapp.com adresinden DB tasarımları test edebilirsiniz