Permintaan untuk membandingkan struktur dua tabel di MySQL

18

Untuk mengotomatiskan proses pencadangan salah satu database MySQL saya, saya ingin membandingkan struktur dua tabel (versi saat ini vs versi lama).

Bisakah Anda memikirkan kueri yang dapat membandingkan dua tabel?

Berikut adalah beberapa contoh tabel yang bisa Anda bandingkan.

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

Dua tabel pertama memiliki struktur yang identik. Yang terakhir berbeda. Saya hanya perlu tahu apakah dua tabel memiliki struktur yang berbeda atau tidak. Saya tidak tertarik dengan perbedaannya.

sjdh
sumber
@ yagmoth555 dengan asumsi pertanyaan saya cukup sesuai dengan topik untuk SF, jika Anda ingin mengetik jawaban yang sama di sini saya akan menerimanya. jika tidak, saya akan menjawab pertanyaan saya sendiri hari ini.
Saya tidak yakin apakah itu cocok di sana, tapi saya akan menulis jawaban, karena bisa muat di sana, karena itu bisa menjadi pertanyaan admin server :) Karena, jika saya akan menjawab dengan todo dump dari struct tabel, dan grep di antara keduanya, itu akan cocok. Ini adalah garis abu-abu menurut pendapat saya sendiri
1
Ini tidak mungkin dilakukan dengan andal. Tidak semua perubahan pada struktur data antara revisi perangkat lunak benar-benar memanifestasikan diri mereka sebagai perubahan dalam skema. Hanya para pengembang aplikasi yang tahu apa yang sebenarnya telah berubah. Jika pengembang belum menyediakan alat resmi untuk migrasi kepada Anda, Anda perlu bertanya kepada mereka cara bermigrasi di antara versi aplikasi tertentu.
kasperd
1
Saya membuat alat gratis yang akan menghasilkan pernyataan alter untuk membuat tabel kedua sama dengan yang pertama tablediff.com . Masih alfa.
Mihai

Jawaban:

34

DUA TABEL DALAM DATABASE SAAT INI

Jika Anda ingin tahu apakah dua tabel berbeda, jalankan ini

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;

Jika Anda benar-benar perlu melihat perbedaannya, jalankan ini

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;

DUA TABEL DALAM DATABASE KHUSUS

Jika Anda ingin tahu apakah dua tabel berbeda dalam database mydb, jalankan ini

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;

Jika Anda benar-benar perlu melihat perbedaannya, jalankan ini

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;

DUA TABEL DALAM DATABASE BERBEDA

Jika Anda ingin tahu apakah db1.tb1dan db2.tb2berbeda, jalankan ini

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;

Jika Anda benar-benar perlu melihat perbedaannya, jalankan ini

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;

COBALAH !!!

RolandoMySQLDBA
sumber
Saya harus melakukan perbandingan berdampingan dari dua basis data dev yang memiliki semua tabel yang sama di negara bagian yang berbeda, saya dapat memodifikasi ini untuk memenuhi tujuan itu dengan baik.
Jason
1
@Jason senang saya bisa membantu !!!
RolandoMySQLDBA
Sangat membantu, menyelamatkan saya waktu berharga
Nikita Kurtin
bagaimana cara menunjukkan nama skema, nama tabel di kolom pilih
iCoders
2

Anda dapat membandingkan checksum dari output 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
sumber
1
Jika ada AUTO_INCREMENT, itu mungkin akan menghalangi.
RolandoMySQLDBA
Benar, maka Anda memotong nilai autoincrement
akuzminsky
Nah, itu cepat dan kotor. +1 !!!
RolandoMySQLDBA
Ini sepertinya solusi cerdas jika Anda bekerja dari shell. Terima kasih.
sjdh
2
Tidak ada jaminan kolom akan berada dalam urutan yang sama, sehingga skema identik khusus dapat menghasilkan checksum yang berbeda.
Zds
1

Memperluas jawaban RolandoMySQLDBA:

Untuk melihat nama tabel juga, kueri ini:

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
sumber
0

Lihatlah tabel kolom di information_schema - bidang column_type. Itu akan memungkinkan Anda untuk membandingkan struktur tabel.

Vérace
sumber
0

Cara pamungkas saya membandingkan 2 database (DB1, DB2) - hanya tabel / tampilan, batasan dan kunci asing tidak termasuk. Dalam kasus saya, saya selalu menggunakan SQL berikut untuk membandingkan PRODUKSI dengan UAT atau UAT dengan DEV.

DB DIFF (bandingkan tabel / tampilan)

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
sumber
-2

untuk semua perubahan dalam struktur tabel dua database:

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 .: dari RolandoMySQLDBA ans

murtaza.webdev
sumber
Apa sebenarnya ini? Peningkatan pada jawaban Rolando?
ypercubeᵀᴹ
tidak ditingkatkan tetapi untuk melihat perubahan langsung di semua tabel antara dua database.
murtaza.webdev