MySQL에서 두 테이블의 구조를 비교하기위한 쿼리


18

내 MySQL 데이터베이스 중 하나의 백업 프로세스를 자동화하기 위해 두 테이블의 구조 (현재 버전과 이전 버전)를 비교하고 싶습니다.

두 테이블을 비교할 수있는 쿼리를 생각할 수 있습니까?

다음은 비교할 수있는 몇 가지 예제 테이블입니다.

CREATE TABLE product_today
(
  pname VARCHAR(150),
  price int,
  PRIMARY KEY (pname)
);

CREATE TABLE product_yesterday
(
  pname VARCHAR(150),
  price int,
  PRIMARY KEY (pname)
);

CREATE TABLE product_2days_back
(
  pname VARCHAR(15),
  price int,
  PRIMARY KEY (pname)
);

처음 두 테이블은 동일한 구조를 갖습니다. 마지막 것은 다릅니다. 두 테이블의 구조가 다른지 여부 만 알면됩니다. 나는 그들이 어떻게 다른지에 관심이 없다.


@ yagmoth555 내 질문에 SF에 대한 주제가 충분하다고 가정하면 비슷한 대답을 여기에 입력하고 싶습니다. 그렇지 않으면 오늘 나 자신의 질문에 대답하겠습니다.

나는 그것이 거기에 맞는지 확실하지 않지만 어쨌든 서버 관리자 질문 일 수 있기 때문에 어쨌든 거기에 맞을 수있는 답변을 쓸 것입니다 :) 그리고 둘 사이의 그렙은 맞았을 것입니다. 내 생각에는 회색 선

1
이것은 확실하게 불가능합니다. 소프트웨어 개정판 간의 데이터 구조에 대한 모든 변경 사항이 실제로 스키마의 변경 사항으로 표시되는 것은 아닙니다. 응용 프로그램 개발자 만이 정확히 변경된 내용을 알고 있습니다. 개발자가 공식 마이그레이션 도구를 제공하지 않은 경우 특정 버전의 응용 프로그램간에 마이그레이션하는 방법을 문의해야합니다.
kasperd

1
두 번째 테이블을 첫 번째 tablediff.com 과 동일하게 만들기 위해 alter 문을 생성하는 무료 도구를 만들었습니다 . 여전히 알파.
Mihai

답변:


34

현재 데이터베이스의 두 테이블

두 테이블이 다른지 알고 싶다면 이것을 실행하십시오.

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

실제로 차이점을 볼 필요가 있다면 이것을 실행하십시오.

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

특정 데이터베이스의 두 테이블

두 테이블이 데이터베이스 mydb에서 다른지 알고 싶다면 이것을 실행하십시오.

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema='mydb'
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

실제로 차이점을 볼 필요가 있다면 이것을 실행하십시오.

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema='mydb'
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

두 가지 다른 데이터베이스의 두 테이블

당신이 알고 싶은 경우 db1.tb1db2.tb2다른이를 실행

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE
    (
        (table_schema='db1' AND table_name='tb1') OR
        (table_schema='db2' AND table_name='tb2')
    )
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

실제로 차이점을 볼 필요가 있다면 이것을 실행하십시오.

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE
    (
        (table_schema='db1' AND table_name='tb1') OR
        (table_schema='db2' AND table_name='tb2')
    )
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

시도 해봐 !!!


서로 다른 상태의 동일한 테이블이 모두있는 두 개의 dev 데이터베이스를 나란히 비교해야했기 때문에이 목표를 잘 충족하도록 수정할 수있었습니다.
Jason

1
@Jason 내가 도울 수있어서 기쁘다 !!!
RolandoMySQLDBA

매우 도움이 좀 귀중한 시간 저장
니키타 Kurtin

선택 열에 스키마 이름, 테이블 이름을 표시하는 방법
iCoders

2

SHOW CREATE TABLE 출력의 체크섬을 비교할 수 있습니다.

# mysql -NBe "SHOW CREATE TABLE sakila.actor"| sed -r 's/AUTO_INCREMENT=[0-9]+/AUTO_INCREMENT=XXX/g' | md5sum
# 1bc0d72b294d1a93ce01b9a2331111cc  -

1
AUTO_INCREMENT가 있으면 방해가 될 수 있습니다.
RolandoMySQLDBA

그러면 자동 증가 값을 줄입니다
akuzminsky

이제는 빠르고 더럽습니다. +1 !!!
RolandoMySQLDBA 1

쉘에서 작업하는 경우 이것은 영리한 솔루션 인 것 같습니다. 감사합니다.
sjdh

2
열의 순서가 동일하다는 보장은 없으므로 스펙별로 동일한 스키마가 다른 체크섬을 생성 할 수 있습니다.
Zds

1

RolandoMySQLDBA의 답변을 확장 :

테이블 이름도 보려면 다음을 쿼리하십시오.

SELECT table_name, column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        table_name, column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('table_1','table_2')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

0

information_schema-column_type 필드의 columns 테이블을 살펴보십시오. 그러면 테이블 구조를 비교할 수 있습니다.


0

2 개의 데이터베이스 (DB1, DB2)를 비교하는 나의 궁극적 인 방법-테이블 / 뷰 만, 제약 및 외래 키는 포함되지 않습니다. 제 경우에는 항상 다음 SQL을 사용하여 PRODUCTION을 UAT로 또는 UAT를 DEV로 비교합니다.

DB DIFF (테이블 / 뷰 비교)

select x.* from (
SELECT a.table_name, a.column_name,
    max(IF(b.TS='S1',b.ordinal_position,null)) as S1_ordinal_position,
    max(IF(b.TS='S2',b.ordinal_position,null)) as S2_ordinal_position,
    max(IF(b.TS='S1',b.data_type       ,null)) as S1_data_type,
    max(IF(b.TS='S2',b.data_type       ,null)) as S2_data_type,
    max(IF(b.TS='S1',b.column_type     ,null)) as S1_column_type,
    max(IF(b.TS='S2',b.column_type     ,null)) as S2_column_type
FROM
(SELECT DISTINCT table_name, column_name
 FROM information_schema.columns
 WHERE table_schema IN ('DB1','DB2')
) a
INNER JOIN
(SELECT IF(table_schema='DB1','S1','S2') as TS,
    table_schema,table_name,column_name,ordinal_position,data_type,column_type
 FROM information_schema.columns
 WHERE table_schema IN ('DB1','DB2')
) b
on (a.table_name = b.table_name and a.column_name = b.column_name)
group by a.table_name, a.column_name
) x
where x.S1_ordinal_position != x.S2_ordinal_position or x.S1_ordinal_position is null or x.S2_ordinal_position is null
or    x.S1_data_type        != x.S2_data_type
or    x.S1_column_type      != x.S2_column_type
ORDER BY x.table_name;

-2

두 데이터베이스의 테이블 구조에서 모든 변경 사항에 대해

SELECT table_schema, table_name, column_name,ordinal_position,data_type,column_type FROM (
    SELECT
        table_schema, table_name, column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema IN ('database1', 'database2')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1 ) A;

참조 : RolandoMySQLDBA ans에서


이것이 정확히 무엇입니까? 롤란도의 답변이 개선 되었습니까?
ypercubeᵀᴹ

두 데이터베이스 사이의 모든 테이블에서 직접 변경 사항을 볼 수는 있지만 개선되지 않았습니다.
murtaza.webdev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.