DBMS munyaya iyi inoshanda pamitemo yakafanana - "Vakanditi ndichere, saka ndinochera". Chikumbiro chako hachingodzikisi maitiro evavakidzani, kugara uchitora processor zviwanikwa, asiwo "kudonhedza" database yese, "kudya" zvese zviripo ndangariro. Naizvozvo dziviriro kubva pakudzokororwa kusingaperi - basa remugadziri pachake.
MuPostgreSQL, kugona kushandisa mibvunzo inodzokororwa kuburikidza WITH RECURSIVE
Usanyore mibvunzo inodzokororwa
Uye nyora zvisiri zvekudzokorora. Nemoyo wese, K.O.
Muchokwadi, PostgreSQL inopa kwakawanda kushanda kwaunogona kushandisa kwete shandisa recursion.
Shandisa imwe nzira yakasiyana kune dambudziko
Dzimwe nguva unogona kungotarisa dambudziko kubva "kudivi rakasiyana". Ndakapa muenzaniso wemamiriro ezvinhu akadaro munyaya yacho
WITH RECURSIVE src AS (
SELECT '{2,3,5,7,11,13,17,19}'::integer[] arr
)
, T(i, val) AS (
SELECT
1::bigint
, 1
UNION ALL
SELECT
i + 1
, val * arr[i]
FROM
T
, src
WHERE
i <= array_length(arr, 1)
)
SELECT
val
FROM
T
ORDER BY -- ΠΎΡΠ±ΠΎΡ ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°
i DESC
LIMIT 1;
Ichi chikumbiro chinogona kutsiviwa nesarudzo kubva kunyanzvi dzemasvomhu:
WITH src AS (
SELECT unnest('{2,3,5,7,11,13,17,19}'::integer[]) prime
)
SELECT
exp(sum(ln(prime)))::integer val
FROM
src;
Shandisa generate_series pachinzvimbo chezvishwe
Ngatitii takatarisana nebasa rekugadzira zvese zvinokwanisika prefixes yetambo 'abcdefgh'
:
WITH RECURSIVE T AS (
SELECT 'abcdefgh' str
UNION ALL
SELECT
substr(str, 1, length(str) - 1)
FROM
T
WHERE
length(str) > 1
)
TABLE T;
Une chokwadi chekuti unoda kudzokororwa pano?.. Kana ukashandisa LATERAL
ΠΈ generate_series
, saka hauzotomboda CTE:
SELECT
substr(str, 1, ln) str
FROM
(VALUES('abcdefgh')) T(str)
, LATERAL(
SELECT generate_series(length(str), 1, -1) ln
) X;
Shandura dhizaini chimiro
Semuenzaniso, iwe une tafura yeforum meseji ine hukama kubva kuna ani akapindura, kana tambo mukati
CREATE TABLE message(
message_id
uuid
PRIMARY KEY
, reply_to
uuid
REFERENCES message
, body
text
);
CREATE INDEX ON message(reply_to);
Zvakanaka, chikumbiro chakajairika chekudhawunirodha mameseji ese pane imwe nyaya inotaridzika seizvi:
WITH RECURSIVE T AS (
SELECT
*
FROM
message
WHERE
message_id = $1
UNION ALL
SELECT
m.*
FROM
T
JOIN
message m
ON m.reply_to = T.message_id
)
TABLE T;
Asi sezvo isu tichigara tichida iyo nyaya yese kubva kumudzi meseji, saka nei isu tisingadi wedzera ID yayo kune yega yega otomatiki?
-- Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ»Π΅ Ρ ΠΎΠ±ΡΠΈΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ ΡΠ΅ΠΌΡ ΠΈ ΠΈΠ½Π΄Π΅ΠΊΡ Π½Π° Π½Π΅Π³ΠΎ
ALTER TABLE message
ADD COLUMN theme_id uuid;
CREATE INDEX ON message(theme_id);
-- ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ΅ΠΌΡ Π² ΡΡΠΈΠ³Π³Π΅ΡΠ΅ ΠΏΡΠΈ Π²ΡΡΠ°Π²ΠΊΠ΅
CREATE OR REPLACE FUNCTION ins() RETURNS TRIGGER AS $$
BEGIN
NEW.theme_id = CASE
WHEN NEW.reply_to IS NULL THEN NEW.message_id -- Π±Π΅ΡΠ΅ΠΌ ΠΈΠ· ΡΡΠ°ΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠΎΠ±ΡΡΠΈΡ
ELSE ( -- ΠΈΠ»ΠΈ ΠΈΠ· ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΡΠ²Π΅ΡΠ°Π΅ΠΌ
SELECT
theme_id
FROM
message
WHERE
message_id = NEW.reply_to
)
END;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER ins BEFORE INSERT
ON message
FOR EACH ROW
EXECUTE PROCEDURE ins();
Iye zvino mubvunzo wedu wese unodzokororwa unogona kudzikiswa kuita izvi chete:
SELECT
*
FROM
message
WHERE
theme_id = $1;
Shandisa yakashandiswa "limiters"
Kana isu tisingakwanisi kushandura chimiro chedhatabhesi nekuda kwechimwe chikonzero, ngationei zvatingavimba nazvo kuitira kuti kunyangwe kuvepo kwekukanganisa mune data kusingatungamirire kusingaperi kudzokorora.
Recursion kudzika counter
Isu tinongowedzera kaunda neimwe pane imwe neimwe nhanho yekudzokorodza kudzamara tasvika pamuganho watinoona sekuti hauna kukwana:
WITH RECURSIVE T AS (
SELECT
0 i
...
UNION ALL
SELECT
i + 1
...
WHERE
T.i < 64 -- ΠΏΡΠ΅Π΄Π΅Π»
)
Pro: Kana isu tikayedza kuruka, isu hatingaite zvinopfuura zvakatarwa muganho wekudzokorodza "zvakadzama".
nezvayakaipira: Iko hakuna vimbiso yekuti isu hatizogadzirise rekodhi imwechete zvakare - semuenzaniso, pakadzika kwe15 ne25, uyezve yega +10. Uye hapana akavimbisa chero chinhu nezve "hupamhi".
Pakare, kudzokororwa kwakadaro hakuzove kusingagumi, asi kana padanho rega rega nhamba yemarekodhi ichiwedzera zvakanyanya, isu tese tinoziva zvakanaka kuti inopera sei ...
Muchengeti we "nzira"
Isu tinowedzera kuwedzera zvese zvinongedzo zvechinhu zvatakasangana nazvo munzira yekudzokorodza muhurongwa, inova yakasarudzika "nzira" kwairi:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) -- Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Π½ΠΈ Ρ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ·
)
Pro: Kana paine kutenderera mune data, isu hatizogadzirise rekodhi imwechete kakawanda mukati menzira imwechete.
nezvayakaipira: Asi panguva imwe cheteyo, tinogona kunzvenga zvinyorwa zvese pasina kudzokorora isu pachedu.
Path Length Limit
Kuti udzivise mamiriro ekudzokorora "kudzungaira" pakudzika kusinganzwisisike, tinogona kusanganisa nzira mbiri dzakapfuura. Kana, kana isu tisingadi kutsigira minda isingakoshi, wedzera mamiriro ekuenderera mberi nekudzokororwa nefungidziro yehurefu hwenzira:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) AND
array_length(T.path, 1) < 10
)
Sarudza nzira yekuda kwako!
Source: www.habr.com