2010-06-16 18 views
12

Biorąc pod uwagę, że musisz zaimplementować kanał informacyjny podobny do tego, który można zobaczyć w sieciach społecznościowych, np. Na Facebooku. Obecnie używam klasy News, która ma polimorficzne powiązanie, które może być dowolnego rodzaju, jak obrazek, komentarz, przyjaźń, członkostwo grupy itp. Zawsze, gdy obiekt jest tworzony, również jako wiadomość jest tworzona. To działa dobrze z AR (ActiveRecords), ale wpadam w kłopoty, kiedy przerzucam się na DM (DataMapper) lub Sequel, ponieważ oba nie obsługują polimorficznych asocjacji i zniechęcają do ich użycia.jak uniknąć skojarzeń polimorficznych

Jednym z obejść byłoby użycie dużej klauzuli SQL z partiami UNIONów do scalenia wszystkich różnych tabel, które powinny być uważane za wiadomości. Ale ma to pewne wady, zwłaszcza wydajność byłaby straszna.

Zastanawiam się, jak rozwiązać bez polimorficznych skojarzeń, a jednocześnie uzyskać dobrą wydajność i żadnych innych wad, takich jak możliwość dodawania meta danych do wiadomości?

Odpowiedz

21

Nota prawna: Jestem głównym programistą Sequel.

Najlepszy sposób na zrobienie tego zazwyczaj zależy od tego, jakie typy danych chcesz wykonać. Jednym ze sposobów, aby go o to, aby mieć kolumn klucza obcego dla wszystkich możliwych relacji:

news: 
    id 
    ... (Other columns) 
    image_id 
    comment_id 
    friendship_id 
    group_membership_id 

Naprawdę nie ma różnicy wydajności w ten drugi sposób kontra posiadające rodzajowe klucza obcego i przechowywania nazwę klasy. W przypadku leniwego ładowania wystarczy wybrać jedno pole klucza obcego, które nie jest zerowe/NULL, i wybrać odpowiednie powiązanie do załadowania. Aby załadować zapytanie na tabelę, wystarczy załadować wszystkie powiązania jednocześnie. Jest to również bardziej elastyczne, ponieważ można je ładować z użyciem JOIN, co nie jest możliwe z podejściem polimorficznym. Dodatkowo zyskujesz na prawdziwej więzi integralności.

Jedną wadą jest to, że jeśli chcesz dodać więcej typów skojarzeń w przyszłości, musisz dodać obce klucze do tabeli.

+0

Dzięki ... to naprawdę prosty, ale dobry pomysł :-). Wymaga to pewnych zmian w modelu (zwracając rzeczywiste skojarzenie ref), ale powinno być ok :) – gucki

+0

Naprawdę nie sądzę, że to jest rozwiązanie. To tak naprawdę nie opisuje pojęcia np. "możliwy do zweryfikowania" będący potencjalnie "Biznesowym" lub "Osobowym" lub "Przedmiotem". Nawet jeśli masz "business_id", "person_id", "item_id" w tabeli "Review", musisz znaleźć pierwsze pole zerowe spośród wszystkich, aby naprawdę wiedzieć, na co wskazuje opinia. Co z przypadkami, w których określone skojarzenie może być jedną z wielu różnych rzeczy? – fatuhoku

2

Oto perełka w celu utrzymania integralności referencyjnej polimorficznych Stowarzyszeń na poziomie bazy danych w szynach:

https://github.com/mkraft/fides

Jak to delegowania są adaptery do SQLite3 i PostgreSQL.

Nota prawna: Napisałem klejnot.