Запрос для сравнения структуры двух таблиц в 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)
);

Первые две таблицы имеют одинаковую структуру. Последний отличается. Мне просто нужно знать, имеют ли две таблицы разную структуру или нет. Меня не интересует, чем они отличаются.

sjdh
источник
@ yagmoth555 при условии, что мой вопрос достаточно актуален для SF, если вы хотите набрать аналогичный ответ здесь, я приму его. в противном случае я отвечу на свой вопрос позже сегодня.
Я не уверен, подходит ли он там, но я напишу ответ, так как он может туда поместиться в любом случае, поскольку это может быть вопрос администратора сервера в любом случае :) Как, если бы я ответил с todo дампом структуры таблицы, и разногласия между ними, это было бы подходящим. По моему мнению, это серая линия
1
Это невозможно сделать надежно. Не все изменения в структуре данных между версиями программного обеспечения на самом деле проявляются как изменения в схеме. Только разработчики приложения знают, что именно изменилось. Если разработчики не предоставили вам официальный инструмент для миграции, вам нужно спросить их, как выполнить миграцию между конкретными версиями приложения.
Касперд
1
Я сделал бесплатный инструмент, который будет генерировать операторы alter, чтобы вторая таблица стала такой же, как первая tablediff.com . Все еще альфа.
Михай

Ответы:

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

ДАЙТЕ ЭТО ПОПРОБУЙТЕ !!!

RolandoMySQLDBA
источник
Мне нужно было провести параллельное сравнение двух баз данных разработчиков, которые имеют все одинаковые таблицы в разных состояниях, и я смог изменить это для достижения этой цели.
Джейсон
1
@ Джейсон рад, что смог помочь !!!
RolandoMySQLDBA
Очень полезно, сэкономило мне драгоценное время
Никита Куртин
как отобразить имя схемы, имя таблицы в выбранных столбцах
iCoders
2

Вы можете сравнить контрольную сумму вывода 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  -
akuzminsky
источник
1
Если есть AUTO_INCREMENT, он может помешать этому.
RolandoMySQLDBA
Правильно, тогда вы сократите значение автоинкремента
акузминский
Теперь это быстро и грязно. +1 !!!
RolandoMySQLDBA
Это кажется разумным решением, если вы работаете из оболочки. Спасибо.
sjdh
2
Нет гарантии, что столбцы будут в одном и том же порядке, поэтому идентичные схемы могут создавать разные контрольные суммы.
Здс
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. Это позволит вам сравнивать структуры таблиц.

Verace
источник
0

Мой лучший способ сравнения 2 баз данных (DB1, DB2) - только таблицы / представления, ограничения и внешний ключ не включены. В моем случае я всегда использую следующий SQL для сравнения PRODUCTION с UAT или UAT с DEV.

БД 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;
JKar
источник
-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 и

murtaza.webdev
источник
Что именно это? Улучшение ответа Роландо?
ypercubeᵀᴹ
не улучшено, но для просмотра прямых изменений во всех таблицах между двумя базами данных.
murtaza.webdev