문제

Postgres에 스키마가 있으며 스키마 패치를 적용하는 좋은 방법을 제정하고 싶습니다.

현재 스키마, 테이블, 시퀀스, 기능 등을 생성하는 일련의 DDL 파일이 있습니다. 또한 테스트 환경에 대한 모집단 스크립트도 있습니다. 이러한 파일은 모두 데이터베이스 환경, 개발, 테스트 등을 재현하는 데 사용됩니다.

또한 시스템 버전에 해당하는 여러 '패치'파일이 있습니다. 즉. 패치/1.0.0.SQL, 패치/1.0.1.sql 등.이 파일은 준비 및 생산 데이터베이스를 업데이트하는 데 사용됩니다.

이 과정은 지금까지 우리에게 효과적이지만, 사내에서 스키마를 가장 잘 패치하는 방법에 대한 논쟁이있었습니다.

프로세스로서 스테이징 및 생산 스키마의 패치 및 데이터베이스 버전을 관리하는 방법에 대한 다른 사람들이 무엇을 가지고 있는지 궁금합니다.

감사!

도움이 되었습니까?

해결책

직장에서 SQL Server의 경우 먼저 변경 사항을 롤백하는 스키마 변경 스크립트를 작성합니다 (IDEMPOTITONTLY, 스키마 변경이 아직 적용되지 않더라도 롤백 섹션은 잘 실행됩니다). . TSQL에서는 시스템 카탈로그 또는 기타 테이블에서 테이블/열/인덱스/행이 이미 존재하는지 확인하기가 쉽고 그렇지 않은 경우 아무것도하지 않습니다.

PostgreSQL에서는 단순히 서버로 보낼 수있는 명령이 조금 더 제한되어 있습니다. 반면에 DDL은 트랜잭션이므로 하프 적용 스키마 변경은 발생하지 않아야합니다. 예를 들어 내 자신의 작은 프로젝트에서 잘 사용하는 데 익숙한 계획을 조정했습니다 (오버 킬? 그러나 여기에도 Dev/Test DB와 "Real"DB가 있습니다).

\echo Rolling back schema change #35

BEGIN;

DELETE FROM schema_version WHERE schema_id = 35;

DROP TABLE IF EXISTS location_coordinates;
DROP FUNCTION IF EXISTS location_coordinates_populate();

END;

\echo Applying schema change #35

BEGIN;

INSERT INTO schema_version(schema_id, description) VALUES(35, 'Add location_coordinates table');

CREATE TABLE location_coordinates(
 location_id INT PRIMARY KEY REFERENCES location(location_id),
 latitude FLOAT NOT NULL,
 longitude FLOAT NOT NULL,
 earth_coordinates earth NOT NULL,
 box_10miles cube NOT NULL
);

GRANT SELECT, INSERT, UPDATE, DELETE ON location_coordinates TO ui;

CREATE FUNCTION location_coordinates_populate() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  new.earth_coordinates := ll_to_earth(new.latitude, new.longitude);
  new.box_10miles := earth_box(new.earth_coordinates, 10 * 1609.344);
  RETURN new;
END
$$;

CREATE TRIGGER location_coordinates_populate BEFORE INSERT OR UPDATE ON location_coordinates
 FOR EACH ROW EXECUTE PROCEDURE location_coordinates_populate();

INSERT INTO location_coordinates(location_id, latitude, longitude)
 SELECT location_id, latitude, longitude FROM location WHERE latitude IS NOT NULL AND longitude IS NOT NULL;

CREATE INDEX location_coordinates_10miles ON location_coordinates USING gist (box_10miles);

END;

\echo Done

이 스크립트는 "PSQL -F Schema -Changes/35.SQL"만으로 데이터베이스에서 실행할 수 있습니다. "Applying ..."메시지를 잘라 내면 명령을 롤백 할 수 있습니다. 보시다시피, 변경 사항은 메타 데이터 테이블 "Schema_version"을 유지하여 어떤 변경 사항이 적용되는지 확인할 수 있습니다. 전체 변경은 거래, 데이터 마이그레이션 및 모든 것으로 수행됩니다. 여기서 나는 Drop 명령의 "존재"기능을 사용하여 변경이 적용되지 않은 경우에도 롤백 섹션을 행복하게 만들었습니다. ISTR Oracle에서 직장에서 한 한 가지 일은 PL/SQL로 쓰기 스키마 변경이었습니다. 아마도 PLPGSQL에 변경을 수행하는 데 도움이 될 수있는 기능이있을 수 있습니까?

위의 변경에서 "위도"및 "경도"열을 "위치"에서 "위치"에서 별도의 "location_coordinates"관계 (및 Earthdistance 물건에 추가)로 마이그레이션하는 경우, 나는하지 않았다. t 기존 열을 떨어 뜨립니다. 우리가 조심해야 할 한 가지는 스키마가 가능한 경우 거꾸로 호환되는 것입니다. 이 스키마 변경을 적용 할 수 있습니다 ~ 전에 새 테이블을 사용하도록 앱을 업데이트합니다. 기존 열을 적용하기 위해 두 번째 변경이있을 것입니다. ~ 후에 앱 업데이트. 직장에서, 이들은 두 가지 다른 릴리스 주기로 수행 될 것이므로 릴리스 X 중에는 모든 스키마 변경을 먼저 롤백하지 않고도 X-1을 릴리스하기 위해 앱을 롤백하는 선택 사항이 있습니다. 앱 전에 별도의 창에 스키마 변경을 배포 할 수 있습니다. (기술적으로 나는 트리거를 작성해야했기 때문에 이전 테이블에 대한 업데이트가 새 테이블과 동기화되었지만 작업과 너무 비슷하기 때문에 그렇지 않았습니다 :)).

우리는 또한 모든 데이터베이스를 거주하는 응용 프로그램과 같은 것들이 있습니다. schema_version 표 및 변경 사항을 추적하므로 사람들은 연결하지 않고 변경된 변경 사항을 확인하고 각 변경의 이력에 대한 아이디어를 얻을 수 있습니다 (우리는 "Dev in Dev", "Dev in Applied"등)를 추적합니다. 직장에서 우리의 schema_version 테이블도 포함됩니다. 저자 정보 등이 포함됩니다. 버전 제어에서 버전 정보를 적용하는 마법의 방법은 쿨합니다. -하나의 통지. 따라서 스키마 변경 35 개정 #4가 적용되었다는 것을 추적하는 방법이 좋을 것입니다.

주목할만한 점- 스키마 변경은 응용 프로그램 버전과 독립적으로 번호가 매겨집니다. 분명히 그것들은 관련이 있습니다 --- 스파이더 앱이 사람들이 입력 할 수있는 또 다른 것입니다. 그러나 우리는 거대한 "릴리스 X의 모든 것"패치가 아닌 작은 변화를 많이하려고 노력합니다. 스키마 변경은 또한 새로운 지수를 추가하는 데 사용되므로 전혀 앱 중심이 아닐 수 있습니다. 일반적으로 스키마 변경은 DBAS가 아닌 개발자가 "소유"합니다. 위의 "인덱스 작성"예제에서 DBA는 기본적으로 개발자 역할을 수행하고 스키마 변경을 소유하고 있습니다. 예, 우리는 개발자의 높은 수준의 SQL 가능성을 고집합니다. 그러나 회사의 다른 그룹은 약간 다르게 일하고 DB 팀에 더 많은 작업을 제공합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top