MySQLデータベースの1つのバックアッププロセスを自動化するために、2つのテーブルの構造を比較したいと思います(現在のバージョンと古いバージョン)。
2つのテーブルを比較できるクエリを考えられますか?
比較できる表の例をいくつか示します。
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)
);
最初の2つのテーブルは同じ構造です。最後のものは違います。 2つのテーブルの構造が異なるかどうかを知る必要があるだけです。それらの違いに興味はありません。
2つのテーブルが異なるかどうかを知りたい場合は、これを実行します
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;
2つのテーブルがデータベース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.tb1
およびdb2.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;
SHOW CREATE TABLE product_todayの出力のチェックサムを比較できます
# mysql -NBe "SHOW CREATE TABLE sakila.actor"| sed -r 's/AUTO_INCREMENT=[0-9]+/AUTO_INCREMENT=XXX/g' | md5sum
# 1bc0d72b294d1a93ce01b9a2331111cc -
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;
Information_schema-column_typeフィールドの列テーブルを見てください。これにより、テーブル構造を比較できます。
2つのデータベース(DB1、DB2)を比較する私の究極の方法-テーブル/ビューのみ、制約、および外部キーは含まれていません。私の場合、以下のSQLを常に使用して、PRODUCTIONとUATまたはUATとDEVを比較します。
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;