1.MySQL创建数据表时设定引擎并添加外键约束
创建两个数据表,在它们之间添加外键约束,然后在被添加外键的表中添加数据,发现并没有提示报错,很正常地插入了数据,说明外键没有添加成功,在SQL可视化工具里查看表的属性,并点击外部键会出现弹窗,提示是因为引擎的问题,导致不能添加外键。MySQL安装时默认用的表引擎是MyISAM,而MyISAM是不支持外键的,如图,
要想解决这个问题,可以在当前的表设置引擎为InnoDB、PBXT或SolidDB,但这只是修改了这一个数据库,下次建新的数据库默认引擎还是MyISAM,我们可以在MySQL的安装目录下的配置文件my.ini中的 [mysqld] 下面加入default-storage-engine=INNODB(其他支持外键的引擎也可)保存,再重启Mysql服务器即可,小编在这块也遇到了问题,很久都没能解决,最后请教老师成功解决了。
可参考https://blog.csdn.net/renwudao24/article/details/52136955。
以更改 Mysql 默认引擎为 InnoDB为例步骤如下:
- 查看Mysql存储引擎情况: mysql>show engines,结果是: InnoDB | YES,说明此Mysql数据库服务器支持InnoDB引擎;
- 设置InnoDB为默认引擎:在配置文件my.ini中的 [mysqld] 下面加入default-storage-engine=INNODB;
- 重启Mysql服务器;
- 登录Mysql数据库,mysql>show engines 如果出现 InnoDB |DEFAULT,则表示设置InnoDB为默认引擎成功。
2.delimiter 详解
作用是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号 ; 。
1DELIMITER $$ 2DROP TRIGGER IF EXISTS `updateegopriceondelete`$$ 3CREATE 4 TRIGGER `updateegopriceondelete` AFTER DELETE ON `customerinfo` 5 FOR EACH ROW BEGIN 6DELETE FROM egoprice WHERE customerId=OLD.customerId; 7 END$$ 8DELIMITER ;
其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";".
在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。如输入下面的语句 select * from test_table; 然后回车,那么MySQL将立即执行该语句。
但有时候,不希望MySQL这么做。在为可能输入较多的语句,且语句中包含有分号。如试图在命令行客户端中创建函数或存储过程时
1mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT) 2mysql> RETURNS varchar(255) 3mysql> BEGIN 4mysql> IF ISNULL(S) THEN 5mysql> RETURN ''; 6mysql> ELSEIF N<15 THEN 7mysql> RETURN LEFT(S, N); 8mysql> ELSE 9mysql> IF CHAR_LENGTH(S) <=N THEN 10mysql> RETURN S; 11mysql> ELSE 12mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5)); 13mysql> END IF; 14mysql> END IF; 15mysql> END;
默认情况下,不可能等到用户把这些语句全部输入完之后,再执行整段语句。 因为mysql一遇到分号,它就要自动执行。 即,在语句RETURN '';时,mysql解释器就要执行了。 这种情况下,就需要事先把delimiter换成其它符号,如//或$$。
1mysql> delimiter // 2mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT) 3mysql> RETURNS varchar(255) 4mysql> BEGIN 5mysql> IF ISNULL(S) THEN 6mysql> RETURN ''; 7mysql> ELSEIF N<15 THEN 8mysql> RETURN LEFT(S, N); 9mysql> ELSE 10mysql> IF CHAR_LENGTH(S) <=N THEN 11mysql> RETURN S; 12mysql> ELSE 13mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5)); 14mysql> END IF; 15mysql> END IF; 16mysql> END;//
这样只有当//出现之后,mysql解释器才会执行这段语句。 默认情况下,delimiter “;” 用于向 MySQL 提交查询语句。在存储过程中每个 SQL 语句的结尾都有个 “;”,如果这时候,每逢 “;” 就向 MySQL 提交的话,当然会出问题了。于是更改 MySQL 的 delimiter:
1delimiter //; -- 改变 MySQL delimiter 为:“//” 2 3drop procedure if exists pr_stat_agent // 4 5-- call pr_stat_agent ('2008-07-17', '2008-07-18') 6 7create procedure pr_stat_agent 8( 9 pi_date_from date 10 ,pi_date_to date 11) 12begin 13 -- check input 14 if (pi_date_from is null) then 15 set pi_date_from = current_date(); 16 end if; 17 18 if (pi_date_to is null) then 19 set pi_date_to = pi_date_from; 20 end if; 21 22 set pi_date_to = date_add(pi_date_from, interval 1 day); 23 24 -- stat 25 select agent, count(*) as cnt 26 from apache_log 27 where request_time >= pi_date_from 28 and request_time < pi_date_to 29 group by agent 30 order by cnt desc; 31end; // 32 33delimiter ; // -- 改回默认的 MySQL delimiter:“;”
即
1mysql> delimiter // -- 末尾不要符号 “;” 2mysql> 3mysql> drop procedure if exists pr_stat_agent // 4Query OK, 0 rows affected (0.00 sec) 5 6mysql> 7mysql> -- call pr_stat_agent ('2008-07-17', '2008-07-18') 8mysql> 9mysql> create procedure pr_stat_agent 10 -> ( 11 -> pi_date_from date 12 -> ,pi_date_to date 13 -> ) 14 -> begin 15 -> -- check input 16 -> if (pi_date_from is null) then 17 -> set pi_date_from = current_date(); 18 -> end if; 19 -> 20 -> if (pi_date_to is null) then 21 -> set pi_date_to = pi_date_from; 22 -> end if; 23 -> 24 -> set pi_date_to = date_add(pi_date_from, interval 1 day); 25 -> 26 -> -- stat 27 -> select agent, count(*) as cnt 28 -> from apache_log 29 -> where request_time >= pi_date_from 30 -> and request_time < pi_date_to 31 -> group by agent 32 -> order by cnt desc; 33 -> end; // 34Query OK, 0 rows affected (0.00 sec) 35 36mysql> 37mysql> delimiter ; -- 末尾不要符号 “//” 38mysql>
3.MySQL清空表之后设置id从1开始自增
我们都知道,在手动清空一个表中的数据后,再添加数据id会从之前数据的id开始自增而不会从1开始自增,这在有时候会显得不友好,因此可以通过执行命令使之从1开始自增,有两种情况:
- 数据已清空
在数据已清空的情况下可以执行
alter table table_name auto_increment=1;或者truncate table_name;来使再次添加数据时id从1开始自增。 - 数据为清空
数据为清空,而要使清空后数据可以从1开始自增,可以直接执行命令
truncate table_name;即可,因为truncate语句本身就是用来删除、截断表里的所有数据,并且相比于delete语句性能更好,还能使id从1开始自增。
4.MySQL删除存在外键约束的数据
在删除具有外键约束的数据时,很容易报错:
1ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
这是因为存在外键关系时,不同的表之间或表内部存在字段之间的约束,导致不能删除,要想强制删除数据,可以通过执行命令SET FOREIGN_KEY_CHECKS = 0;临时解除数据间的约束,然后再删除要删除的表数据。
在删除数据之后,可以通过执行命令SET FOREIGN_KEY_CHECKS = 1;来还原约束(当然,也可以不执行这一步,因为这个设置是基于Session的,当你关闭了你所使用的客户端之后,下次再重新建立连接的时候,变量会恢复默认值)。
本文原文首发来自博客专栏数据库编程,由本人转发至https://www.helloworld.net/p/2QLT76hvgFAD,其他平台均属侵权,可点击https://blog.csdn.net/CUFEECR/article/details/103430520查看原文,也可点击https://blog.csdn.net/CUFEECR浏览更多优质原创内容。
