Domanda

Mi sento come se la questione è probabilmente stato chiesto mille volte già, quindi mi scuso se è stato risposto. E se è così, qualcuno mi può indicare i giusti messaggi / link?

Quello che sto cercando di fare è costruire una navigazione a faccette per il mio sito. Esso utilizza MySQL e qui c'è un abbozzo delle tabelle che sto usando:

products:
- id
- title
- description
attributes:
- product_id
- name
- value
categories:
- id
- name
products_to_categories:
- product_id
- category_id

Quello che voglio fare è visualizzare un elenco di attributi disponibili quando si è in una categoria, che consente di selezionare uno o più valori per ciascuno di questi attributi. Per fare un esempio, guardate questa pagina da Office Depot: http : //www.officedepot.com/a/browse/binders/N=5+2177/

Finora ho usato un sacco di join per filtrare il più attributi:

SELECT products.*, a_options.*
FROM products_to_categories AS pc, products,
attributes AS a_options,    /* list of attribute/value pairs I can continue to refine on */
attributes AS a_select1     /* first selected attribute */
attributes AS a_select2     /* second selected attribute */
...
WHERE pc.category_id = 1
AND products.id = pc.product_id
AND a_options.product_id = products.id
AND a_options.name != 'Color' AND a_options.name != 'Size'
AND a_select1.product_id = products.id
AND a_select1.name = 'Color' AND (a_select1.value = 'Blue' OR a_select1.value = 'Black')
AND a_select2.product_id = products.id
AND a_select2.name = 'Size' AND a_select2.value = '8.5 x 11'

In sostanza a_options torneranno tutti gli attributi per quei prodotti che sono un sottoinsieme dei filtri che ho applicato utilizzando a_select1 e a_select2. Quindi, se io uso l'esempio Leganti da Office Depot, voglio mostrare tutti gli attributi disponibili dopo aver selezionato blu o nero per il colore e "8,5 x 11" per la dimensione.

Ho quindi utilizzare codice PHP per rimuovere i duplicati e disporre gli attributi risultanti in un array come questo:

attributes[name1] = (val1, val2, val3, ...)
attributes[name2] = (val1, val2, val3, ...)

C'è un modo per accelerare la mia domanda o scrivere in modo più efficiente? Ho indici di impostazione sul nome e il valore nella tabella attributi (e anche su tutti i numeri ID). Ma se qualcuno sceglie un paio di attributi, quindi la query viene eseguita lentamente.

Grazie per il vostro aiuto in anticipo,
Sridhar

È stato utile?

Soluzione

"Ho quindi utilizzare il codice PHP per rimuovere i duplicati"

E non scala poi.

Dopo aver letto http://www.amazon.com/Data-Warehouse-Toolkit -Tecniche-Dimensional / dp / 0471153370 stavo rotolando su sfaccettature e meccanismi di filtraggio non stop.

L'idea di base è che si utilizza uno schema a stella ..

Si crea una tabella dei fatti che memorizza fatti

customerid | dateregisteredid | datelastloginid
1 | 1 | 1
2 | 1 | 2

Si utilizza chiavi esterne in tavole di dimensione che memorizzano gli attributi

date_registered
Id | weekday | weeknumber | year | month | month_year | daymonth | daymonthyear
1 | Wed      | 2            | 2009 | 2   |2-2009      | 4        | 4-2-2009

Poi whichver data di "paradigma" che si sta utilizzando, afferrare tutti gli ID di tale tabella dimensioni e

 select * from the fact table where the fact.dateregisteredid is IN( ... the ids from the date dimension table that represent your time period)

Questi "viste indicizzate" dei dati dovrebbero risiedere in un database separato, e un cambiamento a un oggetto in produzione dovrebbero coda che registrano per il re-indicizzazione nel sistema di analisi dei dati. Siti di grandi dimensioni potrebbe lotto i loro dischi in periodi non di punta per le statistiche di reporting applicazione rallentamenti sempre dietro un paio di ore o giorni. Cerco sempre di tenerlo fino al secondo, se l'architettura supporta.

Se si sta visualizzando anteprime rowCount, si potrebbe avere un po 'di ottimizzazione o di caching per implementare pure.

In sostanza per riassumere, si copiano i dati e denormalizzare. La tecnica va sotto il nome di "data warehousing" o OLAP (Online l'elaborazione di analisi).

Ci sono modi migliori, che utilizzano database commerciali come Oracle, ma lo schema a stella rende disponibile a chiunque con un database relazionale open source e un po 'di tempo.

Si dovrebbe leggere il toolkit ma lui discute un sacco di cose che possono risparmiare un tempo considerevole. Come strategie per trattare con i dati aggiornati, e mantenere la storia di revisione nella applicazione di reporting. Per ogni problema che delinea più soluzioni, ognuna delle quali sono applicabili in contesti diversi.

E 'in grado di scalare fino a milioni di righe se non si prendono i modi facili fuori e utilizza una tonnellata di inutile unisce.

Altri suggerimenti

È possibile generare una tabella di sfaccettatura, sulla base di tabelle di database normalizzato.
Ad esempio:

> SELECT * FROM product_facet
product_id | facet_type | facet_value
1          | color      | blue
2          | color      | blue
3          | color      | green
4          | color      | yellow
1          | speed      | slow
2          | speed      | slow

Poi basta fare questa query per ottenere totale per attributo:

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
GROUP BY facet_type, facet_value;

Risultato:

facet_type | facet_value | total
color      | blue        | 2
color      | green       | 1
color      | yellow      | 1
speed      | slow        | 2

Durante la ricerca con criteri, è possibile selezionare la tabella aspetto da id partita di prodotto:

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
WHERE product_id in (SELECT product_id FROM products WHERE ... )
GROUP BY facet_type, facet_value;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top