πŸ”’ Как ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΡ…Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL

Для сохранности Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ структуру Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ "Nested Set" ΠΈΠ»ΠΈ "Π’Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ мноТСство". Π­Ρ‚ΠΎ позволяСт эффСктивно ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ иСрархичСскиС Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ создания Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ с использованиСм "Nested Set":


CREATE TABLE categories (
    category_id INT PRIMARY KEY,
    name VARCHAR(50),
    lft INT,
    rgt INT
);

Для вставки Π½ΠΎΠ²ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ ΠΈ обновлСния Π»Π΅Π²ΠΎΠ³ΠΎ ΠΈ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ значСния Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ SQL-запрос:


INSERT INTO categories (category_id, name, lft, rgt)
VALUES (1, 'Category A', 1, 2);

UPDATE categories
SET rgt = rgt + 2
WHERE rgt >= 2;

UPDATE categories
SET lft = lft + 2
WHERE lft >= 2;

Π”Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚

Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΌΠΈΡ€ сохранности Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL! Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрим, ΠΊΠ°ΠΊ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΡ…Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… MySQL. НачнСм!

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Когда ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… катСгориях, ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π² Π²ΠΈΠ΄Ρƒ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ структуру ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ, Π³Π΄Π΅ каТдая катСгория ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ. НапримСр, Ρƒ нас ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ катСгория "Π­Π»Π΅ΠΊΡ‚Ρ€ΠΎΠ½ΠΈΠΊΠ°", Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π΅ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ "Π’Π΅Π»Π΅Ρ„ΠΎΠ½Ρ‹", "Ноутбуки", "Π’Π΅Π»Π΅Π²ΠΈΠ·ΠΎΡ€Ρ‹" ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ‚Π°ΠΊΠΎΠΉ структуры Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ сохранности Π΄Π°Π½Π½Ρ‹Ρ…. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΈΠ·ΡƒΡ‡ΠΈΠΌ, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π² MySQL.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ

БущСствуСт нСсколько способов ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π² MySQL, ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ… ΠΈΠΌΠ΅Π΅Ρ‚ свои прСимущСства ΠΈ ограничСния. ΠœΡ‹ рассмотрим Π΄Π²Π° самых популярных способа:

1. ΠœΠ΅Ρ‚ΠΎΠ΄ "ΠŸΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ списка" (Path Enumeration)

ΠœΠ΅Ρ‚ΠΎΠ΄ "ΠŸΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ списка" основан Π½Π° Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠΈ ΠΏΡƒΡ‚ΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΠ»Π΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. КаТдая катСгория Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ строку, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ Π½Π΅Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "1/2/3". Π­Ρ‚ΠΎΡ‚ ΠΏΡƒΡ‚ΡŒ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π²Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅: катСгория с ID 3 находится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ с ID 2, которая Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ находится Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ с ID 1. Для обСспСчСния сохранности Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² этом ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ ΠΈΠ»ΠΈ Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ для хранСния ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ с использованиСм ΠΌΠ΅Ρ‚ΠΎΠ΄Π° "ΠŸΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ списка":

CREATE TABLE categories (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    path VARCHAR(255)
);

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡŽ "Π’Π΅Π»Π΅Ρ„ΠΎΠ½Ρ‹" Π²Π½ΡƒΡ‚Ρ€ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ "Π­Π»Π΅ΠΊΡ‚Ρ€ΠΎΠ½ΠΈΠΊΠ°" с использованиСм ΠΌΠ΅Ρ‚ΠΎΠ΄Π° "ΠŸΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ списка":

INSERT INTO categories (id, name, path)
VALUES (1, 'Π­Π»Π΅ΠΊΡ‚Ρ€ΠΎΠ½ΠΈΠΊΠ°', ''),
       (2, 'Π’Π΅Π»Π΅Ρ„ΠΎΠ½Ρ‹', '1');

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ прост Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ, Ссли ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ часто ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ ΠΈΠ»ΠΈ Ссли ΠΈΡ… количСство ΠΎΡ‡Π΅Π½ΡŒ Π²Π΅Π»ΠΈΠΊΠΎ.

2. ΠœΠ΅Ρ‚ΠΎΠ΄ "Записи Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ мноТСства" (Nested Sets)

ΠœΠ΅Ρ‚ΠΎΠ΄ "Записи Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ мноТСства" основан Π½Π° Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π² Π΄Π΅Ρ€Π΅Π²Π΅, состоящСм ΠΈΠ· "Π»Π΅Π²ΠΎΠ³ΠΎ" ΠΈ "ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ" значСния для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ. ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ располоТСны Π² Π΄Π΅Ρ€Π΅Π²Π΅ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ каТдая катСгория содСрТит всС свои ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ сСбя. Для обСспСчСния сохранности Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² этом ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΈΠ»ΠΈ рСкурсивныС запросы.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ для хранСния ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ с использованиСм ΠΌΠ΅Ρ‚ΠΎΠ΄Π° "Записи Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ мноТСства":

CREATE TABLE categories (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    left_value INT,
    right_value INT
);

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡŽ "Π’Π΅Π»Π΅Ρ„ΠΎΠ½Ρ‹" Π²Π½ΡƒΡ‚Ρ€ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ "Π­Π»Π΅ΠΊΡ‚Ρ€ΠΎΠ½ΠΈΠΊΠ°" с использованиСм ΠΌΠ΅Ρ‚ΠΎΠ΄Π° "Записи Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ мноТСства":

INSERT INTO categories (id, name, left_value, right_value)
VALUES (1, 'Π­Π»Π΅ΠΊΡ‚Ρ€ΠΎΠ½ΠΈΠΊΠ°', 1, 6),
       (2, 'Π’Π΅Π»Π΅Ρ„ΠΎΠ½Ρ‹', 2, 3);

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ слоТСн Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½ΠΎ обСспСчиваСт быстроС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ пСрСмСщСния ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ сохранности Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² "ΠŸΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ списка" ΠΈ "ЗаписСй Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ мноТСства". ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· этих ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈΠΌΠ΅Π΅Ρ‚ свои прСимущСства ΠΈ ограничСния, ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ зависит ΠΎΡ‚ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. НадСюсь, эта ΡΡ‚Π°Ρ‚ΡŒΡ ΠΏΠΎΠΌΠΎΠ³Π»Π° Π²Π°ΠΌ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΡ…Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL!

Π’ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

Nested Set - Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π΄Π΅Ρ€Π΅Π²Π° Π² Π‘Π”

Π‘Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…. SQL. MySQL: Π’Π½Π΅ΡˆΠ½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡ΠΈ

Π‘Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…. MySQL. Π’Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ

ΠŸΠΎΡ…ΠΎΠΆΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ:

πŸ”’ Как ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΡ…Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π² MySQL

πŸ”₯ Как вывСсти количСство Π² MySQL: простоС руководство для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ