เชนเซ‡เชชเซเชชเซ€ เชชเชพเชฐเซเชŸเซ€ เช…เชฅเชตเชพ เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ 10 เชฎเชพเช‚ เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเซ‡ เชœเชพเชฃเชตเชพ เชตเชฟเชถเซ‡เชจเซ€ เชฏเชพเชฆเซ‹เชจเซ€ เช•เซ‡เชŸเชฒเซ€เช• เชชเช‚เช•เซเชคเชฟเช“

เชชเซเชฐเชธเซเชคเชพเชตเชจเชพ เช…เชฅเชตเชพ เชตเชฟเชญเชพเช—เซ€เช•เชฐเชฃเชจเซ‹ เชตเชฟเชšเชพเชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช†เชตเซเชฏเซ‹

เชตเชพเชฐเซเชคเชพ เช…เชนเซ€เช‚เชฅเซ€ เชถเชฐเซ‚ เชฅเชพเชฏ เช›เซ‡: เชคเชฎเชจเซ‡ เชฏเชพเชฆ เช›เซ‡ เช•เซ‡ เช† เชฌเชงเซเช‚ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชถเชฐเซ‚ เชฅเชฏเซเช‚. เชฌเชงเซเช‚ เชชเซเชฐเชฅเชฎ เชตเช–เชค เช…เชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชนเชคเซเช‚. เชตเชฟเชจเช‚เชคเซ€เชจเซ‡ เช‘เชชเซเชŸเชฟเชฎเชพเช‡เช เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเชพ เชฒเช—เชญเช— เชคเชฎเชพเชฎ เชธเช‚เชธเชพเชงเชจเซ‹, เชคเซ‡ เชธเชฎเชฏเซ‡, เช–เชคเชฎ เชฅเชˆ เช—เชฏเชพ เชชเช›เซ€, เชชเซเชฐเชถเซเชจ เชŠเชญเซ‹ เชฅเชฏเซ‹ - เช†เช—เชณ เชถเซเช‚? เช† เชฐเซ€เชคเซ‡ เชตเชฟเชญเชพเชœเชจเชจเซ‹ เชตเชฟเชšเชพเชฐ เช†เชตเซเชฏเซ‹.

เชนเซ‡เชชเซเชชเซ€ เชชเชพเชฐเซเชŸเซ€ เช…เชฅเชตเชพ เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ 10 เชฎเชพเช‚ เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเซ‡ เชœเชพเชฃเชตเชพ เชตเชฟเชถเซ‡เชจเซ€ เชฏเชพเชฆเซ‹เชจเซ€ เช•เซ‡เชŸเชฒเซ€เช• เชชเช‚เช•เซเชคเชฟเช“

เช—เซ€เชคเชพเชคเซเชฎเช• เชตเชฟเชทเชฏเชพเช‚เชคเชฐ:
เชšเซ‹เช•เซเช•เชธ 'เชคเซ‡ เช•เซเชทเชฃเซ‡', เช•เชพเชฐเชฃ เช•เซ‡ เชœเซ‡เชฎ เชคเซ‡ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚ เช›เซ‡, เชคเซเชฏเชพเช‚ เชฌเชฟเชจเช‰เชชเชฏเซ‹เช—เซ€ เช“เชชเซเชŸเชฟเชฎเชพเช‡เชเซ‡เชถเชจ เช…เชจเชพเชฎเชค เชนเชคเชพ. เช†เชญเชพเชฐ asmm เช…เชจเซ‡ เชนเชฌเซเชฐเซ!

เชคเซ‡เชฅเซ€, เชคเชฎเซ‡ เช—เซเชฐเชพเชนเช•เชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช–เซเชถ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เช…เชจเซ‡ เชคเซ‡ เชœ เชธเชฎเชฏเซ‡ เชคเชฎเชพเชฐเซ€ เชชเซ‹เชคเชพเชจเซ€ เช•เซเชถเชณเชคเชพ เชธเซเชงเชพเชฐเซ€ เชถเช•เซ‹ เช›เซ‹?

เชถเช•เซเชฏ เชคเซ‡เชŸเชฒเซเช‚ เชฌเชงเซเช‚ เชธเชฐเชณ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡, เชคเซ‹ เชชเช›เซ€ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเชพ เชชเซเชฐเชฆเชฐเซเชถเชจเชฎเชพเช‚ เชงเชฐเชฎเซ‚เชณเชฅเซ€ เช•เช‚เชˆเช• เชธเซเชงเชพเชฐเชตเชพเชจเซ€ เชฎเชพเชคเซเชฐ เชฌเซ‡ เชฐเซ€เชคเซ‹ เช›เซ‡:
1) เชตเซเชฏเชพเชชเช• เชฎเชพเชฐเซเช— - เช…เชฎเซ‡ เชธเช‚เชธเชพเชงเชจเซ‹ เชตเชงเชพเชฐเซ€เช เช›เซ€เช, เช—เซ‹เช เชตเชฃเซ€ เชฌเชฆเชฒเซ€เช เช›เซ€เช;
2) เชธเช˜เชจ เชชเชพเชฅ - เช•เซเชตเซ‡เชฐเซ€ เช‘เชชเซเชŸเชฟเชฎเชพเช‡เชเซ‡เชถเชจ

เช•เชพเชฐเชฃ เช•เซ‡, เชนเซเช‚ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เช•เชฐเซเช‚ เช›เซเช‚, เชคเซ‡ เชธเชฎเชฏเซ‡ เชคเซ‡ เชธเซเชชเชทเซเชŸ เชจ เชนเชคเซเช‚ เช•เซ‡ เชเชกเชช เชตเชงเชพเชฐเชตเชพเชจเซ€ เชตเชฟเชจเช‚เชคเซ€เชฎเชพเช‚ เชฌเซ€เชœเซเช‚ เชถเซเช‚ เชฌเชฆเชฒเชตเซเช‚, เชฐเชธเซเชคเซ‹ เชชเชธเช‚เชฆ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชนเชคเซ‹ - เชŸเซ‡เชฌเชฒ เชกเชฟเชเชพเช‡เชจ เชซเซ‡เชฐเชซเชพเชฐเซ‹.

เชคเซ‡เชฅเซ€, เชฎเซเช–เซเชฏ เชชเซเชฐเชถเซเชจ เชŠเชญเซ‹ เชฅเชพเชฏ เช›เซ‡: เช†เชชเชฃเซ‡ เชถเซเช‚ เช…เชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชพเชˆเชถเซเช‚?

เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชถเชฐเชคเซ‹

เชชเซเชฐเชฅเชฎ, เช† ERD เช›เซ‡ (เชถเชฐเชคเซ€ เชฐเซ€เชคเซ‡ เชธเชฐเชณ เชฐเซ€เชคเซ‡ เชฌเชคเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡):
เชนเซ‡เชชเซเชชเซ€ เชชเชพเชฐเซเชŸเซ€ เช…เชฅเชตเชพ เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ 10 เชฎเชพเช‚ เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเซ‡ เชœเชพเชฃเชตเชพ เชตเชฟเชถเซ‡เชจเซ€ เชฏเชพเชฆเซ‹เชจเซ€ เช•เซ‡เชŸเชฒเซ€เช• เชชเช‚เช•เซเชคเชฟเช“
เชฎเซเช–เซเชฏ เชฒเช•เซเชทเชฃเซ‹:

  1. เช…เชจเซ‡เช•-เชฅเซ€-เช˜เชฃเชพ เชธเช‚เชฌเช‚เชงเซ‹
  2. เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชธเช‚เชญเชตเชฟเชค เชชเชพเชฐเซเชŸเซ€เชถเชจ เช•เซ€ เช›เซ‡

เชฎเซ‚เชณ เชตเชฟเชจเช‚เชคเซ€:

SELECT
            p."PARAMETER_ID" as  parameter_id,
            pc."PC_NAME" AS pc_name,
            pc."CUSTOMER_PARTNUMBER" AS customer_partnumber,
            w."LASERMARK" AS lasermark,
            w."LOTID" AS lotid,
            w."REPORTED_VALUE" AS reported_value,
            w."LOWER_SPEC_LIMIT" AS lower_spec_limit,
            w."UPPER_SPEC_LIMIT" AS upper_spec_limit,
            p."TYPE_CALCUL" AS type_calcul,
            s."SHIPMENT_NAME" AS shipment_name,
            s."SHIPMENT_DATE" AS shipment_date,
            extract(year from s."SHIPMENT_DATE") AS year,
            extract(month from s."SHIPMENT_DATE") as month,
            s."REPORT_NAME" AS report_name,
            p."SPARAM_NAME" AS SPARAM_name,
            p."CUSTOMERPARAM_NAME" AS customerparam_name
        FROM data w INNER JOIN shipment s ON s."SHIPMENT_ID" = w."SHIPMENT_ID"
             INNER JOIN parameters p ON p."PARAMETER_ID" = w."PARAMETER_ID"
             INNER JOIN shipment_pc sp ON s."SHIPMENT_ID" = sp."SHIPMENT_ID"
             INNER JOIN pc pc ON pc."PC_ID" = sp."PC_ID"
             INNER JOIN ( SELECT w2."LASERMARK" , MAX(s2."SHIPMENT_DATE") AS "SHIPMENT_DATE"
                          FROM shipment s2 INNER JOIN data w2 ON s2."SHIPMENT_ID" = w2."SHIPMENT_ID" 
                          GROUP BY w2."LASERMARK"
                         ) md ON md."SHIPMENT_DATE" = s."SHIPMENT_DATE" AND md."LASERMARK" = w."LASERMARK"
        WHERE 
             s."SHIPMENT_DATE" >= '2018-07-01' AND s."SHIPMENT_DATE" <= '2018-09-30' ;

เชŸเซ‡เชธเซเชŸ เชกเซ‡เชŸเชพเชฌเซ‡เช เชชเชฐ เช…เชฎเชฒเชจเชพ เชชเชฐเชฟเชฃเชพเชฎเซ‹:
เช•เชฟเช‚เชฎเชค : 502 997.55
เช…เชฎเชฒ เชธเชฎเชฏ: 505 เชธเซ‡เช•เชจเซเชก.

เช†เชชเชฃเซ‡ เชถเซเช‚ เชœเซ‹เชˆเช เช›เซ€เช? เชธเชฎเชฏเชจเชพ เชŸเซเช•เชกเชพ เชชเชฐ เช†เชงเชพเชฐเชฟเชค เชจเชฟเชฏเชฎเชฟเชค เชตเชฟเชจเช‚เชคเซ€.
เชšเชพเชฒเซ‹ เชธเซŒเชฅเซ€ เชธเชฐเชณ เชคเชพเชฐเซเช•เชฟเช• เชงเชพเชฐเชฃเชพ เช•เชฐเซ€เช: เชœเซ‹ เชธเชฎเชฏเชจเชพ เชŸเซเช•เชกเชพเชจเซ‹ เชจเชฎเซ‚เชจเซ‹ เชนเซ‹เชฏ, เชคเซ‹ เชถเซเช‚ เชคเซ‡ เช†เชชเชฃเชจเซ‡ เชฎเชฆเชฆ เช•เชฐเชถเซ‡? เชคเซ‡ เชธเชพเชšเซเช‚ เช›เซ‡ - เชชเชพเชฐเซเชŸเซ€เชถเชจ.

เชถเซเช‚ เชตเชฟเชญเชพเช— เช•เชฐเชตเซเช‚?

เชชเซเชฐเชฅเชฎ เชจเชœเชฐเชฎเชพเช‚, เชชเชธเช‚เชฆเช—เซ€ เชธเซเชชเชทเซเชŸ เช›เซ‡ - "SHIPMENT_DATE" เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ "เชถเชฟเชชเชฎเซ‡เชจเซเชŸ" เช•เซ‹เชทเซเชŸเช•เชจเซเช‚ เช˜เซ‹เชทเชฃเชพเชคเซเชฎเช• เชชเชพเชฐเซเชŸเซ€เชถเชจ (เช–เซ‚เชฌ เช†เช—เชณ เช•เซ‚เชฆเช•เซ‹ - เช…เช‚เชคเซ‡ เชคเซ‡ เช‰เชคเซเชชเชพเชฆเชจเชฎเชพเช‚ เชฅเซ‹เชกเซเช‚ เช–เซ‹เชŸเซเช‚ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚).

เชชเชพเชฐเซเชŸเซ€เชถเชจ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซเช‚?

เช† เชชเซเชฐเชถเซเชจ เชชเชฃ เชฌเชนเซ เช…เช˜เชฐเซ‹ เชจเชฅเซ€. เชธเชฆเชจเชธเซ€เชฌเซ‡, PostgreSQL 10 เชฎเชพเช‚, เชนเชตเซ‡ เชฎเชพเชจเชต เชชเชพเชฐเซเชŸเซ€เชถเชจเซ€เช‚เช— เชฎเชฟเช•เซ‡เชจเชฟเชเชฎ เช›เซ‡.
เชคเซ‡เชฅเซ€:

  1. เชธเซเชคเซเชฐเซ‹เชค เช•เซ‹เชทเซเชŸเช•เชจเซ‹ เชกเชฎเซเชช เชธเชพเชšเชตเซ‹ - pg_dump source_table
  2. เชฎเซ‚เชณ เช•เซ‹เชทเซเชŸเช• เช•เชพเชขเซ€ เชจเชพเช–เซ‹ - เชกเซเชฐเซ‹เชช เชŸเซ‡เชฌเชฒ เชธเซเชคเซเชฐเซ‹เชค_เชŸเซ‡เชฌเชฒ
  3. เชฐเซ‡เชจเซเชœ เชชเชพเชฐเซเชŸเซ€เชถเชจ เชธเชพเชฅเซ‡ เชชเซ‡เชฐเซ‡เชจเซเชŸ เชŸเซ‡เชฌเชฒ เชฌเชจเชพเชตเซ‹ - เช•เซ‹เชทเซเชŸเช• เชธเซเชคเซเชฐเซ‹เชค_เชŸเซ‡เชฌเชฒ เชฌเชจเชพเชตเซ‹
  4. เชตเชฟเชญเชพเช—เซ‹ เชฌเชจเชพเชตเซ‹ - เช•เซ‹เชทเซเชŸเช• source_table เชฌเชจเชพเชตเซ‹, เช‡เชจเซเชกเซ‡เช•เซเชธ เชฌเชจเชพเชตเซ‹
  5. เชชเช—เชฒเซเช‚ 1 เชฎเชพเช‚ เชฌเชจเชพเชตเซ‡เชฒ เชกเชฎเซเชช เช†เชฏเชพเชค เช•เชฐเซ‹ - pg_restore

เชชเชพเชฐเซเชŸเซ€เชถเชจ เชฎเชพเชŸเซ‡ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹

เชธเชฐเชณเชคเชพ เช…เชจเซ‡ เชธเช—เชตเชกเชคเชพ เชฎเชพเชŸเซ‡, เชชเช—เชฒเชพเช‚ 2,3,4 เชจเซ‡ เชเช• เชธเซเช•เซเชฐเชฟเชชเซเชŸเชฎเชพเช‚ เชœเซ‹เชกเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เช›เซ‡.

เชคเซ‡เชฅเซ€:
เชธเซเชคเซเชฐเซ‹เชค เช•เซ‹เชทเซเชŸเช•เชจเซ‹ เชกเชฎเซเชช เชธเชพเชšเชตเซ‹

pg_dump postgres --file=/dump/shipment.dmp --format=c --table=shipment --verbose > /dump/shipment.log 2>&1

เชธเซเชคเซเชฐเซ‹เชค เช•เซ‹เชทเซเชŸเช• เช•เชพเชขเซ€ เชจเชพเช–เซ‹ + เชฐเซ‡เชจเซเชœ เชชเชพเชฐเซเชŸเซ€เชถเชจ เชธเชพเชฅเซ‡ เชชเซ‡เชฐเซ‡เชจเซเชŸ เชŸเซ‡เชฌเชฒ เชฌเชจเชพเชตเซ‹ + เชชเชพเชฐเซเชŸเซ€เชถเชจเซ‹ เชฌเชจเชพเชตเซ‹

--create_partition_shipment.sql
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;
current_year varchar ;
current_month varchar ;
begin_year varchar ;
begin_month varchar ;
next_year varchar ;
next_month varchar ;
first_flag boolean ;
i integer ;
begin
  RAISE NOTICE 'CREATE TEMPORARY TABLE FOR SHIPMENT_DATE';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;

  RAISE NOTICE 'DROP TABLE shipment';
  drop table shipment cascade ;
  
  CREATE TABLE public.shipment
  (
    "SHIPMENT_ID" integer NOT NULL DEFAULT nextval('shipment_shipment_id_seq'::regclass),
    "SHIPMENT_NAME" character varying(30) COLLATE pg_catalog."default",
    "SHIPMENT_DATE" timestamp without time zone,
    "REPORT_NAME" character varying(40) COLLATE pg_catalog."default"
  )
  PARTITION BY RANGE ("SHIPMENT_DATE")
  WITH (
      OIDS = FALSE
  )
  TABLESPACE pg_default;

  RAISE NOTICE 'CREATE PARTITIONS FOR TABLE shipment';

  current_year:='0';
  current_month:='0';

  begin_year := '0' ;
  begin_month := '0'  ;
  next_year := '0' ;
  next_month := '0'  ;

  FOR rec_shipment_date IN SELECT * FROM tmp_shipment_date LOOP
      
      RAISE NOTICE 'SHIPMENT_DATE=%',rec_shipment_date."SHIPMENT_DATE";
      
      current_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE");
      current_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE") ; 

      IF to_number(current_month,'99') < 10 THEN
        current_month := '0'||current_month ; 
      END IF ;

      --Init borders
      IF   begin_year = '0' THEN
       first_flag := true ; --first time flag
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;

      END IF;

      -- Check current date into borders NOT for First time
      IF to_date( current_year||'.'||current_month, 'YYYY.MM') >= to_date( begin_year||'.'||begin_month, 'YYYY.MM') AND 
         to_date( current_year||'.'||current_month, 'YYYY.MM') < to_date( next_year||'.'||next_month, 'YYYY.MM') AND 
         NOT first_flag 
      THEN
         CONTINUE ; 
      ELSE
       --NEW borders only for second and after time 
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;

      END IF;      

      partition_name := 'shipment_shipment_date_'||begin_year||'-'||begin_month||'-01-'|| next_year||'-'||next_month||'-01'  ;
 
     EXECUTE format('CREATE TABLE ' || quote_ident(partition_name) || ' PARTITION OF shipment FOR VALUES FROM ( %L ) TO ( %L )  ' , current_year||'-'||current_month||'-01' , next_year||'-'||next_month||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      --Drop first time flag
      first_flag := false ;
   
  END LOOP;

end
$$;

เชกเชฎเซเชช เช†เชฏเชพเชค เช•เชฐเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡

pg_restore -d postgres --data-only --format=c --table=shipment --verbose  shipment.dmp > /tmp/data_dump/shipment_restore.log 2>&1

เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเชพ เชชเชฐเชฟเชฃเชพเชฎเซ‹ เชคเชชเชพเชธเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช

เชชเชฐเชฟเชฃเชพเชฎเซ‡ เช†เชชเชฃเซ€ เชชเชพเชธเซ‡ เชถเซเช‚ เช›เซ‡? เชเช•เซเชเซ‡เช•เซเชฏเซเชถเชจ เชชเซเชฒเชพเชจเชจเซ‹ เชธเช‚เชชเซ‚เชฐเซเชฃ เชŸเซ‡เช•เซเชธเซเชŸ เชฎเซ‹เชŸเซ‹ เช…เชจเซ‡ เช•เช‚เชŸเชพเชณเชพเชœเชจเช• เช›เซ‡, เชคเซ‡เชฅเซ€ เชคเชฎเชพเชฐเซ€ เชœเชพเชคเชจเซ‡ เช…เช‚เชคเชฟเชฎ เชธเช‚เช–เซเชฏเชพเช“ เชธเซเชงเซ€ เชฎเชฐเซเชฏเชพเชฆเชฟเชค เช•เชฐเชตเซ€ เชคเชฆเซเชฆเชจ เชถเช•เซเชฏ เช›เซ‡.

เชคเซ‡ เชนเชคเซ€

เช•เชฟเช‚เชฎเชค: 502 997.55
เช…เชฎเชฒ เชธเชฎเชฏ: 505 เชธเซ‡เช•เชจเซเชก.

เชฌเชจเซ€ เช—เชฏเซเช‚ เช›เซ‡

เช•เชฟเช‚เชฎเชค: 77 872.36
เช…เชฎเชฒ เชธเชฎเชฏ: 79 เชธเซ‡เช•เชจเซเชก.

เชคเชฆเซเชฆเชจ เชธเชพเชฐเซเช‚ เชชเชฐเชฟเชฃเชพเชฎ. เช˜เชŸเชพเชกเซ‹ เช–เชฐเซเชš เช…เชจเซ‡ เช…เชฎเชฒ เชธเชฎเชฏ. เช†เชฎ, เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช…เชชเซ‡เช•เซเชทเชฟเชค เช…เชธเชฐ เช†เชชเซ‡ เช›เซ‡ เช…เชจเซ‡, เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เช•เซ‹เชˆ เช†เชถเซเชšเชฐเซเชฏ เชจเชฅเซ€.

เช—เซเชฐเชพเชนเช•เชจเซ‡ เช–เซเชถ เช•เชฐเซ‹

เชชเชฐเซ€เช•เซเชทเชฃ เชชเชฐเชฟเชฃเชพเชฎเซ‹ เช—เซเชฐเชพเชนเช•เชจเซ‡ เชธเชฎเซ€เช•เซเชทเชพ เชฎเชพเชŸเซ‡ เชฐเชœเซ‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เชนเชคเชพ. เช…เชจเซ‡ เชคเซ‡เชจเซ€ เชธเชฎเซ€เช•เซเชทเชพ เช•เชฐเซเชฏเชพ เชชเช›เซ€, เชคเซ‡เช“เชจเซ‡ เช•เช‚เชˆเช• เช…เช‚เชถเซ‡ เช…เชฃเชงเชพเชฐเซเชฏเซ‹ เชšเซเช•เชพเชฆเซ‹ เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹: "เชธเชฐเชธ, "เชกเซ‡เชŸเชพ" เช•เซ‹เชทเซเชŸเช•เชจเซเช‚ เชตเชฟเชญเชพเชœเชจ เช•เชฐเซ‹."

เชนเชพ, เชชเชฐเช‚เชคเซ เช…เชฎเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เช…เชฒเช— "เชถเชฟเชชเชฎเซ‡เชจเซเชŸ" เช•เซ‹เชทเซเชŸเช•เชจเซ€ เชคเชชเชพเชธ เช•เชฐเซ€ เช›เซ‡; "เชกเซ‡เชŸเชพ" เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ "SHIPMENT_DATE" เชซเซ€เชฒเซเชก เชจเชฅเซ€.

เช•เซ‹เชˆ เชธเชฎเชธเซเชฏเชพ เชจเชฅเซ€, เช‰เชฎเซ‡เชฐเซ‹, เชฌเชฆเชฒเซ‹. เชฎเซเช–เซเชฏ เชตเชธเซเชคเซ เช เช›เซ‡ เช•เซ‡ เช—เซเชฐเชพเชนเช• เชชเชฐเชฟเชฃเชพเชฎเชฅเซ€ เชธเช‚เชคเซเชทเซเชŸ เช›เซ‡; เช…เชฎเชฒเซ€เช•เชฐเชฃ เชตเชฟเช—เชคเซ‹ เช–เชพเชธ เชฎเชนเชคเซเชตเชจเซ€ เชจเชฅเซ€.

เชฎเซเช–เซเชฏ เช•เซ‹เชทเซเชŸเช• "เชกเซ‡เชŸเชพ"เชจเซเช‚ เชตเชฟเชญเชพเชœเชจ

เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เช•เซ‹เชˆ เช–เชพเชธ เชฎเซเชถเซเช•เซ‡เชฒเซ€เช“ เชŠเชญเซ€ เชฅเชˆ เชจเชฅเซ€. เชœเซ‹เช•เซ‡, เชชเชพเชฐเซเชŸเซ€เชถเชจเซ€เช‚เช— เชเชฒเซเช—เซ‹เชฐเชฟเชงเชฎ, เช…เชฒเชฌเชคเซเชค, เช•เช‚เชˆเช• เช…เช‚เชถเซ‡ เชฌเชฆเชฒเชพเชˆ เช—เชฏเซเช‚ เช›เซ‡.

"เชกเซ‡เชŸเชพ" เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ "SHIPMENT_DATA" เช•เซ‰เชฒเชฎ เช‰เชฎเซ‡เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช

psql -h ั…ะพัั‚ -U ะฑะฐะทะฐ -d ัŽะทะตั€
=> ALTER TABLE data ADD COLUMN "SHIPMENT_DATE" timestamp without time zone ;

"เชถเชฟเชชเชฎเซ‡เชจเซเชŸ" เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚เชฅเซ€ เชธเชฎเชพเชจ เชจเชพเชฎเชจเชพ เช•เซ‰เชฒเชฎเชจเชพ เชฎเซ‚เชฒเซเชฏเซ‹ เชธเชพเชฅเซ‡ "เชกเซ‡เชŸเชพ" เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ "SHIPMENT_DATA" เช•เซ‰เชฒเชฎเชจเชพ เชฎเซ‚เชฒเซเชฏเซ‹ เชญเชฐเซ‹

-----------------------------
--update_data.sql
--updating for altered table "data" to values of "shipment_data" from the table "shipment"
--version 1.0
do language plpgsql $$
declare 
rec_shipment_data RECORD ;
shipment_date timestamp without time zone ; 
row_count integer ;
total_rows integer ;
begin

  select count(*) into total_rows from shipment ; 
  RAISE NOTICE 'Total %',total_rows;
  row_count:= 0 ;

  FOR rec_shipment_data IN SELECT * FROM shipment LOOP

   update data set "SHIPMENT_DATE" = rec_shipment_data."SHIPMENT_DATE" where "SHIPMENT_ID" = rec_shipment_data."SHIPMENT_ID";
   
   row_count:=  row_count +1 ;
   RAISE NOTICE 'row count = % , from %',row_count,total_rows;
  END LOOP;

end
$$;

"เชกเซ‡เชŸเชพ" เช•เซ‹เชทเซเชŸเช•เชจเซ‹ เชกเชฎเซเชช เชธเชพเชšเชตเซ‹

pg_dump postgres --file=/dump/data.dmp --format=c --table=data --verbose > /dump/data.log 2>&1</source

เชตเชฟเชญเชพเชœเชฟเชค เช•เซ‹เชทเซเชŸเช• "เชกเซ‡เชŸเชพ" เชซเชฐเซ€เชฅเซ€ เชฌเชจเชพเชตเซ‹

--create_partition_data.sql
--create partitions for the table "wafer data" by range column "shipment_data" with one month duration
--version 1.0
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;
current_year varchar ;
current_month varchar ;
begin_year varchar ;
begin_month varchar ;
next_year varchar ;
next_month varchar ;
first_flag boolean ;
i integer ;

begin

  RAISE NOTICE 'CREATE TEMPORARY TABLE FOR SHIPMENT_DATE';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;


  RAISE NOTICE 'DROP TABLE data';
  drop table data cascade ;


  RAISE NOTICE 'CREATE PARTITIONED TABLE data';
  
  CREATE TABLE public.data
  (
    "RUN_ID" integer,
    "LASERMARK" character varying(20) COLLATE pg_catalog."default" NOT NULL,
    "LOTID" character varying(80) COLLATE pg_catalog."default",
    "SHIPMENT_ID" integer NOT NULL,
    "PARAMETER_ID" integer NOT NULL,
    "INTERNAL_VALUE" character varying(75) COLLATE pg_catalog."default",
    "REPORTED_VALUE" character varying(75) COLLATE pg_catalog."default",
    "LOWER_SPEC_LIMIT" numeric,
    "UPPER_SPEC_LIMIT" numeric , 
    "SHIPMENT_DATE" timestamp without time zone
  )
  PARTITION BY RANGE ("SHIPMENT_DATE")
  WITH (
    OIDS = FALSE
  )
  TABLESPACE pg_default ;


  RAISE NOTICE 'CREATE PARTITIONS FOR TABLE data';

  current_year:='0';
  current_month:='0';

  begin_year := '0' ;
  begin_month := '0'  ;
  next_year := '0' ;
  next_month := '0'  ;
  i := 1;

  FOR rec_shipment_date IN SELECT * FROM tmp_shipment_date LOOP
      
      RAISE NOTICE 'SHIPMENT_DATE=%',rec_shipment_date."SHIPMENT_DATE";
      
      current_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE");
      current_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE") ; 

      --Init borders
      IF   begin_year = '0' THEN
       RAISE NOTICE '***Init borders';
       first_flag := true ; --first time flag
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;

      END IF;

--      RAISE NOTICE 'current_year=% , current_month=% ',current_year,current_month;
--      RAISE NOTICE 'begin_year=% , begin_month=% ',begin_year,begin_month;
--      RAISE NOTICE 'next_year=% , next_month=% ',next_year,next_month;

      -- Check current date into borders NOT for First time

      RAISE NOTICE 'Current data = %',to_char( to_date( current_year||'.'||current_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Begin data = %',to_char( to_date( begin_year||'.'||begin_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Next data = %',to_char( to_date( next_year||'.'||next_month, 'YYYY.MM'), 'YYYY.MM');

      IF to_date( current_year||'.'||current_month, 'YYYY.MM') >= to_date( begin_year||'.'||begin_month, 'YYYY.MM') AND 
         to_date( current_year||'.'||current_month, 'YYYY.MM') < to_date( next_year||'.'||next_month, 'YYYY.MM') AND 
         NOT first_flag 
      THEN
         RAISE NOTICE '***CONTINUE';
         CONTINUE ; 
      ELSE
       --NEW borders only for second and after time 
       RAISE NOTICE '***NEW BORDERS';
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;


      END IF;      

      IF to_number(current_month,'99') < 10 THEN
        current_month := '0'||current_month ; 
      END IF ;

      IF to_number(begin_month,'99') < 10 THEN
        begin_month := '0'||begin_month ; 
      END IF ;

      IF to_number(next_month,'99') < 10 THEN
        next_month := '0'||next_month ; 
      END IF ;

      RAISE NOTICE 'current_year=% , current_month=% ',current_year,current_month;
      RAISE NOTICE 'begin_year=% , begin_month=% ',begin_year,begin_month;
      RAISE NOTICE 'next_year=% , next_month=% ',next_year,next_month;

      partition_name := 'data_'||begin_year||begin_month||'01_'||next_year||next_month||'01'  ;

      RAISE NOTICE 'PARTITION NUMBER % , TABLE NAME =%',i , partition_name;
      
      EXECUTE format('CREATE TABLE ' || quote_ident(partition_name) || ' PARTITION OF data FOR VALUES FROM ( %L ) TO ( %L )  ' , begin_year||'-'||begin_month||'-01' , next_year||'-'||next_month||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_parameter_id_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID", "PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_lasermark_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("LASERMARK" COLLATE pg_catalog."default") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_id_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_parameter_id_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_date_idx';
      RAISE NOTICE 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

      --Drop first time flag
      first_flag := false ;

  END LOOP;
end
$$;

เชชเช—เชฒเซเช‚ 3 เชฎเชพเช‚ เชฌเชจเชพเชตเซ‡เชฒ เชกเชฎเซเชช เชฒเซ‹เชก เช•เชฐเซ‹.

pg_restore -h ั…ะพัั‚ -ัŽะทะตั€ -d ะฑะฐะทะฐ --data-only --format=c --table=data --verbose  data.dmp > data_restore.log 2>&1

เชœเซ‚เชจเชพ เชกเซ‡เชŸเชพ เชฎเชพเชŸเซ‡ เชเช• เช…เชฒเช— เชตเชฟเชญเชพเช— เชฌเชจเชพเชตเซ‹

---------------------------------------------------
--create_partition_for_old_dates.sql
--create partitions for keeping old dates 
--version 1.0
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;

begin

      SELECT min("SHIPMENT_DATE") AS min_date INTO rec_shipment_date from data ;

      RAISE NOTICE 'Old date is %',rec_shipment_date.min_date ;

      partition_name := 'data_old_dates'  ;

      RAISE NOTICE 'PARTITION NAME IS %',partition_name;

      EXECUTE format('CREATE TABLE ' || quote_ident(partition_name) || ' PARTITION OF data FOR VALUES FROM ( %L ) TO ( %L )  ' , '1900-01-01' , 
              to_char( rec_shipment_date.min_date,'YYYY')||'-'||to_char(rec_shipment_date.min_date,'MM')||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_parameter_id_idx';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID", "PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_lasermark_idx';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("LASERMARK" COLLATE pg_catalog."default") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_id_idx';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_parameter_id_idx';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_date_idx';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

end
$$;

เช…เช‚เชคเชฟเชฎ เชชเชฐเชฟเชฃเชพเชฎเซ‹:

เชคเซ‡ เชนเชคเซ€
เช•เชฟเช‚เชฎเชค: 502 997.55
เช…เชฎเชฒ เชธเชฎเชฏ: 505 เชธเซ‡เช•เชจเซเชก.

เชฌเชจเซ€ เช—เชฏเซเช‚ เช›เซ‡
เช•เชฟเช‚เชฎเชค: 68 533.70
เช…เชฎเชฒ เชธเชฎเชฏ: 69 เชธเซ‡เช•เชจเซเชก

เชฒเชพเชฏเช•, เชคเชฆเซเชฆเชจ เชฒเชพเชฏเช•. เช…เชจเซ‡ เชคเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชคเชพเช‚ เช…เชฎเซ‡ PostgreSQL 10 เชฎเชพเช‚ เชชเชพเชฐเซเชŸเซ€เชถเชจเซ€เช‚เช— เชฎเชฟเช•เซ‡เชจเชฟเชเชฎเชจเซ‡ เชตเชงเซ เช•เซ‡ เช“เช›เชพ เชฎเชพเชธเซเชŸเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เชตเซเชฏเชตเชธเซเชฅเชพเชชเชฟเชค เชฅเชฏเชพ - เชเช• เช‰เชคเซเชคเชฎ เชชเชฐเชฟเชฃเชพเชฎ.

เชฒเชฟเชฐเชฟเช•เชฒ เชกเชฟเช—เซเชฐเซ‡เชถเชจ

เชถเซเช‚ เชตเชงเซ เชธเชพเชฐเซเช‚ เช•เชฐเชตเซเช‚ เชถเช•เซเชฏ เช›เซ‡ - เชนเชพ, เชคเชฎเซ‡ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹!เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเซ‡ เชฎเชŸเชฟเชฐเชฟเชฏเชฒเชพเช‡เชเซเชก เชตเซเชฏเซ‚เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.
MATERIALIZED View LASERMARK_VIEW เชฌเชจเชพเชตเซ‹

CREATE MATERIALIZED VIEW LASERMARK_VIEW 
AS
SELECT w."LASERMARK" , MAX(s."SHIPMENT_DATE") AS "SHIPMENT_DATE"
FROM shipment s INNER JOIN data w ON s."SHIPMENT_ID" = w."SHIPMENT_ID" 
GROUP BY w."LASERMARK" ;

CREATE INDEX lasermark_vw_shipment_date_ind on lasermark_view USING btree ("SHIPMENT_DATE") TABLESPACE pg_default;
analyze lasermark_view ;

เชซเชฐเซ€ เชเช•เชตเชพเชฐ เช…เชฎเซ‡ เชตเชฟเชจเช‚เชคเซ€เชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชฒเช–เซ€เช เช›เซ€เช:
เชฎเชŸเชฟเชฐเชฟเชฏเชฒเชพเช‡เชเซเชก เชตเซเชฏเซ‚เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เซเชตเซ‡เชฐเซ€

SELECT
            p."PARAMETER_ID" as  parameter_id,
            pc."PC_NAME" AS pc_name,
            pc."CUSTOMER_PARTNUMBER" AS customer_partnumber,
            w."LASERMARK" AS lasermark,
            w."LOTID" AS lotid,
            w."REPORTED_VALUE" AS reported_value,
            w."LOWER_SPEC_LIMIT" AS lower_spec_limit,
            w."UPPER_SPEC_LIMIT" AS upper_spec_limit,
            p."TYPE_CALCUL" AS type_calcul,
            s."SHIPMENT_NAME" AS shipment_name,
            s."SHIPMENT_DATE" AS shipment_date,
            extract(year from s."SHIPMENT_DATE") AS year,
            extract(month from s."SHIPMENT_DATE") as month,
            s."REPORT_NAME" AS report_name,
            p."STC_NAME" AS STC_name,
            p."CUSTOMERPARAM_NAME" AS customerparam_name
        FROM data w INNER JOIN shipment s ON s."SHIPMENT_ID" = w."SHIPMENT_ID"
             INNER JOIN parameters p ON p."PARAMETER_ID" = w."PARAMETER_ID"
             INNER JOIN shipment_pc sp ON s."SHIPMENT_ID" = sp."SHIPMENT_ID"
             INNER JOIN pc pc ON pc."PC_ID" = sp."PC_ID"
             INNER JOIN LASERMARK_VIEW md ON md."SHIPMENT_DATE" = s."SHIPMENT_DATE" AND md."LASERMARK" = w."LASERMARK"
        WHERE 
              s."SHIPMENT_DATE" >= '2018-07-01' AND s."SHIPMENT_DATE" <= '2018-09-30';

เช…เชจเซ‡ เช…เชฎเชจเซ‡ เชฌเซ€เชœเซเช‚ เชชเชฐเชฟเชฃเชพเชฎ เชฎเชณเซ‡ เช›เซ‡:
เชคเซ‡ เชนเชคเซ€
เช•เชฟเช‚เชฎเชค: 502 997.55
เช…เชฎเชฒ เชธเชฎเชฏ: 505 เชธเซ‡เช•เช‚เชก

เชฌเชจเซ€ เช—เชฏเซเช‚ เช›เซ‡
เช•เชฟเช‚เชฎเชค: 42 481.16
เช…เชฎเชฒ เชธเชฎเชฏ: 43 เชธเซ‡เช•เชจเซเชก.

เชœเซ‹เช•เซ‡, เช…เชฒเชฌเชคเซเชค, เช†เชตเชพ เช†เชถเชพเชธเซเชชเชฆ เชชเชฐเชฟเชฃเชพเชฎ เชญเซเชฐเชพเชฎเช• เช›เซ‡; เชตเชฟเชšเชพเชฐเซ‹เชจเซ‡ เชคเชพเชœเซเช‚ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชคเซ‡เชฅเซ€ เชกเซ‡เชŸเชพ เชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเชพเชจเซ‹ เช•เซเชฒ เชธเชฎเชฏ เชตเชงเซ เชฎเชฆเชฆ เช•เชฐเชถเซ‡ เชจเชนเซ€เช‚. เชชเชฐเช‚เชคเซ เชเช• เชชเซเชฐเชฏเซ‹เช— เชคเชฐเซ€เช•เซ‡ เชคเซ‡ เชเช•เชฆเชฎ เชฐเชธเชชเซเชฐเชฆ เช›เซ‡.

เช–เชฐเซ‡เช–เชฐ, เชœเซ‡เชฎ เชคเซ‡ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚ เช›เซ‡, เชซเชฐเซ€เชฅเซ€ เช†เชญเชพเชฐ asmm เช…เชจเซ‡ เชนเชฌเซเชฐเซ!- เช•เซเชตเซ‡เชฐเซ€ เชตเชงเซ เชธเซเชงเชพเชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡.

เช‰เชšเซเชšเชพเชฐเชฃ

เชคเซ‡เชฅเซ€, เช—เซเชฐเชพเชนเช• เชธเช‚เชคเซเชทเซเชŸ เช›เซ‡. เช…เชจเซ‡ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซ‹ เชฒเชพเชญ เชฒเซ‹.

เชจเชตเซเช‚ เช•เชพเชฐเซเชฏ: เชŠเช‚เชกเชพเชฃ เช…เชจเซ‡ เชตเชฟเชธเซเชคเชฐเชฃ เชฎเชพเชŸเซ‡ เชคเชฎเซ‡ เชถเซเช‚ เชธเชพเชฅเซ‡ เช†เชตเซ€ เชถเช•เซ‹ เช›เซ‹?

เช…เชจเซ‡ เชชเช›เซ€ เชฎเชจเซ‡ เชฏเชพเชฆ เช›เซ‡ - เชฎเชฟเชคเซเชฐเซ‹, เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช…เชฎเชพเชฐเชพ PostgreSQL เชกเซ‡เชŸเชพเชฌเซ‡เชธเซ‡เชธเชจเซเช‚ เชจเชฟเชฐเซ€เช•เซเชทเชฃ เชจเชฅเซ€.

เชนเซ‡เชจเซเชก เช“เชจ เชนเชพเชฐเซเชŸ, AWS เชชเชฐ เช•เซเชฒเชพเช‰เชก เชตเซ‹เชšเชจเชพ เชฐเซ‚เชชเชฎเชพเช‚ เชนเชœเซ เชชเชฃ เช…เชฎเซเช• เชฆเซ‡เช–เชฐเซ‡เช– เช›เซ‡. เชชเชฐเช‚เชคเซ เชกเซ€เชฌเซ€เช เชฎเชพเชŸเซ‡ เช† เชฆเซ‡เช–เชฐเซ‡เช–เชจเซ‹ เชถเซเช‚ เชซเชพเชฏเชฆเซ‹ เช›เซ‡? เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เชตเซเชฏเชตเชนเชพเชฐเซ€เช• เช•เซ‹เชˆ เชจเชนเซ€เช‚.

เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชคเชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เช•เช‚เชˆเช• เช‰เชชเชฏเซ‹เช—เซ€ เช…เชจเซ‡ เชฐเชธเชชเซเชฐเชฆ เช•เชฐเชตเชพเชจเซ€ เชคเช• เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเซ‡ เช† เชคเช•เชจเซ‹ เชฒเชพเชญ เชฒเชˆ เชถเช•เชคเชพ เชจเชฅเซ€...
เชฎเชพเชŸเซ‡

เชนเซ‡เชชเซเชชเซ€ เชชเชพเชฐเซเชŸเซ€ เช…เชฅเชตเชพ เชชเซ‹เชธเซเชŸเช—เซเชฐเซ‡เชเชธเช•เซเชฏเซเชเชฒ 10 เชฎเชพเช‚ เชชเชพเชฐเซเชŸเซ€เชถเชจเชจเซ‡ เชœเชพเชฃเชตเชพ เชตเชฟเชถเซ‡เชจเซ€ เชฏเชพเชฆเซ‹เชจเซ€ เช•เซ‡เชŸเชฒเซ€เช• เชชเช‚เช•เซเชคเชฟเช“

เช† เชฐเซ€เชคเซ‡ เช†เชชเชฃเซ‡ เชธเซŒเชฅเซ€ เชฐเชธเชชเซเชฐเชฆ เชญเชพเช— เชชเชฐ เช†เชตเซ€เช เช›เซ€เช:

3 เชกเชฟเชธเซ‡เชฎเซเชฌเชฐ, 2018.
PostgreSQL เช•เซเชตเซ‡เชฐเซ€เชเชจเชพ เชชเซเชฐเชฆเชฐเซเชถเชจ เชชเชฐ เชฆเซ‡เช–เชฐเซ‡เช– เชฐเชพเช–เชตเชพ เชฎเชพเชŸเซ‡ เช‰เชชเชฒเชฌเซเชง เช•เซเชทเชฎเชคเชพเช“เชฎเชพเช‚ เชธเช‚เชถเซ‹เชงเชจ เชถเชฐเซ‚ เช•เชฐเชตเชพเชจเซ‹ เชจเชฟเชฐเซเชฃเชฏ เชฒเซ‡เชตเซ‹.

เชชเชฐเช‚เชคเซ เชคเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เช…เชฒเช— เชตเชพเชฐเซเชคเชพ เช›เซ‡.

เชšเชพเชฒเซ เชฐเชนเซ€ เชถเช•เชพเชฏโ€ฆ

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹