ಡಿಬಿಎ: ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಮತ್ತು ಆಮದುಗಳನ್ನು ಸಮರ್ಥವಾಗಿ ಸಂಘಟಿಸಿ

ದೊಡ್ಡ ಡೇಟಾ ಸೆಟ್‌ಗಳ ಸಂಕೀರ್ಣ ಪ್ರಕ್ರಿಯೆಗಾಗಿ (ವಿಭಿನ್ನ ETL ಪ್ರಕ್ರಿಯೆಗಳು: ಆಮದುಗಳು, ಪರಿವರ್ತನೆಗಳು ಮತ್ತು ಬಾಹ್ಯ ಮೂಲದೊಂದಿಗೆ ಸಿಂಕ್ರೊನೈಸೇಶನ್) ಆಗಾಗ್ಗೆ ಅವಶ್ಯಕತೆ ಇರುತ್ತದೆ ತಾತ್ಕಾಲಿಕವಾಗಿ "ನೆನಪಿಡಿ" ಮತ್ತು ತಕ್ಷಣವೇ ತ್ವರಿತವಾಗಿ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಿ ಏನೋ ಬೃಹತ್.

ಈ ರೀತಿಯ ವಿಶಿಷ್ಟ ಕಾರ್ಯವು ಸಾಮಾನ್ಯವಾಗಿ ಈ ರೀತಿ ಧ್ವನಿಸುತ್ತದೆ: "ಇಲ್ಲಿಯೇ ಕ್ಲೈಂಟ್ ಬ್ಯಾಂಕ್‌ನಿಂದ ಅಕೌಂಟಿಂಗ್ ವಿಭಾಗವನ್ನು ಇಳಿಸಲಾಗಿದೆ ಕೊನೆಯದಾಗಿ ಸ್ವೀಕರಿಸಿದ ಪಾವತಿಗಳನ್ನು ನೀವು ತ್ವರಿತವಾಗಿ ವೆಬ್‌ಸೈಟ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು ನಿಮ್ಮ ಖಾತೆಗಳಿಗೆ ಲಿಂಕ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.

ಆದರೆ ಈ “ಏನಾದರೂ” ಪರಿಮಾಣವು ನೂರಾರು ಮೆಗಾಬೈಟ್‌ಗಳಲ್ಲಿ ಅಳೆಯಲು ಪ್ರಾರಂಭಿಸಿದಾಗ ಮತ್ತು ಸೇವೆಯು ಡೇಟಾಬೇಸ್ 24x7 ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸಬೇಕು, ನಿಮ್ಮ ಜೀವನವನ್ನು ಹಾಳುಮಾಡುವ ಅನೇಕ ಅಡ್ಡಪರಿಣಾಮಗಳು ಉದ್ಭವಿಸುತ್ತವೆ.
ಡಿಬಿಎ: ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಮತ್ತು ಆಮದುಗಳನ್ನು ಸಮರ್ಥವಾಗಿ ಸಂಘಟಿಸಿ
PostgreSQL ನಲ್ಲಿ ಅವರೊಂದಿಗೆ ವ್ಯವಹರಿಸಲು (ಮತ್ತು ಅದರಲ್ಲಿ ಮಾತ್ರವಲ್ಲ), ನೀವು ಕೆಲವು ಆಪ್ಟಿಮೈಸೇಶನ್‌ಗಳನ್ನು ಬಳಸಬಹುದು ಅದು ಎಲ್ಲವನ್ನೂ ವೇಗವಾಗಿ ಮತ್ತು ಕಡಿಮೆ ಸಂಪನ್ಮೂಲ ಬಳಕೆಯೊಂದಿಗೆ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.

1. ಎಲ್ಲಿಗೆ ಸಾಗಿಸಲು?

ಮೊದಲಿಗೆ, ನಾವು "ಪ್ರಕ್ರಿಯೆ" ಮಾಡಲು ಬಯಸುವ ಡೇಟಾವನ್ನು ಎಲ್ಲಿ ಅಪ್‌ಲೋಡ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸೋಣ.

1.1. ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳು (TEMPORARY TABLE)

ತಾತ್ವಿಕವಾಗಿ, PostgreSQL ಗಾಗಿ ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳು ಇತರವುಗಳಂತೆಯೇ ಇರುತ್ತವೆ. ಆದ್ದರಿಂದ, ಮೂಢನಂಬಿಕೆಗಳು ಹಾಗೆ "ಅಲ್ಲಿ ಎಲ್ಲವನ್ನೂ ಮೆಮೊರಿಯಲ್ಲಿ ಮಾತ್ರ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಅದು ಕೊನೆಗೊಳ್ಳಬಹುದು". ಆದರೆ ಹಲವಾರು ಗಮನಾರ್ಹ ವ್ಯತ್ಯಾಸಗಳಿವೆ.

ಡೇಟಾಬೇಸ್‌ಗೆ ಪ್ರತಿ ಸಂಪರ್ಕಕ್ಕಾಗಿ ನಿಮ್ಮ ಸ್ವಂತ "ನೇಮ್ಸ್ಪೇಸ್"

ಎರಡು ಸಂಪರ್ಕಗಳು ಒಂದೇ ಸಮಯದಲ್ಲಿ ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಿದರೆ CREATE TABLE x, ನಂತರ ಯಾರಾದರೂ ಖಂಡಿತವಾಗಿಯೂ ಪಡೆಯುತ್ತಾರೆ ವಿಶಿಷ್ಟವಲ್ಲದ ದೋಷ ಡೇಟಾಬೇಸ್ ವಸ್ತುಗಳು.

ಆದರೆ ಎರಡೂ ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಿದರೆ CREATE TEMPORARY TABLE x, ನಂತರ ಇಬ್ಬರೂ ಅದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಮಾಡುತ್ತಾರೆ, ಮತ್ತು ಪ್ರತಿಯೊಬ್ಬರೂ ಪಡೆಯುತ್ತಾರೆ ನಿಮ್ಮ ಪ್ರತಿ ಕೋಷ್ಟಕಗಳು. ಮತ್ತು ಅವುಗಳ ನಡುವೆ ಸಾಮಾನ್ಯವಾದ ಏನೂ ಇರುವುದಿಲ್ಲ.

ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸುವಾಗ "ಸ್ವಯಂ-ನಾಶ"

ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಿದಾಗ, ಎಲ್ಲಾ ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಅಳಿಸಲಾಗುತ್ತದೆ, ಆದ್ದರಿಂದ ಹಸ್ತಚಾಲಿತವಾಗಿ DROP TABLE x ಹೊರತುಪಡಿಸಿ ಯಾವುದೇ ಅರ್ಥವಿಲ್ಲ ...

ನೀವು ಮೂಲಕ ಕೆಲಸ ಮಾಡುತ್ತಿದ್ದರೆ ವ್ಯವಹಾರ ಕ್ರಮದಲ್ಲಿ pgbouncer, ನಂತರ ಡೇಟಾಬೇಸ್ ಈ ಸಂಪರ್ಕವು ಇನ್ನೂ ಸಕ್ರಿಯವಾಗಿದೆ ಎಂದು ನಂಬಲು ಮುಂದುವರಿಯುತ್ತದೆ ಮತ್ತು ಅದರಲ್ಲಿ ಈ ತಾತ್ಕಾಲಿಕ ಟೇಬಲ್ ಇನ್ನೂ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ.

ಆದ್ದರಿಂದ, pgbouncer ಗೆ ಬೇರೆ ಸಂಪರ್ಕದಿಂದ ಅದನ್ನು ಮತ್ತೆ ರಚಿಸಲು ಪ್ರಯತ್ನಿಸುವುದು ದೋಷಕ್ಕೆ ಕಾರಣವಾಗುತ್ತದೆ. ಆದರೆ ಇದನ್ನು ಬಳಸುವುದರಿಂದ ತಪ್ಪಿಸಿಕೊಳ್ಳಬಹುದು CREATE TEMPORARY TABLE IF NOT EXISTS x.

ನಿಜ, ಇದನ್ನು ಹೇಗಾದರೂ ಮಾಡದಿರುವುದು ಉತ್ತಮ, ಏಕೆಂದರೆ "ಹಿಂದಿನ ಮಾಲೀಕರಿಂದ" ಉಳಿದಿರುವ ಡೇಟಾವನ್ನು ನೀವು "ಇದ್ದಕ್ಕಿದ್ದಂತೆ" ಕಾಣಬಹುದು. ಬದಲಾಗಿ, ಕೈಪಿಡಿಯನ್ನು ಓದುವುದು ಮತ್ತು ಟೇಬಲ್ ಅನ್ನು ರಚಿಸುವಾಗ ಅದನ್ನು ಸೇರಿಸಲು ಸಾಧ್ಯವಿದೆ ಎಂದು ನೋಡುವುದು ಹೆಚ್ಚು ಉತ್ತಮವಾಗಿದೆ ON COMMIT DROP - ಅಂದರೆ, ವಹಿವಾಟು ಪೂರ್ಣಗೊಂಡಾಗ, ಟೇಬಲ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಅಳಿಸಲ್ಪಡುತ್ತದೆ.

ಪುನರಾವರ್ತನೆಯಾಗದಿರುವುದು

ಅವರು ನಿರ್ದಿಷ್ಟ ಸಂಪರ್ಕಕ್ಕೆ ಮಾತ್ರ ಸೇರಿದ ಕಾರಣ, ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳನ್ನು ಪುನರಾವರ್ತಿಸಲಾಗುವುದಿಲ್ಲ. ಆದರೆ ಇದು ಡೇಟಾದ ಡಬಲ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಗತ್ಯವನ್ನು ನಿವಾರಿಸುತ್ತದೆ ರಾಶಿ + ವಾಲ್‌ನಲ್ಲಿ, ಅದರೊಳಗೆ ಸೇರಿಸು/ಅಪ್‌ಡೇಟ್/ಅಳಿಸುವಿಕೆ ಹೆಚ್ಚು ವೇಗವಾಗಿರುತ್ತದೆ.

ಆದರೆ ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕವು ಇನ್ನೂ "ಬಹುತೇಕ ಸಾಮಾನ್ಯ" ಕೋಷ್ಟಕವಾಗಿರುವುದರಿಂದ, ಅದನ್ನು ಪ್ರತಿಕೃತಿಯಲ್ಲಿಯೂ ರಚಿಸಲಾಗುವುದಿಲ್ಲ. ಕನಿಷ್ಠ ಇದೀಗ, ಅನುಗುಣವಾದ ಪ್ಯಾಚ್ ದೀರ್ಘಕಾಲದವರೆಗೆ ಪರಿಚಲನೆಯಾಗಿದ್ದರೂ.

1.2. ಅನ್ಲಾಗ್ಡ್ ಟೇಬಲ್

ಆದರೆ ನೀವು ಏನು ಮಾಡಬೇಕು, ಉದಾಹರಣೆಗೆ, ನೀವು ಕೆಲವು ರೀತಿಯ ತೊಡಕಿನ ETL ಪ್ರಕ್ರಿಯೆಯನ್ನು ಹೊಂದಿದ್ದರೆ ಅದು ಒಂದು ವಹಿವಾಟಿನೊಳಗೆ ಕಾರ್ಯಗತಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ, ಆದರೆ ನೀವು ಇನ್ನೂ ಹೊಂದಿದ್ದೀರಿ ವ್ಯವಹಾರ ಕ್ರಮದಲ್ಲಿ pgbouncer? ..

ಅಥವಾ ಡೇಟಾ ಹರಿವು ತುಂಬಾ ದೊಡ್ಡದಾಗಿದೆ ಒಂದು ಸಂಪರ್ಕದಲ್ಲಿ ಸಾಕಷ್ಟು ಬ್ಯಾಂಡ್‌ವಿಡ್ತ್ ಇಲ್ಲ ಡೇಟಾಬೇಸ್‌ನಿಂದ (ಓದಲು, ಪ್ರತಿ CPU ಗೆ ಒಂದು ಪ್ರಕ್ರಿಯೆ)?..

ಅಥವಾ ಕೆಲವು ಕಾರ್ಯಾಚರಣೆಗಳು ನಡೆಯುತ್ತಿವೆ ಅಸಮಕಾಲಿಕವಾಗಿ ವಿಭಿನ್ನ ಸಂಪರ್ಕಗಳಲ್ಲಿ? ..

ಇಲ್ಲಿ ಒಂದೇ ಒಂದು ಆಯ್ಕೆ ಇದೆ - ತಾತ್ಕಾಲಿಕವಲ್ಲದ ಟೇಬಲ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ರಚಿಸಿ. ಪನ್, ಹೌದು. ಅದು:

  • ಯಾರೊಂದಿಗೂ ಛೇದಿಸದಂತೆ ಗರಿಷ್ಠ ಯಾದೃಚ್ಛಿಕ ಹೆಸರುಗಳೊಂದಿಗೆ "ನನ್ನ ಸ್ವಂತ" ಕೋಷ್ಟಕಗಳನ್ನು ರಚಿಸಲಾಗಿದೆ
  • ಹೊರತೆಗೆಯಿರಿ: ಅವುಗಳನ್ನು ಬಾಹ್ಯ ಮೂಲದಿಂದ ಡೇಟಾ ತುಂಬಿದೆ
  • ರೂಪಾಂತರ: ಪರಿವರ್ತಿಸಲಾಗಿದೆ, ಪ್ರಮುಖ ಲಿಂಕ್ ಮಾಡುವ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ತುಂಬಿದೆ
  • ಲೋಡ್: ಗುರಿ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ಸಿದ್ಧ ಡೇಟಾವನ್ನು ಸುರಿಯಲಾಗುತ್ತದೆ
  • "ನನ್ನ" ಕೋಷ್ಟಕಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ

ಮತ್ತು ಈಗ - ಮುಲಾಮು ಒಂದು ಫ್ಲೈ. ವಾಸ್ತವವಾಗಿ, PostgreSQL ನಲ್ಲಿ ಎಲ್ಲಾ ಬರಹಗಳು ಎರಡು ಬಾರಿ ಸಂಭವಿಸುತ್ತವೆ - WAL ನಲ್ಲಿ ಮೊದಲು, ನಂತರ ಟೇಬಲ್/ಇಂಡೆಕ್ಸ್ ಬಾಡಿಗಳಿಗೆ. ACID ಅನ್ನು ಬೆಂಬಲಿಸಲು ಮತ್ತು ನಡುವೆ ಡೇಟಾ ಗೋಚರತೆಯನ್ನು ಸರಿಪಡಿಸಲು ಇದೆಲ್ಲವನ್ನೂ ಮಾಡಲಾಗುತ್ತದೆ COMMIT'ಅಡಿಕೆ ಮತ್ತು ROLLBACK'ಶೂನ್ಯ ವಹಿವಾಟುಗಳು.

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

ಇದನ್ನು ಮಾಡಲು, PostgreSQL ಡೆವಲಪರ್‌ಗಳು, ಆವೃತ್ತಿ 9.1 ರಲ್ಲಿ, ಅಂತಹ ವಿಷಯವನ್ನು ಪರಿಚಯಿಸಿದರು UNLOGGED ಕೋಷ್ಟಕಗಳು:

ಈ ಸೂಚನೆಯೊಂದಿಗೆ, ಟೇಬಲ್ ಅನ್ನು ಅನ್ಲಾಗ್ ಆಗಿ ರಚಿಸಲಾಗಿದೆ. ಅನ್ಲಾಗ್ ಮಾಡದ ಕೋಷ್ಟಕಗಳಿಗೆ ಬರೆಯಲಾದ ಡೇಟಾವು ಬರೆಯುವ-ಮುಂದಿರುವ ಲಾಗ್ ಮೂಲಕ ಹೋಗುವುದಿಲ್ಲ (ಅಧ್ಯಾಯ 29 ನೋಡಿ), ಅಂತಹ ಕೋಷ್ಟಕಗಳು ಸಾಮಾನ್ಯಕ್ಕಿಂತ ಹೆಚ್ಚು ವೇಗವಾಗಿ ಕೆಲಸ ಮಾಡಿ. ಆದಾಗ್ಯೂ, ಅವರು ವೈಫಲ್ಯದಿಂದ ವಿನಾಯಿತಿ ಹೊಂದಿಲ್ಲ; ಸರ್ವರ್ ವೈಫಲ್ಯ ಅಥವಾ ತುರ್ತು ಸ್ಥಗಿತದ ಸಂದರ್ಭದಲ್ಲಿ, ಅನ್ಲಾಗ್ ಮಾಡಲಾದ ಟೇಬಲ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮೊಟಕುಗೊಳಿಸಲಾಗಿದೆ. ಹೆಚ್ಚುವರಿಯಾಗಿ, ಅನ್ಲಾಗ್ ಮಾಡಲಾದ ಟೇಬಲ್ನ ವಿಷಯಗಳು ಪುನರಾವರ್ತಿಸಲಾಗಿಲ್ಲ ಗುಲಾಮ ಸರ್ವರ್‌ಗಳಿಗೆ. ಅನ್‌ಲಾಗ್ ಮಾಡಲಾದ ಟೇಬಲ್‌ನಲ್ಲಿ ರಚಿಸಲಾದ ಯಾವುದೇ ಸೂಚಿಕೆಗಳು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಅನ್‌ಲಾಗ್ ಆಗುತ್ತವೆ.

ಸಂಕ್ಷಿಪ್ತವಾಗಿ, ಇದು ಹೆಚ್ಚು ವೇಗವಾಗಿರುತ್ತದೆ, ಆದರೆ ಡೇಟಾಬೇಸ್ ಸರ್ವರ್ "ಬೀಳಿದರೆ", ಅದು ಅಹಿತಕರವಾಗಿರುತ್ತದೆ. ಆದರೆ ಇದು ಎಷ್ಟು ಬಾರಿ ಸಂಭವಿಸುತ್ತದೆ ಮತ್ತು ಡೇಟಾಬೇಸ್ ಅನ್ನು "ಪುನರುಜ್ಜೀವನಗೊಳಿಸಿದ" ನಂತರ ಇದನ್ನು "ಮಧ್ಯದಿಂದ" ಸರಿಯಾಗಿ ಸರಿಪಡಿಸುವುದು ಹೇಗೆ ಎಂದು ನಿಮ್ಮ ETL ಪ್ರಕ್ರಿಯೆಯು ತಿಳಿದಿದೆಯೇ?

ಇಲ್ಲದಿದ್ದರೆ, ಮತ್ತು ಮೇಲಿನ ಪ್ರಕರಣವು ನಿಮ್ಮಂತೆಯೇ ಇದ್ದರೆ, ಬಳಸಿ UNLOGGEDಆದರೆ ಎಂದಿಗೂ ನೈಜ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ಈ ಗುಣಲಕ್ಷಣವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಡಿ, ಡೇಟಾವು ನಿಮಗೆ ಪ್ರಿಯವಾಗಿದೆ.

1.3 ಬದ್ಧತೆಯ ಮೇಲೆ { ಸಾಲುಗಳನ್ನು ಅಳಿಸಿ | ಡ್ರಾಪ್}

ಟೇಬಲ್ ರಚಿಸುವಾಗ ವಹಿವಾಟು ಪೂರ್ಣಗೊಂಡಾಗ ಸ್ವಯಂಚಾಲಿತ ನಡವಳಿಕೆಯನ್ನು ಸೂಚಿಸಲು ಈ ರಚನೆಯು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.

ಮೇಲೆ ON COMMIT DROP ನಾನು ಈಗಾಗಲೇ ಮೇಲೆ ಬರೆದಿದ್ದೇನೆ, ಅದು ಉತ್ಪಾದಿಸುತ್ತದೆ DROP TABLE, ಆದರೆ ಜೊತೆ ON COMMIT DELETE ROWS ಪರಿಸ್ಥಿತಿಯು ಹೆಚ್ಚು ಆಸಕ್ತಿದಾಯಕವಾಗಿದೆ - ಇದು ಇಲ್ಲಿ ಉತ್ಪತ್ತಿಯಾಗುತ್ತದೆ TRUNCATE TABLE.

ತಾತ್ಕಾಲಿಕ ಟೇಬಲ್‌ನ ಮೆಟಾ-ವಿವರಣೆಯನ್ನು ಸಂಗ್ರಹಿಸಲು ಸಂಪೂರ್ಣ ಮೂಲಸೌಕರ್ಯವು ಸಾಮಾನ್ಯ ಟೇಬಲ್‌ನಂತೆಯೇ ಇರುತ್ತದೆ. ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳ ನಿರಂತರ ಸೃಷ್ಟಿ ಮತ್ತು ಅಳಿಸುವಿಕೆಯು ಸಿಸ್ಟಮ್ ಕೋಷ್ಟಕಗಳ ತೀವ್ರ "ಊತ" ಗೆ ಕಾರಣವಾಗುತ್ತದೆ pg_class, pg_attribute, pg_attrdef, pg_depend,...

ಈಗ ನೀವು ಡೇಟಾಬೇಸ್‌ಗೆ ನೇರ ಸಂಪರ್ಕದಲ್ಲಿ ಕೆಲಸಗಾರರನ್ನು ಹೊಂದಿದ್ದೀರಿ ಎಂದು ಊಹಿಸಿ, ಅದು ಪ್ರತಿ ಸೆಕೆಂಡಿಗೆ ಹೊಸ ವಹಿವಾಟನ್ನು ತೆರೆಯುತ್ತದೆ, ತಾತ್ಕಾಲಿಕ ಟೇಬಲ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ, ಭರ್ತಿ ಮಾಡುತ್ತದೆ, ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಅಳಿಸುತ್ತದೆ... ಸಿಸ್ಟಮ್ ಟೇಬಲ್‌ಗಳಲ್ಲಿ ಹೆಚ್ಚಿನ ಕಸ ಸಂಗ್ರಹವಾಗುತ್ತದೆ, ಮತ್ತು ಇದು ಪ್ರತಿ ಕಾರ್ಯಾಚರಣೆಗೆ ಹೆಚ್ಚುವರಿ ಬ್ರೇಕ್‌ಗಳನ್ನು ಉಂಟುಮಾಡುತ್ತದೆ.

ಸಾಮಾನ್ಯವಾಗಿ, ಇದನ್ನು ಮಾಡಬೇಡಿ! ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಇದು ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿಯಾಗಿದೆ CREATE TEMPORARY TABLE x ... ON COMMIT DELETE ROWS ವಹಿವಾಟಿನ ಚಕ್ರದಿಂದ ಹೊರತೆಗೆಯಿರಿ - ನಂತರ ಪ್ರತಿ ಹೊಸ ವಹಿವಾಟಿನ ಆರಂಭದ ವೇಳೆಗೆ ಕೋಷ್ಟಕಗಳು ಈಗಾಗಲೇ ಇವೆ ಅಸ್ತಿತ್ವದಲ್ಲಿರುತ್ತದೆ (ಕರೆ ಉಳಿಸಿ CREATE), ಆದರೆ ಖಾಲಿ ಇರುತ್ತದೆ, ಇವರಿಗೆ ಧನ್ಯವಾದಗಳು TRUNCATE ಹಿಂದಿನ ವ್ಯವಹಾರವನ್ನು ಪೂರ್ಣಗೊಳಿಸುವಾಗ (ನಾವು ಅದರ ಕರೆಯನ್ನು ಸಹ ಉಳಿಸಿದ್ದೇವೆ).

1.4 ಇಷ್ಟ... ಸೇರಿದಂತೆ...

ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕಗಳ ವಿಶಿಷ್ಟ ಬಳಕೆಯ ಪ್ರಕರಣಗಳಲ್ಲಿ ಒಂದಾದ ವಿವಿಧ ರೀತಿಯ ಆಮದುಗಳು ಎಂದು ನಾನು ಆರಂಭದಲ್ಲಿ ಉಲ್ಲೇಖಿಸಿದ್ದೇನೆ - ಮತ್ತು ಡೆವಲಪರ್ ಸುಸ್ತಾಗಿ ಟಾರ್ಗೆಟ್ ಟೇಬಲ್‌ನ ಕ್ಷೇತ್ರಗಳ ಪಟ್ಟಿಯನ್ನು ತನ್ನ ತಾತ್ಕಾಲಿಕ ಘೋಷಣೆಗೆ ನಕಲಿಸಿ-ಅಂಟಿಸುತ್ತಾನೆ.

ಆದರೆ ಸೋಮಾರಿತನವು ಪ್ರಗತಿಯ ಎಂಜಿನ್ ಆಗಿದೆ! ಅದಕ್ಕೇ "ಮಾದರಿ ಆಧರಿಸಿ" ಹೊಸ ಕೋಷ್ಟಕವನ್ನು ರಚಿಸಿ ಇದು ಹೆಚ್ಚು ಸರಳವಾಗಬಹುದು:

CREATE TEMPORARY TABLE import_table(
  LIKE target_table
);

ನಂತರ ನೀವು ಈ ಕೋಷ್ಟಕದಲ್ಲಿ ಬಹಳಷ್ಟು ಡೇಟಾವನ್ನು ರಚಿಸಬಹುದಾದ್ದರಿಂದ, ಅದರ ಮೂಲಕ ಹುಡುಕುವುದು ಎಂದಿಗೂ ವೇಗವಾಗಿರುವುದಿಲ್ಲ. ಆದರೆ ಇದಕ್ಕೆ ಸಾಂಪ್ರದಾಯಿಕ ಪರಿಹಾರವಿದೆ - ಸೂಚ್ಯಂಕಗಳು! ಮತ್ತು, ಹೌದು, ತಾತ್ಕಾಲಿಕ ಕೋಷ್ಟಕವು ಸೂಚ್ಯಂಕಗಳನ್ನು ಸಹ ಹೊಂದಬಹುದು.

ಆಗಾಗ್ಗೆ, ಅಗತ್ಯವಿರುವ ಸೂಚ್ಯಂಕಗಳು ಗುರಿ ಕೋಷ್ಟಕದ ಸೂಚಿಕೆಗಳೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದರಿಂದ, ನೀವು ಸರಳವಾಗಿ ಬರೆಯಬಹುದು LIKE target_table INCLUDING INDEXES.

ನಿಮಗೂ ಅಗತ್ಯವಿದ್ದರೆ DEFAULT-ಮೌಲ್ಯಗಳು (ಉದಾಹರಣೆಗೆ, ಪ್ರಾಥಮಿಕ ಕೀ ಮೌಲ್ಯಗಳನ್ನು ತುಂಬಲು), ನೀವು ಬಳಸಬಹುದು LIKE target_table INCLUDING DEFAULTS. ಅಥವಾ ಸರಳವಾಗಿ - LIKE target_table INCLUDING ALL — ಪ್ರತಿಗಳು ಡೀಫಾಲ್ಟ್‌ಗಳು, ಸೂಚಿಕೆಗಳು, ನಿರ್ಬಂಧಗಳು,...

ಆದರೆ ಇಲ್ಲಿ ನೀವು ರಚಿಸಿದರೆ ಅದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬೇಕು ಸೂಚ್ಯಂಕಗಳೊಂದಿಗೆ ತಕ್ಷಣ ಟೇಬಲ್ ಅನ್ನು ಆಮದು ಮಾಡಿ, ನಂತರ ಡೇಟಾವನ್ನು ಲೋಡ್ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆನೀವು ಮೊದಲು ಎಲ್ಲವನ್ನೂ ಭರ್ತಿ ಮಾಡಿದರೆ ಮತ್ತು ನಂತರ ಮಾತ್ರ ಸೂಚ್ಯಂಕಗಳನ್ನು ಸುತ್ತಿಕೊಳ್ಳುವುದಕ್ಕಿಂತ - ಇದು ಹೇಗೆ ಮಾಡುತ್ತದೆ ಎಂಬುದನ್ನು ಉದಾಹರಣೆಯಾಗಿ ನೋಡಿ pg_dump.

ಸಂಕ್ಷಿಪ್ತವಾಗಿ, ಆರ್ಟಿಎಫ್ಎಂ!

2. ಬರೆಯುವುದು ಹೇಗೆ?

ನಾನು ಹೇಳುತ್ತೇನೆ - ಅದನ್ನು ಬಳಸಿ COPY"ಪ್ಯಾಕ್" ಬದಲಿಗೆ ಹರಿವು INSERT, ಕೆಲವೊಮ್ಮೆ ವೇಗವರ್ಧನೆ. ನೀವು ನೇರವಾಗಿ ಪೂರ್ವ-ರಚಿತ ಫೈಲ್‌ನಿಂದ ಕೂಡ ಮಾಡಬಹುದು.

3. ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವುದು ಹೇಗೆ?

ಆದ್ದರಿಂದ, ನಮ್ಮ ಪರಿಚಯವನ್ನು ಈ ರೀತಿ ನೋಡೋಣ:

  • ನಿಮ್ಮ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಕ್ಲೈಂಟ್ ಡೇಟಾದೊಂದಿಗೆ ನೀವು ಟೇಬಲ್ ಅನ್ನು ಹೊಂದಿದ್ದೀರಿ 1M ದಾಖಲೆಗಳು
  • ಪ್ರತಿದಿನ ಕ್ಲೈಂಟ್ ನಿಮಗೆ ಹೊಸದನ್ನು ಕಳುಹಿಸುತ್ತಾನೆ ಪೂರ್ಣ "ಚಿತ್ರ"
  • ಅನುಭವದಿಂದ ನೀವು ಕಾಲಕಾಲಕ್ಕೆ ತಿಳಿದಿರುವಿರಿ 10K ಗಿಂತ ಹೆಚ್ಚಿನ ದಾಖಲೆಗಳನ್ನು ಬದಲಾಯಿಸಲಾಗುವುದಿಲ್ಲ

ಅಂತಹ ಪರಿಸ್ಥಿತಿಗೆ ಒಂದು ಶ್ರೇಷ್ಠ ಉದಾಹರಣೆಯಾಗಿದೆ KLADR ಬೇಸ್ — ಒಟ್ಟಾರೆಯಾಗಿ ಬಹಳಷ್ಟು ವಿಳಾಸಗಳಿವೆ, ಆದರೆ ಪ್ರತಿ ಸಾಪ್ತಾಹಿಕ ಅಪ್‌ಲೋಡ್‌ನಲ್ಲಿ ರಾಷ್ಟ್ರೀಯ ಮಟ್ಟದಲ್ಲಿಯೂ ಸಹ ಕೆಲವೇ ಬದಲಾವಣೆಗಳಿವೆ (ವಸಾಹತುಗಳ ಮರುಹೆಸರಿಸುವುದು, ಬೀದಿಗಳನ್ನು ಸಂಯೋಜಿಸುವುದು, ಹೊಸ ಮನೆಗಳ ನೋಟ).

3.1. ಪೂರ್ಣ ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಅಲ್ಗಾರಿದಮ್

ಸರಳತೆಗಾಗಿ, ನೀವು ಡೇಟಾವನ್ನು ಪುನರ್ರಚಿಸುವ ಅಗತ್ಯವಿಲ್ಲ ಎಂದು ಹೇಳೋಣ - ಟೇಬಲ್ ಅನ್ನು ಬಯಸಿದ ರೂಪಕ್ಕೆ ತನ್ನಿ, ಅಂದರೆ:

  • ತೆಗೆದುಹಾಕಿ ಇನ್ನು ಮುಂದೆ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲದ ಎಲ್ಲವೂ
  • ಅಪ್ಗ್ರೇಡ್ ಮಾಡಿ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಮತ್ತು ನವೀಕರಿಸಬೇಕಾದ ಎಲ್ಲವೂ
  • ಸೇರಿಸಿ ಇನ್ನೂ ಸಂಭವಿಸದ ಎಲ್ಲವೂ

ಈ ಕ್ರಮದಲ್ಲಿ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಏಕೆ ಮಾಡಬೇಕು? ಏಕೆಂದರೆ ಈ ರೀತಿಯಾಗಿ ಟೇಬಲ್ ಗಾತ್ರವು ಕನಿಷ್ಠವಾಗಿ ಬೆಳೆಯುತ್ತದೆ (MVCC ನೆನಪಿಡಿ!).

dst ನಿಂದ ಅಳಿಸಿ

ಇಲ್ಲ, ಖಂಡಿತವಾಗಿಯೂ ನೀವು ಕೇವಲ ಎರಡು ಕಾರ್ಯಾಚರಣೆಗಳ ಮೂಲಕ ಪಡೆಯಬಹುದು:

  • ತೆಗೆದುಹಾಕಿ (DELETE) ಸಾಮಾನ್ಯವಾಗಿ ಎಲ್ಲವೂ
  • ಸೇರಿಸಿ ಎಲ್ಲಾ ಹೊಸ ಚಿತ್ರದಿಂದ

ಆದರೆ ಅದೇ ಸಮಯದಲ್ಲಿ, MVCC ಗೆ ಧನ್ಯವಾದಗಳು, ಮೇಜಿನ ಗಾತ್ರವು ನಿಖರವಾಗಿ ಎರಡು ಬಾರಿ ಹೆಚ್ಚಾಗುತ್ತದೆ! 1K ಅಪ್‌ಡೇಟ್‌ನ ಕಾರಣದಿಂದಾಗಿ +10M ರೆಕಾರ್ಡ್‌ಗಳ ಚಿತ್ರಗಳನ್ನು ಕೋಷ್ಟಕದಲ್ಲಿ ಪಡೆಯುವುದು ತುಂಬಾ ಪುನರುಜ್ಜೀವನವಾಗಿದೆ...

ಮೊಟಕುಗೊಳಿಸಿ dst

ಸಂಪೂರ್ಣ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅಗ್ಗವಾಗಿ ಸ್ವಚ್ಛಗೊಳಿಸಬಹುದು ಎಂದು ಹೆಚ್ಚು ಅನುಭವಿ ಡೆವಲಪರ್ಗೆ ತಿಳಿದಿದೆ:

  • ಸ್ಪಷ್ಟ (TRUNCATE) ಸಂಪೂರ್ಣ ಟೇಬಲ್
  • ಸೇರಿಸಿ ಎಲ್ಲಾ ಹೊಸ ಚಿತ್ರದಿಂದ

ವಿಧಾನವು ಪರಿಣಾಮಕಾರಿಯಾಗಿದೆ, ಕೆಲವೊಮ್ಮೆ ಸಾಕಷ್ಟು ಅನ್ವಯಿಸುತ್ತದೆ, ಆದರೆ ಒಂದು ಸಮಸ್ಯೆ ಇದೆ... ನಾವು ದೀರ್ಘಕಾಲದವರೆಗೆ 1M ದಾಖಲೆಗಳನ್ನು ಸೇರಿಸುತ್ತೇವೆ, ಆದ್ದರಿಂದ ಈ ಸಮಯದಲ್ಲಿ ಟೇಬಲ್ ಅನ್ನು ಖಾಲಿ ಬಿಡಲು ನಮಗೆ ಸಾಧ್ಯವಿಲ್ಲ (ಒಂದೇ ವಹಿವಾಟಿನಲ್ಲಿ ಅದನ್ನು ಸುತ್ತಿಕೊಳ್ಳದೆಯೇ ಸಂಭವಿಸುತ್ತದೆ).

ಅಂದರೆ:

  • ನಾವು ಪ್ರಾರಂಭಿಸುತ್ತಿದ್ದೇವೆ ದೀರ್ಘಾವಧಿಯ ವಹಿವಾಟು
  • TRUNCATE ಹೇರುತ್ತದೆ AccessExclusive- ನಿರ್ಬಂಧಿಸುವುದು
  • ನಾವು ದೀರ್ಘಕಾಲದವರೆಗೆ ಅಳವಡಿಕೆಯನ್ನು ಮಾಡುತ್ತೇವೆ ಮತ್ತು ಈ ಸಮಯದಲ್ಲಿ ಎಲ್ಲರೂ ಸಹ ಸಾಧ್ಯವಿಲ್ಲ SELECT

ಏನೋ ಸರಿ ಹೋಗುತ್ತಿಲ್ಲ...

ಟೇಬಲ್ ಬದಲಿಸಿ... ಮರುಹೆಸರಿಸಿ... / ಡ್ರಾಪ್ ಟೇಬಲ್...

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

  • ಇನ್ನೂ ಕೂಡ AccessExclusive, ಗಮನಾರ್ಹವಾಗಿ ಕಡಿಮೆ ಸಮಯ ಆದರೂ
  • ಈ ಕೋಷ್ಟಕದ ಎಲ್ಲಾ ಪ್ರಶ್ನೆ ಯೋಜನೆಗಳು/ಅಂಕಿಅಂಶಗಳನ್ನು ಮರುಹೊಂದಿಸಲಾಗಿದೆ, ವಿಶ್ಲೇಷಣೆಯನ್ನು ಚಲಾಯಿಸಬೇಕಾಗಿದೆ
  • ಎಲ್ಲಾ ವಿದೇಶಿ ಕೀಲಿಗಳು ಮುರಿದುಹೋಗಿವೆ (FK) ಟೇಬಲ್‌ಗೆ

ಸೈಮನ್ ರಿಗ್ಸ್‌ನಿಂದ WIP ಪ್ಯಾಚ್ ಇತ್ತು ಅದು ತಯಾರಿಸಲು ಸಲಹೆ ನೀಡಿತು ALTERಅಂಕಿಅಂಶಗಳು ಮತ್ತು FK ಅನ್ನು ಸ್ಪರ್ಶಿಸದೆಯೇ, ಫೈಲ್ ಮಟ್ಟದಲ್ಲಿ ಟೇಬಲ್ ದೇಹವನ್ನು ಬದಲಿಸುವ ಕಾರ್ಯಾಚರಣೆ, ಆದರೆ ಕೋರಂ ಅನ್ನು ಸಂಗ್ರಹಿಸಲಿಲ್ಲ.

ಅಳಿಸಿ, ನವೀಕರಿಸಿ, ಸೇರಿಸಿ

ಆದ್ದರಿಂದ, ನಾವು ಮೂರು ಕಾರ್ಯಾಚರಣೆಗಳ ತಡೆರಹಿತ ಆಯ್ಕೆಯನ್ನು ಪರಿಹರಿಸುತ್ತೇವೆ. ಬಹುತೇಕ ಮೂರು... ಇದನ್ನು ಅತ್ಯಂತ ಪರಿಣಾಮಕಾರಿಯಾಗಿ ಮಾಡುವುದು ಹೇಗೆ?

-- все делаем в рамках транзакции, чтобы никто не видел "промежуточных" состояний
BEGIN;

-- создаем временную таблицу с импортируемыми данными
CREATE TEMPORARY TABLE tmp(
  LIKE dst INCLUDING INDEXES -- по образу и подобию, вместе с индексами
) ON COMMIT DROP; -- за рамками транзакции она нам не нужна

-- быстро-быстро вливаем новый образ через COPY
COPY tmp FROM STDIN;
-- ...
-- .

-- удаляем отсутствующие
DELETE FROM
  dst D
USING
  dst X
LEFT JOIN
  tmp Y
    USING(pk1, pk2) -- поля первичного ключа
WHERE
  (D.pk1, D.pk2) = (X.pk1, X.pk2) AND
  Y IS NOT DISTINCT FROM NULL; -- "антиджойн"

-- обновляем оставшиеся
UPDATE
  dst D
SET
  (f1, f2, f3) = (T.f1, T.f2, T.f3)
FROM
  tmp T
WHERE
  (D.pk1, D.pk2) = (T.pk1, T.pk2) AND
  (D.f1, D.f2, D.f3) IS DISTINCT FROM (T.f1, T.f2, T.f3); -- незачем обновлять совпадающие

-- вставляем отсутствующие
INSERT INTO
  dst
SELECT
  T.*
FROM
  tmp T
LEFT JOIN
  dst D
    USING(pk1, pk2)
WHERE
  D IS NOT DISTINCT FROM NULL;

COMMIT;

3.2. ಆಮದು ನಂತರದ ಪ್ರಕ್ರಿಯೆ

ಅದೇ KLADR ನಲ್ಲಿ, ಎಲ್ಲಾ ಬದಲಾದ ದಾಖಲೆಗಳನ್ನು ಹೆಚ್ಚುವರಿಯಾಗಿ ಪೋಸ್ಟ್-ಪ್ರೊಸೆಸಿಂಗ್ ಮೂಲಕ ರನ್ ಮಾಡಬೇಕು - ಸಾಮಾನ್ಯೀಕರಿಸಲಾಗಿದೆ, ಕೀವರ್ಡ್‌ಗಳನ್ನು ಹೈಲೈಟ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ಅಗತ್ಯವಿರುವ ರಚನೆಗಳಿಗೆ ಕಡಿಮೆ ಮಾಡಿ. ಆದರೆ ನಿಮಗೆ ಹೇಗೆ ಗೊತ್ತು - ನಿಖರವಾಗಿ ಏನು ಬದಲಾಗಿದೆಸಿಂಕ್ರೊನೈಸೇಶನ್ ಕೋಡ್ ಅನ್ನು ಸಂಕೀರ್ಣಗೊಳಿಸದೆಯೇ, ಆದರ್ಶಪ್ರಾಯವಾಗಿ ಅದನ್ನು ಮುಟ್ಟದೆಯೇ?

ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ಪ್ರಕ್ರಿಯೆಯು ಬರವಣಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿದ್ದರೆ, ನಂತರ ನೀವು ನಮಗೆ ಎಲ್ಲಾ ಬದಲಾವಣೆಗಳನ್ನು ಸಂಗ್ರಹಿಸುವ ಪ್ರಚೋದಕವನ್ನು ಬಳಸಬಹುದು:

-- целевые таблицы
CREATE TABLE kladr(...);
CREATE TABLE kladr_house(...);

-- таблицы с историей изменений
CREATE TABLE kladr$log(
  ro kladr, -- тут лежат целые образы записей старой/новой
  rn kladr
);

CREATE TABLE kladr_house$log(
  ro kladr_house,
  rn kladr_house
);

-- общая функция логирования изменений
CREATE OR REPLACE FUNCTION diff$log() RETURNS trigger AS $$
DECLARE
  dst varchar = TG_TABLE_NAME || '$log';
  stmt text = '';
BEGIN
  -- проверяем необходимость логгирования при обновлении записи
  IF TG_OP = 'UPDATE' THEN
    IF NEW IS NOT DISTINCT FROM OLD THEN
      RETURN NEW;
    END IF;
  END IF;
  -- создаем запись лога
  stmt = 'INSERT INTO ' || dst::text || '(ro,rn)VALUES(';
  CASE TG_OP
    WHEN 'INSERT' THEN
      EXECUTE stmt || 'NULL,$1)' USING NEW;
    WHEN 'UPDATE' THEN
      EXECUTE stmt || '$1,$2)' USING OLD, NEW;
    WHEN 'DELETE' THEN
      EXECUTE stmt || '$1,NULL)' USING OLD;
  END CASE;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

ಈಗ ನಾವು ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು ಟ್ರಿಗ್ಗರ್‌ಗಳನ್ನು ಅನ್ವಯಿಸಬಹುದು (ಅಥವಾ ಅವುಗಳನ್ನು ಮೂಲಕ ಸಕ್ರಿಯಗೊಳಿಸಿ ALTER TABLE ... ENABLE TRIGGER ...):

CREATE TRIGGER log
  AFTER INSERT OR UPDATE OR DELETE
  ON kladr
    FOR EACH ROW
      EXECUTE PROCEDURE diff$log();

CREATE TRIGGER log
  AFTER INSERT OR UPDATE OR DELETE
  ON kladr_house
    FOR EACH ROW
      EXECUTE PROCEDURE diff$log();

ತದನಂತರ ನಾವು ಲಾಗ್ ಕೋಷ್ಟಕಗಳಿಂದ ಅಗತ್ಯವಿರುವ ಎಲ್ಲಾ ಬದಲಾವಣೆಗಳನ್ನು ಶಾಂತವಾಗಿ ಹೊರತೆಗೆಯುತ್ತೇವೆ ಮತ್ತು ಹೆಚ್ಚುವರಿ ಹ್ಯಾಂಡ್ಲರ್ಗಳ ಮೂಲಕ ಅವುಗಳನ್ನು ಚಲಾಯಿಸುತ್ತೇವೆ.

3.3 ಲಿಂಕ್ಡ್ ಸೆಟ್‌ಗಳನ್ನು ಆಮದು ಮಾಡಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ

ಮೂಲ ಮತ್ತು ಗಮ್ಯಸ್ಥಾನದ ಡೇಟಾ ರಚನೆಗಳು ಒಂದೇ ಆಗಿರುವ ಸಂದರ್ಭಗಳನ್ನು ನಾವು ಮೇಲೆ ಪರಿಗಣಿಸಿದ್ದೇವೆ. ಆದರೆ ಬಾಹ್ಯ ಸಿಸ್ಟಮ್‌ನಿಂದ ಅಪ್‌ಲೋಡ್ ಮಾಡುವಿಕೆಯು ನಮ್ಮ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿನ ಶೇಖರಣಾ ರಚನೆಗಿಂತ ಭಿನ್ನವಾದ ಸ್ವರೂಪವನ್ನು ಹೊಂದಿದ್ದರೆ ಏನು?

ಕ್ಲೈಂಟ್‌ಗಳು ಮತ್ತು ಅವರ ಖಾತೆಗಳ ಸಂಗ್ರಹಣೆಯನ್ನು ಉದಾಹರಣೆಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳೋಣ, ಕ್ಲಾಸಿಕ್ "ಹಲವು-ಒಂದು" ಆಯ್ಕೆ:

CREATE TABLE client(
  client_id
    serial
      PRIMARY KEY
, inn
    varchar
      UNIQUE
, name
    varchar
);

CREATE TABLE invoice(
  invoice_id
    serial
      PRIMARY KEY
, client_id
    integer
      REFERENCES client(client_id)
, number
    varchar
, dt
    date
, sum
    numeric(32,2)
);

ಆದರೆ ಬಾಹ್ಯ ಮೂಲದಿಂದ ಡೌನ್‌ಲೋಡ್ ನಮಗೆ "ಆಲ್ ಇನ್ ಒನ್" ರೂಪದಲ್ಲಿ ಬರುತ್ತದೆ:

CREATE TEMPORARY TABLE invoice_import(
  client_inn
    varchar
, client_name
    varchar
, invoice_number
    varchar
, invoice_dt
    date
, invoice_sum
    numeric(32,2)
);

ನಿಸ್ಸಂಶಯವಾಗಿ, ಗ್ರಾಹಕರ ಡೇಟಾವನ್ನು ಈ ಆವೃತ್ತಿಯಲ್ಲಿ ನಕಲು ಮಾಡಬಹುದು ಮತ್ತು ಮುಖ್ಯ ದಾಖಲೆಯು "ಖಾತೆ" ಆಗಿದೆ:

0123456789;Вася;A-01;2020-03-16;1000.00
9876543210;Петя;A-02;2020-03-16;666.00
0123456789;Вася;B-03;2020-03-16;9999.00

ಮಾದರಿಗಾಗಿ, ನಾವು ನಮ್ಮ ಪರೀಕ್ಷಾ ಡೇಟಾವನ್ನು ಸರಳವಾಗಿ ಸೇರಿಸುತ್ತೇವೆ, ಆದರೆ ನೆನಪಿಡಿ - COPY ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿ!

INSERT INTO invoice_import
VALUES
  ('0123456789', 'Вася', 'A-01', '2020-03-16', 1000.00)
, ('9876543210', 'Петя', 'A-02', '2020-03-16', 666.00)
, ('0123456789', 'Вася', 'B-03', '2020-03-16', 9999.00);

ಮೊದಲಿಗೆ, ನಮ್ಮ "ವಾಸ್ತವಗಳು" ಉಲ್ಲೇಖಿಸುವ "ಕಡಿತಗಳನ್ನು" ಹೈಲೈಟ್ ಮಾಡೋಣ. ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, ಇನ್‌ವಾಯ್ಸ್‌ಗಳು ಗ್ರಾಹಕರನ್ನು ಉಲ್ಲೇಖಿಸುತ್ತವೆ:

CREATE TEMPORARY TABLE client_import AS
SELECT DISTINCT ON(client_inn)
-- можно просто SELECT DISTINCT, если данные заведомо непротиворечивы
  client_inn inn
, client_name "name"
FROM
  invoice_import;

ಗ್ರಾಹಕರ ID ಗಳೊಂದಿಗೆ ಖಾತೆಗಳನ್ನು ಸರಿಯಾಗಿ ಸಂಯೋಜಿಸಲು, ನಾವು ಮೊದಲು ಈ ಗುರುತಿಸುವಿಕೆಗಳನ್ನು ಕಂಡುಹಿಡಿಯಬೇಕು ಅಥವಾ ರಚಿಸಬೇಕು. ಅವುಗಳ ಅಡಿಯಲ್ಲಿ ಕ್ಷೇತ್ರಗಳನ್ನು ಸೇರಿಸೋಣ:

ALTER TABLE invoice_import ADD COLUMN client_id integer;
ALTER TABLE client_import ADD COLUMN client_id integer;

ಸಣ್ಣ ತಿದ್ದುಪಡಿಯೊಂದಿಗೆ ಮೇಲೆ ವಿವರಿಸಿದ ಟೇಬಲ್ ಸಿಂಕ್ರೊನೈಸೇಶನ್ ವಿಧಾನವನ್ನು ಬಳಸೋಣ - ನಾವು ಉದ್ದೇಶಿತ ಕೋಷ್ಟಕದಲ್ಲಿ ಏನನ್ನೂ ನವೀಕರಿಸುವುದಿಲ್ಲ ಅಥವಾ ಅಳಿಸುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ನಾವು ಕ್ಲೈಂಟ್‌ಗಳನ್ನು "ಅನುಬಂಧ-ಮಾತ್ರ" ಆಮದು ಮಾಡಿಕೊಳ್ಳುತ್ತೇವೆ:

-- проставляем в таблице импорта ID уже существующих записей
UPDATE
  client_import T
SET
  client_id = D.client_id
FROM
  client D
WHERE
  T.inn = D.inn; -- unique key

-- вставляем отсутствовавшие записи и проставляем их ID
WITH ins AS (
  INSERT INTO client(
    inn
  , name
  )
  SELECT
    inn
  , name
  FROM
    client_import
  WHERE
    client_id IS NULL -- если ID не проставился
  RETURNING *
)
UPDATE
  client_import T
SET
  client_id = D.client_id
FROM
  ins D
WHERE
  T.inn = D.inn; -- unique key

-- проставляем ID клиентов у записей счетов
UPDATE
  invoice_import T
SET
  client_id = D.client_id
FROM
  client_import D
WHERE
  T.client_inn = D.inn; -- прикладной ключ

ವಾಸ್ತವವಾಗಿ, ಎಲ್ಲವೂ ಇದೆ invoice_import ಈಗ ನಾವು ಸಂಪರ್ಕ ಕ್ಷೇತ್ರವನ್ನು ಭರ್ತಿ ಮಾಡಿದ್ದೇವೆ client_id, ಅದರೊಂದಿಗೆ ನಾವು ಸರಕುಪಟ್ಟಿ ಸೇರಿಸುತ್ತೇವೆ.

ಮೂಲ: www.habr.com

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