sql >> Database >  >> RDS >> MariaDB

Database-ontwerp 101:partities in MySQL

In deze blogpost gaan we het hebben over een van de meest gebruikte functies van MySQL - partities.

Wat is partitioneren?

In MySQL is partitionering een databaseontwerptechniek waarbij een database gegevens in meerdere tabellen opsplitst, maar de gegevens nog steeds als een enkele tabel behandelt door de SQL-laag. Simpel gezegd, wanneer u een tabel partitioneert, splitst u deze in meerdere subtabellen:partitionering wordt gebruikt omdat het de prestaties van bepaalde query's verbetert doordat ze slechts toegang hebben tot een deel van de gegevens, waardoor ze sneller worden. I/O-bewerkingen kunnen ook worden verbeterd omdat gegevens en indexen over veel schijfvolumes kunnen worden verdeeld.

Er zijn twee soorten partitionering:horizontaal en verticaal. Bij horizontale partitionering worden verschillende rijen in verschillende tabellen geplaatst, bij verticale partitionering daarentegen worden tabellen met minder kolommen gemaakt en worden extra tabellen gebruikt om de resterende kolommen op te slaan.

Hoe werkt partitioneren?

  • Wanneer SELECT-query's worden gebruikt, opent en vergrendelt de partitioneringslaag partities, de query-optimizer bepaalt of een van de partities kan worden gesnoeid, waarna de partitioneringslaag de handler-API-aanroepen doorstuurt naar de opslagengine die de partities.
  • Als INSERT-query's worden gebruikt, opent en vergrendelt de partitioneringslaag partities, bepaalt tot welke partitie de rij moet behoren en stuurt de rij vervolgens door naar die partitie.
  • Als DELETE-query's worden gebruikt, opent en vergrendelt de partitioneringslaag partities, bepaalt welke partitie de rij bevat en verwijdert vervolgens de rij van die partitie.
  • Wanneer UPDATE-query's worden gebruikt, opent en vergrendelt de partitioneringslaag partities, zoekt uit welke partitie de rij bevat, haalt de rij op en wijzigt deze, bepaalt vervolgens welke partitie de nieuwe rij moet bevatten, stuurt de rij door naar de nieuwe partitie met een invoegverzoek en stuurt het verwijderingsverzoek vervolgens door naar de oorspronkelijke partitie.

Wanneer moet je partitioneren?

In het algemeen is partitioneren handig wanneer:

  • Je hebt veel gegevens die je moet doorzoeken.
  • Uw tabellen zijn te groot om in het geheugen te passen.
  • Uw tabellen bevatten historische gegevens en nieuwe gegevens zijn toegevoegd aan de nieuwste partitie.
  • U denkt dat u de inhoud van een tabel over verschillende opslagapparaten moet verdelen.
  • U denkt dat u afzonderlijke partities moet herstellen.

Als een of meer van de hierboven beschreven scenario's uw situatie beschrijven, kan partitionering helpen. Houd er echter rekening mee dat MySQL-partities hun eigen beperkingen hebben voordat u uw gegevens partitioneert:

  • Uitdrukkingen voor partitionering staan ​​het gebruik van opgeslagen procedures, opgeslagen functies, door de gebruiker gedefinieerde functies (UDF's) of plug-ins niet toe, en bieden beperkte ondersteuning voor SQL-functies. U kunt ook geen gedeclareerde of opgeslagen variabelen gebruiken.
  • Gepartitioneerde tabellen kunnen geen externe sleutels bevatten of ernaar verwijzen.
  • Er is een limiet van 1.024 partities per tabel (vanaf MariaDB 10.0.4 kunnen tabellen maximaal 8.192 partities bevatten).
  • Een tabel kan alleen worden gepartitioneerd als de storage-engine partitionering ondersteunt.
  • De query-cache is niet op de hoogte van partitionering of partitie opschonen.
  • Alle partities moeten dezelfde opslagengine gebruiken.
  • FullTEXT-indexen worden niet ondersteund
  • Tijdelijke tabellen kunnen niet worden gepartitioneerd

De bovenstaande opties zouden u moeten helpen beslissen of partitioneren een optie voor u is of niet.

Typen partitionering

Als je besluit partities te gebruiken, houd er dan rekening mee dat je een aantal partitietypes hebt om uit te kiezen. We zullen uw opties hieronder kort bespreken en er vervolgens dieper op ingaan:

  • Partitionering op RANGE kan u helpen om rijen te partitioneren op basis van kolomwaarden die binnen een bepaald bereik vallen.
  • Partitionering op LIST kan u helpen om rijen te partitioneren op basis van het lidmaatschap van kolomwaarden in een bepaalde lijst.
  • Partitionering door HASH kan u helpen om rijen te partitioneren op basis van een waarde die wordt geretourneerd door een door de gebruiker gedefinieerde expressie.
  • Partitionering met KEY kan u helpen om rijen te partitioneren op basis van een hash-functie die wordt geleverd door MySQL.

Partitionering op BEREIK

Partitionering op RANGE is een van de meest populaire vormen van partitionering van MySQL-tabellen. Wanneer u een tabel partitioneert op RANGE, partitioneert u de tabel op zo'n manier dat elke partitie een bepaald aantal rijen bevat die binnen een bepaald bereik vallen. Om een ​​partitie te definiëren, definieert u de naam ervan en vertelt u vervolgens welke waarden deze moet bevatten - om een ​​tabel op bereik te partitioneren, voegt u een PARTITION BY RANGE-instructie toe. Als u bijvoorbeeld uw partitie p0 wilt noemen en ervoor wilt zorgen dat deze elke waarde heeft die kleiner is dan 5, moet u ervoor zorgen dat uw query PARTITIE p0 WAARDEN MINDER DAN (5) bevat. Hier is een voorbeeld van een gepartitioneerde tabel:

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),

...

);

Je kunt ook een partitie definiëren die alle waarden bevat die niet binnen bepaalde bereiken vallen, zoals:

PARTITION p5 VALUES LESS THAN MAXVALUE

De bovenstaande partitie heet p5 en bevat alle waarden die andere partities niet hebben - MAXVALUE vertegenwoordigt een waarde die altijd hoger is dan de grootst mogelijke waarde. U kunt ook functies gebruiken door uw partities als volgt te definiëren:

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

);

In dit geval worden alle waarden die kleiner zijn dan 2000 opgeslagen in partitie p0, alle waarden die kleiner zijn dan 2010 worden opgeslagen in partitie p1, alle waarden die kleiner zijn dan 2020 worden opgeslagen in de partitie p2 en alle waarden die niet in een van deze bereiken vallen, worden opgeslagen in de partitie p3.

Partitionering op LIST

Het partitioneren van MySQL-tabellen op LIST is vergelijkbaar met het partitioneren op RANGE - het belangrijkste verschil tussen het partitioneren van tabellen op LIST is dat wanneer tabellen worden gepartitioneerd door LIST, elke partitie wordt gedefinieerd en geselecteerd op basis van het lidmaatschap van een kolomwaarde in een reeks waardenlijsten in plaats van een reeks waarden. Partitioneren op LIST kan handig zijn als u weet dat u bijvoorbeeld gegevens hebt die kunnen worden opgedeeld in meerdere kleinere gegevenssets (bijvoorbeeld regio's). Stel dat u een winkel heeft met 4 franchises:een in het centrum van de stad, de tweede in het noorden, de derde in het oosten en de vierde in het westen. U kunt een tabel zo partitioneren dat gegevens die bij een bepaalde franchise horen, worden opgeslagen in een partitie die aan die franchise is toegewezen:

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)

);

Partitionering door HASH

Het partitioneren van MySQL-tabellen met HASH kan een manier zijn om ervoor te zorgen dat gegevens over partities gelijkmatig worden verdeeld. Als u uw tabellen met HASH partitioneert, hoeft u alleen aan te geven in hoeveel partities uw gegevens moeten worden verdeeld - de rest wordt verzorgd door MySQL. U kunt partitionering met HASH gebruiken door de volgende instructie toe te voegen aan CREATE TABLE:

PARTITION BY HASH(id)

PARTITIONS 5;

Vervang 5 door het getal dat aangeeft in hoeveel partities je gegevens moeten worden verdeeld - het standaardnummer is 1.

MySQL ondersteunt ook partitionering door middel van LINEAIRE HASH - lineaire hashing verschilt van reguliere hashing omdat lineaire hashing gebruik maakt van een lineair algoritme van twee machten. Als u tabellen wilt partitioneren met een LINEAR HASH, vervangt u PARTITION BY HASH door PARTITION BY LINEAR HASH.

Partitionering op KEY

Het partitioneren van MySQL-tabellen met KEY is vergelijkbaar met het partitioneren van MySQL-tabellen met HASH - in dit geval wordt de hashfunctie voor sleutelpartitionering geleverd door de MySQL-server. Alle kolommen die als partitiesleutel worden gebruikt, moeten de primaire sleutel van de hele tabel bevatten of op zijn minst een deel van de primaire sleutel van de tabel zijn. Als er geen kolomnaam is opgegeven als partitiesleutel, wordt de primaire sleutel gebruikt. Als er geen primaire sleutel is, maar wel een unieke sleutel, wordt in plaats daarvan de unieke sleutel gebruikt. De volgende instructies zijn bijvoorbeeld beide geldig, ook al specificeert de eerste instructie niet eens de partitiesleutel:

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;

Conclusie

Om samen te vatten, partities kunnen handig zijn als je veel gegevens hebt, je tabellen te groot zijn om in het geheugen te passen of historische gegevens bevatten. Partities kunnen ook handig zijn als u denkt dat u de inhoud van een tabel over verschillende opslagmedia moet verdelen, ook als u de mogelijkheid wilt hebben om afzonderlijke partities te verwijderen of te herstellen.

Houd er echter rekening mee dat partities in MySQL hun eigen nadelen hebben. Een van de grootste nadelen van partitioneren is dat het je tafels groter maakt - je kunt geen snelheid winnen zonder in te leveren op ruimte. Als je een zeer grote hoeveelheid gegevens hebt, kan dit een behoorlijk groot probleem zijn.


  1. Vermijd duplicaten in INSERT INTO SELECT-query in SQL Server

  2. Hoe gebruik je afbeeldingen in Android SQLite die groter zijn dan de beperkingen van een CursorWindow?

  3. Problemen met MySQL-replicatie oplossen:deel twee

  4. MySQL-back-up- en herstelopdrachten voor databasebeheer