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

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

เชธเช‚เช•เซเชทเชฟเชชเซเชค เชชเซเชฒเซ‹เชŸ เช‰เชคเซเชคเชฎ เชฒเซ‡เช–:

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

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

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

เชชเชฐเช‚เชคเซ เช† เชคเชฐเชค เชœ เชฅเชถเซ‡ เชจเชนเซ€เช‚, เชชเชฐเช‚เชคเซ "เชฎเซƒเชค" เชธเชพเชฅเซ‡เชจเซ€ เชธเชฎเชธเซเชฏเชพเช“ เช–เซ‚เชฌ เชœ เชเชกเชชเชฅเซ€ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡ - เชตเชพเชฐเช‚เชตเชพเชฐ เช…เชฅเชตเชพ เชฐเซ‡เช•เซ‹เชฐเซเชกเชจเซเช‚ เชฎเซ‹เชŸเชพ เชชเชพเชฏเซ‡ เช…เชชเชกเซ‡เชŸเชฟเช‚เช— เชเช• เชฎเซ‹เชŸเชพ เชŸเซ‡เชฌเชฒ เชชเชฐ, เช…เชจเซ‡ เชฅเซ‹เชกเซ€ เชตเชพเชฐ เชชเช›เซ€ เชเชตเซ€ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซ‹ เชธเชพเชฎเชจเซ‹ เช•เชฐเชตเซ‹ เชชเชกเซ‡ เช›เซ‡ เช•เซ‡ 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;

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

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

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

#2: เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹ "IS DISTINCT FROM, เชฒเซเชฏเซเช•!"

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

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