315  /  331

Набор полей

Просмотров: 1265 (Статистика ведётся с 06.02.2017)

Необходимо исследовать наборов полей в соответствующих таблицах: какие поля есть в таблице MySQL, которых нет в таблице SQL Server и наоборот.

Собственно набор полей

use bitrix

with
col_sqlsrv as (
select t.name as tbl_name, c.name as col_name from sys.columns c join sys.tables t on c.object_id = t.object_id
)
, col_mysql as (
select * from openquery(mysql, 'select table_name tbl_name,
                        column_name col_name from information_schema.columns where table_schema = ''bsm_demo''')
)
select * from col_sqlsrv sqlsrv full outer join col_mysql mysql 
on sqlsrv.tbl_name = mysql.tbl_name and sqlsrv.col_name = mysql.col_name
where sqlsrv.col_name is null or mysql.col_name is null

Вывод. Сравнение выявило абсолютное тождество наборов полей в соответствующих таблицах. Исключением являются три таблицы в SQL Server, которых нет в варианте установки MySQL.

Порядковый номер

Также существенным фактором является совпадение порядкового номера одноименной колонки, потому что если это так, процесс переноса данных будет проще. В противном случае придется явно перечислять поля в списке в нужном порядке или строить соответствие полей источника с полями назначения.

with 
col_sqlsrv(tbl_name, col_name,  col_pos) as (
select object_name(object_id), name, column_id from sys.columns
)
, col_mysql(tbl_name, col_name,  col_pos) as (
select * from openquery(mysql, 'select table_name, column_name,
                        ordinal_position from information_schema.columns where table_schema = ''bsm_demo''')
)
select * from col_sqlsrv sqlsrv join col_mysql mysql 
on sqlsrv.tbl_name = mysql.tbl_name and sqlsrv.col_name = mysql.col_name
where sqlsrv.col_pos <> mysql.col_pos

Вывод. Порядковый номер колонки не совпадает в 80 случаях, что необходимо учитывать при переносе данных.

Соответствие типов и длины полей

Необходимо выяснить соответствие типов и длины в одноименных колонках. Этим скриптом можно получить типы колонок, использующиеся «1С-Битрикс: Управление сайтом» в случае установки на MySQL и на SQL Server:

select * from openquery(mysql, 'select distinct data_type from information_schema.columns where table_schema = ''bsm_demo''')
select distinct type_name(c.user_type_id) from sys.columns c join sys.tables t on c.object_id = t.object_id where type = 'U'

Вывод. В SQL Server типов колонок - 11, в MySQL – 16. Например, в случае инсталляции MySQL используется тип smallint, а в варианте инсталляции SQL Server он не используется. В MySQL есть разновидности блобовских типов, которых действительно нет в SQL Server, например, mediumtext, longtext. В случае SQL Server им соответствует один тип text.

«1С-Битрикс: Управление сайтом» в SQL Server использует text/image, datetime. в MySQL - тип date. Необходимо вручную построить таблицу соответствия типов, т.е. какой тип MySQL в какой тип SQL Server можно без потерь переносить.

Примечание: Если существует экземпляр типа А, который не перенесется в тип Б без обрезания или дополнительных преобразований, такой перенос считается невозможным. Все типы и в MySQL, и в SQL Server можно разбить на числовые, строковые, бинарные и календарные. Перенос внутри каждой категории считается допустимым, при этом длина поля приемника должна быть не меньше, чем у источника, а, в случае численных полей с фиксированной точкой то же распространяется и на количество знаков после запятой.

Пример запроса, который проверяет нарушения этого правила:

with 
col_sqlsrv(tbl_name, col_name, col_type, col_len, col_prec, col_scal) as (
select object_name(object_id), name, type_name(user_type_id), max_length, precision, scale from sys.columns
),
col_sqlsrv1(tbl_name, col_name, col_type, col_len, col_prec, col_scal) as (
select tbl_name, col_name, 
       case when col_type in ('bigint', 'int', 'tinyint', 'decimal', 'numeric') then 'N'
            when col_type in ('float') then 'F' 
            when col_type in ('datetime') then 'D'
            when col_type in ('char', 'varchar', 'text') then 'C'
            when col_type in ('image') then 'B' 
       end, 
       case when col_type = 'text' then power(cast(2 as bigint), 31) - 1
            else col_len
       end, 
       col_prec, col_scal from col_sqlsrv
)       
, col_mysql(tbl_name, col_name, col_type, col_len, col_prec, col_scal) as (
select * from openquery(mysql, 'select table_name, column_name, data_type, character_maximum_length, numeric_precision,
                        numeric_scale from information_schema.columns where table_schema = ''bsm_demo''')
)
, col_mysql1(tbl_name, col_name, col_type, col_len, col_prec, col_scal) as (
select tbl_name, col_name, 
       case when col_type in ('bigint', 'int', 'tinyint', 'decimal', 'smallint') then 'N'
            when col_type in ('float') then 'F' 
            when col_type in ('datetime', 'timestamp') then 'D'
            when col_type in ('char', 'varchar', 'text', 'mediumtext', 'longtext') then 'C'
            when col_type in ('longblob') then 'B' end, 
       col_len, col_prec, col_scal from col_mysql
)       
select sqlsrv.*, mysql.col_type, mysql.col_len, mysql.col_prec, mysql.col_scal from col_sqlsrv1 sqlsrv join col_mysql1 mysql 
on sqlsrv.tbl_name = mysql.tbl_name and sqlsrv.col_name = mysql.col_name 
where mysql.col_type <> sqlsrv.col_type
   or mysql.col_type = sqlsrv.col_type and mysql.col_len > sqlsrv.col_len
   or mysql.col_type = sqlsrv.col_type and (mysql.col_prec > sqlsrv.col_prec or mysql.col_scal > sqlsrv.col_scal)
order by 1, 2

Первое условие в where не нарушается, что означает, что с преобразованием типов проблем нет – числовые типы переносятся в числовые, текстовые в текстовые и т.д. Однако выявлено 128 колонок, нарушающих второе и третье условие в where. Это означает, что при переносе данных возможно возникновение ошибки из-за недостаточного размера поля приемника.

Список колонок

Примечание: Строго говоря, следует исследовать тождественность признаков NULL у соответствующих полей и других ограничений. Например, если некоторое поле допускает NULLы в MySQL, но является NOT NULL в SQL Server, перенос данных может завершиться с ошибкой. Если сразу перейти к процессу переноса данных и такие несоответствия имеются, то они будет выявлены в ходе переноса.

0
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии