首先,引用官方文档上的语法:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
[IGNORE | REPLACE]
[AS] query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
create_definition:
col_name column_definition
| {INDEX|KEY} [index_name] [index_type] (key_part,...)
[index_option] ...
| {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] PRIMARY KEY
[index_type] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
[index_name] [index_type] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name,...)
reference_definition
| CHECK (expr)
column_definition:
data_type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[COLLATE collation_name]
[COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
[STORAGE {DISK|MEMORY|DEFAULT}]
[reference_definition]
| data_type
[COLLATE collation_name]
[GENERATED ALWAYS] AS (expr)
[VIRTUAL | STORED] [NOT NULL | NULL]
[UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[reference_definition]
data_type:
(see Chapter 11, Data Types)
key_part:
col_name [(length)] [ASC | DESC]
index_type:
USING {BTREE | HASH}
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
reference_definition:
REFERENCES tbl_name (key_part,...)
[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
table_option [[,] table_option] ...
table_option:
AUTO_INCREMENT [=] value
| AVG_ROW_LENGTH [=] value
| [DEFAULT] CHARACTER SET [=] charset_name
| CHECKSUM [=] {0 | 1}
| [DEFAULT] COLLATE [=] collation_name
| COMMENT [=] 'string'
| COMPRESSION [=] {'ZLIB'|'LZ4'|'NONE'}
| CONNECTION [=] 'connect_string'
| {DATA|INDEX} DIRECTORY [=] 'absolute path to directory'
| DELAY_KEY_WRITE [=] {0 | 1}
| ENCRYPTION [=] {'Y' | 'N'}
| ENGINE [=] engine_name
| INSERT_METHOD [=] { NO | FIRST | LAST }
| KEY_BLOCK_SIZE [=] value
| MAX_ROWS [=] value
| MIN_ROWS [=] value
| PACK_KEYS [=] {0 | 1 | DEFAULT}
| PASSWORD [=] 'string'
| ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
| STATS_AUTO_RECALC [=] {DEFAULT|0|1}
| STATS_PERSISTENT [=] {DEFAULT|0|1}
| STATS_SAMPLE_PAGES [=] value
| TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]
| UNION [=] (tbl_name[,tbl_name]...)
partition_options:
PARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1|2}] (column_list)
| RANGE{(expr) | COLUMNS(column_list)}
| LIST{(expr) | COLUMNS(column_list)} }
[PARTITIONS num]
[SUBPARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1|2}] (column_list) }
[SUBPARTITIONS num]
]
[(partition_definition [, partition_definition] ...)]
partition_definition:
PARTITION partition_name
[VALUES
{LESS THAN {(expr | value_list) | MAXVALUE}
|
IN (value_list)}]
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
[(subpartition_definition [, subpartition_definition] ...)]
subpartition_definition:
SUBPARTITION logical_name
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
query_expression:
SELECT ... (Some valid select or union statement)
关于create table
,我们有以下7个话题需要讨论:
- 表名;
- 临时表;
- 表的克隆和复制;
- 列的数据类型和属性;
- 索引和外键;
- 表的选项;
- 表分区。
表名
tbl_name
我们可以使用db_name.tbl_name
来在指定的数据库中创建表,但这样要假定指定的数据库是已经存在的。对此,我们可以使用引号,比如,"db_name"."tbl_name"
。
IF NOT EXISTS
使用IF NOT EXISTS
,可以避免在表已经存在的情况下重复建表而报错,也就是说,在表已经存在的情况下,IF NOT EXISTS
会使得不会重复建表。
临时表
我们可以使用TEMPORARY
关键词来建临时表。不过,临时表仅仅存在于当前会话,因此,当前会话关闭时,临时表会自动被drop
掉。
表的克隆和复制
LIKE
使用CREATE TABLE ... LIKE
,将会基于原表的定义,包括列属性、索引,而创建一个空表:
CREATE TABLE new_tbl LIKE orig_tbl;
[AS] query_expression
使用该语句,可以基于查询另一个表的数据,而创建出一个有数据的表。
CREATE TABLE new_tbl AS SELECT * FROM orig_tbl;
IGNORE|REPLACE
在使用select
而创建一个表时,有时可能出现在唯一键的列上重复值的问题,对此可以使用IGNORE
而忽略重复值,或者使用REPLACE
而覆盖重复值。
列的数据类型和属性
每个表列的数量是有限的,最多4096个。
data_type
data_type
代表了列定义里的数据类型。
-
有些属性是不应用于所有的数据类型的。比如,
AUTO_INCREMENT
只应用于整数和浮点数类型;DEFAULT
不能应用于BLOB
、TEXT
、GEOMETRY
和JSON
类型; -
所有的字符类型都能包含
CHARACTER SET
和COLLATE
,比如:
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
- 对于长度,即数据类型所指定的长度,比如
char(10)
指定了长度为10,都是以字符数为单位的,但对于BINARY
和VARBINARY
则以字节数为单位;
NOT NULL | NULL
任何列默认被指定为NULL
。
在MySQL5.7,只有InnoDB
、MyISAM
和 MEMORY
存储引擎支持在可具有NULL
值的列上的索引,但是在其它存储引擎,你必须将索引列声明为NOT NULL
或一个错误结果。
DEFAULT
DEFAULT
指定了一个列的默认值。
如果启用了NO_ZERO_DATE
或NO_ZERO_IN_DATE SQL
模式,并且默认值不符合该模式,则CREATE TABLE
会在未启用严格SQL模式时产生警告,如果启用了严格模式则会导致错误。 例如,在启用NO_ZERO_IN_DATE
的情况下,c1 DATE DEFAULT'2010-00-00'
会发出警告。
AUTO_INCREMENT
整数或浮点列可以具有附加属性AUTO_INCREMENT
。将值NULL
(推荐)或0
插入索引的AUTO_INCREMENT
列时,该列将设置为下一个序列值。通常,该值为value
+1,其中value
是表中当前列的最大值。AUTO_INCREMENT
序列以1开头。
要在插入行后检索AUTO_INCREMENT
值,请使用LAST_INSERT_ID()
SQL函数或mysql_insert_id()
C API函数。
如果启用了NO_AUTO_VALUE_ON_ZERO SQL模式,则可以在AUTO_INCREMENT列中存储值0,而不生成新的序列值。
每个表只能有一个AUTO_INCREMENT
列,必须将其编入索引,并且不能具有DEFAULT
值。仅当AUTO_INCREMENT
列仅包含正值时,它才能正常工作。插入负数被视为插入一个非常大的正数。这样做是为了避免数字从正到负“包裹”时的精度问题,并确保您不会意外地获得包含0的AUTO_INCREMENT
列。
对于MyISAM表,可以在多列键中指定AUTO_INCREMENT
辅助列。
要使MySQL与某些ODBC应用程序兼容,您可以使用以下查询找到最后一个插入行的AUTO_INCREMENT
值:
SELECT * FROM tbl_name WHERE auto_col IS NULL
此方法要求sql_auto_is_null
变量未设置为0。
COMMENT
我们可以使用COMMENT
选项,最多1024个字符长度,来注释一个列。当执行SHOW CREATE TABLE
和SHOW FULL COLUMNS
语句时,可以显示注释。
【待补充更多教程】
网友评论