Truy vấn để so sánh cấu trúc của hai bảng trong MySQL


18

Để tự động hóa quá trình sao lưu của một trong các cơ sở dữ liệu MySQL của tôi, tôi muốn so sánh cấu trúc của hai bảng (phiên bản hiện tại so với phiên bản cũ).

Bạn có thể nghĩ ra một truy vấn có thể so sánh hai bảng không?

Dưới đây là một số bảng ví dụ mà bạn có thể so sánh.

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

Hai bảng đầu tiên có cấu trúc giống hệt nhau. Người cuối cùng là khác nhau. Tôi chỉ cần biết liệu hai bảng có cấu trúc khác nhau hay không. Tôi không quan tâm đến sự khác biệt của chúng.


@ yagmoth555 giả sử câu hỏi của tôi đủ về chủ đề cho SF, nếu bạn cảm thấy muốn gõ một câu trả lời tương tự ở đây tôi sẽ chấp nhận nó. nếu không, tôi sẽ trả lời câu hỏi của riêng tôi sau ngày hôm nay.

Tôi không chắc nó có phù hợp ở đó không, nhưng tôi sẽ viết một câu trả lời, vì dù sao nó cũng có thể phù hợp với nó, vì dù sao nó cũng có thể là một câu hỏi của quản trị viên máy chủ :) Vì, nếu tôi sẽ trả lời bằng cách làm đổ một cấu trúc bảng, và một grep giữa hai, nó sẽ phù hợp. Theo quan điểm của riêng tôi, đó là một đường màu xám

1
Điều này là không thể làm đáng tin cậy. Không phải tất cả các thay đổi về cấu trúc dữ liệu giữa các phiên bản phần mềm thực sự biểu hiện như những thay đổi trong lược đồ. Chỉ các nhà phát triển của ứng dụng biết chính xác những gì đã thay đổi. Nếu các nhà phát triển chưa cung cấp cho bạn một công cụ chính thức để di chuyển, bạn cần hỏi họ cách di chuyển giữa các phiên bản cụ thể của ứng dụng.
kasperd

1
Tôi đã tạo ra một công cụ miễn phí sẽ tạo ra các câu lệnh thay đổi để làm cho bảng thứ hai giống như bảng thứ nhất tablediff.com . Vẫn là alpha.
Mihai

Câu trả lời:


34

HAI BẢNG TRONG CƠ SỞ HIỆN TẠI

Nếu bạn muốn biết hai bảng có khác nhau không, hãy chạy 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;

Nếu bạn thực sự cần thấy sự khác biệt, hãy chạy 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;

HAI BẢNG TRONG MỘT CƠ SỞ CỤ THỂ

Nếu bạn muốn biết hai bảng có khác nhau trong cơ sở dữ liệu hay không mydb, hãy chạy 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;

Nếu bạn thực sự cần thấy sự khác biệt, hãy chạy 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;

HAI BẢNG TRONG HAI BẢNG KHÁC NHAU

Nếu bạn muốn biết nếu db1.tb1db2.tb2khác nhau, hãy chạy 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='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;

Nếu bạn thực sự cần thấy sự khác biệt, hãy chạy 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;

HÃY THỬ MỘT LẦN !!!


Tôi cần phải so sánh song song hai cơ sở dữ liệu dev có tất cả các bảng giống nhau ở các trạng thái khác nhau, tôi đã có thể sửa đổi điều này để đáp ứng mục tiêu đó một cách độc đáo.
Jason

1
@Jason rất vui vì tôi có thể giúp !!!
RolandoMySQLDBA

Rất hữu ích, giúp tôi tiết kiệm thời gian quý báu
Nikita Kurtin

cách hiển thị tên lược đồ, tên bảng trong các cột được chọn
iCoders

2

Bạn có thể so sánh tổng kiểm tra đầu ra của SHOW CREATE TABLE sản phẩm_today

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

1
Nếu có AUTO_INCREMENT, nó có thể cản trở bạn.
RolandoMySQLDBA

Đúng rồi, sau đó bạn cắt giá trị tự động
akuzminsky

Bây giờ, đó là nhanh chóng và bẩn. +1 !!!
RolandoMySQLDBA

Đây có vẻ là một giải pháp thông minh nếu bạn đang làm việc từ vỏ. Cảm ơn bạn.
sjdh

2
Không có gì đảm bảo các cột sẽ theo cùng một thứ tự, vì vậy các lược đồ giống hệt nhau có thể tạo ra các tổng kiểm tra khác nhau.
Zds

1

Mở rộng câu trả lời của RolandoMySQLDBA:

Để xem tên bảng là tốt, truy vấn này:

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

Hãy xem bảng cột trong information_schema - trường cột_type. Điều đó sẽ cho phép bạn so sánh các cấu trúc bảng.


0

Cách cuối cùng của tôi để so sánh 2 cơ sở dữ liệu (DB1, DB2) - không bao gồm bảng / khung nhìn, các ràng buộc và khóa ngoại. Trong trường hợp của tôi, tôi luôn sử dụng SQL sau để so sánh SẢN XUẤT với UAT hoặc UAT với DEV.

DB DIFF (so sánh bảng / lượt xem)

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

cho tất cả các thay đổi trong cấu trúc bảng của hai cơ sở dữ liệu:

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;

Tham khảo: từ RolandoMySQLDBA ans


Chính xác thì đây là cái gì? Một cải tiến về câu trả lời của Rolando?
ypercubeᵀᴹ

không được cải thiện nhưng để xem các thay đổi trực tiếp trong tất cả các bảng giữa hai cơ sở dữ liệu.
murtaza.webdev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.