MySQL'de iki tablonun yapısını karşılaştırma sorgusu


18

MySQL veritabanlarımdan birinin yedekleme işlemini otomatikleştirmek için, iki tablonun yapısını karşılaştırmak istiyorum (mevcut sürüm ile eski sürüm).

İki tabloyu karşılaştırabilecek bir sorgu düşünebiliyor musunuz?

İşte karşılaştırabileceğiniz bazı örnek tablolar.

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

İlk iki tablo aynı yapılara sahiptir. Sonuncusu farklı. İki tablonun farklı yapılara sahip olup olmadığını bilmem gerekiyor. Farklılıklarıyla ilgilenmiyorum.


@ yagmoth555 sorumun SF için yeterince konu olduğunu varsayarsak, benzer bir cevap yazmak istiyorsanız bunu kabul edeceğim. Aksi takdirde bugün kendi soruma cevap vereceğim.

Oraya uygun olup olmadığından emin değilim, ama yine de oraya sığabileceği için bir cevap yazacağım, çünkü yine de bir sunucu yöneticisi sorusu olabilir :) Gibi, tablo yapısının bir dökümünü todo ile cevaplarsam, ve ikisi arasında bir grep, uygun olurdu. Bence gri bir çizgi

1
Bunu güvenilir bir şekilde yapmak imkansızdır. Yazılım revizyonları arasındaki veri yapısındaki tüm değişiklikler aslında kendilerini şemadaki değişiklikler olarak göstermez. Neyin değiştiğini yalnızca uygulamanın geliştiricileri bilir. Geliştiriciler size taşıma için resmi bir araç sağlamadıysa, onlara uygulamanın belirli sürümleri arasında nasıl geçiş yapılacağını sormanız gerekir.
kasperd

1
İkinci tabloyu ilk tablediff.com ile aynı yapmak için alter ifadeleri üretecek ücretsiz bir araç yaptım . Hala alfa.
Mihai

Yanıtlar:


35

GÜNCEL VERİTABANINDA İKİ TABLOLAR

İki tablonun farklı olup olmadığını bilmek istiyorsanız, bunu çalıştırın

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;

Farklılıkları gerçekten görmeniz gerekiyorsa, bunu çalıştırın

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;

ÖZEL VERİTABANI İKİ TABLOLARI

Veritabanında iki tablonun farklı olup olmadığını bilmek istiyorsanız, bunu mydbçalıştırın

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;

Farklılıkları gerçekten görmeniz gerekiyorsa, bunu çalıştırın

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;

İKİ FARKLI VERİTABANINDA İKİ TABLOLAR

Eğer bilmek istiyorsanız db1.tb1ve db2.tb2farklı, bu koşmak

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;

Farklılıkları gerçekten görmeniz gerekiyorsa, bunu çalıştırın

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;

BİR ŞANS VER !!!


Farklı eyaletlerde aynı tablolara sahip iki dev veritabanının yan yana karşılaştırmasını yapmam gerekiyordu, bu hedefe güzel bir şekilde ulaşmak için bunu değiştirebildim.
Jason

1
@ Jason yardımcı olabilir sevindim !!!
RolandoMySQLDBA

Çok faydalı, beni değerli zamandan kurtardı
Nikita Kurtin

şema adı, belirli sütunlarda tablo adı nasıl gösterilir
iCoders

2

SHOW CREATE TABLE product_today çıktı kontrol toplamını karşılaştırabilirsiniz

# mysql -NBe "SHOW CREATE TABLE sakila.actor"| sed -r 's/AUTO_INCREMENT=[0-9]+/AUTO_INCREMENT=XXX/g' | md5sum
# 1bc0d72b294d1a93ce01b9a2331111cc  -

1
Bir AUTO_INCREMENT varsa, bunu engelleyebilir.
RolandoMySQLDBA

Doğru, o zaman
otomatik enterrement

Şimdi, bu hızlı ve kirli. +1 !!!
RolandoMySQLDBA

Kabuktan çalışıyorsanız bu akıllıca bir çözüm gibi görünüyor. Teşekkür ederim.
sjdh

2
Sütunların aynı sırada olacağının garantisi yoktur, bu nedenle belirli özdeş şemalar farklı sağlama toplamları oluşturabilir.
Zds

1

RolandoMySQLDBA'nın cevabına genişleyen:

Tablo adını da görmek için şunu sorgulayın:

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

İnformation_schema - column_type alanı içindeki sütunlar tablosuna bakın. Bu tablo yapılarını karşılaştırmanıza izin verecektir.


0

2 veritabanını (DB1, DB2) karşılaştırmamın nihai yolu - yalnızca tablolar / görünümler, kısıtlamalar ve yabancı anahtar dahil değildir. Benim durumumda UAT ile ÜRETİM veya DEV ile UAT karşılaştırmak için her zaman aşağıdaki SQL kullanın.

DB DIFF (tabloları / görünümleri karşılaştırın)

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

iki veritabanının tablo yapısındaki tüm değişiklikler için:

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;

Referans: RolandoMySQLDBA ans'tan


Bu tam olarak nedir? Rolando'nun cevabında bir gelişme mi var?
ypercubeᵀᴹ

geliştirilmedi ancak iki veritabanı arasındaki tüm tablolarda doğrudan değişiklikleri görüntülemek için.
murtaza.webdev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.