PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Съхранявайте многоизмерен масив в база данни:релационен или многоизмерен?

Ако това е всичко, от което се нуждаете, можете да използвате търсене с LIKE

SELECT *FROM Table1WHERE CELL LIKE 'AEE%'; 

С индекс, започващ с CELL това е проверка на диапазон, която е бърза.

Ако вашите данни не изглеждат така, можете да създадете path колона, която изглежда като път на директория и съдържа всички възли "по пътя/пътя" от корена до елемента.

<предварителен код>| ID | КЛЕТКА | parent_id | път ||====|======|===========|==========|| 1 | A | NULL | 1/ || 2 | AA | 1 | 1/2/ || 3 | AAA | 2 | 1/2/3/ || 4 | AAC | 2 | 1/2/4/ || 5 | AB | 1 | 1/5/ || 6 | AE | 1 | 1/6/ | | 7 | AEA | 6 | 1/6/7/ || 8 | AEE | 6 | 1/6/8/ || 9 | AEEB | 8 | 1/6/8/9/ |

За да извлечете всички наследници на „AE“ (включително себе си), вашата заявка ще бъде

SELECT *FROM дърво tWHERE път КАТО '1/6/%'; 

или (специфично за MySQL конкатенация)

SELECT t.*FROM дърво tCROSS JOIN дърво r -- rootWHERE r.CELL ='AE' И t.path LIKE CONCAT(r.path, '%'); 

Резултат:

<предварителен код>| ID | КЛЕТКА | parent_id | път ||====|======|===========|==========|| 6 | AE | 1 | 1/6/ || 7 | AEA | 6 | 1/6/7/ || 8 | AEE | 6 | 1/6/8/ || 9 | AEEB | 8 | 1/6/8/9/ |

Демо

Ефективност

Създадох 100 хиляди реда с фалшиви данни в MariaDB с плъгин за последователност използвайки следния скрипт:

изтрийте таблица, ако съществува дърво; CREATE TABLE дърво ( `id` int първичен ключ, `CELL` varchar(50), `parent_id` int, `path` varchar(255), уникален индекс (`CELL` ), уникален индекс (`path`)); ПУСКАНЕ НА ЗАПУСКАНЕ, АКО СЪЩЕСТВУВА `tree_after_insert`; РАЗДЕЛИТЕЛ //СЪЗДАВАНЕ НА ЗАПУСКАНЕ `tree_after_insert` ПРЕДИ ВМЪКВАНЕ НА `дърво` ЗА ВСЕКИ РЕД НАЧАЛО ако new.id =1 след това задайте new.path :='1/'; else set new.path :=concat(( изберете път от дърво, където id =new.parent_id), new.id, '/'); end if;END//DELIMITER;вмъкване в дърво изберете seq като id, conv(seq, 10, 36) като CELL, случай когато seq =1 тогава null else floor(rand(1) * (seq-1)) + 1 край като parent_id, null като път от seq_1_to_100000; ОТПУСКАНЕ НА ЗАПУСКАНЕ, АКО СЪЩЕСТВУВА `tree_after_insert`;-- време на изпълнение ~ 4 сек. 

Тестове

Пребройте всички елементи под корена:

SELECT count(*)FROM дърво tCROSS JOIN дърво r -- rootWHERE r.CELL ='1' И t.path LIKE CONCAT(r.path, '%');-- резултат:100000-- време на работа:~ 30 ms 

Вземете елементи на поддърво под конкретен възел:

SELECT t.*FROM дърво tCROSS JOIN дърво r -- rootWHERE r.CELL ='3B0' И t.path LIKE CONCAT(r.path, '%');-- време на изпълнение:~ 30 ms 

Резултат:

<предварителен код>| ID | КЛЕТКА | parent_id | път ||=======|======|===========|======================================|| 4284 | 3B0 | 614 | 1/4/11/14/614/4284/ || 6560 | 528 | 4284 | 1/4/11/14/614/4284/6560/ || 8054 | 67Q | 6560 | 1/4/11/14/614/4284/6560/8054/ || 14358 | B2U | 6560 | 1/4/11/14/614/4284/6560/14358/ || 51911 | 141Z | 4284 | 1/4/11/14/614/4284/51911/ || 55695 | 16Z3 | 4284 | 1/4/11/14/614/4284/55695/ || 80172 | 1PV0 | 8054 | 1/4/11/14/614/4284/6560/8054/80172/ || 87101 | 1V7H | 51911 | 1/4/11/14/614/4284/51911/87101/ |

PostgreSQL

Това също работи за PostgreSQL. Трябва да се промени само синтаксисът за конкатенация на низове:

SELECT t.*FROM дърво tCROSS JOIN дърво r -- rootWHERE r.CELL ='AE' И t.path LIKE r.path || '%'; 

Демо: sqlfiddle - rextester

Как работи търсенето

Ако погледнете тестовия пример, ще видите, че всички пътища в резултата започват с '1/4/11/14/614/4284/'. Това е пътят на корена на поддървото с CELL='3B0' . Ако пътят колоната е индексирана, машината ще ги намери всички ефективно, тъй като индексът е сортиран по path . Все едно бихте искали да намерите всички думи, които започват с „pol“ в речник със 100K думи. Няма нужда да четете целия речник.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. sqlalchemy не се изпълнява Коментар на схемата

  2. Какъв е вторият аргумент във функцията array_length()?

  3. PostgreSQL ръчно променя плана за изпълнение на заявката, за да принуди да използва сортиране и последователен достъп вместо пълно сканиране

  4. Защо имаме нужда от посредници на съобщения като RabbitMQ върху база данни като PostgreSQL?

  5. Как мога да получа достъп до база данни postgresql от matlab без кутия с инструменти за база данни на matlabs?