MySQL兼容SQL-92吗?

6

前几天我试图使用标准语法在mysql中创建表:

create table client(
    rc character varying(11)
    constraint client_pk primary key 
);

然而,MySQL不支持以这种方式设置主键。(我99%确定它符合sql-92标准)。所以我的问题是:MySQL是否连20年前的标准基础都不支持,还是我漏掉了什么?编辑:我的目标不是使用某种MySQL方言创建此表,而是使用标准化语法创建此表。问题是是否可能。

我不太同意 :) 当然你必须指定主键属于哪个(些)字段,但是既然我在 rc 字段后面没有写逗号,约束应该会自动应用到这个字段上。 - Novellizator
啊,抱歉。没有注意到。MySQL不支持这个(即使它支持:你也不能指定主键约束的名称)。 - user330315
1
MySQL只识别SQL-92标准语法的一个子集;而且在它所接受的子集中,有些语法可能会导致行为与SQL-92规范不符。因此,MySQL在某种程度上是兼容的,但在一些关键领域也是不符合规范的。文档的一个完整部分专门介绍了这些关键的“差异”,并且这取决于MySQL的版本。对于MySQL 5.5,请参见:http://dev.mysql.com/doc/refman/5.5/en/compatibility.html - spencer7593
3个回答

6
回答你的问题,MySQL不完全符合SQL-92规范,因为MySQL仅支持规范的子集,并且MySQL具有一些重要(有用的)扩展,这些扩展不是SQL-92规范的一部分。
这不仅仅涉及MySQL接受和识别的SQL语法,更重要的是MySQL实际上对语法执行的操作,MySQL使用它接受的语法执行的实际操作。这比MySQL识别哪些语法更加重要。
并不是MySQL懒惰,也不是MySQL不在意。
MySQL文档中有一个整个章节专门讲解MySQL与SQL标准的区别。最重要的差异并不是语法问题,而是"MySQL在某些情况下以不同方式执行操作"。
例如,MySQL接受CHECK约束的语法,但MySQL实际上不会检查或尝试执行CHECK约束。MySQL接受满足SQL-92规范的语法,但MySQL的行为与其他接受相同语法的数据库完全不同。
另一个例子是,MySQL在处理FOREIGN KEY约束时的行为存在显著差异,取决于表的存储引擎是MyISAM还是InnoDB。
为了使CREATE TABLE语句在MySQL中执行,您需要进行更改。
对于您来说,最简单的选择似乎是从sql文本中删除'constraint client_pk'。您可以在列定义中指定表约束:
create table client(
   rc character varying(11) primary key 
);

或者单独声明表约束。
create table client(
   rc character varying(11),
   primary key (rc)
);

这两种形式完全符合SQL-92规范。

注意,当约束的声明不在列上时(例如),MySQL确实接受约束名定义的语法。

create table client(
   rc character varying(11),
   constraint client_pk primary key (rc)
);

这种语法也完全符合SQL-92规范。

但请注意,MySQL会忽略提供的约束名,并将名称“PRIMARY”赋予主键约束。即使约束在单独的ALTER TABLE语句中声明,这也是正确的。

请注意,MySQL接受的语法以及它执行的某些操作取决于特定的MySQL变量设置,特别是sql_mode以及在您的语句中特别关注的default-storage-engine变量的设置,以及是否使用MyISAM引擎或InnoDB引擎创建此表,甚至是当default-storage-engine设置为BLACKHOLE的特殊情况。

我了解您的目标是“使用标准化语法创建此表”。

但我认为您确实需要关注MySQL特定语法的至少一些最小子集,因为MySQL在面对“标准化语法”时可能会展现出多种可能的行为。考虑以下内容:

SET default-storage-engine = 'MyISAM' ;
SET default-storage-engine = 'InnoDB' ;
SET sql_mode = '' ; 
SET sql_mode = 'ANSI' ; 

这很有趣。因此,MySQL接受和支持的内容存在很大差异(以我们想要的方式)。一个问题:为什么MySQL不支持一些非常重要的完整性参数(比如你提到的CHECK或ON CASCADE DELETE...)?我的意思是,这是某种缺陷(可能在未来出现),还是某种(奇怪的)特性? - Novellizator
@Novellizator:这些差异不是MySQL实现中的缺陷或缺点,而是MySQL达到其指定设计目标的结果。旧版本的MySQL不接受一些“标准”语法,这给试图从其他DBMS(例如Oracle)“导入”定义的用户带来了困难。我认为“从外部数据库导入模式”的问题是新版本MySQL接受额外语法的主要驱动力之一,它基本上会忽略这些语法。MySQL为未来的实现留下了空间... - spencer7593

2

您不需要一个名为client_pk的列。这应该是约束的名称。语法符合SQL-92标准的,它是一个列级约束:http://savage.net.au/SQL/sql-92.bnf.html#column%20definition - user330315
啊,感谢@a_horse_with_no_name指出这一点。我经常使用不同的数据库(DB2和MySQL),因此我一直在努力使用有效的SQL-92语法来执行SQL代码以针对任何数据库。然而,我们从未使用“原始”的SQL语句在这两个系统上创建表格,它们总是以其他方式创建,所以我对CREATE语法不太熟悉。 - Benny Hill

1
create table tablename
(
    column_Name varchar(20) not null,
    column_Name varchar(20),
    primary key(column_name)
);

以此方式您可以创建表并设置主键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接