PostgreSQL เชฎเชพเช‚ เชชเช‚เช•เซเชคเชฟ เชธเซเชคเชฐเชจเซ€ เชธเซเชฐเช•เซเชทเชพเชจเชพ เช…เชฎเชฒเซ€เช•เชฐเชฃ เชชเชฐเชจเซ‹ เช…เชญเซเชฏเชพเชธ

เชจเชพ เชชเซ‚เชฐเช• เชคเชฐเซ€เช•เซ‡ PostgreSQL เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชพเชฐเซเชฏเซ‹เชจเชพ เชธเซเชคเชฐเซ‡ เชฌเชฟเชเชจเซ‡เชธ เชฒเซ‹เชœเซ€เช•เชจเชพ เช…เชฎเชฒเซ€เช•เชฐเชฃ เชชเชฐเชจเซ‹ เช…เชญเซเชฏเชพเชธ ะธ เชฎเซเช–เซเชฏเชคเซเชตเซ‡ เชตเชฟเช—เชคเชตเชพเชฐ เชœเชตเชพเชฌ เชฎเชพเชŸเซ‡ เชชเชฐ เชญเชพเชทเซเชฏ.

เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชญเชพเช— เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃเชฎเชพเช‚ เชธเชพเชฐเซ€ เชฐเซ€เชคเซ‡ เชตเชฐเซเชฃเชตเซ‡เชฒ เช›เซ‡ PostgreSQL - เชชเช‚เช•เซเชคเชฟ เชธเช‚เชฐเช•เซเชทเชฃ เชจเซ€เชคเชฟเช“. เชจเซ€เชšเซ‡ เชเช• เชจเชพเชจเซเช‚ เชตเซเชฏเชตเชนเชพเชฐเซ เช…เชฎเชฒเซ€เช•เชฐเชฃ เช›เซ‡ เชตเชฟเชถเชฟเชทเซเชŸ เชตเซเชฏเชตเชธเชพเชฏ เช•เชพเชฐเซเชฏ - เช•เชพเชขเซ€ เชจเชพเช–เซ‡เชฒเซ‹ เชกเซ‡เชŸเชพ เช›เซเชชเชพเชตเชตเซ‹. เช…เชฎเชฒเซ€เช•เชฐเชฃ เชฎเชพเชŸเซ‡ เชธเชฎเชฐเซเชชเชฟเชค เชธเซเช•เซ‡เชš RLS เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชฐเซ‹เชฒ เชฎเซ‹เชกเซ‡เชฒเชฟเช‚เช— เช…เชฒเช—เชฅเซ€ เชฐเชœเซ‚ เช•เชฐเซเชฏเซเช‚.

PostgreSQL เชฎเชพเช‚ เชชเช‚เช•เซเชคเชฟ เชธเซเชคเชฐเชจเซ€ เชธเซเชฐเช•เซเชทเชพเชจเชพ เช…เชฎเชฒเซ€เช•เชฐเชฃ เชชเชฐเชจเซ‹ เช…เชญเซเชฏเชพเชธ

เชฒเซ‡เช–เชฎเชพเช‚ เช•เช‚เชˆ เชจเชตเซเช‚ เชจเชฅเซ€, เช•เซ‹เชˆ เช›เซเชชเชพเชฏเซ‡เชฒ เช…เชฐเซเชฅ เช•เซ‡ เช—เซเชชเซเชค เชœเซเชžเชพเชจ เชจเชฅเซ€. เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชตเชฟเชšเชพเชฐเชจเชพ เชตเซเชฏเชตเชนเชพเชฐเชฟเช• เช…เชฎเชฒเซ€เช•เชฐเชฃ เชตเชฟเชถเซ‡ เชฎเชพเชคเซเชฐ เชเช• เชธเซเช•เซ‡เชš. เชœเซ‹ เช•เซ‹เชˆเชจเซ‡ เชฐเชธ เชนเซ‹เชฏ เชคเซ‹ เชตเชพเช‚เชšเซ‹. เชœเซ‹ เชคเชฎเชจเซ‡ เชฐเชธ เชจเชฅเซ€, เชคเซ‹ เชคเชฎเชพเชฐเซ‹ เชธเชฎเชฏ เชฌเช—เชพเชกเซ‹ เชจเชนเซ€เช‚.

เชธเชฎเชธเซเชฏเชพเชจเซ€ เชฐเชšเชจเชพ

เชตเชฟเชทเชฏเชจเชพ เช•เซเชทเซ‡เชคเซเชฐเชฎเชพเช‚ เชŠเช‚เชกเชพเชฃเชชเซ‚เชฐเซเชตเช• เชกเชพเช‡เชต เช•เชฐเซเชฏเชพ เชตเชฟเชจเชพ, เชธเช‚เช•เซเชทเชฟเชชเซเชคเชฎเชพเช‚, เชธเชฎเชธเซเชฏเชพ เชจเซ€เชšเซ‡ เชชเซเชฐเชฎเชพเชฃเซ‡ เช˜เชกเซ€ เชถเช•เชพเชฏ เช›เซ‡: เชคเซเชฏเชพเช‚ เชเช• เชŸเซ‡เชฌเชฒ เช›เซ‡ เชœเซ‡ เชšเซ‹เช•เซเช•เชธ เชฌเชฟเชเชจเซ‡เชธ เชเชจเซเชŸเชฟเชŸเซ€เชจเซ‹ เช…เชฎเชฒ เช•เชฐเซ‡ เช›เซ‡. เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚เชจเซ€ เชชเช‚เช•เซเชคเชฟเช“ เช•เชพเชขเซ€ เชถเช•เชพเชฏ เช›เซ‡, เชชเชฐเช‚เชคเซ เชชเช‚เช•เซเชคเชฟเช“ เชญเซŒเชคเชฟเช• เชฐเซ€เชคเซ‡ เช•เชพเชขเซ€ เชถเช•เชพเชคเซ€ เชจเชฅเซ€; เชคเซ‡ เช›เซเชชเชพเชฏเซ‡เชฒเซ€ เชนเซ‹เชตเซ€ เช†เชตเชถเซเชฏเช• เช›เซ‡.

เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เช•เชนเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡: "เช•เช‚เชˆเชชเชฃ เช•เชพเชขเซ€ เชจเชพเช–เชถเซ‹ เชจเชนเซ€เช‚, เชซเช•เซเชค เชคเซ‡เชจเซเช‚ เชจเชพเชฎ เชฌเชฆเชฒเซ‹. เชˆเชจเซเชŸเชฐเชจเซ‡เชŸ เชฌเชงเซเช‚ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‡ เช›เซ‡"

เชฐเชธเซเชคเชพเชฎเชพเช‚, เช† เชเชจเซเชŸเชฟเชŸเซ€ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชคเชพ เชนเชพเชฒเชจเชพ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชพเชฐเซเชฏเซ‹เชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชฒเช–เชตเชพเชจเซ€ เชธเชฒเชพเชน เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เช† เช–เซเชฏเชพเชฒเชจเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเชพ เชฎเชพเชŸเซ‡, เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ เชตเชฟเชถเซ‡เชทเชคเชพ เช›เซ‡ เช•เชพเชขเซ€ เชจเชพเช–เซ‡เชฒ เช›เซ‡. เชชเช›เซ€ เชฌเชงเซเช‚ เชธเชฐเชณ เช›เซ‡ - เชคเชฎเชพเชฐเซ‡ เช–เชพเชคเชฐเซ€ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เช•เซ‡ เช•เซเชฒเชพเชฏเช‚เชŸ เชซเช•เซเชค เชคเซ‡ เชœ เชฐเซ‡เช–เชพเช“ เชœเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡ เชœเซ‡เชฎเชพเช‚ เชฒเช•เซเชทเชฃ เช›เซ‡ เช•เชพเชขเซ€ เชจเชพเช–เซ‡เชฒ เช›เซ‡ เช–เซ‹เชŸเซเช‚ เชฎเชฟเช•เซ‡เชจเชฟเชเชฎ เชถเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เชตเชชเชฐเชพเชฏ เช›เซ‡? เชชเช‚เช•เซเชคเชฟ เชธเซเชคเชฐ เชธเซเชฐเช•เซเชทเชพ.

ะ ะตะฐะปะธะทะฐั†ะธั

เชเช• เช…เชฒเช— เชญเซ‚เชฎเชฟเช•เชพ เช…เชจเซ‡ เชธเซเช•เซ€เชฎเชพ เชฌเชจเชพเชตเซ‹

CREATE ROLE repos;
CREATE SCHEMA repos;

เชฒเช•เซเชทเซเชฏ เชŸเซ‡เชฌเชฒ เชฌเชจเชพเชตเซ‹

CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos

เชšเชพเชฒเซ เช•เชฐเซ‹ เชชเช‚เช•เซเชคเชฟ เชธเซเชคเชฐ เชธเซเชฐเช•เซเชทเชพ

ALTER TABLE repos.file  ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted  ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;

เชธเซ‡เชตเชพ เช•เชพเชฐเซเชฏ - เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚เชฅเซ€ เชเช• เชชเช‚เช•เซเชคเชฟ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚

CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE 
WHERE id = curr_id ; 
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

เชตเซเชฏเชพเชชเชพเชฐ เช•เชพเชฐเซเชฏ - เชฆเชธเซเชคเชพเชตเซ‡เชœ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚

CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM  repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

เชฐเชฟเชเชฒเซเชŸ

เช•เซเชฒเชพเชฏเช‚เชŸ เชฆเชธเซเชคเชพเชตเซ‡เชœ เช•เชพเชขเซ€ เชจเชพเช–เซ‡ เช›เซ‡

SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );

เช•เชพเชขเซ€ เชจเชพเช–เซเชฏเชพ เชชเช›เซ€, เช•เซเชฒเชพเชฏเช‚เชŸ เชฆเชธเซเชคเชพเชตเซ‡เชœ เชœเซ‹เชคเซ‹ เชจเชฅเซ€

SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)

เชชเชฐเช‚เชคเซ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เชฆเชธเซเชคเชพเชตเซ‡เชœ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชฎเชพเช‚ เช†เชตเชคเซ‹ เชจเชฅเซ€, เชฎเชพเชคเซเชฐ เชฒเช•เซเชทเชฃ เชฌเชฆเชฒเชพเชฏ เช›เซ‡ is_del

psql -d my_db
SELECT  id, name , is_del FROM repos.file ;
id |  name  | is_del
--+---------+------------
 1 |  test_1 | t
(1 row)

เชœเซ‡ เชธเชฎเชธเซเชฏเชพ เชจเชฟเชตเซ‡เชฆเชจเชฎเชพเช‚ เชœเชฐเซ‚เชฐเซ€ เชนเชคเซเช‚.

เชชเชฐเชฟเชฃเชพเชฎ

เชœเซ‹ เชตเชฟเชทเชฏ เชฐเชธเชชเซเชฐเชฆ เช›เซ‡, เชคเซ‹ เชชเช›เซ€เชจเชพ เช…เชญเซเชฏเชพเชธเชฎเชพเช‚ เชคเชฎเซ‡ เชฐเซ‹ เชฒเซ‡เชตเชฒ เชธเชฟเช•เซเชฏเซ‹เชฐเชฟเชŸเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชกเซ‡เชŸเชพ เชเช•เซเชธเซ‡เชธเชจเซ‡ เช…เชฒเช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฐเซ‹เชฒ-เช†เชงเชพเชฐเชฟเชค เชฎเซ‹เชกเชฒเชจเชพ เช…เชฎเชฒเซ€เช•เชฐเชฃเชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เชฌเชคเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹.

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹