Perl MSSQL 에 접근 하여 MySQL 데이터베이스 스 크 립 트 인 스 턴 스 로 이전
using DBI;
my $cs = "DRIVER={FreeTDS};SERVER= ;PORT=1433;DATABASE= ;UID=sa;PWD= ;TDS_VERSION=7.1;charset=gb2312";
my $dbh = DBI->connect("dbi:ODBC:$cs") or die $@;
본인 은 windows 를 잘 사용 하지 않 기 때문에 QQ 군 데이터 베 이 스 를 연구 하기 위해 데 이 터 를 MSSQL 에서 MySQL 로 옮 겨 야 한다.특히 QQ 군 데이터 베 이 스 를 위해 Windows Server 2008 과 SQL Server 2008 r2 를 설치 했다.그러나 며칠 후 평가 가 만 료 되 었 습 니 다.MySQL 의 Workbench 는 MS SQL Server 에서 데 이 터 를 이전 하 는 능력 이 있 습 니 다.그러나 QQ 군 과 같은 거대 한 데이터 와 분 표 라 이브 러 리 의 데이터 에 있어 서 너무 번 거 로 워 서 통용 되 는 perl 스 크 립 트 를 썼 습 니 다.데이터 베 이 스 를 MSSQL 에서 MySQL 로 이전 하고 bash 와 결합 합 니 다.이 20 여 개의 라 이브 러 리 에 있 는 백 장의 시 계 를 편리 하 게 옮 겼 습 니 다.Perl 코드 는 다음 과 같 습 니 다
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
die "Usage: qq db
" if @ARGV != 1;
my $db = $ARGV[0];
print "Connectin to databases $db...
";
my $cs = "DRIVER={FreeTDS};SERVER=MSSQL ;PORT=1433;DATABASE=$db;UID=sa;PWD=MSSQL ;TDS_VERSION=7.1;charset=gb2312";
sub db_connect
{
my $src = DBI->connect("dbi:ODBC:$cs") or die $@;
my $target = DBI->connect("dbi:mysql:host=MySQL ", "MySQL ", "MySQL ") or die $@;
return ($src, $target);
}
my ($src, $target) = db_connect;
print "Reading table schemas....
";
my $q_tables = $src->prepare("SELECT name FROM sysobjects WHERE xtype = 'U' AND name != 'dtproperties';");#
my $q_key_usage = $src->prepare("SELECT TABLE_NAME, COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE;");#
$q_tables->execute;
my @tables = ();
my %keys = ();
push @tables, @_ while @_ = $q_tables->fetchrow_array;
$q_tables->finish;
$q_key_usage->execute();
$keys{$_[0]} = $_[1] while @_ = $q_key_usage->fetchrow_array;
$q_key_usage->finish;
#
my $q_index = $src->prepare(qq(
SELECT T.name, C.name
FROM sys.index_columns I
INNER JOIN sys.tables T ON T.object_id = I.object_id
INNER JOIN sys.columns C ON C.column_id = I.column_id AND I.object_id = C.object_id;
));
$q_index->execute;
my %table_indices = ();
while(my @row = $q_index->fetchrow_array)
{
my ($table, $column) = @row;
my $columns = $table_indices{$table};
$columns = $table_indices{$table} = [] if not $columns;
push @$columns, $column;
}
$q_index->finish;
# MySQL
$target->do("DROP DATABASE IF EXISTS `$db`;") or die "Cannot drop old database $db
";
$target->do("CREATE DATABASE `$db` DEFAULT CHARSET = utf8 COLLATE utf8_general_ci;") or die "Cannot create database $db
";
$target->disconnect;
$src->disconnect;
my $total_start = time;
for my $table(@tables)
{
my $pid = fork;
unless($pid)
{
($src, $target) = db_connect;
my $start = time;
$src->do("USE $db;");
# , MySQL DDL
my $q_schema = $src->prepare("SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ? ORDER BY ORDINAL_POSITION;");
$target->do("USE `$db`;");
$target->do("SET NAMES utf8;");
my $key_column = $keys{$table};
my $ddl = "CREATE TABLE `$table` (
";
$q_schema->execute($table);
my @fields = ();
while(my @row = $q_schema->fetchrow_array)
{
my ($column, $nullable, $datatype, $length) = @row;
my $field = "`$column` $datatype";
$field .= "($length)" if $length;
$field .= " PRIMARY KEY" if $key_column eq $column;
push @fields, $field;
}
$ddl .= join(",
", @fields);
$ddl .= "
) ENGINE = MyISAM;
";
$target->do($ddl) or die "Cannot create table $table
";
#
my $indices = $table_indices{$table};
if($indices)
{
for(@$indices)
{
$target->do("CREATE INDEX `$_` ON `$table`(`$_`);
") or die "Cannot create index on $db.$table$.$_
";
}
}
#
my @placeholders = map {'?'} @fields;
my $insert_sql = "INSERT DELAYED INTO $table VALUES(" .(join ', ', @placeholders) . ");
";
my $insert = $target->prepare($insert_sql);
my $select = $src->prepare("SELECT * FROM $table;");
$select->execute;
$select->{'LongReadLen'} = 1000;
$select->{'LongTruncOk'} = 1;
$target->do("SET AUTOCOMMIT = 0;");
$target->do("START TRANSACTION;");
my $rows = 0;
while(my @row = $select->fetchrow_array)
{
$insert->execute(@row);
$rows++;
}
$target->do("COMMIT;");
# ,
my $elapsed = time - $start;
print "Child process $$ for table $db.$table done, $rows records, $elapsed seconds.
";
exit(0);
}
}
print "Waiting for child processes
";
#
while (wait() != -1) {}
my $total_elapsed = time - $total_start;
print "All tasks from $db finished, $total_elapsed seconds.
";
이 스 크 립 트 는 모든 표 fork 에 따라 키 프로 세 스 와 해당 하 는 데이터 베 이 스 를 연결 합 니 다.따라서 이 이전 을 하기 전에 목표 MySQL 데이터베이스 설정 의 최대 연결 수 를 확보 해 야 합 니 다.그리고 bash 에서 실행 합 니 다
for x in {1..11};do ./qq.pl QunInfo$x; done
for x in {1..11};do ./qq.pl GroupData$x; done
스 크 립 트 는 MSSQL 이쪽 표 구조 에 따라 MySQL 쪽 에서 같은 구 조 를 만 들 고 색인 을 설정 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
cowsay로 현장 고양이에 요시! 되고 싶은 건업무 중에도 현장 고양이에 요시! 하고 싶었기 때문에, cowsay 를 사용해 어떻게든 해 보았습니다. cowsay는 말할 것도없이 오징어 한 서버에 적합한 매혹적인 도구입니다. 살벌한 우리 마음에 일복의 청량을 줍...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.