PK ಇಲ್ಲದೆಯೇ ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸುವುದು

ಯಾವಾಗ ಸಂದರ್ಭಗಳಿವೆ ಪ್ರಾಥಮಿಕ ಕೀ ಇಲ್ಲದ ಟೇಬಲ್‌ಗೆ ಅಥವಾ ಕೆಲವು ಇತರ ವಿಶಿಷ್ಟ ಸೂಚ್ಯಂಕಗಳು, ಮೇಲ್ವಿಚಾರಣೆಯ ಕಾರಣದಿಂದಾಗಿ, ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ದಾಖಲೆಗಳ ಸಂಪೂರ್ಣ ತದ್ರೂಪುಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.

PK ಇಲ್ಲದೆಯೇ ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸುವುದು

ಉದಾಹರಣೆಗೆ, ಕಾಲಾನುಕ್ರಮದ ಮೆಟ್ರಿಕ್‌ನ ಮೌಲ್ಯಗಳನ್ನು COPY ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು PostgreSQL ಗೆ ಬರೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ನಂತರ ಹಠಾತ್ ವೈಫಲ್ಯವಿದೆ ಮತ್ತು ಸಂಪೂರ್ಣವಾಗಿ ಒಂದೇ ರೀತಿಯ ಡೇಟಾದ ಭಾಗವು ಮತ್ತೆ ಬರುತ್ತದೆ.

ಅನಗತ್ಯ ತದ್ರೂಪುಗಳ ಡೇಟಾಬೇಸ್ ಅನ್ನು ತೊಡೆದುಹಾಕಲು ಹೇಗೆ?

ಪಿಕೆ ಸಹಾಯಕನಲ್ಲದಿದ್ದಾಗ

ಅಂತಹ ಪರಿಸ್ಥಿತಿಯು ಮೊದಲ ಸ್ಥಾನದಲ್ಲಿ ಸಂಭವಿಸದಂತೆ ತಡೆಯುವುದು ಸುಲಭವಾದ ಮಾರ್ಗವಾಗಿದೆ. ಉದಾಹರಣೆಗೆ, ರೋಲ್ ಪ್ರೈಮರಿ ಕೀ. ಆದರೆ ಸಂಗ್ರಹಿಸಿದ ಡೇಟಾದ ಪರಿಮಾಣವನ್ನು ಹೆಚ್ಚಿಸದೆ ಇದು ಯಾವಾಗಲೂ ಸಾಧ್ಯವಿಲ್ಲ.

ಉದಾಹರಣೆಗೆ, ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿನ ಕ್ಷೇತ್ರದ ನಿಖರತೆಗಿಂತ ಮೂಲ ವ್ಯವಸ್ಥೆಯ ನಿಖರತೆ ಹೆಚ್ಚಿದ್ದರೆ:

metric   | ts                  | data
--------------------------------------------------
cpu.busy | 2019-12-20 00:00:00 | {"value" : 12.34}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 10}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 11.2}
cpu.busy | 2019-12-20 00:00:03 | {"value" : 15.7}

ನೀವು ಗಮನಿಸಿದ್ದೀರಾ? 00:00:02 ಬದಲಿಗೆ ಕೌಂಟ್‌ಡೌನ್ ಅನ್ನು ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಒಂದು ಸೆಕೆಂಡ್‌ಗೆ ಮುಂಚಿತವಾಗಿ TS ನೊಂದಿಗೆ ದಾಖಲಿಸಲಾಗಿದೆ, ಆದರೆ ಅಪ್ಲಿಕೇಶನ್ ದೃಷ್ಟಿಕೋನದಿಂದ ಸಾಕಷ್ಟು ಮಾನ್ಯವಾಗಿದೆ (ಎಲ್ಲಾ ನಂತರ, ಡೇಟಾ ಮೌಲ್ಯಗಳು ವಿಭಿನ್ನವಾಗಿವೆ!).

ಖಂಡಿತ ನೀವು ಮಾಡಬಹುದು PK(ಮೆಟ್ರಿಕ್, ಟಿಎಸ್) - ಆದರೆ ನಂತರ ನಾವು ಮಾನ್ಯ ಡೇಟಾಕ್ಕಾಗಿ ಅಳವಡಿಕೆ ಸಂಘರ್ಷಗಳನ್ನು ಪಡೆಯುತ್ತೇವೆ.

ಮಾಡಬಹುದು PK(ಮೆಟ್ರಿಕ್, ಟಿಎಸ್, ಡೇಟಾ) - ಆದರೆ ಇದು ಅದರ ಪರಿಮಾಣವನ್ನು ಹೆಚ್ಚು ಹೆಚ್ಚಿಸುತ್ತದೆ, ಅದನ್ನು ನಾವು ಬಳಸುವುದಿಲ್ಲ.

ಆದ್ದರಿಂದ, ಸಾಮಾನ್ಯವಾದ ವಿಶಿಷ್ಟವಲ್ಲದ ಸೂಚ್ಯಂಕವನ್ನು ಮಾಡುವುದು ಅತ್ಯಂತ ಸರಿಯಾದ ಆಯ್ಕೆಯಾಗಿದೆ (ಮೆಟ್ರಿಕ್, ಟಿಎಸ್) ಮತ್ತು ವಾಸ್ತವದ ನಂತರ ಸಮಸ್ಯೆಗಳು ಉದ್ಭವಿಸಿದರೆ ಅವುಗಳನ್ನು ನಿಭಾಯಿಸಿ.

"ಕ್ಲೋನಿಕ್ ಯುದ್ಧ ಪ್ರಾರಂಭವಾಗಿದೆ"

ಕೆಲವು ರೀತಿಯ ಅಪಘಾತ ಸಂಭವಿಸಿದೆ, ಮತ್ತು ಈಗ ನಾವು ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ನಾಶಪಡಿಸಬೇಕಾಗಿದೆ.

PK ಇಲ್ಲದೆಯೇ ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸುವುದು

ಮೂಲ ಡೇಟಾವನ್ನು ಮಾದರಿ ಮಾಡೋಣ:

CREATE TABLE tbl(k text, v integer);

INSERT INTO tbl
VALUES
  ('a', 1)
, ('a', 3)
, ('b', 2)
, ('b', 2) -- oops!
, ('c', 3)
, ('c', 3) -- oops!!
, ('c', 3) -- oops!!
, ('d', 4)
, ('e', 5)
;

ಇಲ್ಲಿ ನಮ್ಮ ಕೈ ಮೂರು ಬಾರಿ ನಡುಗಿತು, Ctrl+V ಸಿಲುಕಿಕೊಂಡಿತು, ಮತ್ತು ಈಗ...

ಮೊದಲಿಗೆ, ನಮ್ಮ ಟೇಬಲ್ ತುಂಬಾ ದೊಡ್ಡದಾಗಿದೆ ಎಂದು ಅರ್ಥಮಾಡಿಕೊಳ್ಳೋಣ, ಆದ್ದರಿಂದ ನಾವು ಎಲ್ಲಾ ತದ್ರೂಪುಗಳನ್ನು ಕಂಡುಕೊಂಡ ನಂತರ, ಅಳಿಸಲು ಅಕ್ಷರಶಃ “ನಮ್ಮ ಬೆರಳನ್ನು ಇರಿ” ಮಾಡುವುದು ಸೂಕ್ತವಾಗಿದೆ. ನಿರ್ದಿಷ್ಟ ದಾಖಲೆಗಳನ್ನು ಮರು-ಶೋಧನೆ ಮಾಡದೆ.

ಮತ್ತು ಅಂತಹ ಒಂದು ಮಾರ್ಗವಿದೆ - ಇದು ctid ಮೂಲಕ ಉದ್ದೇಶಿಸಿ, ನಿರ್ದಿಷ್ಟ ದಾಖಲೆಯ ಭೌತಿಕ ಗುರುತಿಸುವಿಕೆ.

ಅಂದರೆ, ಮೊದಲನೆಯದಾಗಿ, ಟೇಬಲ್ ಸಾಲಿನ ಸಂಪೂರ್ಣ ವಿಷಯದ ಸಂದರ್ಭದಲ್ಲಿ ನಾವು ದಾಖಲೆಗಳ ctid ಅನ್ನು ಸಂಗ್ರಹಿಸಬೇಕಾಗಿದೆ. ಸಂಪೂರ್ಣ ಸಾಲನ್ನು ಪಠ್ಯಕ್ಕೆ ಬಿತ್ತರಿಸುವುದು ಸರಳವಾದ ಆಯ್ಕೆಯಾಗಿದೆ:

SELECT
  T::text
, array_agg(ctid) ctids
FROM
  tbl T
GROUP BY
  1;

t     | ctids
---------------------------------
(e,5) | {"(0,9)"}
(d,4) | {"(0,8)"}
(c,3) | {"(0,5)","(0,6)","(0,7)"}
(b,2) | {"(0,3)","(0,4)"}
(a,3) | {"(0,2)"}
(a,1) | {"(0,1)"}

ಬಿತ್ತರಿಸದೇ ಇರಲು ಸಾಧ್ಯವೇ?ತಾತ್ವಿಕವಾಗಿ, ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದು ಸಾಧ್ಯ. ನೀವು ಈ ಕೋಷ್ಟಕದಲ್ಲಿ ಕ್ಷೇತ್ರಗಳನ್ನು ಬಳಸಲು ಪ್ರಾರಂಭಿಸುವವರೆಗೆ ಸಮಾನತೆ ಆಪರೇಟರ್ ಇಲ್ಲದ ವಿಧಗಳು:

CREATE TABLE tbl(k text, v integer, x point);
SELECT
  array_agg(ctid) ctids
FROM
  tbl T
GROUP BY
  T;
-- ERROR:  could not identify an equality operator for type tbl

ಹೌದು, ರಚನೆಯಲ್ಲಿ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ನಮೂದುಗಳಿದ್ದರೆ, ಇವೆಲ್ಲವೂ ತದ್ರೂಪುಗಳಾಗಿವೆ ಎಂದು ನಾವು ತಕ್ಷಣ ನೋಡುತ್ತೇವೆ. ಅವರನ್ನು ಸುಮ್ಮನೆ ಬಿಡೋಣ:

SELECT
  unnest(ctids[2:])
FROM
  (
    SELECT
      array_agg(ctid) ctids
    FROM
      tbl T
    GROUP BY
      T::text
  ) T;

unnest
------
(0,6)
(0,7)
(0,4)

ಚಿಕ್ಕದಾಗಿ ಬರೆಯಲು ಇಷ್ಟಪಡುವವರಿಗೆನೀವು ಇದನ್ನು ಈ ರೀತಿ ಸಹ ಬರೆಯಬಹುದು:

SELECT
  unnest((array_agg(ctid))[2:])
FROM
  tbl T
GROUP BY
  T::text;

ಧಾರಾವಾಹಿಯ ಸ್ಟ್ರಿಂಗ್‌ನ ಮೌಲ್ಯವು ನಮಗೆ ಆಸಕ್ತಿದಾಯಕವಲ್ಲದ ಕಾರಣ, ನಾವು ಅದನ್ನು ಸಬ್‌ಕ್ವೆರಿಯ ಹಿಂತಿರುಗಿದ ಕಾಲಮ್‌ಗಳಿಂದ ಸರಳವಾಗಿ ಎಸೆದಿದ್ದೇವೆ.

ಮಾಡಲು ಸ್ವಲ್ಪ ಮಾತ್ರ ಉಳಿದಿದೆ - ನಾವು ಸ್ವೀಕರಿಸಿದ ಸೆಟ್ ಅನ್ನು ಬಳಸಿ ಅಳಿಸಿ:

DELETE FROM
  tbl
WHERE
  ctid = ANY(ARRAY(
    SELECT
      unnest(ctids[2:])
    FROM
      (
        SELECT
          array_agg(ctid) ctids
        FROM
          tbl T
        GROUP BY
          T::text
      ) T
  )::tid[]);

ನಮ್ಮನ್ನು ನಾವು ಪರೀಕ್ಷಿಸಿಕೊಳ್ಳೋಣ:

PK ಇಲ್ಲದೆಯೇ ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸುವುದು
[explain.tensor.ru ನೋಡಿ]

ಹೌದು, ಎಲ್ಲವೂ ಸರಿಯಾಗಿದೆ: ನಮ್ಮ 3 ದಾಖಲೆಗಳನ್ನು ಸಂಪೂರ್ಣ ಟೇಬಲ್‌ನ ಏಕೈಕ Seq ಸ್ಕ್ಯಾನ್‌ಗಾಗಿ ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ ಮತ್ತು ಡೇಟಾವನ್ನು ಹುಡುಕಲು ಡಿಲೀಟ್ ನೋಡ್ ಅನ್ನು ಬಳಸಲಾಗಿದೆ ಟಿಡ್ ಸ್ಕ್ಯಾನ್‌ನೊಂದಿಗೆ ಒಂದೇ ಪಾಸ್:

->  Tid Scan on tbl (actual time=0.050..0.051 rows=3 loops=1)
      TID Cond: (ctid = ANY ($0))

ನೀವು ಸಾಕಷ್ಟು ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿದರೆ, ನಿರ್ವಾತ ವಿಶ್ಲೇಷಣೆಯನ್ನು ಚಲಾಯಿಸಲು ಮರೆಯಬೇಡಿ.

ದೊಡ್ಡ ಟೇಬಲ್ ಮತ್ತು ಹೆಚ್ಚಿನ ಸಂಖ್ಯೆಯ ನಕಲುಗಳೊಂದಿಗೆ ಪರಿಶೀಲಿಸೋಣ:

TRUNCATE TABLE tbl;

INSERT INTO tbl
SELECT
  chr(ascii('a'::text) + (random() * 26)::integer) k -- a..z
, (random() * 100)::integer v -- 0..99
FROM
  generate_series(1, 10000) i;

PK ಇಲ್ಲದೆಯೇ ಟೇಬಲ್‌ನಿಂದ ಕ್ಲೋನ್ ದಾಖಲೆಗಳನ್ನು ತೆರವುಗೊಳಿಸುವುದು
[explain.tensor.ru ನೋಡಿ]

ಆದ್ದರಿಂದ, ವಿಧಾನವು ಯಶಸ್ವಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಅದನ್ನು ಸ್ವಲ್ಪ ಎಚ್ಚರಿಕೆಯಿಂದ ಬಳಸಬೇಕು. ಏಕೆಂದರೆ ಅಳಿಸಲಾದ ಪ್ರತಿಯೊಂದು ದಾಖಲೆಗೆ, ಟಿಡ್ ಸ್ಕ್ಯಾನ್‌ನಲ್ಲಿ ಒಂದು ಡೇಟಾ ಪುಟವನ್ನು ಓದಲಾಗುತ್ತದೆ ಮತ್ತು ಅಳಿಸುವಿಕೆಯಲ್ಲಿ ಒಂದು ಇರುತ್ತದೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ