แบบสอบถามเพื่อเปรียบเทียบโครงสร้างของสองตารางใน 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 สมมติว่าคำถามของฉันอยู่ในหัวข้อเพียงพอสำหรับเอสเอฟถ้าคุณรู้สึกอยากพิมพ์คำตอบที่คล้ายกันที่นี่ฉันจะยอมรับมัน มิฉะนั้นฉันจะตอบคำถามของตัวเองในวันนี้

ฉันไม่แน่ใจว่ามันเหมาะสมหรือไม่ แต่ฉันจะเขียนคำตอบเพราะมันสามารถใส่ได้ แต่อย่างใดเพราะมันอาจเป็นคำถามของผู้ดูแลระบบเซิร์ฟเวอร์ แต่อย่างใด :) เป็นถ้าฉันจะตอบด้วยการทิ้งดั๊กของโครงสร้างตาราง และ grep ระหว่างสองมันจะพอดี มันเป็นเส้นสีเทาตามความเห็นของฉันเอง

1
นี่เป็นไปไม่ได้ที่จะทำอย่างน่าเชื่อถือ การเปลี่ยนแปลงโครงสร้างของข้อมูลระหว่างการแก้ไขซอฟต์แวร์ไม่ได้แสดงให้เห็นว่าเป็นการเปลี่ยนแปลงในสคีมา เฉพาะนักพัฒนาแอปพลิเคชันเท่านั้นที่ทราบว่ามีการเปลี่ยนแปลงอะไรบ้าง หากนักพัฒนาซอฟต์แวร์ไม่ได้ให้เครื่องมืออย่างเป็นทางการสำหรับการย้ายข้อมูลคุณจำเป็นต้องถามพวกเขาถึงวิธีการโยกย้ายระหว่างแอปพลิเคชันเฉพาะรุ่น
kasperd

1
ฉันทำเครื่องมือฟรีที่จะสร้างการเปลี่ยนแปลงงบที่จะทำให้ตารางที่สองเช่นเดียวกับคนแรก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;

ให้มันลอง !!!


ฉันต้องทำการเปรียบเทียบแบบเคียงข้างกันของฐานข้อมูล dev สองตัวที่มีตารางเดียวกันทั้งหมดในสถานะที่แตกต่างกันฉันสามารถแก้ไขสิ่งนี้เพื่อให้บรรลุเป้าหมายนั้นได้อย่างดี
Jason

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

ใช่แล้วคุณก็ตัดค่า autoincrement
akuzminsky

ตอนนี้มันเร็วและสกปรก +1 !!!
RolandoMySQLDBA

นี่ดูเหมือนจะเป็นทางออกที่ฉลาดหากคุณกำลังทำงานจากเชลล์ ขอขอบคุณ.
sjdh

2
ไม่มีการรับประกันว่าคอลัมน์จะอยู่ในลำดับเดียวกันดังนั้นสกีมาที่เหมือนกันที่ชาญฉลาดสามารถสร้าง checksums ที่แตกต่างกันได้
Zds

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

ดูที่ตารางคอลัมน์ใน data_schema - ฟิลด์ column_type ที่จะช่วยให้คุณเปรียบเทียบโครงสร้างตาราง


0

วิธีที่ดีที่สุดของฉันในการเปรียบเทียบ 2 ฐานข้อมูล (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


อะไรกันแน่ การปรับปรุงคำตอบของ Rolando?
ypercubeᵀᴹ

ไม่ปรับปรุง แต่เพื่อดูการเปลี่ยนแปลงโดยตรงในตารางทั้งหมดระหว่างสองฐานข้อมูล
murtaza.webdev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.