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是分号 ; 。
DELIMITER $$
DROP TRIGGER IF EXISTS `updateegopriceondelete`$$
CREATE
TRIGGER `updateegopriceondelete` AFTER DELETE ON `customerinfo`
FOR EACH ROW BEGIN
DELETE FROM egoprice WHERE customerId=OLD.customerId;
END$$
DELIMITER ;
其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";".
在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。如输入下面的语句 select * from test_table;
然后回车,那么MySQL将立即执行该语句。
但有时候,不希望MySQL这么做。在为可能输入较多的语句,且语句中包含有分号。如试图在命令行客户端中创建函数或存储过程时
mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
mysql> RETURNS varchar(255)
mysql> BEGIN
mysql> IF ISNULL(S) THEN
mysql> RETURN '';
mysql> ELSEIF N<15 THEN
mysql> RETURN LEFT(S, N);
mysql> ELSE
mysql> IF CHAR_LENGTH(S) <=N THEN
mysql> RETURN S;
mysql> ELSE
mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
mysql> END IF;
mysql> END IF;
mysql> END;
默认情况下,不可能等到用户把这些语句全部输入完之后,再执行整段语句。 因为mysql一遇到分号,它就要自动执行。 即,在语句RETURN '';时,mysql解释器就要执行了。 这种情况下,就需要事先把delimiter换成其它符号,如//或$$。
mysql> delimiter //
mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
mysql> RETURNS varchar(255)
mysql> BEGIN
mysql> IF ISNULL(S) THEN
mysql> RETURN '';
mysql> ELSEIF N<15 THEN
mysql> RETURN LEFT(S, N);
mysql> ELSE
mysql> IF CHAR_LENGTH(S) <=N THEN
mysql> RETURN S;
mysql> ELSE
mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
mysql> END IF;
mysql> END IF;
mysql> END;//
这样只有当//出现之后,mysql解释器才会执行这段语句。 默认情况下,delimiter “;” 用于向 MySQL 提交查询语句。在存储过程中每个 SQL 语句的结尾都有个 “;”,如果这时候,每逢 “;” 就向 MySQL 提交的话,当然会出问题了。于是更改 MySQL 的 delimiter:
delimiter //; -- 改变 MySQL delimiter 为:“//”
drop procedure if exists pr_stat_agent //
-- call pr_stat_agent ('2008-07-17', '2008-07-18')
create procedure pr_stat_agent
(
pi_date_from date
,pi_date_to date
)
begin
-- check input
if (pi_date_from is null) then
set pi_date_from = current_date();
end if;
if (pi_date_to is null) then
set pi_date_to = pi_date_from;
end if;
set pi_date_to = date_add(pi_date_from, interval 1 day);
-- stat
select agent, count(*) as cnt
from apache_log
where request_time >= pi_date_from
and request_time < pi_date_to
group by agent
order by cnt desc;
end; //
delimiter ; // -- 改回默认的 MySQL delimiter:“;”
即
mysql> delimiter // -- 末尾不要符号 “;”
mysql>
mysql> drop procedure if exists pr_stat_agent //
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> -- call pr_stat_agent ('2008-07-17', '2008-07-18')
mysql>
mysql> create procedure pr_stat_agent
-> (
-> pi_date_from date
-> ,pi_date_to date
-> )
-> begin
-> -- check input
-> if (pi_date_from is null) then
-> set pi_date_from = current_date();
-> end if;
->
-> if (pi_date_to is null) then
-> set pi_date_to = pi_date_from;
-> end if;
->
-> set pi_date_to = date_add(pi_date_from, interval 1 day);
->
-> -- stat
-> select agent, count(*) as cnt
-> from apache_log
-> where request_time >= pi_date_from
-> and request_time < pi_date_to
-> group by agent
-> order by cnt desc;
-> end; //
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> delimiter ; -- 末尾不要符号 “//”
mysql>
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删除存在外键约束的数据
在删除具有外键约束的数据时,很容易报错:
ERROR 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浏览更多优质原创内容。