เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ เชเชจเซเชŸเชฟเชชเซ‡เชŸเชฐเซเชจ: "เชฎเซƒเชค" เชจเซ€ เชฒเชกเชพเชˆ

PostgreSQL เชจเซ€ เช†เช‚เชคเชฐเชฟเช• เชฎเชฟเช•เซ‡เชจเชฟเชเชฎเซเชธเชจเซ€ เชตเชฟเชถเชฟเชทเซเชŸเชคเชพเช“ เชคเซ‡เชจเซ‡ เช•เซ‡เชŸเชฒเซ€เช• เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเช“เชฎเชพเช‚ เช–เซ‚เชฌ เชœ เชเชกเชชเซ€ เช…เชจเซ‡ เช…เชจเซเชฏเชฎเชพเช‚ "เช–เซ‚เชฌ เชเชกเชชเซ€ เชจเชนเซ€เช‚" เชฅเชตเชพ เชฆเซ‡ เช›เซ‡. เช†เชœเซ‡ เช†เชชเชฃเซ‡ DBMS เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฐเซเชฏ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพ เชคเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เชถเซเช‚ เช•เชฐเซ‡ เช›เซ‡ เชคเซ‡ เชตเชšเซเชšเซ‡เชจเชพ เชธเช‚เช˜เชฐเซเชทเชจเชพ เช‰เชคเซเชคเชฎ เช‰เชฆเชพเชนเชฐเชฃ เชชเชฐ เชงเซเชฏเชพเชจ เช•เซ‡เชจเซเชฆเซเชฐเชฟเชค เช•เชฐเซ€เชถเซเช‚ - เช…เชชเชกเซ‡เชŸ เชตเชฟ MVCC เชธเชฟเชฆเซเชงเชพเช‚เชคเซ‹.

เชฎเชพเช‚เชฅเซ€ เชธเช‚เช•เซเชทเชฟเชชเซเชค เชตเชพเชฐเซเชคเชพ เชฎเชนเชพเชจ เชฒเซ‡เช–:

เชœเซเชฏเชพเชฐเซ‡ เชชเช‚เช•เซเชคเชฟ เช…เชชเชกเซ‡เชŸ เช†เชฆเซ‡เชถ เชฆเซเชตเชพเชฐเชพ เชธเช‚เชถเซ‹เชงเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เช–เชฐเซ‡เช–เชฐ เชฌเซ‡ เช•เชพเชฎเช—เซ€เชฐเซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡: เช•เชพเชขเซ€ เชจเชพเช–เซ‹ เช…เชจเซ‡ เชฆเชพเช–เชฒ เช•เชฐเซ‹. IN เชถเชฌเซเชฆเชฎเชพเชณเชพเชจเซเช‚ เชตเชฐเซเชคเชฎเชพเชจ เชธเช‚เชธเซเช•เชฐเชฃ xmax เช เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡เชฒ เชตเซเชฏเชตเชนเชพเชฐเชจเซ€ เชธเช‚เช–เซเชฏเชพเชจเซ€ เชฌเชฐเชพเชฌเชฐ เชธเซ‡เชŸ เช•เชฐเซ‡เชฒ เช›เซ‡. เชชเช›เซ€ เชคเซ‡ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชจเชตเซ€ เช†เชตเซƒเชคเซเชคเชฟ เชธเชฎเชพเชจ เชฐเซ‡เช–เชพ; เชคเซ‡เชจเซเช‚ xmin เชฎเซ‚เชฒเซเชฏ เช…เช—เชพเช‰เชจเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเชพ xmax เชฎเซ‚เชฒเซเชฏ เชธเชพเชฅเซ‡ เชเช•เชฐเซเชช เช›เซ‡.

เช† เชŸเซเชฐเชพเชจเซเชเซ‡เช•เซเชถเชจ เชชเซ‚เชฐเซเชฃ เชฅเชฏเชพเชจเชพ เช…เชฎเซเช• เชธเชฎเชฏ เชชเช›เซ€, เชœเซ‚เชจเซ€ เช…เชฅเชตเชพ เชจเชตเซ€ เช†เชตเซƒเชคเซเชคเชฟ, เชคเซ‡เชจเชพ เช†เชงเชพเชฐเซ‡ COMMIT/ROOLBACK, เช“เชณเช–เชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ "เชฎเซƒเชค" (เชฎเซƒเชค เชŸเชชเชฒเซเชธ) เชœเซเชฏเชพเชฐเซ‡ เชชเชธเชพเชฐ เชฅเชพเชฏ เช›เซ‡ VACUUM เชŸเซ‡เชฌเชฒ เช…เชจเซเชธเชพเชฐ เช…เชจเซ‡ เชธเชพเชซ.

เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ เชเชจเซเชŸเชฟเชชเซ‡เชŸเชฐเซเชจ: "เชฎเซƒเชค" เชจเซ€ เชฒเชกเชพเชˆ

เชชเชฐเช‚เชคเซ เช† เชคเชฐเชค เชœ เชฅเชถเซ‡ เชจเชนเซ€เช‚, เชชเชฐเช‚เชคเซ "เชฎเซƒเชค" เชธเชพเชฅเซ‡เชจเซ€ เชธเชฎเชธเซเชฏเชพเช“ เช–เซ‚เชฌ เชœ เชเชกเชชเชฅเซ€ เชนเชธเซเชคเช—เชค เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡ - เชตเชพเชฐเช‚เชตเชพเชฐ เช…เชฅเชตเชพ เชฐเซ‡เช•เซ‹เชฐเซเชกเชจเซเช‚ เชธเชพเชฎเซ‚เชนเชฟเช• เช…เชชเชกเซ‡เชŸ เชฎเซ‹เชŸเชพ เชŸเซ‡เชฌเชฒเชฎเชพเช‚, เช…เชจเซ‡ เชฅเซ‹เชกเซ€ เชตเชพเชฐ เชชเช›เซ€ เชคเชฎเซ‡ เชธเชฎเชพเชจ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซ‹ เชธเชพเชฎเชจเซ‹ เช•เชฐเชถเซ‹ เชตเซ‡เช•เซเชฏเซเชฎ เชฎเชฆเชฆ เช•เชฐเซ€ เชถเช•เชถเซ‡ เชจเชนเซ€เช‚.

#1: เชฎเชจเซ‡ เชคเซ‡เชจเซ‡ เช–เชธเซ‡เชกเชตเชพเชจเซเช‚ เช—เชฎเซ‡ เช›เซ‡

เชšเชพเชฒเซ‹ เช•เชนเซ€เช เช•เซ‡ เชคเชฎเชพเชฐเซ€ เชชเชฆเซเชงเชคเชฟ เชตเซเชฏเชตเชธเชพเชฏเชจเชพ เชคเชฐเซเช• เชชเชฐ เช•เชพเชฎ เช•เชฐเซ€ เชฐเชนเซ€ เช›เซ‡, เช…เชจเซ‡ เช…เชšเชพเชจเช• เชคเซ‡เชจเซ‡ เช–เซเชฏเชพเชฒ เช†เชตเซ‡ เช›เซ‡ เช•เซ‡ เช•เซ‡เชŸเชฒเชพเช• เชฐเซ‡เช•เซ‹เชฐเซเชกเชฎเชพเช‚ X เชซเซ€เชฒเซเชกเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเซเช‚ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡:

UPDATE tbl SET X = <newX> WHERE pk = $1;

เชชเช›เซ€, เชœเซ‡เชฎ เชœเซ‡เชฎ เชเช•เซเชเซ‡เช•เซเชฏเซเชถเชจ เช†เช—เชณ เชตเชงเซ‡ เช›เซ‡, เชคเซ‡ เชคเชพเชฐเชฃ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ Y เชซเซ€เชฒเซเชกเชจเซ‡ เชชเชฃ เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเซเช‚ เชœเซ‹เชˆเช:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... เช…เชจเซ‡ เชชเช›เซ€ Z เชชเชฃ - เชถเชพ เชฎเชพเชŸเซ‡ เชจเชพเชจเช•เชกเซ€ เชตเชธเซเชคเซเช“ เชชเชฐ เชธเชฎเชฏ เชฌเช—เชพเชกเซ‹?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เชนเชตเซ‡ เช† เชฐเซ‡เช•เซ‹เชฐเซเชกเชจเซ€ เช•เซ‡เชŸเชฒเซ€ เช†เชตเซƒเชคเซเชคเชฟเช“ เช›เซ‡? เชนเชพ, 4 เชŸเซเช•เชกเชพเช“! เช†เชฎเชพเช‚เชฅเซ€, เชเช• เชธเช‚เชฌเช‚เชงเชฟเชค เช›เซ‡, เช…เชจเซ‡ 3 เชคเชฎเชพเชฐเชพ เชชเช›เซ€ [เช“เชŸเซ‹]เชตเซ‡เช•เซเชฏเซเชฎ เชฆเซเชตเชพเชฐเชพ เชธเชพเชซ เช•เชฐเชตเชพเชจเชพ เชฐเชนเซ‡เชถเซ‡.

เช† เชฐเซ€เชคเซ‡ เชจ เช•เชฐเซ‹! เชตเชพเชชเชฐเชตเซ เชเช• เชตเชฟเชจเช‚เชคเซ€เชฎเชพเช‚ เชคเชฎเชพเชฎ เชซเซ€เชฒเซเชก เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช เชฒเช—เชญเช— เชนเช‚เชฎเซ‡เชถเชพ เชชเชฆเซเชงเชคเชฟเชจเซ‹ เชคเชฐเซเช• เช† เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเซ€ เชถเช•เชพเชฏ เช›เซ‡:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

#2: เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹ เชคเซ‡เชจเชพเชฅเซ€ เช…เชฒเช— เช›เซ‡, เชฒเซเชฏเซเช•!

เชคเซ‡เชฅเซ€, เชคเชฎเซ‡ เชนเชœเซ เชชเชฃ เช‡เชšเซเช›เชคเชพ เชนเชคเชพ เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ เช˜เชฃเชพ เชฌเชงเชพ เชฐเซ‡เช•เซ‹เชฐเซเชก เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‹ (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชธเซเช•เซเชฐเชฟเชชเซเชŸ เช…เชฅเชตเชพ เช•เชจเซเชตเชฐเซเชŸเชฐเชจเชพ เช‰เชชเชฏเซ‹เช— เชฆเชฐเชฎเชฟเชฏเชพเชจ). เช…เชจเซ‡ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เช•เช‚เชˆเช• เชธเซเช•เซเชฐเชฟเชชเซเชŸเชฎเชพเช‚ เช‰เชกเซ‡ เช›เซ‡:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

เชฒเช—เชญเช— เช† เชซเซ‹เชฐเซเชฎเชฎเชพเช‚ เชตเชฟเชจเช‚เชคเซ€ เช˜เชฃเซ€ เชตเชพเชฐ เชฅเชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชฒเช—เชญเช— เชนเช‚เชฎเซ‡เชถเชพ เช–เชพเชฒเซ€ เชจเชตเซเช‚ เชซเซ€เชฒเซเชก เชญเชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชนเซ€เช‚, เชชเชฐเช‚เชคเซ เชกเซ‡เชŸเชพเชฎเชพเช‚ เช•เซ‡เชŸเชฒเซ€เช• เชญเซ‚เชฒเซ‹ เชธเซเชงเชพเชฐเชตเชพ เชฎเชพเชŸเซ‡. เชคเซ‡ เชœ เชธเชฎเชฏเซ‡, เชคเซ‡เชฃเซ€เช เชชเซ‹เชคเซ‡ เชนเชพเชฒเชจเชพ เชกเซ‡เชŸเชพเชจเซ€ เชšเซ‹เช•เชธเชพเชˆเชจเซ‡ เชฌเชฟเชฒเช•เซเชฒ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเชคเซ€ เชจเชฅเซ€ - เชชเชฐเช‚เชคเซ เชจเชฟเชฐเชฐเซเชฅเช•! เชเชŸเชฒเซ‡ เช•เซ‡, เชฐเซ‡เช•เซ‹เชฐเซเชกเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชฒเช–เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชญเชฒเซ‡ เชคเซ‡เชฎเชพเช‚ เชฌเชฐเชพเชฌเชฐ เชถเซเช‚ เชœเซ‹เชˆเช เช›เซ‡ - เชชเชฃ เชถเชพ เชฎเชพเชŸเซ‡? เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ‡ เช เซ€เช• เช•เชฐเซ€เช:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

เช˜เชฃเชพ เชฒเซ‹เช•เซ‹ เช†เชตเชพ เช…เชฆเซเชญเซเชค เช“เชชเชฐเซ‡เชŸเชฐเชจเชพ เช…เชธเซเชคเชฟเชคเซเชต เชตเชฟเชถเซ‡ เชœเชพเชฃเชคเชพ เชจเชฅเซ€, เชคเซ‡เชฅเซ€ เช…เชนเซ€เช‚ เชเช• เชšเซ€เชŸ เชถเซ€เชŸ เช›เซ‡ IS DISTINCT FROM เช…เชจเซ‡ เช…เชจเซเชฏ เชฒเซ‹เชœเชฟเช•เชฒ เช“เชชเชฐเซ‡เชŸเชฐเซ‹ เชฎเชฆเชฆ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡:
เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ เชเชจเซเชŸเชฟเชชเซ‡เชŸเชฐเซเชจ: "เชฎเซƒเชค" เชจเซ€ เชฒเชกเชพเชˆ
... เช…เชจเซ‡ เชœเชŸเชฟเชฒ เชชเชฐเชจเซ€ เช•เชพเชฎเช—เซ€เชฐเซ€ เชตเชฟเชถเซ‡ เชฅเซ‹เชกเซเช‚ ROW()- เช…เชญเชฟเชตเซเชฏเช•เซเชคเชฟเช“:
เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ เชเชจเซเชŸเชฟเชชเซ‡เชŸเชฐเซเชจ: "เชฎเซƒเชค" เชจเซ€ เชฒเชกเชพเชˆ

#3: เชนเซเช‚ เชฎเชพเชฐเชพ เชชเซเชฐเซ‡เชฎเชฟเช•เชพเชจเซ‡... เชฌเซเชฒเซ‹เช• เช•เชฐเซ€เชจเซ‡ เช“เชณเช–เซเช‚ เช›เซเช‚

เชฒเซ‹เชจเซเชš เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡ เชฌเซ‡ เชธเชฎเชพเชจ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เชฆเชฐเซ‡เช• เชชเซเชฐเชตเซ‡เชถเชจเซ‡ เชšเชฟเชนเซเชจเชฟเชค เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ‡ เช›เซ‡ เช•เซ‡ เชคเซ‡ "เชชเซเชฐเช—เชคเชฟเชฎเชพเช‚ เช›เซ‡":

UPDATE tbl SET processing = TRUE WHERE pk = $1;

เชœเซ‹ เช† เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“ เชตเชพเชธเซเชคเชตเชฎเชพเช‚ เชเช•เชฌเซ€เชœเชพเชฅเซ€ เชธเซเชตเชคเช‚เชคเซเชฐ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเชคเซ€ เชนเซ‹เชฏ, เชชเชฃ เชเช• เชœ IDเชจเซ€ เช…เช‚เชฆเชฐ, เชชเซเชฐเชฅเชฎ เชตเซเชฏเชตเชนเชพเชฐ เชชเซ‚เชฐเซเชฃ เชจ เชฅเชพเชฏ เชคเซเชฏเชพเช‚ เชธเซเชงเซ€ เชฌเซ€เชœเชพ เช•เซเชฒเชพเชฏเชจเซเชŸเชจเซ‡ เช† เชตเชฟเชจเช‚เชคเซ€ เชชเชฐ "เชฒเซ‰เช•" เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡.

เช‰เช•เซ‡เชฒ เชจเช‚เชฌเชฐ 1: เช•เชพเชฐเซเชฏ เชชเชพเช›เชฒเชพ เชเช•เชฎเชพเช‚ เช˜เชŸเชพเชกเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡

เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ‡ เชซเชฐเซ€เชฅเซ€ เช‰เชฎเซ‡เชฐเซ€เช IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

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

เช‰เช•เซ‡เชฒ เชจเช‚เชฌเชฐ 2: เชธเชฒเชพเชนเช•เชพเชฐเซ€ เชคเชพเชณเชพเช“

เชเช• เช…เชฒเช— เชฒเซ‡เช– เชฎเชพเชŸเซ‡ เชเช• เชฎเซ‹เชŸเซ‹ เชตเชฟเชทเชฏ, เชœเซ‡เชจเชพ เชตเชฟเชถเซ‡ เชคเชฎเซ‡ เชตเชพเช‚เชšเซ€ เชถเช•เซ‹ เช›เซ‹ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชชเชฆเซเชงเชคเชฟเช“ เช…เชจเซ‡ เชญเชฒเชพเชฎเชฃ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชตเชพเชจเซ€ "เชฐเซ‡เช•"..

เช‰เช•เซ‡เชฒ เชจเช‚เชฌเชฐ 3: เชฎเซ‚เชฐเซเช– เช•เซ‹เชฒเซเชธ

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

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

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