ืžื–ืœ ืคืืจื˜ื™ื™ ืึธื“ืขืจ ืขื˜ืœืขื›ืข ืฉื•ืจื•ืช ืคื•ืŸ ื–ื›ืจื•ื ื•ืช ื•ื•ืขื’ืŸ ืฆื• ื•ื•ื™ืกืŸ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืื™ืŸ PostgreSQL10

ื”ืงื“ืžื” ืึธื“ืขืจ ื•ื•ื™ ื“ืขืจ ื’ืขื“ืึทื ืง ืคื•ืŸ ืกืขืงืฉืึทืŸ ื’ืขืงื•ืžืขืŸ

ื“ื™ ื’ืขืฉื™ื›ื˜ืข ื”ื™ื™ื‘ื˜ ื–ื™ืš ื“ืึธ: ืฆื™ ืื™ืจ ื’ืขื“ืขื ืงืขืŸ ื•ื•ื™ ืขืก ืึทืœืข ืื ื’ืขื”ื•ื™ื‘ืŸ. ืึทืœืฅ ืื™ื– ื’ืขื•ื•ืขืŸ ืฆื•ื ืขืจืฉื˜ืŸ ืžืึธืœ ืื•ืŸ ื•ื•ื™ื“ืขืจ. ื ืึธืš ื›ึผืžืขื˜ ืึทืœืข ื“ื™ ืจืขืกื•ืจืกืŸ ืคึฟืึทืจ ืึธืคึผื˜ื™ืžื™ื–ื™ื ื’ ื“ื™ ื‘ืงืฉื”, ืื™ืŸ ื“ืขืจ ืฆื™ื™ื˜, ื–ืขื ืขืŸ ื•ื™ืกื’ืขืžืึทื˜ืขืจื˜, ื“ื™ ืงืฉื™ื ืื™ื– ืื•ื™ืคื’ืขืฉื˜ืื ืขืŸ - ื•ื•ืึธืก ื•ื•ื™ื™ึทื˜ืขืจ? ื“ืึธืก ืื™ื– ื•ื•ื™ ื“ืขืจ ื’ืขื“ืึทื ืง ืคื•ืŸ ืฆืขื˜ื™ื™ืœื•ื ื’ ืื™ื– ืื•ื™ืคื’ืขืฉื˜ืื ืขืŸ.

ืžื–ืœ ืคืืจื˜ื™ื™ ืึธื“ืขืจ ืขื˜ืœืขื›ืข ืฉื•ืจื•ืช ืคื•ืŸ ื–ื›ืจื•ื ื•ืช ื•ื•ืขื’ืŸ ืฆื• ื•ื•ื™ืกืŸ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืื™ืŸ PostgreSQL10

ืœื™ืจื™ืง ื“ื™ื’ืจืขืฉืึทืŸ:
ื’ืขื ื•ื™ 'ืื™ืŸ ื“ืขื ืžืึธืžืขื ื˜', ื•ื•ื™ื™ึทืœ ื•ื•ื™ ืขืก ืคืืจืงืขืจื˜ ืื•ื™ืก, ืขืก ื–ืขื ืขืŸ ื’ืขื•ื•ืขืŸ ืึทื ืึทืคึผื˜ื™ื“ ืึทืคึผื˜ืึทืžืึทื–ื™ื™ืฉืึทืŸ ืจื™ื–ืขืจื•ื•ื–. ื ื“ืื ืง asmm ืื•ืŸ ื”ื‘ืจื•!

ืึทื–ื•ื™, ื•ื•ื™ ืึทื ื“ืขืจืฉ ืงืขื ืขืŸ ืื™ืจ ืžืึทื›ืŸ ื“ืขื ืงื•ื ื” ืฆื•ืคืจื™ื“ืŸ, ืื•ืŸ ืื™ืŸ ื“ืขืจ ื–ืขืœื‘ื™ืงืขืจ ืฆื™ื™ื˜ ืคึฟืึทืจื‘ืขืกืขืจืŸ ื“ื™ื™ืŸ ืื™ื™ื’ืขื ืข ืกืงื™ืœื–?

ืฆื• ืคืึทืจืคึผืึธืฉืขื˜ืขืจืŸ ืึทืœืฅ ื•ื•ื™ ืคื™ืœ ื•ื•ื™ ืžืขื’ืœืขืš, ืขืก ื–ืขื ืขืŸ ื‘ืœื•ื™ื– ืฆื•ื•ื™ื™ ื•ื•ืขื’ืŸ ืฆื• ืจืึทื“ื™ืงืึทืœืœื™ ืคึฟืึทืจื‘ืขืกืขืจืŸ ืขืคึผืขืก ืื™ืŸ ื“ื™ ืคืึธืจืฉื˜ืขืœื•ื ื’ ืคื•ืŸ ื“ื™ ื“ืึทื˜ืึทื‘ื™ื™ืก:
1) ื‘ืจื™ื™ื˜ ื“ืจืš - ืžื™ืจ ืคืึทืจื’ืจืขืกืขืจืŸ ืจืขืกื•ืจืกืŸ, ื˜ื•ื™ืฉืŸ ื“ื™ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ;
2) ืื™ื ื˜ืขื ืกื™ื•ื•ืข ื“ืจืš - ืึธื ืคึฟืจืขื’ ืึทืคึผื˜ืึทืžืึทื–ื™ื™ืฉืึทืŸ

ื•ื•ื™ื‘ืืœื“, ืื™ืš ื—ื–ืจ ืื™ื‘ืขืจ, ืื™ื– ื“ืขืžืืœื˜ ืฉื•ื™ืŸ ื ื™ืฉื˜ ื’ืขื•ื•ืขืŸ ืงืœืืจ ื•ื•ืืก ื ืืš โ€‹โ€‹ืฆื• ื˜ื•ื™ืฉืŸ ืื™ืŸ ื“ืขืจ ื‘ืงืฉื” ืฆื• ืคืืจืฉื ืขืœืขืจืŸ, ื”ืื˜ ืžืขืŸ ืื•ื™ืกื’ืขืงืœื™ื‘ืŸ ื“ืขืจ ื•ื•ืขื’ - ื˜ื™ืฉ ืคึผืœืึทืŸ ืขื ื“ืขืจื•ื ื’ืขืŸ.

ืึทื–ื•ื™, ื“ื™ ื”ื•ื™ืคึผื˜ ืงืฉื™ื ืขืจื™ื™ื–ืึทื–: ื•ื•ืึธืก ืื•ืŸ ื•ื•ื™ ื•ื•ืขื˜ ืžื™ืจ ื˜ื•ื™ืฉืŸ?

ืขืจืฉื˜ ื‘ืื“ื™ื ื’ื•ื ื’ืขืŸ

ืขืจืฉื˜ืขืจ, ืขืก ืื™ื– ื“ืขื ERD (ื’ืขื•ื•ื™ื–ืŸ ืื™ืŸ ืึท ืงืึทื ื“ื™ืฉืึทื ืึทืœื™ ืกื™ืžืคึผืœืึทืคื™ื™ื“ ื•ื•ืขื’):
ืžื–ืœ ืคืืจื˜ื™ื™ ืึธื“ืขืจ ืขื˜ืœืขื›ืข ืฉื•ืจื•ืช ืคื•ืŸ ื–ื›ืจื•ื ื•ืช ื•ื•ืขื’ืŸ ืฆื• ื•ื•ื™ืกืŸ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืื™ืŸ PostgreSQL10
ื”ื•ื™ืคึผื˜ ืคึฟืขื™ึดืงื™ื™ื˜ืŸ:

  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' ;

ืจืขื–ื•ืœื˜ืึทื˜ืŸ ืคื•ืŸ ื“ื•ืจื›ืคื™ืจื•ื ื’ ืื•ื™ืฃ ื“ื™ ืคึผืจืึธื‘ืข ื“ืึทื˜ืึทื‘ื™ื™ืก:
ืงืึธืกื˜ืŸ : ืงืกื ื•ืžืงืก ืงืกื ื•ืžืงืก
ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ื˜: 505 ืกืขืงื•ื ื“ืขืก.

ื•ื•ืึธืก ื˜ืึธืŸ ืžื™ืจ ื–ืขืŸ? ื ืจืขื’ื•ืœืขืจ ื‘ืงืฉื”, ื‘ืื–ื™ืจื˜ ืื•ื™ืฃ ืึท ืฆื™ื™ื˜ ืจืขืคื˜ืœ.
ืœืึธืžื™ืจ ืžืึทื›ืŸ ื“ื™ ืกื™ืžืคึผืœืึทืกื˜ ืœืึทื“ื–ืฉื™ืงืึทืœ ื”ืึทืฉืึธืจืข: ืื•ื™ื‘ ืขืก ืื™ื– ืึท ืžื•ืกื˜ืขืจ ืคื•ืŸ ืึท ืฆื™ื™ื˜ ืจืขืคื˜ืœ, ื•ื•ืขื˜ ืขืก ื”ืขืœืคึฟืŸ ืื•ื ื“ื–? ืึทื– ืก ืจืขื›ื˜ - ืฆืขื˜ื™ื™ืœื•ื ื’.

ื•ื•ืึธืก ืฆื• ื˜ื™ื™ืœืŸ?

ืื™ืŸ ืขืจืฉื˜ืขืจ ื‘ืœื™ืง, ื“ื™ ื‘ืจื™ืจื” ืื™ื– ืงืœืึธืจ ื•ื•ื™ ื“ืขืจ ื˜ืึธื’ - ื“ืขืงืœืึทืจืึทื˜ื™ื•ื•ืข ืฆืขื˜ื™ื™ืœื•ื ื’ ืคื•ืŸ ื“ื™ "ื˜ืจืึทื ืกืคึผืึธืจื˜" ื˜ื™ืฉ ื ื™ืฆืŸ ื“ื™ "SHIPMENT_DATE" ืฉืœื™ืกืœ (ืฉืคึผืจื™ื ื’ืขืŸ ืฆื• ื•ื•ื™ื™ึทื˜ ืคืึธืจื•ื™ืก - ืื™ืŸ ื“ื™ ืกื•ืฃ ืขืก ืื™ื– ื’ืขื•ื•ืขืŸ ืึท ื‘ื™ืกืœ ืคืึทืœืฉ ืื™ืŸ ืคึผืจืึธื“ื•ืงืฆื™ืข).

ื•ื•ื™ ืฆื• ืฆืขื˜ื™ื™ืœืŸ?

ื“ื™ ืงืฉื™ื ืื™ื– ืื•ื™ืš ื ื™ืฉื˜ ืฆื• ืฉื•ื•ืขืจ. ืฆื•ืž ื’ืœื™ืง, ืื™ืŸ PostgreSQL 10, ืขืก ืื™ื– ืื™ืฆื˜ ืึท ืžืขื ื˜ืฉ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืžืขืงืึทื ื™ื–ืึทื.
ืึทื–ื•ื™:

  1. ื”ื™ื˜ ืึท ื“ืึทืžืคึผ ืคื•ืŸ ื“ื™ ืžืงื•ืจ ื˜ื™ืฉ - pg_dump source_table
  2. ื•ื™ืกืžืขืงืŸ ื“ื™ ืึธืจื™ื’ื™ื ืขืœ ื˜ื™ืฉ - ืคืึทืœืŸ ื˜ื™ืฉ ืžืงื•ืจ_ื˜ืึทื‘ืœืข
  3. ืฉืึทืคึฟืŸ ืึท ืคืึธื˜ืขืจ ื˜ื™ืฉ ืžื™ื˜ ืงื™ื™ื˜ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ - ืฉืึทืคึฟืŸ ื˜ื™ืฉ ืžืงื•ืจ_ื˜ืึทื‘ืœืข
  4. ืฉืึทืคึฟืŸ ืกืขืงืฉืึทื ื– - ืฉืึทืคึฟืŸ ื˜ื™ืฉ ืžืงื•ืจ_ื˜ืึทื‘ืœืข, ืฉืึทืคึฟืŸ ืื™ื ื“ืขืงืก
  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
ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ื˜: ืงืกื ื•ืžืงืก ืกืขืงื•ื ื“ืขืก.

ืื™ื– ื’ืขื•ื•ืืจืŸ

ืคึผืจื™ื™ึทื–: 77 872.36
ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ื˜: ืงืกื ื•ืžืงืก ืกืขืงื•ื ื“ืขืก.

ื’ืึทื ืฅ ืึท ื’ื•ื˜ ืจืขื–ื•ืœื˜ืึทื˜. ืจื™ื“ื•ืกื˜ ืคึผืจื™ื™ึทื– ืื•ืŸ ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ึทื˜. ืื–ื•ื™, ื“ื™ ื ื•ืฆืŸ ืคื•ืŸ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ื’ื™ื˜ ื“ื™ ื“ืขืจื•ื•ืึทืจื˜ ื•ื•ื™ืจืงื•ื ื’ ืื•ืŸ, ืื™ืŸ ืึทืœื’ืขืžื™ื™ืŸ, ืงื™ื™ืŸ ืกืึทืคึผืจื™ื™ื–ื™ื–.

ืžืึทื›ืŸ ื“ื™ ืงื•ื ื” ืฆื•ืคืจื™ื“ืŸ

ื“ื™ ืคึผืจืึธื‘ืข ืจืขื–ื•ืœื˜ืึทื˜ืŸ ื–ืขื ืขืŸ ื“ืขืจืœืื ื’ื˜ ืฆื• ื“ืขืจ ืงื•ื ื” ืคึฟืึทืจ ืึธืคึผืฉืึทืฆื•ื ื’. ืื•ืŸ ื ืึธืš ืจื™ื•ื•ื™ื•ื™ื ื’ ืขืก, ื–ื™ื™ ื–ืขื ืขืŸ ื’ืขื’ืขื‘ืŸ ืึท ืขืคึผืขืก ืื•ืžื’ืขืจื™ื›ื˜ ื•ื•ืขืจื“ื™ืงื˜: "ื’ืจื•ื™ืก, ืฆืขื˜ื™ื™ืœื•ื ื’ ื“ื™ "ื“ืึทื˜ืŸ" ื˜ื™ืฉ."

ื™ืึธ, ืึธื‘ืขืจ ืžื™ืจ ื™ื’ื–ืึทืžืึทื ื“ ืึท ื’ืึธืจ ืึทื ื“ืขืจืฉ "ื˜ืจืึทื ืกืคึผืึธืจื˜" ื˜ื™ืฉ; ื“ื™ "ื“ืึทื˜ืŸ" ื˜ื™ืฉ ื˜ื•ื˜ ื ื™ืฉื˜ ื”ืึธื‘ืŸ ื“ื™ "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
ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ื˜: ืงืกื ื•ืžืงืก ืกืขืงื•ื ื“ืขืก

ื•ื•ืขืจื˜, ื’ืึทื ืฅ ื•ื•ืขืจื˜. ืื•ืŸ ืงืึทื ืกื™ื“ืขืจื™ื ื’ ืึทื– ืฆื•ื–ืืžืขืŸ ื“ืขื ื•ื•ืขื’ ืžื™ืจ ื’ืขืจืื˜ืŸ ืฆื• ืžืขืจ ืึธื“ืขืจ ื•ื•ื™ื™ื ื™ืงืขืจ ื‘ืขืœ ื“ื™ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืžืขืงืึทื ื™ื–ืึทื ืื™ืŸ 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
ื“ื•ืจื›ืคื™ืจื•ื ื’ ืฆื™ื™ื˜: ืงืกื ื•ืžืงืก ืกืขืงื•ื ื“ืขืก.

ื›ืึธื˜ืฉ ืึทื–ืึท ืคึผืจืึทืžืึทืกื™ื ื’ ืจืขื–ื•ืœื˜ืึทื˜ ืื™ื– ืคืึทืจืคื™ืจืขืจื™ืฉ, ื“ื™ ื’ืขื“ืื ืงืขืŸ ื“ืึทืจืคึฟืŸ ืฆื• ื–ื™ื™ืŸ ื“ืขืจืงื•ื•ื™ืงื˜. ืึทื–ื•ื™ ื“ื™ ื’ืึทื ืฅ ืฆื™ื™ื˜ ืคึฟืึทืจ ืจื™ืกื™ื•ื•ื™ื ื’ ื“ืึทื˜ืŸ ื•ื•ืขื˜ ื ื™ืฉื˜ ื”ืขืœืคืŸ ืคื™ืœ. ืื‘ืขืจ ื•ื•ื™ ืึทืŸ ืขืงืกืคึผืขืจื™ืžืขื ื˜ ืขืก ืื™ื– ื’ืึทื ืฅ ื˜ืฉื™ืงืึทื•ื•ืข.

ืึทืงื˜ื•ืึทืœืœื™, ื•ื•ื™ ืขืก ืคืืจืงืขืจื˜ ืื•ื™ืก, ื“ืึทื ืงืขืŸ ื•ื•ื™ื“ืขืจ asmm ืื•ืŸ ื”ื‘ืจื•! ื“ื™ ืึธื ืคึฟืจืขื’ ืงืขื ืขืŸ ื–ื™ื™ืŸ ืžืขืจ ื™ืžืคึผืจื•ื•ื•ื“.

ืึทืคื˜ืขืจื•ื•ืึธืจื“

ืึทื–ื•ื™, ื“ืขืจ ืงื•ื ื” ืื™ื– ืฆื•ืคึฟืจื™ื“ืŸ. ืื•ืŸ ื“ืึทืจืคึฟืŸ ืฆื• ื ืขืžืขืŸ ืžื™ื™ึทืœืข ืคื•ืŸ โ€‹โ€‹ื“ื™ ืกื™ื˜ื•ืึทืฆื™ืข.

ื ื™ื• ืึทืจื‘ืขื˜: ื•ื•ืึธืก ืงืขื ืขืŸ ืื™ืจ ืงื•ืžืขืŸ ืึทืจื•ื™ืฃ ืžื™ื˜ ืฆื• ื“ื™ืคึผืขืจ ืื•ืŸ ื™ืงืกืคึผืึทื ื“?

ืื•ืŸ ื“ืขืžืึธืœื˜ ืื™ืš ื’ืขื“ืขื ืงืขืŸ - ื’ื™ื™ื–, ืžื™ืจ ื˜ืึธืŸ ื ื™ื˜ ื”ืึธื‘ืŸ ืžืึธื ื™ื˜ืึธืจื™ื ื’ ืคื•ืŸ ืื•ื ื“ื–ืขืจ PostgreSQL ื“ืึทื˜ืึทื‘ื™ื™ืกื™ื–.

ื”ืึทื ื˜ ืื•ื™ืฃ ื”ืึทืจืฅ, ืขืก ืื™ื– ื ืึธืš ืขื˜ืœืขื›ืข ืžืึธื ื™ื˜ืึธืจื™ื ื’ ืื™ืŸ ื“ื™ ืคืึธืจืขื ืคื•ืŸ ืงืœืึธื•ื“ ื•ื•ืึทืš ืื•ื™ืฃ AWS. ืึธื‘ืขืจ ื•ื•ืึธืก ืื™ื– ื“ื™ ื ื•ืฅ ืคื•ืŸ ื“ืขื ืžืึธื ื™ื˜ืึธืจื™ื ื’ ืคึฟืึทืจ ื“ื™ ื“ื‘ืึท? ืื™ืŸ ืึทืœื’ืขืžื™ื™ืŸ, ื›ึผืžืขื˜ ื’ืึธืจื ื™ื˜.

ืื•ื™ื‘ ืื™ืจ ื”ืึธื˜ ืึท ื’ืขืœืขื’ื ื”ื™ื™ื˜ ืฆื• ื˜ืึธืŸ ืขืคึผืขืก ื ื•ืฆื™ืง ืื•ืŸ ื˜ืฉื™ืงืึทื•ื•ืข ืคึฟืึทืจ ื–ื™ืš, ืื™ืจ ืงืขื ื˜ ื ื™ืฉื˜ ื ื•ืฆืŸ ื“ื™ ื’ืขืœืขื’ื ื”ื™ื™ื˜ ...
ื™ื‘ืึธ

ืžื–ืœ ืคืืจื˜ื™ื™ ืึธื“ืขืจ ืขื˜ืœืขื›ืข ืฉื•ืจื•ืช ืคื•ืŸ ื–ื›ืจื•ื ื•ืช ื•ื•ืขื’ืŸ ืฆื• ื•ื•ื™ืกืŸ ืคึผืึทืจื˜ื™ืฉืึทื ื™ื ื’ ืื™ืŸ PostgreSQL10

ื“ืึธืก ืื™ื– ื•ื•ื™ ืžื™ืจ ืงื•ืžืขืŸ ืฆื• ื“ื™ ืžืขืจืกื˜ ื˜ืฉื™ืงืึทื•ื•ืข ื˜ื™ื™ืœ:

3 ื“ืขืฆืขืžื‘ืขืจ 2018.
ืžืึทื›ืŸ ืึท ื‘ืึทืฉืœื•ืก ืฆื• ืึธื ื”ื™ื™ื‘ืŸ ืคืึธืจืฉื•ื ื’ ืื™ืŸ ืคืึทืจืึทื ืขืŸ ืงื™ื™ืคึผืึทื‘ื™ืœืึทื˜ื™ื– ืคึฟืึทืจ ืžืึธื ื™ื˜ืึธืจื™ื ื’ ื“ื™ ืคืึธืจืฉื˜ืขืœื•ื ื’ ืคื•ืŸ PostgreSQL ืงื•ื•ื™ืจื™ื–.

ืึธื‘ืขืจ ื“ืึธืก ืื™ื– ื’ืึธืจ ืึทืŸ ืึทื ื“ืขืจ ื’ืขืฉื™ื›ื˜ืข.

ื”ืžืฉืš...

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’