MySQL基本语法(一):和SQL Server语法的差异小归纳

因为一早就接触过SQL Server,所以对sql server的语法比较熟悉,后来转学mysql,还有些不适应,所以大致总结了一些mysql和sql server语法不同的地方,其中借鉴了些此文中的内容。

因为本文是SQL server和mysql语法差异性的总结,所以内容比较杂,没什么逻辑也不详细,还请见谅。在后面的文章中将只说明MySQL的语法。

1. 和SQL server语法主要不同的地方

1.1 大小写敏感性

MySQL和SQL Server一样,对大小写不敏感。但不同的是,在MySQL中对部分对象的引用是大小写敏感的,如数据库名、表名,但对字段、索引、函数、存储过程等的引用不敏感。

1.2 注释符

在MySQL中支持三种注释方法:以下都可以是行内注释。

  1. 使用#作为开头,后面的全是注释。
  2. 使用--作为注释开头,但要注意,MySQL中这种注释方法和SQL Server等其他标准数据库注释语法稍有不同,MySQL要求第二个短线后面必须跟一个空白字符,如空格、制表符等。
  3. 使用/**/注释符。

1.3 自增列

MySQL中设置自增列(auto_increment)的列必须是有索引的列,且创建表时要显式指定的种子值需要在建表语句之后。另外MySQL一张表只能有一个自增列。且MySQL中向自增列插入数据时必须使用null来表示插入的是自增列,除非显式指定插入列表中不包含自增列,而SQL Server向自增列插入数据时可以且必须无视该列,除非设置显示插入模式。

-- SQL Server直接使用identity,但必须有非自增列之外的列才能插入,除非显式开启手动插入自增列
create table emp1(id int not null identity(1,2),name CHAR(20));
insert into emp1 VALUES('malongshuai');
insert into emp1 values('gaoxiaofang');
select * from emp1; 

-- MySQL中自增列必须为索引列,并且只能设置种子值而不能直接设置步长
create table emp1(id int not null primary key AUTO_INCREMENT);
create table emp2(id int not null primary key AUTO_INCREMENT) auto_increment=100;
insert into emp1 values(null);
insert into emp2 values(null);

设置自增列的步长,分为全局级别和会话级别。但它们都是临时生效的,重启实例后效果就消失,要永久生效可以将其写入配置文件中。如果是会话级别,那么当用户新建一个会话的时候,那么步长又回到了全局级别。

mysql不能设置为表级别的步长!!

设置和查看全局和会话级别的变量时,分别使用如下语句:

set [session] auto_increment_increment=100;  -- 会话级的步长设置
set global auto_increment_offset=12;         -- 全局级的种子值
show [session] variables like 'auto_inc%';
show global variables like 'auto_inc%';

这两个变量都有session级和global级。其中auto_increment_offset项为起始计算项,auto_increment_increment项为步长项。它们的处理模式和SQL server的处理方式相差甚远。当同时设置了这两个变量时,如果offsert设置的值大于increment的值,则offset将被忽略,且MySQL会以"offset+N\*increment"计算下一条插入的记录值。例如,"offset=3、increment=5",当前表的最后一个自增列值为13,则下一条插入的自增值为18,因为"offset+N\*increment"将计算得到[3,8,13,18,23,28...]序列,所以从序列中挑出大于且最接近当前最后一个值13的项,即18。

以上言论为官方手册上的解释(原文:the next value inserted is the least value in the series that is greater than the maximum existing value in the AUTO_INCREMENT column),但实际上并不标准,更准确的说法是:根据当前offset和increment计算增长序列,并从中挑出大于或等于原序列的下一个值。例如上面offset=3,生成的序列为[3,8,13,18,23...],下一个要插入的值为18,但插入之前如果将offset改为4,则新的序列为[4,9,14,19,24],那么它将插入19,而不是14,尽管14大于当前最后一个记录值13。同理,如果将offset改小,例如设置为2,则序列为[2,7,12,17,22],那么下一个插入的值将是22。同理,修改increment也是一样计算的。

问:如果有一张表,里面有个字段为id的自增主键,当已经向表里面插入了10条数据之后,删除了id为8、9、10的数据,再把mysql重启,之后再插入一条数据,那么这条数据的id值应该是多少,是8还是11?

答:是11。但是在老版本中,innodb存储引擎的表会是8,这是innodb的bug,在后来修复了,只是在mysql5.6中没有了。更简单地说,在未修复之前,auto_increment的值来自于内存中的自增计数器,当停止服务后,内存中的计数器就消失了,在重启时,auto_increment的值会根据表中已有的值进行初始化。当修复该功能之后,auto_increment计数器的值会持久化。对于MariaDB而言,则是从MariaDB 10.2.4开始持久化的。

查看当前自增值的方法:

show table status like "table_name_string";   -- 查看某个表的下一个自增值
select last_insert_id();   -- 查看当前环境下最后一次自增列的插入值

关于"last_insert_id"函数,在下一篇文章"内置函数"中再做介绍。

1.4 查看表的属性

-- SQL Server使用存储过程sp_help
exec sp_help emp;

-- MySQL使用desc描述或者使用show
mysql> desc emp1;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
+-------+---------+------+-----+---------+----------------+

mysql> show table status like 'emp1'\G
*************************** 1. row ***************************
           Name: emp1
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 1
 Avg_row_length: 16384
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 2
    Create_time: 2017-03-22 10:05:49
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)

1.5 修改表名

-- SQL Server使用存储过程sp_rename
EXEC sp_rename emp,emp2 [object]

-- mysql使用alter语句中的rename功能
alter table emp rename [to] emp3;

1.6 删除表

在删除表方面,MySQL比SQL Server要方便很多,判断起来也方便很多。

-- SQL Server删除表,每次只能删除一张表
if object_id('table_name') is not null 
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值