Istnieje kilka głównych powodów używania dziedziczenia tabel w Postgres.
Powiedzmy, że mamy kilka tabel potrzebnych do statystyk, które są tworzone i wypełniane co miesiąc:
statistics
- statistics_2010_04 (inherits statistics)
- statistics_2010_05 (inherits statistics)
W tym przykładzie mamy 2 000 000 wierszy w każdej tabeli. Każda tabela ma ograniczenie typu CHECK, aby mieć pewność, że zostaną w niej zapisane tylko dane z odpowiedniego miesiąca.
Co więc sprawia, że dziedziczenie jest fajną funkcją - dlaczego dzielenie danych jest fajne?
- WYDAJNOŚĆ: Wybierając dane, WYBIERAMY * FROM statystyki WHERE data BETWEEN x i Y, a Postgres korzysta z tabel tylko tam, gdzie ma to sens. Na przykład. WYBIERZ * FROM statystyki GDZIE data MIĘDZY „2010-04-01” a „2010-04-15” skanuje tylko tabelę statistics_2010_04, wszystkie inne tabele nie zostaną dotknięte - szybko!
- Rozmiar indeksu: nie mamy dużej tabeli tłuszczu z dużym indeksem tłuszczu według daty kolumny. Mamy małe tabele miesięcznie, z małymi indeksami - szybsze odczyty.
- Konserwacja: Możemy uruchomić próżnię, reindeks, klaster na każdej tabeli miesiąca bez blokowania wszystkich innych danych
Aby uzyskać informacje na temat prawidłowego używania dziedziczenia tabeli jako wzmacniacza wydajności, zapoznaj się z podręcznikiem postgresql. Musisz ustawić ograniczenia CHECK dla każdej tabeli, aby poinformować bazę danych, według którego klucza dane zostaną podzielone (podzielone na partycje).
W dużym stopniu korzystam z dziedziczenia tabel, zwłaszcza jeśli chodzi o przechowywanie danych dziennika pogrupowanych według miesięcy. Wskazówka: jeśli przechowujesz dane, które nigdy się nie zmienią (loguj dane), utwórz lub indeksuj za pomocą CREATE INDEX ON () WITH (fillfactor = 100); Oznacza to, że w indeksie nie zostanie zarezerwowane miejsce na aktualizacje - indeks na dysku jest mniejszy.
AKTUALIZACJA: domyślny współczynnik wypełnienia to 100, z http://www.postgresql.org/docs/9.1/static/sql-createtable.html :
Współczynnik wypełnienia tabeli wynosi od 10 do 100 procent. 100 (pełne opakowanie) jest wartością domyślną
„Dziedziczenie tabeli” oznacza coś innego niż „dziedziczenie klas” i służą one innym celom.
Postgres dotyczy definicji danych. Czasami naprawdę złożone definicje danych. OOP (w typowym znaczeniu dla języka Java) polega na podporządkowaniu zachowań definicjom danych w pojedynczej strukturze atomowej. Cel i znaczenie słowa „dziedziczenie” są tutaj znacząco inne.
W krainie OOP mogę zdefiniować (będąc tutaj bardzo luźnym ze składnią i semantyką):
Tabele do tego mogą wyglądać następująco:
CREATE TABLE animal (name varchar(20) PRIMARY KEY, metabolism boolean NOT NULL); CREATE TABLE mammal (hair_color varchar(20) REFERENCES hair_color(code) NOT NULL, PRIMARY KEY (name)) INHERITS (animal); CREATE TABLE human (alcoholic boolean NOT NULL, FOREIGN KEY (hair_color) REFERENCES hair_color(code), PRIMARY KEY (name)) INHERITS (mammal);
Ale gdzie są zachowania? Nigdzie nie pasują. Nie jest to celem „obiektów”, ponieważ są one omawiane w świecie baz danych, ponieważ bazy danych dotyczą danych, a nie kodu proceduralnego. Możesz zapisać funkcje w bazie danych, aby wykonać obliczenia za Ciebie (często bardzo dobry pomysł, ale nie jest to coś, co pasuje do tego przypadku), ale funkcje to nie to samo co metody - metody rozumiane w postaci OOP, o którym mówisz około są celowo mniej elastyczne.
Jest jeszcze jedna rzecz, na którą należy zwrócić uwagę, jeśli chodzi o dziedziczenie jako urządzenie schematyczne: od Postgres 9.2 nie ma możliwości odniesienia się do ograniczenia klucza obcego dla wszystkich członków rodziny partycji / tabel jednocześnie. Możesz napisać kontrole, aby to zrobić, lub obejść to w inny sposób, ale nie jest to wbudowana funkcja (sprowadza się do problemów ze złożonym indeksowaniem, a nikt nie napisał bitów niezbędnych do wykonania tego automatycznego). Zamiast używać dziedziczenia tabel do tego celu, często lepszym rozwiązaniem w bazie danych dla dziedziczenia obiektów jest tworzenie schematycznych rozszerzeń tabel. Coś takiego:
CREATE TABLE animal (name varchar(20) PRIMARY KEY, ilk varchar(20) REFERENCES animal_ilk NOT NULL, metabolism boolean NOT NULL); CREATE TABLE mammal (animal varchar(20) REFERENCES animal PRIMARY KEY, ilk varchar(20) REFERENCES mammal_ilk NOT NULL, hair_color varchar(20) REFERENCES hair_color(code) NOT NULL); CREATE TABLE human (mammal varchar(20) REFERENCES mammal PRIMARY KEY, alcoholic boolean NOT NULL);
Teraz mamy odwołanie kanoniczne do instancji zwierzęcia, którego możemy niezawodnie użyć jako odniesienia do klucza obcego, i mamy kolumnę „podobną”, która odwołuje się do tabeli definicji xxx_ilk, która wskazuje na „następną” tabelę danych rozszerzonych ( lub wskazuje, że nie ma żadnego, jeśli podobny jest sam typem ogólnym). Pisanie funkcji tabel, widoków itp. W tego rodzaju schemacie jest tak łatwe, że większość frameworków ORM robi dokładnie tego rodzaju rzeczy w tle, kiedy uciekasz się do dziedziczenia klas w stylu OOP, aby utworzyć rodziny typów obiektów.
źródło
mammal JOIN human
tylko dlatego, że pisanie złączenia za każdym razem jest denerwujące. Ale nie unikaj połączeń . Połączenia są tym, co umieszcza R w RDBMS. Jeśli nie lubisz łączenia, powinieneś użyć innego typu bazy danych.Dziedziczenie może być używane w paradygmacie OOP, o ile nie ma potrzeby tworzenia kluczy obcych w tabeli nadrzędnej. Na przykład, jeśli masz pojazd klasy abstrakcyjnej przechowywany w tabeli pojazdów i samochód stołowy, który dziedziczy po nim, wszystkie samochody będą widoczne w tabeli pojazdu, ale klucz obcy z tabeli kierowcy na stole pojazdu nie będzie pasował do tych dokumentacja.
Dziedziczenie może być również używane jako narzędzie do partycjonowania . Jest to szczególnie przydatne, gdy masz tabele, które mają rosnąć wiecznie (tabele dziennika itp.).
źródło
Dziedziczenie jest głównie używane do partycjonowania, ale czasami jest to przydatne w innych sytuacjach. W mojej bazie danych jest wiele tabel różniących się tylko kluczem obcym. Obraz mojej tabeli „klasy abstrakcyjnej” zawiera identyfikator (klucz podstawowy musi znajdować się w każdej tabeli) i raster PostGIS 2.0. Dziedziczone tabele, takie jak „site_map” lub „artifact_drawing”, mają kolumnę z kluczem obcym (kolumna tekstowa „site_name” dla „site_map”, kolumna „artifact_id” z liczbą całkowitą dla tabeli „artifact_drawing” itp.) Oraz ograniczenia klucza podstawowego i obcego; reszta jest dziedziczona z tabeli „image”. Podejrzewam, że w przyszłości będę musiał dodać kolumnę „opis” do wszystkich tabel obrazów, więc zaoszczędzi mi to sporo pracy bez robienia prawdziwych problemów (cóż,
EDYCJA: kolejne dobre zastosowanie: przy dwóch tabelach obsługi niezarejestrowanych użytkowników , inne RDBMS mają problemy z obsługą dwóch tabel, ale w PostgreSQL jest to łatwe - po prostu dodaj,
ONLY
gdy nie jesteś zainteresowany danymi w odziedziczonej tabeli "niezarejestrowanych użytkowników".źródło
Jedyne doświadczenie, jakie mam z dziedziczonymi tabelami, dotyczy podziału na partycje. Działa dobrze, ale nie jest to najbardziej wyrafinowana i łatwa w użyciu część PostgreSQL.
W zeszłym tygodniu szukaliśmy tego samego problemu OOP, ale mieliśmy zbyt wiele problemów z Hibernacją (nie podobała nam się nasza konfiguracja), więc nie używaliśmy dziedziczenia w PostgreSQL.
źródło
Dziedziczenie używam, gdy mam więcej niż 1 na 1 relacji między tabelami.
Przykład: załóżmy, że chcesz przechowywać lokalizacje map obiektów z atrybutami x, y, obrót, skalę.
Załóżmy teraz, że masz kilka różnych rodzajów obiektów do wyświetlenia na mapie, a każdy obiekt ma własne parametry lokalizacji na mapie, a parametry mapy nigdy nie są ponownie używane.
W takich przypadkach dziedziczenie tabel byłoby całkiem przydatne, aby uniknąć konieczności utrzymywania nienormalizowanych tabel lub tworzenia identyfikatorów lokalizacji i odwoływania się do innych tabel.
źródło
Używaj go jak najmniej. A to zwykle oznacza nigdy, sprowadza się do sposobu tworzenia struktur, które naruszają model relacyjny, na przykład poprzez łamanie zasady informacji i tworzenie worków zamiast relacji.
Zamiast tego użyj partycjonowania tabel połączonego z odpowiednim modelowaniem relacyjnym, w tym innymi formami normalnymi.
źródło