PostgreSQL Antipatterns: เบœเปˆเบฒเบ™เบŠเบธเบ”เปเบฅเบฐเป€เบฅเบทเบญเบ SQL

เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบœเบนเป‰เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ•เป‰เบญเบ‡เบเบฒเบ™ เบœเปˆเบฒเบ™เบŠเบธเบ”เบ‚เบญเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบซเบผเบทเปเบกเป‰เบเบฐเบ—เบฑเป‰เบ‡เบเบฒเบ™เป€เบฅเบทเบญเบเบ—เบฑเบ‡เบซเบกเบปเบ”เบ•เปเปˆเบเบฑเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป "เบขเบนเปˆเบ—เบฒเบ‡เป€เบ‚เบปเป‰เบฒ". เบšเบฒเบ‡โ€‹เบ„เบฑเป‰เบ‡โ€‹เบ—เปˆเบฒเบ™โ€‹เป„เบ”เป‰โ€‹เบžเบปเบšโ€‹เป€เบซเบฑเบ™โ€‹เบงเบดโ€‹เบ—เบตโ€‹เปเบเป‰โ€‹เป„เบ‚ strange เบซเบผเบฒเบโ€‹เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เบšเบฑเบ™โ€‹เบซเบฒโ€‹เบ™เบตเป‰โ€‹.
PostgreSQL Antipatterns: เบœเปˆเบฒเบ™เบŠเบธเบ”เปเบฅเบฐเป€เบฅเบทเบญเบ SQL
เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบเบฑเบšเบ„เบทเบ™เป„เบ›เป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเบšเปเปˆเบ„เบงเบ™เป€เบฎเบฑเบ”, เป€เบ›เบฑเบ™เบซเบเบฑเบ‡, เปเบฅเบฐเบงเบดเบ—เบตเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰เบ”เบตเบเบงเปˆเบฒ.

เบเบฒเบ™เปƒเบชเปˆเบ„เปˆเบฒเป‚เบ”เบเบเบปเบ‡เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบฎเปˆเบฒเบ‡เบเบฒเบเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป

เป‚เบ”เบเบ›เบปเบเบเบฐเบ•เบดเบกเบฑเบ™เป€เบšเบดเปˆเบ‡เบ„เบทเบงเปˆเบฒ:

query = "SELECT * FROM tbl WHERE id = " + value

...เบซเบผเบทเปเบšเบšเบ™เบตเป‰:

query = "SELECT * FROM tbl WHERE id = :param".format(param=value)

เบงเบดเบ—เบตเบเบฒเบ™เบ™เบตเป‰เป„เบ”เป‰เบ–เบทเบเป€เบงเบปเป‰เบฒ, เบ‚เบฝเบ™เปเบฅเบฐ เปเบกเป‰เปเบ•เปˆเปเบ•เป‰เบก เบžเปเบชเบปเบก:

PostgreSQL Antipatterns: เบœเปˆเบฒเบ™เบŠเบธเบ”เปเบฅเบฐเป€เบฅเบทเบญเบ SQL

เป€เบเบทเบญเบšเบชเบฐเป€เบซเบกเบตเบ™เบตเป‰เปเบกเปˆเบ™ เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เป‚เบ”เบเบเบปเบ‡เบเบฑเบšเบเบฒเบ™เบชเบฑเบเบขเบฒ SQL เปเบฅเบฐเบเบฒเบ™เป‚เบซเบผเบ”เบ—เบตเปˆเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบเปˆเบฝเบงเบเบฑเบšเป€เบซเบ”เบœเบปเบ™เบ—เบฒเบ‡เบ—เบธเบฅเบฐเบเบดเบ”, เป€เบŠเบดเปˆเบ‡เบ–เบทเบเบšเบฑเบ‡เบ„เบฑเบšเปƒเบซเป‰ "เบเบฒเบง" เป€เบชเบฑเป‰เบ™เบ„เปเบฒเบ–เบฒเบกเบ‚เบญเบ‡เบ—เปˆเบฒเบ™.

เบงเบดเบ—เบตเบเบฒเบ™เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™ justified เบšเบฒเบ‡เบชเปˆเบงเบ™เบžเบฝเบ‡เปเบ•เปˆเบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบกเบตเบ„เบงเบฒเบกเบˆเปเบฒเป€เบ›เบฑเบ™ เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบเบฒเบ™โ€‹เปเบšเปˆเบ‡โ€‹เบ›เบฑเบ™โ€‹ เปƒเบ™ PostgreSQL เบฎเบธเปˆเบ™ 10 เปเบฅเบฐเบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เป€เบžเบทเปˆเบญเปƒเบซเป‰เป„เบ”เป‰เปเบœเบ™เบเบฒเบ™เบ—เบตเปˆเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบซเบผเบฒเบเบ‚เบถเป‰เบ™. เปƒเบ™เบชเบฐเบšเบฑเบšเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰, เบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ‚เบญเบ‡เบžเบฒเบเบชเปˆเบงเบ™เบ—เบตเปˆเบชเบฐเปเบเบ™เป„เบ”เป‰เบ–เบทเบเบเปเบฒเบ™เบปเบ”เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ„เปเบฒเบ™เบถเบ‡เป€เบ–เบดเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ–เปˆเบฒเบเบ—เบญเบ”, เบžเบฝเบ‡เปเบ•เปˆเบšเบปเบ™เบžเบทเป‰เบ™เบ–เบฒเบ™เบ‚เบญเบ‡เบญเบปเบ‡เบเบฒเบ™เบˆเบฑเบ”เบ•เบฑเป‰เบ‡เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เป.

$n-arguments

เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ เบ•เบปเบงเบเบถเบ” เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เปเบกเปˆเบ™เบ”เบต, เบกเบฑเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ เบ–เบฐเปเบซเบผเบ‡เบเบฒเบ™เบ—เบตเปˆเบเบฝเบกเป„เบงเป‰, เบเบฒเบ™เบซเบผเบธเบ”เบœเปˆเบญเบ™เบเบฒเบ™เป‚เบซเบผเบ”เบ—เบฑเบ‡เปƒเบ™เป€เบซเบ”เบœเบปเบ™เบ—เบฒเบ‡เบ—เบธเบฅเบฐเบเบดเบ” (เบชเบฒเบเปเบšเบšเบชเบญเบšเบ–เบฒเบกเบ–เบทเบเบชเป‰เบฒเบ‡เปเบฅเบฐเบชเบปเปˆเบ‡เบžเบฝเบ‡เปเบ•เปˆเบ„เบฑเป‰เบ‡เบ”เบฝเบง) เปเบฅเบฐเปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ‚เบญเบ‡เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™ (เบเบฒเบ™เปเบเบเบงเบดเป€เบ„เบฒเบฐเบ„เบทเบ™เปƒเบซเบกเปˆเปเบฅเบฐเบเบฒเบ™เบเปเบฒเบ™เบปเบ”เป€เบงเบฅเบฒเบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบ•เบปเบงเบขเปˆเบฒเบ‡เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเปเบกเปˆเบ™เบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™).

เบˆเปเบฒเบ™เบงเบ™เบ•เบปเบงเปเบ›เบ‚เบญเบ‡เบญเบฒเบเบดเบงเป€เบกเบฑเบ™

เบšเบฑเบ™เบซเบฒเบˆเบฐเบฅเปเบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเป€เบกเบทเปˆเบญเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบœเปˆเบฒเบ™เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบ—เบตเปˆเบšเปเปˆเบฎเบนเป‰เบˆเบฑเบ:

... id IN ($1, $2, $3, ...) -- $1 : 2, $2 : 3, $3 : 5, ...

เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบญเบญเบเบˆเบฒเบเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเปƒเบ™เบฎเบนเบšเปเบšเบšเบ™เบตเป‰, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบกเบฑเบ™เบˆเบฐเบ›เบปเบเบ›เป‰เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบˆเบฒเบเบเบฒเบ™เบชเบฑเบเบขเบฒเบ—เบตเปˆเบกเบตเบ—เปˆเบฒเปเบฎเบ‡, เบกเบฑเบ™เบเบฑเบ‡เบ™เปเบฒเป„เบ›เบชเบนเปˆเบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบฅเบงเบก / เปเบเบเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป. เบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ‚เบถเป‰เบ™เบขเบนเปˆเบเบฑเบšเบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡. เบกเบฑเบ™เบ”เบตเบเบงเปˆเบฒเบเบฒเบ™เป€เบฎเบฑเบ”เบกเบฑเบ™เบ—เบธเบเบ„เบฑเป‰เบ‡, เปเบ•เปˆเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰เป‚เบ”เบเบšเปเปˆเบกเบตเบกเบฑเบ™.

เบกเบฑเบ™เบžเบฝเบ‡เบžเปเบ—เบตเปˆเบˆเบฐเบœเปˆเบฒเบ™เบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ—เบตเปˆเบกเบต เบเบฒเบ™เป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™ serialized array:

... id = ANY($1::integer[]) -- $1 : '{2,3,5,8,13}'

เบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡เบžเบฝเบ‡เปเบ•เปˆเปเบกเปˆเบ™เบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ›เปˆเบฝเบ™ argument เป€เบ›เบฑเบ™เบ›เบฐเป€เบžเบ” array เบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เบขเปˆเบฒเบ‡เบŠเบฑเบ”เป€เบˆเบ™. เปเบ•เปˆเบ™เบตเป‰เบšเปเปˆเป„เบ”เป‰เป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบเบตเบ”เบšเบฑเบ™เบซเบฒ, เป€เบžเบฒเบฐเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบฅเปˆเบงเบ‡เบซเบ™เป‰เบฒเปเบฅเป‰เบงเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป„เบ›เปƒเบช.

เบเบฒเบ™โ€‹เป‚เบญเบ™โ€‹เบ•เบปเบงโ€‹เบขเปˆเบฒเบ‡ (matrixโ€‹)

เบ›เบปเบเบเบฐเบ•เบดเปเบฅเป‰เบงเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบ—เบธเบเบ›เบฐเป€เบžเบ”เบ‚เบญเบ‡เบ—เบฒเบ‡เป€เบฅเบทเบญเบเปƒเบ™เบเบฒเบ™เป‚เบญเบ™เบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เปƒเบชเปˆเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™ "เปƒเบ™เบซเบ™เบถเปˆเบ‡เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป":

INSERT INTO tbl(k, v) VALUES($1,$2),($3,$4),...

เบ™เบญเบ เป€เปœเบทเบญ เป„เบ›เบˆเบฒเบเบšเบฑเบ™เบซเบฒเบ—เบตเปˆเบญเบฐเบ—เบดเบšเบฒเบเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡เบ”เป‰เบงเบ "เบเบฒเบ™เบ•เบดเบ”เบเบฒเบงเบ„เบทเบ™" เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เป, เบ™เบตเป‰เบเบฑเบ‡เบชเบฒเบกเบฒเบ” เบ™เบณ เบžเบฒเบžเบงเบเป€เบฎเบปเบฒเป„เบ› เบญเบญเบเบˆเบฒเบเบ„เบงเบฒเบกเบŠเบปเบ‡เบˆเปเบฒ เปเบฅเบฐเป€เบŠเบตเบšเป€เบงเบต crash. เป€เบซเบ”เบœเบปเบ™เปเบกเปˆเบ™เบ‡เปˆเบฒเบเบ”เบฒเบ - PG เบชเบฐเบซเบ‡เบงเบ™เบ„เบงเบฒเบกเบŠเบปเบ‡เบˆเปเบฒเป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡, เปเบฅเบฐเบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡เบšเบฑเบ™เบ—เบถเบเปƒเบ™เบŠเบธเบ”เป„เบ”เป‰เบ–เบทเบเบˆเปเบฒเบเบฑเบ”เบžเบฝเบ‡เปเบ•เปˆเบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเบ‚เบญเบ‡เป€เบซเบ”เบœเบปเบ™เบ—เบฒเบ‡เบ—เบธเบฅเบฐเบเบดเบ”. เป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบเปเบฅเบฐเบ™เบตเบ—เบฒเบ‡เบ”เป‰เบฒเบ™เบ„เบฅเบตเบ™เบดเบเบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เป€เบšเบดเปˆเบ‡ เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡ "เบˆเปเบฒเบ™เบงเบ™" เปเบกเปˆเบ™เบซเบผเบฒเบเบเปˆเบงเบฒ $9000 - เบขเปˆเบฒเป€เบฎเบฑเบ”เปเบšเบšเบ™เบตเป‰.

เปƒเบซเป‰เบ‚เบฝเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบ„เบทเบ™เปƒเบซเบกเปˆเป‚เบ”เบเปƒเบŠเป‰เปเบฅเป‰เบง serialization "เบชเบญเบ‡เบฅเบฐเบ”เบฑเบš".:

INSERT INTO tbl
SELECT
  unnest[1]::text k
, unnest[2]::integer v
FROM (
  SELECT
    unnest($1::text[])::text[] -- $1 : '{"{a,1}","{b,2}","{c,3}","{d,4}"}'
) T;

เปเบกเปˆเบ™เปเบฅเป‰เบง, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡เบ„เปˆเบฒ "เบŠเบฑเบšเบŠเป‰เบญเบ™" เบžเบฒเบเปƒเบ™ array, เบžเบงเบเป€เบ‚เบปเบฒเบ•เป‰เบญเบ‡เบ–เบทเบเบญเป‰เบญเบกเบฎเบญเบšเบ”เป‰เบงเบเบงเบปเบ‡เบขเบทเบก.
เบกเบฑเบ™เป€เบ›เบฑเบ™เบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™เบงเปˆเบฒเบ”เป‰เบงเบเบงเบดเบ—เบตเบ™เบตเป‰, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ” "เบ‚เบฐเบซเบเบฒเบ" เบเบฒเบ™เบ„เบฑเบ”เป€เบฅเบทเบญเบเบ—เบตเปˆเบกเบตเบˆเปเบฒเบ™เบงเบ™เป€เบ‚เบ”เบ—เบตเปˆเบ•เบปเบ™เป€เบญเบ‡เบกเบฑเบ.

unnest, unnest, โ€ฆ

เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบกเบตเบ—เบฒเบ‡เป€เบฅเบทเบญเบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ–เปˆเบฒเบเบ—เบญเบ”เปเบ—เบ™เบ—เบตเปˆเบˆเบฐเป€เบ›เบฑเบ™ "เบญเบฒเป€เบฃเบ‚เบญเบ‡เบญเบฒเป€เบฃ" เบซเบผเบฒเบ "เบญเบฒเป€เบฃเบ‚เบญเบ‡เบ–เบฑเบ™" เบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบเปˆเบฒเบงเป€เบ–เบดเบ‡. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ:

SELECT
  unnest($1::text[]) k
, unnest($2::integer[]) v;

เบ”เป‰เบงเบเบงเบดเบ—เบตเบ™เบตเป‰, เบ–เป‰เบฒเบ—เปˆเบฒเบ™เป€เบฎเบฑเบ”เบœเบดเบ”เบžเบฒเบ”เปƒเบ™เป€เบงเบฅเบฒเบชเป‰เบฒเบ‡เบฅเบฒเบเบเบฒเบ™เบกเบนเบ™เบ„เปˆเบฒเบชเปเบฒเบฅเบฑเบšเบ„เปเบฅเปเบฒเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™, เบกเบฑเบ™เบ‡เปˆเบฒเบเบ—เบตเปˆเบˆเบฐเป„เบ”เป‰เบฎเบฑเบš. เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบ—เบตเปˆเบšเปเปˆเบ„เบฒเบ”เบ„เบดเบ”, เป€เบŠเบดเปˆเบ‡เบ‚เบถเป‰เบ™เบเบฑเบšเป€เบงเบตเบŠเบฑเบ™เป€เบŠเบตเบšเป€เบงเบต:

-- $1 : '{a,b,c}', $2 : '{1,2}'
-- PostgreSQL 9.4
k | v
-----
a | 1
b | 2
c | 1
a | 2
b | 1
c | 2
-- PostgreSQL 11
k | v
-----
a | 1
b | 2
c |

JSON

เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบชเบฐเบšเบฑเบš 9.3, PostgreSQL เบกเบตเบซเบ™เป‰เบฒเบ—เบตเปˆเป€เบ•เบฑเบกเบ—เบตเปˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบ›เบฐเป€เบžเบ” json. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ–เป‰เบฒเบ„เปเบฒเบ™เบดเบเบฒเบกเบ‚เบญเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ›เป‰เบญเบ™เบ‚เปเป‰เบกเบนเบ™เป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เบ•เบปเบงเบ—เปˆเบญเบ‡เป€เบงเบฑเบšเบ‚เบญเบ‡เบ—เปˆเบฒเบ™, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ›เบฐเบเบญเบšเบกเบฑเบ™เบขเบนเปˆเบ—เบตเปˆเบ™เบฑเป‰เบ™ json object เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเบญเบšเบ–เบฒเบก SQL:

SELECT
  key k
, value v
FROM
  json_each($1::json); -- '{"a":1,"b":2,"c":3,"d":4}'

เบชเปเบฒเบฅเบฑเบšเบชเบฐเบšเบฑเบšเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ, เบงเบดเบ—เบตเบเบฒเบ™เบ”เบฝเบงเบเบฑเบ™เบชเบฒเบกเบฒเบ”เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป€เบžเบทเปˆเบญ เปเบ•เปˆเบฅเบฐ(hstore), เปเบ•เปˆ "convolution" เบ—เบตเปˆเบ–เบทเบเบ•เป‰เบญเบ‡เบเบฑเบš escaping เบงเบฑเบ”เบ–เบธเบชเบฐเบฅเบฑเบšเบชเบฑเบšเบŠเป‰เบญเบ™เปƒเบ™ hstore เบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบเบตเบ”เบšเบฑเบ™เบซเบฒ.

json_populate_recordset

เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบฎเบนเป‰เบฅเปˆเบงเบ‡เบซเบ™เป‰เบฒเบงเปˆเบฒเบ‚เปเป‰เบกเบนเบ™เบˆเบฒเบ "input" json array เบˆเบฐเบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป€เบžเบทเปˆเบญเบ•เบทเปˆเบกเบ‚เปเป‰เบกเบนเบ™เปƒเบชเปˆเบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบˆเปเบฒเบ™เบงเบ™เบซเบ™เบถเปˆเบ‡, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ›เบฐเบซเบเบฑเบ”เป„เบ”เป‰เบซเบผเบฒเบเปƒเบ™ "dereferencing" เบžเบฒเบเบชเบฐเบซเบ™เบฒเบกเปเบฅเบฐเป‚เบเบ™เบžเบงเบเบกเบฑเบ™เป„เบ›เบซเบฒเบ›เบฐเป€เบžเบ”เบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เป‚เบ”เบเปƒเบŠเป‰เบŸเบฑเบ‡เบŠเบฑเบ™ json_populate_recordset:

SELECT
  *
FROM
  json_populate_recordset(
    NULL::pg_class
  , $1::json -- $1 : '[{"relname":"pg_class","oid":1262},{"relname":"pg_namespace","oid":2615}]'
  );

json_to_recordset

เปเบฅเบฐเบŸเบฑเบ‡เบŠเบฑเบ™เบ™เบตเป‰เบˆเบฐเบžเบฝเบ‡เปเบ•เปˆ "เบ‚เบฐเบซเบเบฒเบ" array เบ—เบตเปˆเบœเปˆเบฒเบ™เบ‚เบญเบ‡เบงเบฑเบ”เบ–เบธเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบเบฒเบ™เบ„เบฑเบ”เป€เบฅเบทเบญเบ, เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบญเบตเบ‡เปƒเบชเปˆเบฎเบนเบšเปเบšเบšเบ•เบฒเบ•เบฐเบฅเบฒเบ‡:

SELECT
  *
FROM
  json_to_recordset($1::json) T(k text, v integer);
-- $1 : '[{"k":"a","v":1},{"k":"b","v":2}]'
k | v
-----
a | 1
b | 2

เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบŠเบปเปˆเบงเบ„เบฒเบง

เปเบ•เปˆเบ–เป‰เบฒเบˆเปเบฒเบ™เบงเบ™เบ‚เปเป‰เบกเบนเบ™เปƒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบ–เบทเบเป‚เบญเบ™เปเบกเปˆเบ™เปƒเบซเบเปˆเบซเบผเบฒเบ, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบเบฒเบ™เบ–เบดเป‰เบกเบกเบฑเบ™เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™ serialized เบซเบ™เบถเปˆเบ‡เปเบกเปˆเบ™เบกเบตเบ„เบงเบฒเบกเบซเบเบธเป‰เบ‡เบเบฒเบเปเบฅเบฐเบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบเปเปˆเป€เบ›เบฑเบ™เป„เบ›เบšเปเปˆเป„เบ”เป‰, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบกเบฑเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบซเบ™เบถเปˆเบ‡เบ„เบฑเป‰เบ‡. เบˆเบฑเบ”เบชเบฑเบ™เบˆเปเบฒเบ™เบงเบ™เบ‚เบฐเบซเบ™เบฒเบ”เปƒเบซเบเปˆเบ‚เบญเบ‡เบซเบ™เปˆเบงเบเบ„เบงเบฒเบกเบˆเปเบฒ. เบ•เบปเบงเบขเปˆเบฒเบ‡, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบเบฑเบšเบเปเบฒเบ‚เปเป‰เบกเบนเบ™เบŠเบธเบ”เปƒเบซเบเปˆเบเปˆเบฝเบงเบเบฑเบšเป€เบซเบ”เบเบฒเบ™เบˆเบฒเบเบฅเบฐเบšเบปเบšเบžเบฒเบเบ™เบญเบเป€เบ›เบฑเบ™เป€เบงเบฅเบฒเบ”เบปเบ™, เบ”เบปเบ™เบ™เบฒเบ™, เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบซเบ™เบถเปˆเบ‡เบ„เบฑเป‰เบ‡เปƒเบ™เบ”เป‰เบฒเบ™เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™.

เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบ™เบตเป‰, เบเบฒเบ™เปเบเป‰เป„เบ‚เบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบชเบธเบ”เปเบกเปˆเบ™เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ เบ•เบฒโ€‹เบ•เบฐโ€‹เบฅเบฒเบ‡โ€‹เบŠเบปเปˆเบงโ€‹เบ„เบฒเบงโ€‹:

CREATE TEMPORARY TABLE tbl(k text, v integer);
...
INSERT INTO tbl(k, v) VALUES($1, $2); -- ะฟะพะฒั‚ะพั€ะธั‚ัŒ ะผะฝะพะณะพ-ะผะฝะพะณะพ ั€ะฐะท
...
-- ั‚ัƒั‚ ะดะตะปะฐะตะผ ั‡ั‚ะพ-ั‚ะพ ะฟะพะปะตะทะฝะพะต ัะพ ะฒัะตะน ัั‚ะพะน ั‚ะฐะฑะปะธั†ะตะน ั†ะตะปะธะบะพะผ

เบงเบดเบ—เบตเบเบฒเบ™เปเบกเปˆเบ™เบ”เบต เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบเป‰เบฒเบเปƒเบ™เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบ„เบฒเบงเบ‚เบญเบ‡เบ›เบฐเบฅเบดเบกเบฒเบ™เบ‚เบฐเบซเบ™เบฒเบ”เปƒเบซเบเปˆ เบ‚เปเป‰เบกเบนเบ™.
เบˆเบฒเบเบ—เบฑเบ”เบชเบฐเบ™เบฐเบ‚เบญเบ‡เบเบฒเบ™เบญเบฐเบ—เบดเบšเบฒเบเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ‚เบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เบกเบฑเบ™, เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบŠเบปเปˆเบงเบ„เบฒเบงเปเบ•เบเบ•เปˆเบฒเบ‡เบˆเบฒเบ "เบ›เบปเบเบเบฐเบ•เบด" เปƒเบ™เบ—เบฒเบ‡เบ”เบฝเบง. เปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบฅเบฐเบšเบปเบš pg_class, เปเบฅเบฐเปƒเบ™ pg_type, pg_depend, pg_attribute, pg_attrdef, ... - เบšเปเปˆโ€‹เบกเบตโ€‹เบซเบเบฑเบ‡โ€‹เป€เบฅเบตเบ.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปƒเบ™เบฅเบฐเบšเบปเบšเป€เบงเบฑเบšเป„เบŠเบ•เปŒเบ—เบตเปˆเบกเบตเบˆเปเบฒเบ™เบงเบ™เบ‚เบฐเบซเบ™เบฒเบ”เปƒเบซเบเปˆเบ‚เบญเบ‡เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบชเบฑเป‰เบ™เบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบ„เบปเบ™, เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบˆเบฐเบชเป‰เบฒเบ‡เบšเบฑเบ™เบ—เบถเบเบฅเบฐเบšเบปเบšเปƒเบซเบกเปˆเปƒเบ™เปเบ•เปˆเบฅเบฐเบ„เบฑเป‰เบ‡, เป€เบŠเบดเปˆเบ‡เบˆเบฐเบ–เบทเบเบฅเบถเบšเบ–เบดเป‰เบกเป€เบกเบทเปˆเบญเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบšเบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบ–เบทเบเบ›เบดเบ”. เปƒเบ™เบ—เบตเปˆเบชเบธเบ”, เบเบฒเบ™เปƒเบŠเป‰ TEMP TABLE เบ—เบตเปˆเบšเปเปˆเบชเบฒเบกเบฒเบ”เบ„เบงเบšเบ„เบธเบกเป„เบ”เป‰เป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบเบตเบ” "เบญเบฒเบเบฒเบ™เบšเบงเบก" เบ‚เบญเบ‡เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เปƒเบ™ pg_catalog. เปเบฅเบฐเบŠเป‰เบฒเบฅเบปเบ‡เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบˆเปเบฒเบ™เบงเบ™เบซเบผเบฒเบเบ—เบตเปˆเปƒเบŠเป‰เบžเบงเบเบกเบฑเบ™.
เปเบ™เปˆเบ™เบญเบ™, เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เบˆเบฑเบ”เบเบฒเบ™เบเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ passage เป€เบ›เบฑเบ™เป„เบฅเบเบฐ VACUUM เป€เบ•เบฑเบก เบญเบตเบ‡เบ•เบฒเบกเบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบฅเบฐเบšเบปเบš.

เบ•เบปเบงเปเบ›เบ‚เบญเบ‡เป€เบŠเบ”เบŠเบฑเบ™

เปƒเบซเป‰เบชเบปเบกเบกเบธเบ”เบงเปˆเบฒเบเบฒเบ™เบ›เบธเบ‡เปเบ•เปˆเบ‡เบ‚เปเป‰เบกเบนเบ™เบˆเบฒเบเบเปเบฅเบฐเบ™เบตเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเปเบกเปˆเบ™เบ‚เป‰เบญเบ™เบ‚เป‰เบฒเบ‡เบชเบฑเบšเบชเบปเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเบญเบšเบ–เบฒเบก SQL เบซเบ™เบถเปˆเบ‡, เปเบ•เปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบกเบฑเบ™เป€เบฅเบทเป‰เบญเบเป†. เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เปƒเบŠเป‰เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ›เบธเบ‡เปเบ•เปˆเบ‡เปƒเบ™ เป€เบฎเบฑเบ”เบšเบฅเบฑเบญเบ, เปเบ•เปˆเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เป‚เบญเบ™เบ‚เปเป‰เบกเบนเบ™เบœเปˆเบฒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบŠเบปเปˆเบงเบ„เบฒเบงเบˆเบฐเบกเบตเบฅเบฒเบ„เบฒเปเบžเบ‡เป€เบเบตเบ™เป„เบ›.

เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเบเบฑเบ‡เบˆเบฐเบšเปเปˆเบชเบฒเบกเบฒเบ”เปƒเบŠเป‰ $n-parameters เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเบปเปˆเบ‡เบ•เปเปˆเบเบฑเบšเบšเบฅเบฑเบญเบเบ—เบตเปˆเบšเปเปˆเป€เบ›เบตเบ”เป€เบœเบตเบเบŠเบทเปˆเป„เบ”เป‰. เบ•เบปเบงเปเบ› Session เปเบฅเบฐเบซเบ™เป‰เบฒเบ—เบตเปˆเบˆเบฐเบŠเปˆเบงเบเปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบญเบญเบเบˆเบฒเบเบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™เบ™เบตเป‰ เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ›เบฐเบˆเบธเบšเบฑเบ™.

เบเปˆเบญเบ™โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบชเบฐโ€‹เบšเบฑเบš 9.2 เบกเบฑเบ™โ€‹เบˆเปเบฒโ€‹เป€เบ›เบฑเบ™โ€‹เบ•เป‰เบญเบ‡โ€‹เป„เบ”เป‰โ€‹เบเปเบฒโ€‹เบ™เบปเบ”โ€‹เป„เบงเป‰โ€‹เบฅเปˆเบงเบ‡โ€‹เบซเบ™เป‰เบฒโ€‹ namespace เบžเบดเป€เบชเบ” custom_variable_classes เบชเปเบฒเบฅเบฑเบšเบ•เบปเบงเปเบ›เบ‚เบญเบ‡เป€เบŠเบ”เบŠเบฑเบ™ "เบ‚เบญเบ‡เป€เบˆเบปเป‰เบฒ". เปƒเบ™เบชเบฐเบšเบฑเบšเบ›เบฐเบˆเบธเบšเบฑเบ™เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ‚เบฝเบ™เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™เบ™เบตเป‰:

SET my.val = '{1,2,3}';
DO $$
DECLARE
  id integer;
BEGIN
  FOR id IN (SELECT unnest(current_setting('my.val')::integer[])) LOOP
    RAISE NOTICE 'id : %', id;
  END LOOP;
END;
$$ LANGUAGE plpgsql;
-- NOTICE:  id : 1
-- NOTICE:  id : 2
-- NOTICE:  id : 3

เบงเบดเบ—เบตเปเบเป‰เป„เบ‚เบญเบทเปˆเบ™เป†เบญเบฒเบ”เบˆเบฐเบ–เบทเบเบžเบปเบšเป€เบซเบฑเบ™เบขเบนเปˆเปƒเบ™เบžเบฒเบชเบฒเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบญเบทเปˆเบ™เป†เบ—เบตเปˆเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™.

เป€เบˆเบปเป‰เบฒเบฎเบนเป‰เบงเบดเบ—เบตเบญเบทเปˆเบ™เบšเป? เปเบšเปˆเบ‡เบ›เบฑเบ™เปƒเบ™เบ„เปเบฒเป€เบซเบฑเบ™!

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™