ΠΡΠΎΠ±Π΅Π½ΠΎΡΡΠΈΡΠ΅ Π½Π° Π²ΡΡΡΠ΅ΡΠ½ΠΈΡΠ΅ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠΈ Π½Π° PostgreSQL ΠΌΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Ρ Π΄Π° Π±ΡΠ΄Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π±ΡΡΠ· Π² Π½ΡΠΊΠΎΠΈ ΡΠΈΡΡΠ°ΡΠΈΠΈ ΠΈ βΠ½Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π±ΡΡΠ·β Π² Π΄ΡΡΠ³ΠΈ. ΠΠ½Π΅Ρ ΡΠ΅ ΡΠ΅ ΡΡΡΡΠ΅Π΄ΠΎΡΠΎΡΠΈΠΌ Π²ΡΡΡ Ρ ΠΊΠ»Π°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ²Π° ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠΈ Π‘Π£ΠΠ ΠΈ ΠΊΠ°ΠΊΠ²ΠΎ ΠΏΡΠ°Π²ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡΡ Ρ Π½Π΅Ρ - UPDATE ΡΡΠ΅ΡΡ MVCC ΠΏΡΠΈΠ½ΡΠΈΠΏΠΈ.
ΠΡΠ°ΡΠΊΠ° ΠΈΡΡΠΎΡΠΈΡ ΠΎΡ
ΠΠΎΠ³Π°ΡΠΎ ΡΠ΅Π΄ ΡΠ΅ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠ° ΡΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄Π° UPDATE, Π²ΡΡΡΠ½ΠΎΡΡ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°Ρ Π΄Π²Π΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ: DELETE ΠΈ INSERT. 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 ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΠΎΡΠΈΡΡΠ΅Π½ΠΈ ΡΠ»Π΅Π΄ Π²Π°Ρ ΡΡΠ΅Π· [auto]VACUUM.
ΠΠ΅ Π³ΠΎ ΠΏΡΠ°Π²Π΅ΡΠ΅ ΠΏΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½! ΠΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ Π°ΠΊΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΠΏΠΎΠ»Π΅ΡΠ° Π² Π΅Π΄Π½Π° Π·Π°ΡΠ²ΠΊΠ° β ΠΏΠΎΡΡΠΈ Π²ΠΈΠ½Π°Π³ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° Π½Π° ΠΌΠ΅ΡΠΎΠ΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ ΠΏΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°ΡΠΈΠ½:
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;
ΠΠΎΡΠΈ Π°ΠΊΠΎ ΡΠ΅Π·ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»Π½ΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π°Ρ Π½Π΅ΡΠ°, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΈ Π΅Π΄ΠΈΠ½ ΠΎΡ Π΄ΡΡΠ³, Π½ΠΎ Π² ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° Π΅Π΄ΠΈΠ½ ΠΈ ΡΡΡΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, Π²ΡΠΎΡΠΈΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ ΡΠ΅ Π±ΡΠ΄Π΅ βΠ·Π°ΠΊΠ»ΡΡΠ΅Π½β ΠΏΡΠΈ ΡΠ°Π·ΠΈ Π·Π°ΡΠ²ΠΊΠ°, Π΄ΠΎΠΊΠ°ΡΠΎ ΠΏΡΡΠ²Π°ΡΠ° ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΡ Π½Π΅ Π±ΡΠ΄Π΅ Π·Π°Π²ΡΡΡΠ΅Π½Π°.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ #1: Π·Π°Π΄Π°ΡΠ°ΡΠ° ΡΠ΅ ΡΠ²Π΅ΠΆΠ΄Π° Π΄ΠΎ ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ°
ΠΠ΅ΠΊΠ° ΠΏΡΠΎΡΡΠΎ Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΎΡΠ½ΠΎΠ²ΠΎ IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
Π ΡΠ°Π·ΠΈ ΡΠΎΡΠΌΠ° Π²ΡΠΎΡΠ°ΡΠ° Π·Π°ΡΠ²ΠΊΠ° ΠΏΡΠΎΡΡΠΎ Π½ΡΠΌΠ° Π΄Π° ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π½ΠΈΡΠΎ Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ, Π²ΡΠΈΡΠΊΠΎ Π²Π΅ΡΠ΅ Π΅ ΠΊΠ°ΠΊΡΠΎ ΡΡΡΠ±Π²Π° - ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ Π½ΡΠΌΠ° Π΄Π° Π½Π°ΡΡΡΠΏΠΈ Π±Π»ΠΎΠΊΠΈΡΠ°Π½Π΅. Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π°ΠΌΠ΅ ΡΠ°ΠΊΡΠ° βΠ½Π΅Π½Π°ΠΌΠΈΡΠ°Π½Π΅β Π½Π° Π·Π°ΠΏΠΈΡΠ° Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π°Π»Π³ΠΎΡΠΈΡΡΠΌ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ #2: ΡΡΠ²Π΅ΡΠ½ΠΈ ΠΊΠ»ΡΡΠ°Π»ΠΊΠΈ
ΠΠΎΠ»ΡΠΌΠ° ΡΠ΅ΠΌΠ° Π·Π° ΠΎΡΠ΄Π΅Π»Π½Π° ΡΡΠ°ΡΠΈΡ, Π² ΠΊΠΎΡΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅
Π Π΅ΡΠ΅Π½ΠΈΠ΅ #3: Π³Π»ΡΠΏΠ°Π²ΠΈ ΠΎΠ±Π°ΠΆΠ΄Π°Π½ΠΈΡ
ΠΠΎ ΡΠΎΡΠ½ΠΎ ΡΠΎΠ²Π° ΡΡΡΠ±Π²Π° Π΄Π° Π²ΠΈ ΡΠ΅ ΡΠ»ΡΡΠΈ Π΅Π΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½Π° ΡΠ°Π±ΠΎΡΠ° Ρ Π΅Π΄ΠΈΠ½ ΠΈ ΡΡΡΠΈ Π·Π°ΠΏΠΈΡ? ΠΠ»ΠΈ ΡΠΈ ΠΎΠ±ΡΡΠΊΠ°Π» Π°Π»Π³ΠΎΡΠΈΡΠΌΠΈΡΠ΅ Π·Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° Π±ΠΈΠ·Π½Π΅Ρ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° ΠΎΡ ΡΡΡΠ°Π½Π° Π½Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ? Π Π°ΠΊΠΎ ΡΠ΅ Π·Π°ΠΌΠΈΡΠ»ΠΈΡΠ΅?..
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com