Zapytanie MySQL pokazujące różnicę między schematem rozwoju i produkcji

Chciałbym mieć zapytanie używając bazy danych schematu w MySQL
to pokazuje różnicę między kolumnami, wyzwalaczami i procedurami składowanymi pomiędzy dwoma schematami bazy danych: produkcja i rozwój.

Zapytanie, Nie narzędzia
Widziałem porównanie dwóch baz danych MySQL
Która wymienia narzędzia, które mogą wykonać to zadanie, ale chciałbym wiedzieć, czy istnieje zapytanie , które może wykonać to zadanie.
Proszę tylko sugerować zapytania, naprawdę tak nie chcesz wiedzieć o narzędziach, hackach linii poleceń itp.

Szukam, czy baza danych produkcji i bazy danych rozwoju są zsynchronizowane.
I które pola, procedury itp., gdzie dodane lub zmienione, więc mogę zaktualizować bazę danych produkcji, jeśli wprowadzę nową aktualizację oprogramowania klienta, który korzysta z bazy danych.

Używam najnowszej wersji MySQL 5.1.

Author: Community, 2011-04-14

5 answers

Johan, spróbuj uruchomić ten skrypt. Określ dwie bazy danych, które chcesz porównać w zmiennych na początku skryptu. Zapytanie zwraca data-set i ustawia statusy dla kolumn table/view.

Status 'Only in source' - obiekt istnieje tylko w db1; Status 'Only in target' - obiekt istnieje tylko w db2; Status 'w obu schematach' - obiekt istnieje w db1 i w db2, ale szczegóły mogą być różne; na przykład: wartość 'varchar(255)/int(11)' mówi, że typem pola źródłowego jest 'varchar(255)', a docelowym jest "int (11)", wartość "null" mówi, że szczegóły są równe;

SET @source_db = 'db1';
SET @target_db = 'db2';

SELECT 
  'Only in source' exist_type,
  c1.table_schema, c1.table_name, c1.column_name, c1.ordinal_position, c1.column_default, c1.is_nullable, c1.numeric_precision, c1.numeric_scale, c1.character_set_name, c1.collation_name, c1.column_type, c1.column_key, c1.extra, c1.column_comment
FROM
  (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1
  LEFT JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name
WHERE c2.column_name is null

UNION ALL

SELECT
  'Only in target' exist_type,
  c2.table_schema, c2.table_name, c2.column_name, c2.ordinal_position, c2.column_default, c2.is_nullable, c2.numeric_precision, c2.numeric_scale, c2.character_set_name, c2.collation_name, c2.column_type, c2.column_key, c2.extra, c2.column_comment
FROM
  (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1
  RIGHT JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name
WHERE c1.column_name is null

UNION ALL

SELECT 
  'In both schemas' exist_type,
  CONCAT(c1.table_schema, '/', c2.table_schema),
  c1.table_name, c1.column_name,
  IF(c1.ordinal_position = c2.ordinal_position OR c1.ordinal_position IS NULL AND c2.ordinal_position IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.ordinal_position, ''), IFNULL(c2.ordinal_position, ''))),
  IF(c1.column_default = c2.column_default OR c1.column_default IS NULL AND c2.column_default IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_default, ''), IFNULL(c2.column_default, ''))),
  IF(c1.is_nullable = c2.is_nullable OR c1.is_nullable IS NULL AND c2.is_nullable IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.is_nullable, ''), IFNULL(c2.is_nullable, ''))),
  IF(c1.numeric_precision = c2.numeric_precision OR c1.numeric_precision IS NULL AND c2.numeric_precision IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.numeric_precision, ''), IFNULL(c2.numeric_precision, ''))),
  IF(c1.numeric_scale = c2.numeric_scale OR c1.numeric_scale IS NULL AND c2.numeric_scale IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.numeric_scale, ''), IFNULL(c2.numeric_scale, ''))),
  IF(c1.character_set_name = c2.character_set_name OR c1.character_set_name IS NULL AND c2.character_set_name IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.character_set_name, ''), IFNULL(c2.character_set_name, ''))),
  IF(c1.collation_name = c2.collation_name OR c1.collation_name IS NULL AND c2.collation_name IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.collation_name, ''), IFNULL(c2.collation_name, ''))),
  IF(c1.column_type = c2.column_type OR c1.column_type IS NULL AND c2.column_type IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_type, ''), IFNULL(c2.column_type, ''))),
  IF(c1.column_key = c2.column_key OR c1.column_key IS NULL AND c2.column_key IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_key, ''), IFNULL(c2.column_key, ''))),
  IF(c1.extra = c2.extra OR c1.extra IS NULL AND c2.extra IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.extra, ''), IFNULL(c2.extra, ''))),
  IF(c1.column_comment = c2.column_comment OR c1.column_comment IS NULL AND c2.column_comment IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_comment, ''), IFNULL(c2.column_comment, '')))
FROM
  (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1
  JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name;

Ten skrypt można modyfikować, aby znaleźć różnice między wyzwalaczami i procedurami.

 22
Author: Devart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-22 13:51:09

Wszystkie dane, których szukasz, powinny znajdować się w tabelach w bazie danych information_schema.

Możesz być w stanie zrobić porównanie z jakimś łącznikiem, który pokazuje tylko różnice, ale próba zrobienia tego w zapytaniach lub pojedynczym zapytaniu wydaje się zbyt skomplikowanym sposobem podejścia do problemu, myślę, że strzelasz sobie w stopę.

Szybkim i łatwym rozwiązaniem byłoby uzyskanie diff zawartości mysqldump --no-data każdej bazy danych lub wyciągnięcie danych z schemat informacji i diff that.

 3
Author: James C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-14 12:54:13

T1 porównaj z t2

select 
 (case t1.table_name=t2.table_name when 1 then concat(t1.table_name,"==",t2.table_name) else concat(t1.table_name,"!=",t2.table_name) end) as table_name,
 (case t1.column_name=t2.column_name when 1 then concat(t1.column_name,"==", t2.column_name) else concat(t1.column_name,"!=", t2.column_name) end) as column_name,
 (case t1.ORDINAL_POSITION=t2.ORDINAL_POSITION when 1 then concat(t1.ORDINAL_POSITION,"==", t2.ORDINAL_POSITION) else concat(t1.ORDINAL_POSITION,"!=", t2.ORDINAL_POSITION) end) as ORDINAL_POSITION
......--columns in information_schema
from columns t1 left join (select * from columns where table_schema='t2') t2 on t2.table_name=t1.table_name and t2.column_name=t1.column_name where t1.table_schema='t1'; 
Mam nadzieję, że to pomoże!!
 0
Author: Neo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-18 11:01:23

Johan już zawęziłeś odpowiadasz domenie mówiąc, że chcesz" zapytanie " do porównywania baz danych:)

Jednak moja sugestia dla Ciebie jest, aby pomyśleć o "Binary Logging". Używałem go z powodzeniem do podobnych celów.

       a) enable logs 
       b) Go through all binary logs files 
       c) grep desired statements
       d) at then end purge/reset binary logs  ie. RESET MASTER 

Oczywiście zrobisz to na produkcji db.

Inne sposoby mogą być: Jak zsynchronizować bazę danych rozwoju i produkcji

 0
Author: sakhunzai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:23:03

To stare, ale działa. Bazując na przykładzie devarta, zbudowałem porównanie dla procedur i funkcji:

SET @source_db = 'qls_projects_for_comparison';
SET @target_db = 'qls_projects';

-- Pick one and comment out the other
-- SET @routine_type = 'FUNCTION';
SET @routine_type = 'PROCEDURE';

-- Get the ones only in the source
SELECT
  'Only in SOURCE' exist_type, C1.ROUTINE_NAME, C1.ROUTINE_SCHEMA,         
C1.ROUTINE_TYPE, C1.LAST_ALTERED, C1.DEFINER as 'Source Definer', C2.DEFINER 
as     'Target Definer', def_compare as 'Compare Definitions'  
FROM (    
(SELECT *,'' as def_compare FROM INFORMATION_SCHEMA.ROUTINES WHERE 
ROUTINE_TYPE = @routine_type AND ROUTINE_SCHEMA = @source_db) C1
LEFT JOIN (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 
@routine_type AND ROUTINE_SCHEMA = @target_db) C2
ON C1.ROUTINE_NAME = C2.ROUTINE_NAME
)
WHERE C2.ROUTINE_NAME IS NULL

UNION ALL

-- Get the ones only in the target
SELECT
  'Only in TARGET' exist_type, C2.ROUTINE_NAME, C2.ROUTINE_SCHEMA,             
C2.ROUTINE_TYPE, C2.LAST_ALTERED, C1.DEFINER as 'Source Definer', C2.DEFINER 
as 'Target Definer', def_compare as 'Compare Definitions'  
FROM (    
(SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 
@routine_type AND ROUTINE_SCHEMA = @source_db) C1
RIGHT JOIN (SELECT *,'' as def_compare FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_TYPE = @routine_type AND ROUTINE_SCHEMA = @target_db) C2
ON C1.ROUTINE_NAME = C2.ROUTINE_NAME
)
WHERE C1.ROUTINE_NAME IS NULL

UNION ALL

-- Get the ones in both and compare the bodies of the routines 

SELECT 
'In both schemas' exist_type
, C2.ROUTINE_NAME
, C2.ROUTINE_SCHEMA
, C2.ROUTINE_TYPE
, C2.LAST_ALTERED
, C1.DEFINER as 'Source Definer'
, C2.DEFINER as 'Target Definer', 
IF(C1.ROUTINE_DEFINITION=C2.ROUTINE_DEFINITION, 'Matches','Does Not Match') 
as 'Compare Definitions'
FROM (    
   (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 
@routine_type AND ROUTINE_SCHEMA = @source_db) C1
  INNER JOIN (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 
@routine_type AND ROUTINE_SCHEMA = @target_db) C2
    ON C1.ROUTINE_NAME = C2.ROUTINE_NAME
)
 0
Author: fitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 21:37:26