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.
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.
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.
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!!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
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
)
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