>  기사  >  백엔드 개발  >  트리 데이터 구조 저장 방법(CUD)

트리 데이터 구조 저장 방법(CUD)

藏色散人
藏色散人앞으로
2019-09-10 11:31:162778검색

이전 글에서는 중첩 컬렉션의 데이터 모델과 쿼리 방식을 간략하게 소개했습니다. 포털: 트리 데이터 구조 저장 방법(쿼리)

Create

중첩 컬렉션 모델에서는 각 데이터가 실제로 노드이고, 각 노드는 2비트 값을 차지합니다. 예를 들어 스마트폰의 첫 번째 레벨 노드를 추가하는 것부터 시작하겠습니다.

INSERT INTO `categories` (`title`, `lft`, `rgt`) VALUES('Smartphones', 1, 2);

스마트폰 기본 노드(루트)로서 lft는 1이어야 하며 컬렉션의 하위 요소가 증가함에 따라 rgt 값도 증가합니다.

이제 스마트폰 내부에 Android 하위 요소를 추가하려고 합니다. mysql 저장 프로시저를 사용하세요.

LOCK TABLE categories WRITE;
SELECT @root_left := lft FROM categories WHERE title = 'Smartphones';
UPDATE categories SET rgt = rgt + 2 WHERE rgt > @root_left;
UPDATE categories SET lft = lft + 2 WHERE lft > @root_left;
INSERT INTO categories (title, lft, rgt) VALUES('Android', @root_left + 1, @root_left + 2);
UNLOCK TABLES;
SELECT `title`, `lft`, `rgt` FROM `categories`;
+-------------+-----+-----+
| title       | lft | rgt |
+-------------+-----+-----+
| Smartphones |   1 |   4 |
| Android     |   2 |   3 |
+-------------+-----+-----+

다시 Android에 Xiaomi 하위 요소를 추가하려고 합니다.

LOCK TABLE categories WRITE;
SELECT @root_left := lft FROM categories WHERE title = 'Android';
UPDATE categories SET rgt = rgt + 2 WHERE rgt > @root_left;
UPDATE categories SET lft = lft + 2 WHERE lft > @root_left;
INSERT INTO categories (title, lft, rgt) VALUES('小米', @root_left + 1, @root_left + 2);
UNLOCK TABLES;
SELECT `title`, `lft`, `rgt` FROM `categories`;
+-------------+-----+-----+
| title       | lft | rgt |
+-------------+-----+-----+
| Smartphones |   1 |   6 |
| Android     |   2 |   5 |
| 小米        |   3 |   4 |
+-------------+-----+-----+

이번에는 스마트폰에 하위 요소인 iOS를 추가하려고 하므로 이전에는 Android 요소를 추가해야 합니다. 여기에서 조정하세요. 저장된 프로세스를 살펴보고 Android의 오른쪽에 iOS를 삽입해 보겠습니다

LOCK TABLE categories WRITE;
SELECT @next_right := rgt FROM categories WHERE title = 'Android';
UPDATE categories SET rgt = rgt + 2 WHERE rgt > @next_right;
UPDATE categories SET lft = lft + 2 WHERE lft > @next_right;
INSERT INTO categories(title, lft, rgt) VALUES('iOS', @next_right + 1, @next_right + 2);
UNLOCK TABLES;
SELECT `title`, `lft`, `rgt` FROM `categories`;
+-------------+-----+-----+
| title       | lft | rgt |
+-------------+-----+-----+
| Smartphones |   1 |   8 |
| Android     |   2 |   5 |
| 小米        |   3 |   4 |
| iOS         |   6 |   7 |
+-------------+-----+-----+

Delete

노드를 삭제하는 경우 실제로는 노드를 추가하는 역과정으로 볼 수 있습니다. 노드의 넓은 세그먼트를 측정하기 위한 너비입니다. rgt - lft + 1이므로 다음과 같이 저장 프로시저를 작성할 수 있습니다.

LOCK TABLE categories WRITE;
SELECT @delete_left := lft, @delete_right := rgt, @delete_width := rgt - lft + 1
FROM categories WHERE title = 'Android';
DELETE FROM categories WHERE lft BETWEEN @delete_left AND @delete_right;
UPDATE categories SET rgt = rgt - @delete_width WHERE rgt > @delete_right;
UPDATE categories SET lft = lft - @delete_width WHERE lft > @delete_right;
UNLOCK TABLES;
SELECT `title`, `lft`, `rgt` FROM `categories`;
+-------------+-----+-----+
| title       | lft | rgt |
+-------------+-----+-----+
| Smartphones |   1 |   4 |
| iOS         |   2 |   3 |
+-------------+-----+-----+

Update

노드 이동은 상대적으로 복잡한 프로세스입니다. 예를 들어, 아래 그림에서 macOS는 Unix 범주로 분류되어야 합니다.

트리 데이터 구조 저장 방법(CUD)

노드의 이동을 구현하려면 다음 세 단계가 필요합니다.

1. 이동할 노드를 꺼냅니다.

2 lft 및 rgt 매개변수를 재정렬합니다.

3 노드를 지정된 위치로 이동합니다.

LOCK TABLE categories WRITE;
-- 将要移动的节点摘出来,并且重新边篇 lft 和 rgt
SELECT @move_left := lft , @move_right := rgt, @move_width := rgt - lft + 1
FROM categories WHERE title = 'macOS';
UPDATE categories SET rgt = -rgt WHERE lft BETWEEN @move_left AND @move_right;
UPDATE categories SET lft = -lft WHERE lft BETWEEN @move_left AND @move_right;
UPDATE categories SET rgt = rgt - @move_width WHERE rgt > @move_right;
UPDATE categories SET lft = lft - @move_width WHERE lft > @move_right;
-- 将节点放到 Unix 节点里
SELECT @root_left := lft FROM categories WHERE title = 'Unix';
UPDATE categories SET rgt = rgt + @move_width WHERE rgt > @root_left;
UPDATE categories SET lft = lft + @move_width WHERE lft > @root_left;
-- 
UPDATE categories SET lft = @root_left + 1 WHERE lft BETWEEN -@move_right AND -@move_left;
UPDATE categories SET rgt = @root_left + 2 WHERE rgt BETWEEN -@move_right AND -@move_left;
UNLOCK TABLES;

요약

실제로 SQL에서 중첩 세트의 데이터 모델은 오랫동안 제안되었으며 laravel-nestedset 또는 django-mptt

등 많은 패키지에서 이 기능을 구현했습니다. 이 시리즈의 모든 사람에게 소개되어야 하는 닫힌 테이블이라는 데이터 모델과 같은 단순한 테이블 구조 디자인이나 기타 최적화는 확실히 없습니다.

위 내용은 트리 데이터 구조 저장 방법(CUD)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제