2013-01-15 13 views
5

Ho un modello A che contiene una relazione di chiave esterna generica con le opzioni limite per altri 3 modelli (considerali come B, C e D) nella stessa app. E conosco i limiti delle chiavi esterne generiche che non possiamo usare filter o get o altre operazioni di queryset.Django Chiavi esterne generiche - buone o cattive considerando le prestazioni SQL?

in modo da ottenere qualcosa di simile, A.objects.filter(generic_object__name="foo") devo filtrare gli oggetti B, C e D prima come set di query, scorrere su di loro e usare la relazione inversa generica per ottenere i A oggetti come lista (non set di query).

Non sono sicuro di come influenzerà l'esecuzione SQL sul database poiché l'interrogazione non è diretta.

PS: Ho bisogno di utilizzare i tasti stranieri generici, quindi per favore suggerire per qualsiasi miglioramento SQL piuttosto che riprogettare i modelli.

Utilizzo di Django 1.4.3 e Postgres.

+0

Quali sono esattamente le chiavi esterne "generiche"? –

+0

Ho usato la stessa configurazione descritta qui, https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 – Babu

risposta

7

vorrei citare alcune parole di David Cramer: sviluppatore del Disqus, Django commiter

rapporti generici vanno bene. Non sono lenti, solo più difficili da gestire nella tua base di codice.

Ho visto molte persone dire agli altri di non usare relazioni generiche perché è lento, ma mai dire com'è lento.

+0

Questo è vero.Ma sono d'accordo con il 'codebase difficile da gestire' – Babu

+2

Ecco la [Fonte] (http://www.quora.com/What-are-the-best-ways-to-improve-Django-performance) –

+0

@ ChrisVilla grazie! – L42y

0

aggiungere un'opzione Meta index_together al modello:

class Meta: 
    index_together = [('cprofile_id', 'cprofile_type')] 
1

Avoid Django's GenericForeignKey ha una buona e approfondita descrizione dei antipattern progettazione di database coinvolti nella chiavi esterne generici (o "associazioni polimorfiche", come li chiamano in rotaie -parlare).

quanto riguarda le prestazioni, ci vogliono 3 query di database ogni volta che si desidera recuperare la risorsa GenericForeignKey legati dal modello:

  1. SELEZIONA object_id_field, object_id da myapp_a WHERE id = 1;
  2. SELECT app_label, model FROM django_content_type WHERE id = A.object_type_field;
    • nel codice dell'applicazione, nome della tabella di calcolo model + _ + app_label
  3. SELEZIONA A.object_id_field FROM TABLE_NAME;

Quando le persone dicono che le chiavi esterne generiche hanno una penalizzazione delle prestazioni, fanno riferimento a questa query.

Ci sono solo un insieme molto ristretto di circostanze in cui si vuole veramente usare le chiavi esterne generiche. L'articolo sopra riportato discute anche quelli.

Problemi correlati