Запрос MySQL, чтобы показать разницу между схемой разработки и производства
Я хотел бы иметь запрос с использованием базы данных схемы в MySQL
это показывает разницу между столбцами, триггерами и хранимыми процедурами между двумя схемами базы данных: производство и разработка.
запрос, а не инструменты
Я видел сравните две базы данных MySQL
Перечислены инструменты, которые могут выполнять эту задачу, но я хотел бы знать, если есть запрос что может выполнить эту задачу.
Пожалуйста только предлагать запросы,Я действительно не хочу знать об инструментах командной строки хаки или такие.
Я ищу, чтобы увидеть, если производственная база данных и база данных разработки не синхронизированы.
И какие поля, процедуры и т. д. добавлены или изменены, поэтому я могу обновить производственную базу данных, если я разверну новое обновление клиентского программного обеспечения, которое использует базу данных.
Я использую последнюю версию MySQL 5.1.
5 ответов
Йохан, попробуй запустить этот скрипт. Укажите две базы данных, которые вы хотите сравнить в переменных в начале сценария. Запрос возвращает набор данных и задает состояния для столбцов таблицы/представления.
Status 'Only in source' - объект существует только в db1; Статус "только в target" - объект существует только в db2; Состояние "в обеих схемах" - объект существует в db1 и db2, но детали могут быть разными; например: значение "varchar (255)/int (11)" говорит, что тип исходного поля - "varchar (255)" и цель - " int (11)", значение "null" говорит, что детали равны;
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;
этот скрипт можно изменить, чтобы найти различия между триггерами и подпрограммами.
T1 сравнить с 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';
надеюсь, что это поможет!!
Йохан вы уже сузили домен ответа, сказав, что хотите" запрос " для сравнения баз данных:)
однако мое предложение для вас-подумать о" двоичном журнале". Я успешно использовал его для подобных целей.
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
очевидно, вы сделаете это на производственной БД.
другие способы могут быть:как синхронизировать базу данных разработки и производства
Это старый, но он работает. Основываясь на примере деварта, я пошел вперед и построил сравнение для процедур и функций:
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
)