记录SQL Server向MySQL数据库导入数据过程(SQL Server服务器拒绝连接解决方式、MySQL大数据批量导入)

我司现在全面切换MySQL,因此,原来部分的SQLserver的数据要导入到MySQL中。

导数据工具用的是Navicat的导入向导。

1.右击表选择 导入向导

2.选择ODBC,进入,选择SQL Server

3.输入SQL Server服务器IP 地址,输入用户名、密码,勾选 允许保存密码、输入要导入的库名字

4.测试连接。连接成功,选择要导入的表即可完成导入。

基本问题都出现在第三步,如果测试连接的时候提示SQL Server拒绝访问或者不存在。可以用如下措施排查

1.检查SQLserver服务器防火墙是否开启,如果开启了,可以暂时关闭,导完数据之后在开启

2.如果防火墙已经关闭,检查SQLserver服务器是否开启了TCP/IP连接,这个选项默认是关闭的。打开SQLserver的配置工具,找到网络配置,点击启用即可。

3.上述两步之后还是不行,需要看一下,SQLserver登录时什么模式,是window验证模式还是SQLserver验证方式。

4.开启SQLserver 验证方式,具体方法是,在SQLserver managent studio中,右击服务器,属性,安全项中点选“SQL Server和Windows身份验证模式”,点击确定。

5.还是在属性中,找到常规项,设置用户名、密码,可以设置简单点,并且把强制密码策略不勾选。

6.重启SQLsever服务器。

这时候再连接基本可以了。

部分高级Navicat版本,如Mac版的Navicat12的ODBC中没有SQLserver选项,只有用户名、密码,可以在Navicat上新建一个SQLserver的连接,然后使用另一种方式----数据传输也可以完成

完成了数据库中的表结构和表数据的迁移,还有部分工作未完成。有几个json文件的数据还没有表接收,于是新建了表,打算使用Navicat的导入向导导入。总是不成功,也没有去找原因,时间比较紧,于是使用官方的MySQL work bench 工具导入

接送数据如下:

json数据

如下图

一步步操作即可,导入后发现created和updated都是空的,由于字段类型都是datetime,并不是时间戳,所以没有办法在插入时设置为当前时间戳,于是写一个触发器,在插入之前,设置这两个字段即可。

CREATE TRIGGER 触发器名字 BEFORE INSERT ON area_province_gb FOR EACH ROW
BEGIN
SET new.created = NOW();
SET new.updated = NOW();
END;

重新导入一次,数据全部正常了。

于是想在深入点,了解一下MySQL的导入和导出

导出:官方有select * from tablename into outfile '/导出文件地址'  fields terminated by ",";例如

select * from city into outfile '/usr/local/mysql8/city.txt' fields terminated by ",";

将city的表导入到city.txt中,字段之间用 逗号分隔,默认使用制表符分隔。

导出时要注意,如果提示这种错误

--secure-file-priv option so it cannot execute

首先执行:

SHOW VARIABLES LIKE '%secure%'

查看secure_file_priv是不是NULL,如果不是,你的导出路径要设置为查出来的值,如果是NULL,你可以在my.cnf中mysqld下配置你想要存储的路径即可,这个路径一定要是mysql用户组也要具备的权限(切记切记切记),否则依旧会提示错误

errno 13 - Permission denied

你也可以配置为 secure_file_priv= ,这种就是随便你往哪里导入都行,前提是mysql的用户组具备这个目录的写权限,否则依旧会提示错误。

配置完了之后重启MySQL即可。

在此期间出现了一个小插曲:

由于修改my.cnf的时候系统提示只可读,不可以写,于是我将my.cnf文件的权限改为所有可读可写,但是还是不行,因为他的上一级目录还是只读的,于是又把上一级的文件夹改为所有人可读可写。

但是在重启的时候,提示我

World-writable config file ‘/etc/my.cnf’ is ignored

后来发现,这是MySQL的一个策略,MySQL的文件夹是不允许所有人可读可写的,否则就会出现这种错误,关不了或者启动不了。于是又把刚才改的所有权限改回去,重启之后再执行导出,导出到mysql用户组具备的权限的目录下。

导入:

load data infile '文件地址' into table tablename fields terminated by ',';例子如下:

load data infile '/usr/local/mysql8/city.txt' into table city fields terminated by ',';

 将city.txt文件里的数据导入到city表中。

10几万的数据一秒之内分分钟搞定,很快的。

注意:

1、如果是本地文件向服务器上的MySQL导入,那么需要加上LOCAL 参数

命令就变成了

load data LOCAL infile '/usr/local/mysql8/city.txt' into table city fields terminated by ',';

2、如果导入的数据中存在字符串、数字,但是只有字符串是用""包起来的,那么可以加入[FIELDS/COLUMS] optionally enclosed by '具体的符号',

命令变成了

load data LOCAL infile '/usr/local/mysql8/city.txt' into table city fields terminated by ',',optionally enclosed by '"';

因为前面已经有了fields了,所以在optionally前面就不需要加fields标识了

3、如果数据库中已存在了部分数据,而此时导入的数据中也存在了和数据库一样的数据,唯一约束是一致的,主键或者唯一索引一致,那么默认情况下,MySQL导入的时候是不会导入这部分相同的数据的(也就是默认的参数IGNORE),如果,想要导入的数据替换数据库中已存在的数据,则使用REPLACE参数

命令变成了

load data LOCAL infile REPLACE '/usr/local/mysql8/city.txt' into table city fields terminated by ',',optionally enclosed by '"';

4、如果只想导入导入数据的部分列,或者在导入的时候设置一些列的默认值,则可以在导入命令最后设置,一定是放在最后的位置

命令变成了

load data LOCAL infile REPLACE '/usr/local/mysql8/city.txt' into table city fields terminated by ',',optionally enclosed by '"' (name,age,gender,created) set created = now();

5、在导入的时候,需要告知MySQL,区分一条数据的分隔符是什么,使用 LINES terminated by ''

命令变成了

load data LOCAL infile REPLACE '/usr/local/mysql8/city.txt' into table city fields terminated by ',',optionally enclosed by '"', Lines terminated by '\r' (name,age,gender,created) set created = now();

综上所述:

将本地文件导入服务器的MySQL实例中,

对重复数据采用更新数据的方式,

每条数据以换行符作为分隔标志,

每个字段以逗号作为分隔标志,

对于数据中的字符串使用双引号进行区分,

只导入name,age,genter这三列,对数据库中的created设置默认值为当前时间

 

 

到此为止MySQL的导入和导出基本完成。上面的两种方式还有许多参数没介绍,有兴趣的可以去官方文档了解下。

官方也提供了mysqldump和mysqlimport这两种,其实和上面的一样,有兴趣的可以了解下。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章