Запит для порівняння структури двох таблиць у 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
Я зробив безкоштовний інструмент, який генерує заяви 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;

СПРОБУВАТИ !!!


Мені потрібно було порівнювати дві бази даних розробників, які мають однакові таблиці в різних станах, я зміг це змінити, щоб чудово досягти цієї мети.
Джейсон

1
@Jason рада, що можу допомогти !!!
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  -

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

Погляньте на таблицю стовпців у інформаційній схемі - поле стовпця_типу. Це дозволить вам порівняти структури таблиць.


0

Мій кінцевий спосіб порівняння двох баз даних (DB1, DB2) - таблиці або представлення даних, обмеження та зовнішній ключ не включені. У моєму випадку я завжди використовую наступний SQL для порівняння ВИРОБНИЦТВА з 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.