2013-01-15 7 views
5

Mam model A, który zawiera ogólną relację klucza obcego z opcjami ograniczenia do 3 innych modeli (traktuj je jako B, C i D) w tej samej aplikacji. I znam ograniczenia generycznych kluczy obcych, których nie możemy używać filter lub get ani żadnych innych operacji związanych z zapytaniami.Django Ogólne klucze obce - dobre czy złe, biorąc pod uwagę wydajność SQL?

Aby coś takiego osiągnąć, Muszę najpierw filtrować obiekty B, C i D jako zestaw zapytań, iterować nad nimi i używać ogólnej relacji odwrotnej, aby uzyskać obiekty A jako listę (nie zestaw zapytań).

Nie jestem pewien, w jaki sposób wpłynie to na wydajność SQL w bazie danych, ponieważ zapytanie nie jest bezpośrednie.

PS: Potrzebuję użyć ogólnych znaków obce, więc proszę sugerować jakiekolwiek ulepszenie SQL zamiast przeprojektowywania modeli.

Korzystanie z Django 1.4.3 i PostgreSQL.

+0

czym właściwie są "ogólne" klucze zagraniczne? –

+0

Użyłem tego samego ustawienia, co opisano tutaj, https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 – Babu

Odpowiedz

7

Chciałbym przytoczyć kilka słów od Dawida Cramer: deweloper Disqus Django commiter

stosunki generyczne są w porządku. Nie są powolne, tylko trudniejsze do zarządzania w bazie kodu.

Widziałem, jak wielu ludzi mówi innym, że nie używają ogólnych relacji, ponieważ jest powolny, ale nigdy nie mówią, jak powolne.

+0

To prawda.Ale zgodziłbym się z 'trudną do zarządzania bazą kodu' – Babu

+2

Oto [Źródło] (http://www.quora.com/What-are-the-bestways-to-improve-Django-performance) –

+0

@ ChrisVilla dzięki! – L42y

0

Dodaj index_together Meta opcję modelu:

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

Avoid Django's GenericForeignKey ma dobre i dokładne opis antipatterns projektowania baz danych biorących udział w ogólnych kluczy obcych (lub „polimorficznych związków”, jak nazywają je w szynach -mówić).

Jeśli chodzi o wydajność, to zajmuje 3 w bazie zapytań za każdym razem chcesz pobrać związanego zasobu GenericForeignKey od modelu:

  1. SELECT object_id_field, object_id z myapp_a WHERE id = 1;
  2. WYBIERZ app_label, model FROM django_content_type WHERE id = A.object_type_field;
    • W kodzie aplikacji, obliczyć nazwa tabeli model + _ + app_label
  3. SELECT A.object_id_field OD TABLE_NAME;

Kiedy ludzie mówią, że ogólne klucze obce mają obniżoną wydajność, odnoszą się do tego zapytania.

Istnieje tylko bardzo wąski zestaw okoliczności, w których naprawdę chcesz używać ogólnych kluczy obcych. Powyższy artykuł również omawia te artykuły.

Powiązane problemy