6

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

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

但是,mysql 不支持以这种方式设置主键。(我 99% 确定它符合 sql-92 规范)所以我的问题是:MySQL 是否无法支持 20 年前的标准中的这些基本内容,还是我遗漏了什么?

编辑:我的目标不是使用某些 mysql 方言创建此表,而是使用标准化语法创建此表。问题是这是否可能。

4

3 回答 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 中执行,您需要更改它。

看起来最简单的选择是constraint client_pk从 sql 文本中删除。您可以在列定义中指定表约束:

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_modedefault-storage-engine该表是使用MyISAM引擎还是InnoDB引擎创建,甚至是默认存储引擎设置为的极端情况BLACKHOLE

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

但我认为您确实需要关注 MySQL 特定语法的至少一些最小子集,就 MySQL 在“标准化语法”呈现时可能表现出的各种可能行为而言。考虑:

SET default-storage-engine = 'MyISAM' ;
SET default-storage-engine = 'InnoDB' ;
SET sql_mode = '' ; 
SET sql_mode = 'ANSI' ; 
于 2013-02-15T16:28:08.413 回答
2

这在 MySQL 5.5.29 中对我有用:

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

但是,正如 a_horse_with_no_name 指出的那样,MySQL 忽略了该client_pk名称并调用它PRIMARY

参考:

http://savage.net.au/SQL/sql-92.bnf.html

http://owen.sj.ca.us/~rk/howto/sql92.html

于 2013-02-15T13:54:59.957 回答
1
create table tablename
(
    column_Name varchar(20) not null,
    column_Name varchar(20),
    primary key(column_name)
);

通过这种方式,您可以创建表并设置主键。

于 2013-02-15T13:48:03.960 回答