60.5. ÐÑовеÑки ÑникалÑноÑÑи в индекÑе #
Postgres Pro ÑеализÑÐµÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи SQL, пÑименÑÑ ÑникалÑнÑе индекÑÑ, Ñо еÑÑÑ Ñакие индекÑÑ, коÑоÑÑе не пÑинимаÑÑ Ð½ÐµÑколÑко запиÑей Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñми клÑÑами. ÐÐ»Ñ Ð¼ÐµÑода доÑÑÑпа, поддеÑживаÑÑего ÑÑо ÑвойÑÑво, ÑÑÑанавливаеÑÑÑ Ð¿Ñизнак amcanunique. (РнаÑÑоÑÑее вÑÐµÐ¼Ñ ÑÑо поддеÑживаÑÑ ÑолÑко Ð-деÑевÑÑ.) СÑолбÑÑ, ÑказаннÑе в пÑедложении INCLUDE, не ÑÑиÑÑваÑÑÑÑ Ð¿Ñи конÑÑоле ÑникалÑноÑÑи.
ÐÑледÑÑвие оÑобенноÑÑей MVCC, вÑегда Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ допÑÑкаÑÑ ÑизиÑеÑкое ÑоÑÑÑеÑÑвование в индекÑе дÑблиÑÑÑÑÐ¸Ñ ÑÑ Ð·Ð°Ð¿Ð¸Ñей: Ñакие запиÑи могÑÑ Ð¾ÑноÑиÑÑÑÑ Ðº поÑледоваÑелÑнÑм веÑÑиÑм одной логиÑеÑкой ÑÑÑоки. Ðа Ñамом деле Ð¼Ñ Ñ Ð¾Ñим добиÑÑÑÑ ÑолÑко Ñого, ÑÑÐ¾Ð±Ñ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð¹ Ñнимок MVCC не мог ÑодеÑжаÑÑ Ð´Ð²Ðµ ÑÑÑоки Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñми клÑÑами индекÑа. Ðз ÑÑого вÑÑекаÑÑ ÑледÑÑÑие ÑиÑÑаÑии, коÑоÑÑе Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ оÑÑледиÑÑ, добавлÑÑ Ð½Ð¾Ð²ÑÑ ÑÑÑÐ¾ÐºÑ Ð² ÑникалÑнÑй индекÑ:
ÐÑли конÑликÑÑÑÑÐ°Ñ ÑÑÑока бÑла Ñдалена ÑекÑÑей ÑÑанзакÑией, ÑÑо не пÑоблема. (Ð ÑаÑÑноÑÑи из-за Ñого, ÑÑо UPDATE вÑегда ÑдалÑÐµÑ ÑÑаÑÑÑ Ð²ÐµÑÑÐ¸Ñ ÑÑÑоки, пÑежде Ñем вÑÑавлÑÑÑ Ð½Ð¾Ð²ÑÑ, опеÑаÑÐ¸Ñ UPDATE можно вÑполнÑÑÑ Ñо ÑÑÑокой, не менÑÑ ÐµÑ ÐºÐ»ÑÑ.)
ÐÑли конÑликÑÑÑÑÐ°Ñ ÑÑÑока бÑла добавлена еÑÑ Ð½Ðµ заÑикÑиÑованной ÑÑанзакÑией, запÑоÑ, пÑеÑендÑÑÑий на добавление новой ÑÑÑоки, должен подождаÑÑ, пока ÑÑа ÑÑанзакÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ Ð·Ð°ÑикÑиÑована. ÐÑли она оÑкаÑÑваеÑÑÑ, конÑÐ»Ð¸ÐºÑ Ð¸ÑÑезаеÑ. ÐÑли она ÑикÑиÑÑеÑÑÑ Ð¸ пÑи ÑÑом оÑÑавлÑÐµÑ ÐºÐ¾Ð½ÑликÑÑÑÑÑÑ ÑÑÑокÑ, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð½Ð°ÑÑÑение ÑникалÑноÑÑи. (Ðа пÑакÑике Ð¼Ñ Ð¿ÑоÑÑо ждÑм завеÑÑÐµÐ½Ð¸Ñ Ð´ÑÑгой ÑÑанзакÑии и заÑем пеÑеÑмаÑÑиваем пÑовеÑÐºÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑи.)
ÐодобнÑм обÑазом, еÑли конÑликÑÑÑÑÐ°Ñ ÑÑÑока бÑла Ñдалена еÑÑ Ð½Ðµ заÑикÑиÑованной ÑÑанзакÑией, запÑоÑ, пÑеÑендÑÑÑий на добавление новой ÑÑÑоки, должен дождаÑÑÑÑ ÑикÑаÑии или оÑкаÑа ÑÑой ÑÑанзакÑии, а заÑем повÑоÑиÑÑ Ð¿ÑовеÑкÑ.
Ðолее Ñого, непоÑÑедÑÑвенно пеÑед Ñем как ÑообÑаÑÑ Ð¾ наÑÑÑении ÑникалÑноÑÑи ÑоглаÑно вÑÑепÑиведÑннÑм пÑавилам, меÑод доÑÑÑпа должен пеÑепÑовеÑиÑÑ, пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ Ð»Ð¸ ÑÑÑеÑÑвоваÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÐµÐ¼Ð°Ñ ÑÑÑока. ÐÑли она пÑизнана «мÑÑÑвой», о пÑедвиденном наÑÑÑении он ÑообÑаÑÑ Ð½Ðµ должен. (Такого не должно бÑÑÑ Ð¿Ñи обÑÑном ÑÑенаÑии Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑоки ÑекÑÑей ÑÑанзакÑией, однако ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизойÑи в пÑоÑеÑÑе CREATE UNIQUE INDEX CONCURRENTLY.)
ÐÑ ÑÑебÑем, ÑÑÐ¾Ð±Ñ Ð¼ÐµÑод доÑÑÑпа вÑполнÑл ÑÑи пÑовеÑки Ñам, и ÑÑо ознаÑаеÑ, ÑÑо он должен обÑаÑиÑÑÑÑ Ðº оÑновнÑм даннÑм и пÑовеÑиÑÑ ÑоÑÑоÑние ÑикÑаÑии вÑÐµÑ ÑÑÑок, коÑоÑÑе ÑоглаÑно ÑодеÑжимого индекÑа ÑодеÑÐ¶Ð°Ñ Ð´ÑблиÑÑÑÑиеÑÑ ÐºÐ»ÑÑи. ÐÑо без ÑÐ¾Ð¼Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÐºÑаÑивÑй и немодÑлÑнÑй Ð¿Ð¾Ð´Ñ Ð¾Ð´, но он избавлÑÐµÑ Ð¾Ñ Ð¸Ð·Ð»Ð¸Ñней ÑабоÑÑ: еÑли Ð±Ñ Ð¼Ñ Ð´ÐµÐ»Ð°Ð»Ð¸ оÑделÑнÑÑ Ð¿ÑобÑ, Ñо поиÑк конÑликÑÑÑÑей ÑÑÑоки по индекÑÑ Ð¿ÑиÑлоÑÑ Ð±Ñ Ð¿Ð¾ ÑÑÑи повÑоÑÑÑÑ, пÑÑаÑÑÑ Ð½Ð°Ð¹Ñи меÑÑо, кÑда вÑÑавиÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð¹ ÑÑÑоки. Ðолее Ñого, не пÑедÑÑавлÑеÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñм избежаÑÑ ÑÑловий гонки, еÑли пÑовеÑка конÑликÑа не бÑÐ´ÐµÑ Ð½ÐµÐ¾ÑÑемлемой ÑаÑÑÑÑ Ð¿ÑоÑедÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ запиÑи индекÑа.
ÐÑли огÑаниÑение ÑникалÑноÑÑи оÑкладÑваемое, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑÐ½Ð°Ñ ÑложноÑÑÑ: нам нÑжна возможноÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð½Ð´ÐµÐºÑа Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð¹ ÑÑÑоки, но оÑложиÑÑ Ð²ÑÐ²Ð¾Ð´Ñ Ð¾ наÑÑÑении ÑникалÑноÑÑи до конÑа опеÑаÑоÑа или даже позже. ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð½ÐµÐ½Ñжного повÑоÑного поиÑка по индекÑÑ, меÑод доÑÑÑпа должен пÑоизвеÑÑи пÑедваÑиÑелÑнÑÑ Ð¿ÑовеÑÐºÑ ÑникалÑноÑÑи во вÑÐµÐ¼Ñ Ð¸Ð·Ð½Ð°ÑалÑного Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑок. ÐÑли пÑи ÑÑом окажеÑÑÑ, ÑÑо никакие коÑÑежи не конÑликÑÑÑÑ, на ÑÑом пÑовеÑка заканÑиваеÑÑÑ. РпÑоÑивном ÑлÑÑае Ð¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÑем пеÑепÑовеÑÐºÑ Ð½Ð° вÑемÑ, когда ÑÑо огÑаниÑение наÑÐ¸Ð½Ð°ÐµÑ Ð´ÐµÐ¹ÑÑвоваÑÑ. ÐÑли во вÑÐµÐ¼Ñ Ð¿ÐµÑепÑовеÑки пÑодолжаÑÑ ÑÑÑеÑÑвоваÑÑ Ð¸ вÑÑавленнÑй коÑÑеж, и какой-либо дÑÑгой Ñ Ñем же клÑÑом, должна вÑдаваÑÑÑÑ Ð¾Ñибка. (ÐамеÑÑÑе, ÑÑо в данном ÑлÑÑае под «ÑÑÑеÑÑвованием» понимаеÑÑÑ Â«ÑÑÑеÑÑвование лÑбого коÑÑежа в ÑепоÑке HOT запиÑей индекÑа».) ÐÐ»Ñ ÑеализаÑии ÑÑой ÑÑ
ÐµÐ¼Ñ Ð² aminsert пеÑедаÑÑÑÑ Ð¿Ð°ÑамеÑÑ checkUnique, пÑинимаÑÑий одно из ÑледÑÑÑиÑ
знаÑений:
UNIQUE_CHECK_NOÑказÑваеÑ, ÑÑо пÑовеÑка ÑникалÑноÑÑи не должна вÑполнÑÑÑÑÑ (ÑÑо не ÑникалÑнÑй индекÑ).UNIQUE_CHECK_YESÑказÑваеÑ, ÑÑо ÑÑо неоÑкладÑваемÑй ÑникалÑнÑй Ð¸Ð½Ð´ÐµÐºÑ Ð¸ пÑовеÑÐºÑ ÑникалÑноÑÑи нÑжно вÑполниÑÑ Ð½ÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾, как опиÑано вÑÑе.UNIQUE_CHECK_PARTIALÑказÑваеÑ, ÑÑо ÑÑо оÑкладÑваемое огÑаниÑение ÑникалÑноÑÑи. Postgres Pro вÑбиÑÐ°ÐµÑ ÑÑÐ¾Ñ Ñежим Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñи индекÑа Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки. ÐеÑод доÑÑÑпа должен допÑÑкаÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ в Ð¸Ð½Ð´ÐµÐºÑ Ð´ÑблиÑÑÑÑÐ¸Ñ ÑÑ Ð·Ð°Ð¿Ð¸Ñей и ÑообÑаÑÑ Ð¾ возможнÑÑ ÐºÐ¾Ð½ÑликÑÐ°Ñ , возвÑаÑÐ°Ñ false изaminsert. ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ñакой ÑÑÑоки (Ð´Ð»Ñ ÐºÐ¾ÑоÑой возвÑаÑаеÑÑÑ false) бÑÐ´ÐµÑ Ð·Ð°Ð¿Ð»Ð°Ð½Ð¸Ñована оÑÐ»Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ Ð¿ÐµÑепÑовеÑка.ÐеÑод доÑÑÑпа должен оÑмеÑиÑÑ Ð²Ñе ÑÑÑоки, коÑоÑÑе могÑÑ Ð½Ð°ÑÑÑаÑÑ Ð¾Ð³ÑаниÑение ÑникалÑноÑÑи, но не бÑÐ´ÐµÑ Ð¾Ñибкой, еÑли он допÑÑÑÐ¸Ñ Ð»Ð¾Ð¶Ð½Ð¾Ðµ ÑÑабаÑÑвание. ÐÑо позволÑÐµÑ Ð¿ÑоизвеÑÑи пÑовеÑкÑ, не дожидаÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð´ÑÑÐ³Ð¸Ñ ÑÑанзакÑий; конÑликÑÑ, вÑÑвленнÑе на ÑÑой ÑÑадии, не ÑÑиÑаÑÑÑÑ Ð¾Ñибками и бÑдÑÑ Ð¿ÐµÑепÑовеÑÐµÐ½Ñ Ð¿Ð¾Ð·Ð¶Ðµ, когда они могÑÑ Ð±ÑÑÑ Ñже иÑÑеÑпанÑ.
UNIQUE_CHECK_EXISTINGÑказÑваеÑ, ÑÑо ÑÑо оÑÐ»Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ Ð¿ÐµÑепÑовеÑка ÑÑÑоки, коÑоÑÐ°Ñ Ð±Ñла оÑмеÑена как возможно наÑÑÑаÑÑÐ°Ñ Ð¾Ð³ÑаниÑение. ХоÑÑ Ð´Ð»Ñ ÑÑой пÑовеÑки вÑзÑваеÑÑÑaminsert, меÑод доÑÑÑпа не должен добавлÑÑÑ Ð½Ð¾Ð²ÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð½Ð´ÐµÐºÑа в данном ÑлÑÑае, Ñак как ÑÑа запиÑÑ Ñже ÑÑÑеÑÑвÑеÑ. ÐмеÑÑо ÑÑого, меÑод доÑÑÑпа должен пÑовеÑиÑÑ, Ð½ÐµÑ Ð»Ð¸ в индекÑе дÑÑгой Ñакой же запиÑи. ÐÑли она Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð¸ ÑооÑвеÑÑÑвÑÑÑÐ°Ñ ÐµÐ¹ ÑÑÑока пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ ÑÑÑеÑÑвоваÑÑ, должна вÑдаваÑÑÑÑ Ð¾Ñибка.ÐÐ»Ñ Ð²Ð°ÑианÑа
UNIQUE_CHECK_EXISTINGв меÑоде доÑÑÑпа ÑекомендÑеÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑно пÑовеÑиÑÑ, ÑÑо Ð´Ð»Ñ Ñелевой ÑÑÑоки дейÑÑвиÑелÑно имееÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð² индекÑе и ÑообÑиÑÑ Ð¾Ð± оÑибке, еÑли ÑÑо не Ñак. ÐÑо Ñ Ð¾ÑоÑÐ°Ñ Ð¸Ð´ÐµÑ, Ñак как знаÑÐµÐ½Ð¸Ñ ÐºÐ¾ÑÑежа индекÑа, пеÑедаваемÑе вaminsert, бÑдÑÑ ÑаÑÑÑиÑÐ°Ð½Ñ Ð·Ð°Ð½Ð¾Ð²Ð¾. ÐÑли в опÑеделении индекÑа задейÑÑÐ²Ð¾Ð²Ð°Ð½Ñ ÑÑнкÑии, коÑоÑÑе на Ñамом деле не поÑÑоÑннÑе, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пÑовеÑÑÑÑ Ð½ÐµÐ¿ÑавилÑнÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð¸Ð½Ð´ÐµÐºÑа. ÐополниÑелÑно ÑбедивÑиÑÑ Ð² ÑÑÑеÑÑвовании Ñелевой ÑÑÑоки пÑи пеÑепÑовеÑке, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ бÑÑÑ ÑвеÑенÑ, ÑÑо ÑканиÑÑÑÑÑÑ Ñе же знаÑÐµÐ½Ð¸Ñ ÐºÐ¾ÑÑежа, ÑÑо пеÑедавалиÑÑ Ð¿Ñи изнаÑалÑном добавлении ÑÑÑоки.