Хусусиятҳои механизмҳои дохилии PostgreSQL имкон медиҳанд, ки он дар баъзе ҳолатҳо хеле зуд бошад ва дар дигар ҳолатҳо «на чандон тез» бошад. Имрӯз мо ба як мисоли классикии ихтилоф байни чӣ гуна кор кардани DBMS ва он чизе ки таҳиякунанда бо он кор мекунад, тамаркуз хоҳем кард - UPDATE против принсипҳои MVCC.
Ҳикояи мухтасар аз
Вақте ки сатр бо фармони UPDATE тағир дода мешавад, воқеан ду амал иҷро карда мешавад: DELETE ва INSERT. ДАР версияи ҷории сатр xmax ба рақами транзаксияе, ки UPDATE анҷом дода шудааст, муқаррар карда мешавад. Он гоҳ он офарида мешавад версияи нав ҳамон хат; арзиши 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: зангҳои беақл
Аммо ин маҳз ҳамон чизест, ки бояд бо шумо рӯй диҳад кори ҳамзамон бо як сабт? Ё шумо, масалан, бо алгоритмҳои занги мантиқи тиҷорӣ дар тарафи муштарӣ халалдор кардаед? Ва агар шумо дар ин бора фикр кунед?..
Манбаъ: will.com