Abfrage zum Vergleichen der Struktur zweier Tabellen in MySQL

18

Um den Sicherungsprozess einer meiner MySQL-Datenbanken zu automatisieren, möchte ich die Struktur zweier Tabellen (aktuelle Version vs. alte Version) vergleichen.

Können Sie sich eine Abfrage vorstellen, mit der zwei Tabellen verglichen werden können?

Hier sind einige Beispieltabellen, die Sie vergleichen können.

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

Die ersten beiden Tabellen sind identisch aufgebaut. Der letzte ist anders. Ich muss nur wissen, ob zwei Tabellen unterschiedliche Strukturen haben oder nicht. Es interessiert mich nicht, wie sie sich unterscheiden.

sjdh
quelle
@ yagmoth555 Angenommen, meine Frage ist für SF themenbezogen genug. Wenn Sie eine ähnliche Antwort hier eingeben möchten, akzeptiere ich sie. Ansonsten beantworte ich meine Frage später.
Ich bin nicht sicher, ob es dort passt, aber ich werde eine Antwort schreiben, da es sowieso dort passen kann, da es sowieso eine Serveradministratorfrage sein kann :) Als ob ich mit todo einen Dump der Tabellenstruktur beantworten würde, und ein Grep zwischen den beiden hätte gepasst. Meiner Meinung nach ist es eine graue Linie
1
Dies ist unmöglich, zuverlässig zu tun. Nicht alle Änderungen der Datenstruktur zwischen Softwareversionen äußern sich tatsächlich als Änderungen im Schema. Nur die Entwickler der Anwendung wissen, was sich genau geändert hat. Wenn die Entwickler Ihnen kein offizielles Tool für die Migration zur Verfügung gestellt haben, müssen Sie sie fragen, wie sie zwischen bestimmten Versionen der Anwendung migrieren sollen.
Kasperd
1
Ich habe ein kostenloses Tool erstellt, mit dem die alter -Anweisungen generiert werden, um die zweite Tabelle mit der ersten Tabelle auf tablediff.com identisch zu machen . Immer noch Alpha.
Mihai

Antworten:

34

ZWEI TABELLEN IN DER AKTUELLEN DATENBANK

Wenn Sie wissen möchten, ob zwei Tabellen unterschiedlich sind, führen Sie dies aus

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;

Wenn Sie die Unterschiede tatsächlich sehen müssen, führen Sie dies aus

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;

ZWEI TABELLEN IN EINER SPEZIFISCHEN DATENBANK

Wenn Sie wissen möchten, ob zwei Tabellen in der Datenbank unterschiedlich sind mydb, führen Sie dies aus

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;

Wenn Sie die Unterschiede tatsächlich sehen müssen, führen Sie dies aus

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;

ZWEI TABELLEN IN ZWEI VERSCHIEDENEN DATENBANKEN

Wenn Sie wissen möchten, ob db1.tb1und db2.tb2anders sind, führen Sie dies aus

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;

Wenn Sie die Unterschiede tatsächlich sehen müssen, führen Sie dies aus

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;

VERSUCHE ES !!!

RolandoMySQLDBA
quelle
Ich musste zwei Entwicklerdatenbanken, die alle die gleichen Tabellen in verschiedenen Status haben, nebeneinander vergleichen. Ich konnte dies ändern, um dieses Ziel gut zu erreichen.
Jason
1
@ Jason froh, dass ich helfen konnte !!!
RolandoMySQLDBA
Sehr hilfreich, hat mir einige wertvolle Zeit gespart
Nikita Kurtin
Anzeigen von
2

Sie können die Prüfsumme der Ausgabe von SHOW CREATE TABLE product_today vergleichen

# mysql -NBe "SHOW CREATE TABLE sakila.actor"| sed -r 's/AUTO_INCREMENT=[0-9]+/AUTO_INCREMENT=XXX/g' | md5sum
# 1bc0d72b294d1a93ce01b9a2331111cc  -
akuzminsky
quelle
1
Wenn es ein AUTO_INCREMENT gibt, könnte es im Weg stehen.
RolandoMySQLDBA
Richtig, dann schneiden Sie den Autoincrement-Wert
akuzminsky
Nun, das ist schnell und schmutzig. +1 !!!
RolandoMySQLDBA
Dies scheint eine clevere Lösung zu sein, wenn Sie von der Shell aus arbeiten. Vielen Dank.
sjdh
2
Es gibt keine Garantie dafür, dass die Spalten in derselben Reihenfolge angeordnet sind. Daher können identische Schemata unterschiedliche Prüfsummen erzeugen.
Zds
1

Erweiterung der Antwort von RolandoMySQLDBA:

Fragen Sie Folgendes ab, um auch den Tabellennamen anzuzeigen:

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;
Bibek Lekhak
quelle
0

Schauen Sie sich die Spaltentabelle im Feld information_schema - column_type an. Auf diese Weise können Sie Tabellenstrukturen vergleichen.

Vérace
quelle
0

Meine ultimative Methode zum Vergleichen von 2 Datenbanken (DB1, DB2) - nur Tabellen / Ansichten, Einschränkungen und Fremdschlüssel sind nicht enthalten. In meinem Fall verwende ich immer folgendes SQL, um PRODUCTION mit UAT oder UAT mit DEV zu vergleichen.

DB DIFF (Tabellen / Views vergleichen)

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;
JKar
quelle
-2

für alle Änderungen in der Tabellenstruktur zweier Datenbanken:

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;

Ref .: von RolandoMySQLDBA ans

murtaza.webdev
quelle
Was ist das genau? Eine Verbesserung der Antwort von Rolando?
ypercubeᵀᴹ
nicht verbessert, sondern um direkte Änderungen in allen Tabellen zwischen zwei Datenbanken anzuzeigen.
murtaza.webdev