Pour automatiser le processus de sauvegarde d'une de mes bases de données MySQL, je voudrais comparer la structure de deux tables (version actuelle vs ancienne version).
Pouvez-vous penser à une requête qui peut comparer deux tableaux?
Voici quelques exemples de tableaux que vous pouvez comparer.
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)
);
Les deux premiers tableaux ont des structures identiques. Le dernier est différent. J'ai juste besoin de savoir si deux tables ont des structures différentes ou non. Je ne suis pas intéressé par la façon dont ils diffèrent.
Si vous voulez savoir si deux tables sont différentes, exécutez cette
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;
Si vous avez réellement besoin de voir les différences, exécutez cette
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;
Si vous voulez savoir si deux tables sont différentes dans la base de données mydb
, exécutez cette
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;
Si vous avez réellement besoin de voir les différences, exécutez cette
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;
Si vous voulez savoir si db1.tb1
et db2.tb2
sont différents, exécutez ceci
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;
Si vous avez réellement besoin de voir les différences, exécutez cette
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;
Vous pouvez comparer la somme de contrôle de la sortie de 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 -
Extension de la réponse de RolandoMySQLDBA:
Pour voir également le nom de la table, interrogez ceci:
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;
Jetez un œil à la table des colonnes dans le champ information_schema - le champ column_type. Cela vous permettra de comparer les structures de table.
Ma façon ultime de comparer 2 bases de données (DB1, DB2) - les tables/vues uniquement, les contraintes et la clé étrangère ne sont pas incluses. Dans mon cas, j'utilise toujours SQL suivant pour comparer la PRODUCTION avec UAT ou UAT avec 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;