W tym wpisie na blogu będziemy omawiać jedną z najczęściej używanych funkcji MySQL - partycje.
Co to jest partycjonowanie?
W MySQL partycjonowanie to technika projektowania bazy danych, w której baza danych dzieli dane na wiele tabel, ale nadal traktuje dane jako pojedynczą tabelę według warstwy SQL. Mówiąc najprościej, kiedy dzielisz tabelę na partycje, dzielisz ją na wiele podtabeli:partycjonowanie jest używane, ponieważ poprawia wydajność niektórych zapytań, umożliwiając im dostęp tylko do części danych, dzięki czemu są szybsze. Operacje we/wy można również ulepszyć, ponieważ dane i indeksy można podzielić na wiele woluminów dyskowych.
Istnieją dwa rodzaje partycjonowania:poziomy i pionowy. Podział poziomy obejmuje umieszczanie różnych wierszy w różnych tabelach, z drugiej strony podział pionowy obejmuje tworzenie tabel z mniejszą liczbą kolumn i używanie dodatkowych tabel do przechowywania pozostałych kolumn.
Jak działa partycjonowanie?
- Kiedy używane są zapytania SELECT, warstwa partycjonowania otwiera i blokuje partycje, optymalizator zapytań określa, czy którakolwiek z partycji może zostać oczyszczona, a następnie warstwa partycjonowania przekazuje wywołania interfejsu API obsługi do silnika pamięci, który obsługuje partycje.
- Kiedy używane są zapytania INSERT, warstwa partycjonowania otwiera i blokuje partycje, określa, do której partycji powinien należeć wiersz, a następnie przekazuje wiersz do tej partycji.
- Kiedy używane są zapytania DELETE, warstwa partycjonowania otwiera i blokuje partycje, określa, która partycja zawiera wiersz, a następnie usuwa wiersz z tej partycji.
- Kiedy używane są zapytania UPDATE, warstwa partycjonowania otwiera i blokuje partycje, określa, która partycja zawiera wiersz, pobiera wiersz i modyfikuje go, a następnie określa, która partycja powinna zawierać nowy wiersz, przekazuje wiersz dalej do nowej partycji z żądaniem wstawienia, a następnie przekazuje żądanie usunięcia do oryginalnej partycji.
Kiedy należy używać partycjonowania?
Na ogół partycjonowanie jest przydatne, gdy:
- Masz dużo danych, które musisz przeszukać.
- Twoje tabele są zbyt duże, aby zmieścić się w pamięci.
- Twoje tabele zawierają dane historyczne, a nowe dane są dodawane do najnowszej partycji.
- Myślisz, że będziesz musiał rozdzielić zawartość tabeli na różne urządzenia pamięci masowej.
- Myślisz, że będziesz musiał przywrócić poszczególne partycje.
Jeśli jeden lub więcej opisanych powyżej scenariuszy opisuje twoją sytuację, partycjonowanie może pomóc. Zanim jednak podzielisz swoje dane, pamiętaj, że partycje MySQL mają swoje własne ograniczenia:
- Wyrażenia partycjonowania nie pozwalają na używanie procedur składowanych, funkcji składowanych, funkcji zdefiniowanych przez użytkownika (UDF) lub wtyczek oraz przy ograniczonej obsłudze funkcji SQL. Nie możesz również używać zadeklarowanych lub przechowywanych zmiennych.
- Tabele podzielone na partycje nie mogą zawierać kluczy obcych ani do nich się odwoływać.
- Istnieje limit 1024 partycji na tabelę (począwszy od MariaDB 10.0.4, tabele mogą zawierać maksymalnie 8192 partycji).
- Tabela może być partycjonowana tylko wtedy, gdy silnik pamięci obsługuje partycjonowanie.
- Pamięć podręczna zapytań nie jest świadoma partycjonowania lub czyszczenia partycji.
- Wszystkie partycje muszą używać tego samego silnika pamięci masowej.
- Indeksy FullTEXT nie są obsługiwane
- Tabele tymczasowe nie mogą być partycjonowane
Powyższe opcje powinny pomóc Ci zdecydować, czy partycjonowanie jest opcją dla Ciebie, czy nie.
Typy partycjonowania
Jeśli zdecydujesz się na użycie partycji, pamiętaj, że masz do wyboru kilka typów partycjonowania. Poniżej krótko omówimy Twoje opcje, a następnie zagłębimy się w nie:
- Podział według RANGE może pomóc w podzieleniu wierszy na podstawie wartości kolumn mieszczących się w danym zakresie.
- Podział według LISTY może pomóc Ci podzielić wiersze na podstawie przynależności wartości kolumn do danej listy.
- Podział na partycje przez HASH może pomóc Ci podzielić wiersze na podstawie wartości zwróconej przez wyrażenie zdefiniowane przez użytkownika.
- Podział na partycje według KEY może pomóc w podzieleniu wierszy na partycje w oparciu o funkcję mieszającą dostarczoną przez MySQL.
Partycjonowanie według RANGE
Partycjonowanie według RANGE jest jedną z najpopularniejszych form partycjonowania tabel MySQL. Kiedy dzielisz tabelę według RANGE, dzielisz ją w taki sposób, że każda partycja zawiera pewną liczbę wierszy mieszczących się w danym zakresie. Aby zdefiniować partycję, zdefiniuj jej nazwę, a następnie wskaż, jakie wartości ma zawierać - aby podzielić tabelę według zakresu, dodaj instrukcję PARTITION BY RANGE. Na przykład, jeśli chcesz nazwać partycję p0 i sprawić, by zawierała wszystkie wartości mniejsze niż 5, musisz upewnić się, że zapytanie zawiera WARTOŚCI PARTYCJI p0 MNIEJSZE NIŻ (5). Oto przykład tabeli podzielonej na partycje:
CREATE TABLE sample_table (
id INT(255) NOT NULL AUTO_INCREMENT PRIMARY KEY,
column_name VARCHAR(255) NOT NULL DEFAULT ‘’
...
) PARTITION BY RANGE (column_name) (
PARTITION p0 VALUES LESS THAN (5),
PARTITION p1 VALUES LESS THAN (10),
PARTITION p2 VALUES LESS THAN (15),
PARTITION p3 VALUES LESS THAN (20),
...
);
Możesz także zdefiniować partycję, która przechowuje wszystkie wartości, które nie mieszczą się w określonych zakresach, na przykład:
PARTITION p5 VALUES LESS THAN MAXVALUE
Powyższa partycja nosi nazwę p5 i przechowuje wszystkie wartości, których nie mają inne partycje - MAXVALUE reprezentuje wartość, która jest zawsze wyższa niż największa możliwa wartość. Możesz również użyć funkcji, definiując swoje partycje w następujący sposób:
PARTITION BY RANGE (YEAR(date)) (
PARTITION p0 VALUES LESS THAN (2000),
PARTITION p1 VALUES LESS THAN (2010),
PARTITION p2 VALUES LESS THAN (2020),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
W tym przypadku wszystkie wartości mniejsze niż 2000 są przechowywane w partycji p0, wszystkie wartości mniejsze niż 2010 są przechowywane w partycji p1, wszystkie wartości mniejsze niż 2020 są przechowywane w partycja p2 i wszystkie wartości, które nie mieszczą się w żadnym z tych zakresów, są przechowywane w partycji p3.
Partycjonowanie według LISTY
Partycjonowanie tabel MySQL według LISTY jest podobne do partycjonowania według RANGE - główna różnica w partycjonowaniu tabel według LISTY polega na tym, że gdy tabele są partycjonowane według LISTY, każda partycja jest definiowana i wybierana na podstawie przynależności wartości kolumny w zestawie list wartości, a nie w zakresie wartości. Partycjonowanie według LISTY może być przydatne, gdy wiesz, że na przykład masz dane, które można podzielić na wiele mniejszych zestawów danych (np. regiony). Załóżmy, że masz sklep, który ma 4 franczyzy:jedną w centralnej części miasta, drugą na północy, trzecią na wschodzie, czwartą na zachodzie. Możesz podzielić tabelę w taki sposób, aby dane należące do określonej franczyzy były przechowywane na partycji przeznaczonej dla tej franczyzy:
PARTITION BY LIST(store) (
PARTITION central VALUES IN (1,3,5),
PARTITION north VALUES IN (2,4,7),
PARTITION east VALUES IN (8,9),
PARTITION west VALUES IN (10,11)
);
Partycjonowanie przez HASH
Partycjonowanie tabel MySQL przez HASH może być sposobem na zapewnienie równomiernego rozmieszczenia danych na partycjach. Jeśli partycjonujesz tabele za pomocą HASH, wystarczy określić, na ile partycji chcesz podzielić dane - resztę zajmuje się MySQL. Możesz użyć partycjonowania przez HASH, dodając następującą instrukcję do CREATE TABLE:
PARTITION BY HASH(id)
PARTITIONS 5;
Zastąp 5 liczbą, która określa, na ile partycji chcesz podzielić dane — domyślna liczba to 1.
MySQL obsługuje również partycjonowanie za pomocą LINEAR HASH — haszowanie liniowe różni się od zwykłego haszowania, ponieważ wykorzystuje on liniowy algorytm potęgi dwojga. Aby podzielić tabele za pomocą LINEAR HASH, zastąp PARTITION BY HASH przez PARTITION BY LINEAR HASH.
Partycjonowanie według KLUCZY
Partycjonowanie tabel MySQL według KEY jest podobne do partycjonowania tabel MySQL według HASH - w tym przypadku funkcja mieszająca do partycjonowania kluczy jest dostarczana przez serwer MySQL. Wszelkie kolumny używane jako klucz partycjonowania muszą zawierać klucz podstawowy całej tabeli lub przynajmniej być częścią klucza podstawowego tabeli. Jeśli żadna nazwa kolumny nie zostanie określona jako klucz partycjonowania, zostanie użyty klucz podstawowy. Jeśli nie ma klucza podstawowego, ale istnieje klucz unikalny, zamiast niego zostanie użyty klucz unikalny. Na przykład, obie instrukcje są poprawne, chociaż pierwsza nie określa nawet klucza partycjonowania:
CREATE TABLE demo_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL DEFAULT ''
)
PARTITION BY KEY()
PARTITIONS 2;
CREATE TABLE demo_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
)
PARTITION BY KEY(id)
PARTITIONS 5;
Wnioski
Podsumowując, partycje mogą być pomocne, jeśli masz dużo danych, tabele są zbyt duże, aby zmieścić się w pamięci lub zawierają dane historyczne. Partycje mogą być również przydatne, jeśli uważasz, że będziesz musiał rozmieścić zawartość tabeli na różnych nośnikach pamięci, a także jeśli chcesz mieć opcję usuwania lub przywracania poszczególnych partycji.
Należy jednak pamiętać, że partycje w MySQL mają swoje wady. Jedną z głównych wad partycjonowania jest to, że zwiększy to twoje stoły - nie można uzyskać prędkości bez poświęcania miejsca. Jeśli masz bardzo duży zestaw danych, może to stanowić spory problem.