2017-07-02 62 views
11

Mam ponad miliard nazw domen, które zamiast umieszczać je wszystkie w jednej tabeli, postanowiłem podzielić je na 36 tabel (ta sama struktura db dla każdej tabeli).Jak skonstruować model podzielony na bazę danych na 36 tabel?

Istnieje tabela na podstawie pierwszego znaku nazwy domeny (ex tabele: domains_a ... domains_z).

Jak mogę utworzyć pojedynczy model Domain w szynach, który automatycznie przełącza się między tymi tabelami w sposób płynny na podstawie określonego znaku?

+0

Co powiesz na używanie ilala? –

+4

Dlaczego, na Boga, podzieliłeś dane? Jest to błąd, chyba że masz doskonały powód. Bilans miliardów nie jest zbyt duży dla np. postresql. Pozwala na 32 TB tabel. Tak długo, jak twoje rekordy są 30KB lub mniej, jesteś gotowy do pracy. MySQL umożliwia wiele, znacznie większych tabel. – Gene

+2

Proszę określić, z której bazy danych korzystasz - każde rozwiązanie będzie w dużym stopniu dotyczyć funkcji specyficznych dla DB. –

Odpowiedz

2

Nie możesz: musisz napisać własną logikę, aby sobie z tym poradzić. Railsy muszą znać twoją logikę biznesową i analizować zapytanie SQL, aby dowiedzieć się, którą tabelę wybrać i nie możesz tego zrobić domyślnie, musisz napisać ten kod samodzielnie.

Jednak pod numerem jest taka sztuczka, która znacznie ułatwi ci pracę. A co z obsługą tego na poziomie bazy danych? Sprawdziłem i wszystkie główne bazy danych obsługują aktualizowalne widoki .

Więc utworzyć nowy widok, nazwij go domains i upewnić się, że tworzy unii wszystkich tabel domen (od A do Z), a następnie createa model:

class Domain 
    self.table_name = "your_view_name" 
end 

by to zrobić podstęp pod odczytywanie strony. Teraz, bazując na bazie danych, której używasz, możesz w ten sposób rozwiązać problem zapisu (z wyzwalaczami i podobnymi funkcjami DB), w przeciwnym razie musisz napisać własny kod dla części do zapisu, która prawdopodobnie będzie potrzebna uruchamiać nieprzetworzone zapytania.

Alternatywnie można sobie z tym poradzić na poziomie Ruby, tworząc wszystkie modele (DomainA, DomainB itd.) Ręcznie lub za pomocą generatora, a następnie tworząc wspólną klasę, która działa jako interfejs. Można też utworzyć te modele za pomocą metaprogramowania i ponownie mieć wspólną klasę, która działa jako interfejs.

3

Zasadniczo ten typ partycjonowania tabel jest obsługiwany na poziomie bazy danych. Powinieneś określić, z której bazy danych korzystasz, ponieważ będzie to bardzo istotne tutaj. Na przykład PostgreSQL ma podstawową obsługę table partition. Wskażesz model Rails w tabeli głównej, a partycjonowanie będzie przezroczyste dla warstwy Ruby.

+0

Czy istnieje sposób partycjonowania tabel Postgres, aby automatycznie przenosić wiersze do odpowiedniej partycji, jeśli wartość zakresu została zaktualizowana? – Jacob

0

Podział tabel jest drogą do zrobienia. Nie twórz wszystkich identycznych struktur tabel.

Co tabela partycjonowania da Ci

  1. Będziesz mieć pojedynczą tabelę, która jest logicznie podzielona przez bazy danych.
  2. W widoku aplikacji kwerendy są wysyłane do pojedynczej tabeli, tak jak każdej innej tabeli bazy danych.
  3. W perspektywie bazy danych przechowuje dane według partycji, które są zdefiniowane przez typ partycji i logikę partycji. W mysql, możesz odwołać się do https://dev.mysql.com/doc/refman/5.7/en/partitioning-types.html
  4. korzyści wydajności, jeśli zdefiniowane poprawnie.Pozwoli to uniknąć skanowania 1 miliarda wierszy, ale zamiast tego skanuje odpowiednią partycję podczas wykonywania zapytań.

Partycja tabel może być bardzo specyficzna dla bazy danych.

Prosty przykład z mysql.

CREATE TABLE employees (
    id INT NOT NULL, 
    fname VARCHAR(30), 
    lname VARCHAR(30), 
    hired DATE NOT NULL DEFAULT '1970-01-01', 
    separated DATE NOT NULL DEFAULT '9999-12-31', 
    job_code INT NOT NULL, 
    store_id INT NOT NULL 
) 
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6), 
    PARTITION p1 VALUES LESS THAN (11), 
    PARTITION p2 VALUES LESS THAN (16), 
    PARTITION p3 VALUES LESS THAN MAXVALUE 
); 

Pracownik są zapisywane w określonej strefie, do albo P0, P1, P2 i P3, w zależności od magazynu (store_id) pracownik należy.

Nadal uzyskujesz dostęp do niego za pośrednictwem pojedynczej tabeli, ale dane są przechowywane logicznie według partycji w zależności od id store_id.

SELECT * FROM employee WHERE store_id = 10 

Baza danych będzie po prostu patrzeć na partycji p1 i nie skanuje inną partycję (P0, P2 i P3), ponieważ po prostu, że kwerenda nie znajdzie danych w tych partycji.