ITPub博客

首页 > 数据库 > > 13.1 数据库定义语句

13.1 数据库定义语句

作者:飘絮絮絮丶 时间:2020-05-12 10:26:27 0 删除 编辑

参考官方文档:

dev.mysql.com/doc/refma




13.1.1 alter datanase 语法



ALTER {DATABASE | SCHEMA} [db_name] alter_specification ...

ALTER {DATABASE | SCHEMA} db_name UPGRADE DATA DIRECTORY NAME


alter_specification: [DEFAULT] CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name



ALTER DATABASE使您可以更改数据库的整体特征。 这些特征存储在数据库目录的db.opt文件中。 要使用ALTER DATABASE,您需要数据库的ALTER权限。 ALTER SCHEMA是ALTER DATABASE的同义词。



数据库名称可以从第一个语法中省略,在这种情况下,该语句适用于默认数据库。





13.1.2 ALTER EVENT 语法


ALTER

[DEFINER = { user | CURRENT_USER }]

EVENT event_name

[ON SCHEDULE schedule]

[ON COMPLETION [NOT] PRESERVE]

[RENAME TO new_event_name]

[ENABLE | DISABLE | DISABLE ON SLAVE]

[COMMENT 'string']

[DO event_body]


ALTER EVENT语句更改现有事件的一个或多个特征,而无需删除并重新创建它。 DEFINER,ON SCHEDULE,ON COMPLETION,COMMENT,ENABLE / DISABLE和DO子句的语法与使用CREATE EVENT时的语法完全相同。



任何用户都可以更改该用户拥有EVENT权限的数据库上定义的事件。 当用户执行成功的ALTER EVENT语句时,该用户将成为受影响事件的定义者。


ALTER EVENT仅适用于现有事件:


mysql> ALTER EVENT no_such_event ON SCHEDULE > EVERY '2:3 DAY_HOUR; ERROR 1517 (HY000): Unknown event 'no_such_event'


在以下每个示例中,假定名为myevent的事件的定义如下所示:


CREATE EVENT myevent ON SCHEDULE EVERY 6 HOUR COMMENT 'A sample comment.' DO UPDATE myschema.mytable SET mycol = mycol + 1;



以下语句将立即从每六小时一次开始更改为每十二小时一次,从语句运行时间起四小时开始:


ALTER EVENT myevent ON SCHEDULE EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 4 HOUR;




可以在单个语句中更改事件的多个特征。 此示例将由myevent执行的SQL语句更改为从mytable中删除所有记录的SQL语句; 它还会更改事件的计划,以便在此ALTER EVENT语句运行一天后执行一次。


ALTER EVENT myevent ON SCHEDULE

AT CURRENT_TIMESTAMP + INTERVAL 1 DAY

DO TRUNCATE TABLE myschema.mytable;



仅在您想要更改的特性中指定ALTER EVENT语句中的选项; 省略选项保留其现有值。 这包括CREATE EVENT的任何默认值,例如ENABLE。


要禁用myevent,请使用以下ALTER EVENT语句:


ALTER EVENT myevent DISABLE;



ON SCHEDULE子句可以使用涉及内置MySQL函数和用户变量的表达式来获取它包含的任何时间戳记或间隔值。 您不能在这些表达式中使用存储的例程或用户定义的函数,并且不能使用任何表引用; 但是,您可以使用SELECT FROM DUAL。 对于ALTER EVENT和CREATE EVENT语句都是如此。 在这种情况下,对存储例程,用户定义函数和表的引用是不允许的,并且会因错误而失败(请参见BUG#22830)。


尽管在其DO子句中包含另一个ALTER EVENT语句的ALTER EVENT语句似乎成功,但当服务器尝试执行结果的预定事件时,执行失败并显示错误。


要重命名事件,请使用ALTER EVENT语句的RENAME TO子句。 该语句将事件myevent重命名为yourevent:


ALTER EVENT myevent RENAME TO yourevent;



您还可以使用ALTER EVENT ... RENAME TO ...和db_name.event_name表示法将事件移至其他数据库,如下所示:


ALTER EVENT olddb.myevent RENAME TO newdb.myevent;


要执行前面的语句,执行它的用户必须在olddb和newdb数据库上具有EVENT特权。


注意:没有RENAME EVENT语句。


值DISABLE ON SLAVE而不是ENABLE或DISABLE用于复制从站,用于指示在主站上创建并复制到从站的事件,但不在从站上执行。 通常情况下,根据需要自动设置DISABLE ON SLAVE; 但是,有些情况下您可能需要或需要手动更改它。 有关更多信息,请参见第16.4.1.16节“调用的功能的复制”。




13.1.3 ALTER FUNCTION 语法


ALTER FUNCTION func_name [characteristic ...]


characteristic:

COMMENT 'string' |

LANGUAGE SQL

| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }

| SQL SECURITY { DEFINER | INVOKER }



这个语句可以用来改变存储函数的特性。 可以在ALTER FUNCTION语句中指定多个更改。 但是,您不能使用此语句更改存储函数的参数或主体; 要进行这样的更改,您必须使用DROP FUNCTION和CREATE FUNCTION删除并重新创建函数。


您必须具有该功能的ALTER ROUTINE权限。 (该权限自动授予函数创建者。)如果启用二进制日志记录,则ALTER FUNCTION语句可能还需要SUPER权限,如第23.7节“存储程序的二进制日志记录”中所述。



13.1.4 ALTER INSTANCE 语法


ALTER INSTANCE ROTATE INNODB MASTER KEY



在MySQL 5.7.11中引入的ALTER INSTANCE定义了适用于MySQL服务器实例的动作。


ALTER INSTANCE ROTATE INNODB MASTER KEY语句用于 rotate 用于InnoDB表空间加密的主加密密钥。 keyring 插件必须加载才能使用此语句。有关 keyring 插件的信息,请参见第6.5.4节“MySQL keyring ”。密钥轮换需要SUPER权限。


ALTER INSTANCE ROTATE INNODB MASTER KEY支持并发DML。但是,它不能与CREATE TABLE ... ENCRYPTION或ALTER TABLE ... ENCRYPTION操作同时运行,并且会执行锁定以防止这些语句的并发执行可能导致冲突。如果其中一个冲突语句正在运行,则必须先完成另一个语句才能继续。


将ALTER INSTANCE操作写入二进制日志,以便它们可以在复制服务器上执行。


有关其他ALTER INSTANCE ROTATE INNODB MASTER KEY用法信息,请参见第14.7.10节“InnoDB表空间加密”。





13.1.5 ALTER LOGFILE GROUP 语法


ALTER LOGFILE GROUP logfile_group

ADD UNDOFILE 'file_name'

[INITIAL_SIZE [=] size]

[WAIT]

ENGINE [=] engine_name





该语句将名为'file_name'的UNDO文件添加到现有的日志文件组logfile_group。 ALTER LOGFILE GROUP语句只有一个ADD UNDOFILE子句。 目前不支持DROP UNDOFILE子句。


注意:

所有NDB群集磁盘数据对象共享相同的名称空间。 这意味着每个磁盘数据对象必须是唯一命名的(而不仅仅是给定类型的每个磁盘数据对象)。 例如,不能使用同名的表空间和撤消日志文件,或者具有相同名称的撤消日志文件和数据文件。


可选的INITIAL_SIZE参数以字节为单位设置UNDO文件的初始大小; 如果未指定,则初始大小默认为134217728(128 MB)。 您可以选择遵循一个单字母缩写的大小,类似于my.cnf中使用的缩写。 通常,这是字母M(兆字节)或G(千兆字节)之一。 (BUG#13116514,BUG#16104705,BUG#62858)


在32位系统上,INITIAL_SIZE的最大支持值为4294967296(4 GB)。 (BUG#29186)


INITIAL_SIZE的最小允许值是1048576(1 MB)。 (BUG#29574)



注意:

WAIT被解析,但被忽略。 此关键字目前不起作用,并且用于未来的扩展。


ENGINE参数(必需)确定此日志文件组使用的存储引擎,其中engine_name是存储引擎的名称。 目前,唯一可接受的engine_name值是“NDBCLUSTER”和“NDB”。 这两个值是等价的。


下面是一个例子,它假定日志文件组lg_3已经使用CREATE LOGFILE GROUP创建(参见第13.1.15节“CREATE LOGFILE GROUP语法”):


ALTER LOGFILE GROUP lg_3 ADD UNDOFILE 'undo_10.dat' INITIAL_SIZE=32M ENGINE=NDBCLUSTER;



当ALTER LOGFILE GROUP与ENGINE = NDBCLUSTER(或者ENGINE = NDB)一起使用时,将在每个NDB群集数据节点上创建一个UNDO日志文件。 您可以通过查询INFORMATION_SCHEMA.FILES表来验证是否创建了UNDO文件并获取有关它们的信息。 例如:



mysql> SELECT FILE_NAME, LOGFILE_GROUP_NUMBER, EXTRA

-> FROM INFORMATION_SCHEMA.FILES

-> WHERE LOGFILE_GROUP_NAME = 'lg_3';

+-------------+----------------------+----------------+

| FILE_NAME | LOGFILE_GROUP_NUMBER | EXTRA |

+-------------+----------------------+----------------+

| newdata.dat | 0 | CLUSTER_NODE=3 |

| newdata.dat | 0 | CLUSTER_NODE=4 |

| undo_10.dat | 11 | CLUSTER_NODE=3 |

| undo_10.dat | 11 | CLUSTER_NODE=4 |

+-------------+----------------------+----------------+

4 rows in set (0.01 sec)



用于UNDO_BUFFER_SIZE的内存来自全局池,其大小由SharedGlobalMemory数据节点配置参数的值决定。 这包括通过设置InitialLogFileGroup数据节点配置参数为此选项隐含的任何默认值。


ALTER LOGFILE GROUP仅适用于NDB群集的磁盘数据存储。 有关更多信息,请参见第21.5.13节“NDB群集磁盘数据表”。




13.1.6 ALTER PROCEDURE 语法



ALTER PROCEDURE proc_name [characteristic ...]


characteristic: COMMENT 'string' | LANGUAGE SQL | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }



此语句可用于更改存储过程的特征。 可以在ALTER PROCEDURE语句中指定多个更改。 但是,您无法使用此语句更改存储过程的参数或主体; 要进行这样的更改,您必须使用DROP PROCEDURE和CREATE PROCEDURE删除并重新创建该过程。



您必须拥有该过程的ALTER ROUTINE权限。 默认情况下,该权限被自动授予过程创建者。 可以通过禁用automatic_sp_privileges系统变量来更改此行为。 请参见第23.2.2节“存储例程和MySQL 权限”。




13.1.7 ALTER SERVER 语法


ALTER SERVER server_name OPTIONS (option [, option] ...)


更改server_name的服务器信息,调整CREATE SERVER语句中允许的任何选项。 相应地更新mysql.servers表中的相应字段。 该声明需要SUPER特权。


例如,要更新USER选项:

ALTER SERVER s OPTIONS (USER 'sally');


ALTER SERVER导致隐式提交。



不管正在使用的记录格式如何,ALTER SERVER都不会写入二进制日志。






13.1.8 ALTER TABLE 语法



ALTER TABLE更改表的结构。 例如,您可以添加或删除列,创建或销毁索引,更改现有列的类型或重命名列或表本身。 您还可以更改特征,例如用于表或表注释的存储引擎。


  • 要使用ALTER TABLE,您需要表的ALTER,CREATE和INSERT权限。 重命名表需要旧表上的ALTER和DROP,ALTER,CREATE和INSERT在新表上。
  • 在表名之后,指定要进行的更改。 如果没有给出,ALTER TABLE什么都不做。
  • 许多允许的更改的语法与CREATE TABLE语句的子句相似。 对于CREATE TABLE,column_definition子句对ADD和CHANGE使用相同的语法。 有关更多信息,请参见第13.1.18节“CREATE TABLE语法”。
  • 单词COLUMN是可选的,可以省略。
  • 在单个ALTER TABLE语句中允许多个ADD,ALTER,DROP和CHANGE子句,用逗号分隔。 这是标准SQL的MySQL扩展,每个ALTER TABLE语句只允许每个子句中的一个。 例如,要在单个语句中删除多个列,请执行以下操作:


ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;

  • 如果存储引擎不支持尝试的ALTER TABLE操作,则可能会导致警告。 这些警告可以用SHOW WARNINGS显示。 请参见第13.7.5.40节“SHOW WARNINGS Syntax”。 有关ALTER TABLE故障排除的信息,请参见第B.5.6.1节“ALTER TABLE的问题”。




表选项


在ALTER TABLE中使用表选项提供了一种改变单个表特征的便捷方式。 例如:


  • 如果t1当前不是InnoDB表,则此语句会将其存储引擎更改为InnoDB:


ALTER TABLE t1 ENGINE = InnoDB;


  • 当您指定一个ENGINE子句时,ALTER TABLE会重建该表。 即使表已经有指定的存储引擎,情况也是如此。
  • 在现有InnoDB表上运行ALTER TABLE tbl_name ENGINE = INNODB将执行“null”ALTER TABLE操作,该操作可用于对InnoDB表进行碎片整理,如第14.12.4节“碎片整理表”中所述。 在InnoDB表上运行ALTER TABLE tbl_name FORCE执行相同的功能。
  • ALTER TABLE tbl_name ENGINE = INNODB和ALTER TABLE tbl_name FORCE使用在线DDL。
  • 尝试更改表的存储引擎的结果受所需存储引擎是否可用以及NO_ENGINE_SUBSTITUTION SQL模式的设置的影响,如第5.1.8节“服务器SQL模式”中所述。
  • 为防止无意中丢失数据,ALTER TABLE不能用于将表的存储引擎更改为MERGE或BLACKHOLE。
  • 要将InnoDB表更改为使用压缩的行存储格式:


ALTER TABLE t1 ROW_FORMAT = COMPRESSED;

  • 如果启用InnoDB表空间加密功能(请参见第14.7.10节“InnoDB表空间加密”),则可以像下面这样启用或禁用t1的加密:


ALTER TABLE t1 ENCRYPTION='Y';

ALTER TABLE t1 ENCRYPTION='N';


  • 重置当前自动增量值:


ALTER TABLE t1 AUTO_INCREMENT = 13;


您不能将计数器重置为小于或等于当前正在使用的值。 对于InnoDB和MyISAM,如果该值小于或等于当前AUTO_INCREMENT列中的最大值,则将该值重置为当前最大AUTO_INCREMENT列值加1。

  • 更改表的默认字符集:

ALTER TABLE t1 CHARACTER SET = utf8;

  • 增加(或变更) 表注释:

ALTER TABLE t1 COMMENT = 'New table comment';



--在alter table 准备安装新版本表(合并副本)时,在这个点上,会等待读完成,并阻塞新读和写(短暂的)



锁和并发控制


要控制表的并发读写的级别,请使用LOCK子句。 为此子句指定非默认值使您可以在alter操作期间要求一定数量的并发访问权限或排他性权限,并且如果请求的锁定级别不可用,则会暂停操作。 LOCK子句的参数是:



  • LOCK = DEFAULT

给定ALGORITHM子句(如果有)和ALTER TABLE操作的最大并发级别:允许并发读写(如果受支持)。 如果不支持,则允许并行读取。 如果不是,则强制执行独占访问。

  • LOCK = NONE


如果支持,允许并发读取和写入。 否则,会发生错误。

  • LOCK = SHARED


如果支持,则允许并发读取但阻止写入。 即使存储引擎对给定的ALGORITHM子句(如果有)和ALTER TABLE操作支持并发写入,写入也会被阻止。 如果不支持并发读取,则会发生错误。

  • LOCK = EXCLUSIVE


强制独占访问。 即使存储引擎对给定ALGORITHM子句(如果有)和ALTER TABLE操作支持并发读/写,也会执行此操作。



增加和删除字段

使用ADD将新列添加到表中,并使用DROP删除现有列。


DROP col_name是标准SQL的MySQL扩展。



要在表行中的特定位置添加列,请使用FIRST或AFTER col_name。 默认是最后添加列。


如果一个表只包含一列,则该列不能被删除。 如果您打算删除表,请改用DROP TABLE语句。


如果从表中删除列,则列也将从它们所属的任何索引中删除。 如果组成索引的所有列都被删除,那么索引也会被删除。


重命名,重新定义和重新排序列



CHANGE,MODIFY和ALTER子句可以改变现有列的名称和定义。 他们有这些比较特征:



  • CHANGE
    • 可以重命名列并更改其定义,或两者都可以。
    • 具有比MODIFY更多的功能,但是以某些操作的便利为代价。 如果不进行重命名,CHANGE需要命名该列两次。
    • 使用FIRST或AFTER,可以对列进行重新排序。
  • MODIFY
    • 可以更改列定义,但不能更改其名称。
    • 比CHANGE更方便地更改列定义而不重命名它。
    • 使用FIRST或AFTER,可以对列进行重新排序。
  • ALTER:仅用于更改列默认值。



CHANGE是标准SQL的MySQL扩展。 MODIFY是用于Oracle兼容性的MySQL扩展。


要更改列以更改其名称和定义,请使用CHANGE,指定旧名称和新名称以及新定义。 例如,要将INT NOT NULL列从a重命名为b并将其定义更改为使用BIGINT数据类型,同时保留NOT NULL属性,请执行以下操作:

ALTER TABLE t1 CHANGE a b BIGINT NOT NULL;



要更改列定义但不更改其名称,请使用CHANGE或MODIFY。 使用CHANGE,语法需要两个列名,所以您必须指定两个相同的名称才能保持名称不变。 例如,要更改列b的定义,请执行以下操作:


ALTER TABLE t1 CHANGE b b INT NOT NULL;

MODIFY更改定义而不更改名称更方便,因为它仅需要一次列名称:

ALTER TABLE t1 MODIFY b INT NOT NULL;


要更改列名称而不是其定义,请使用CHANGE。 该语法需要列定义,因此要保持定义不变,您必须重新指定列当前具有的定义。 例如,要将一个INT NOT NULL列从b重命名为a,请执行以下操作:


ALTER TABLE t1 CHANGE b a INT NOT NULL;

对于使用CHANGE或MODIFY的列定义更改,除了索引属性(如PRIMARY KEY或UNIQUE)之外,定义必须包括数据类型和应用于新列的所有属性。 原始定义中存在但未为新定义指定的属性不会继续执行。 假设列col1被定义为INT UNSIGNED DEFAULT 1 COMMENT'my column',并且您按如下方式修改列,打算仅将INT更改为BIGINT:


ALTER TABLE t1 MODIFY col1 BIGINT;

该语句将数据类型从INT更改为BIGINT,但它也会删除UNSIGNED,DEFAULT和COMMENT属性。 要保留它们,声明必须明确地包含它们:

ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';

对于使用CHANGE或MODIFY的数据类型更改,MySQL会尝试尽可能将现有列值转换为新类型。



注意:

此转换可能会导致数据更改。 例如,如果您缩短字符串列,值可能会被截断。 如果转换为新数据类型会导致数据丢失,请在使用ALTER TABLE之前启用严格SQL模式(请参见第5.1.8节“服务器SQL模式”)以防止操作成功。


如果使用CHANGE或MODIFY缩短列上存在索引的列,并且得到的列长度小于索引长度,则MySQL会自动缩短索引。


对于CHANGE重命名的列,MySQL自动将这些引用重命名为已重命名的列:

  • 引用旧列的索引,包括索引和禁用的MyISAM索引。
  • 指向旧列的外键。

对于CHANGE重命名的列,MySQL不会自动将这些引用重命名为已重命名的列:

  • 生成引用重命名列的列和分区表达式。 您必须使用CHANGE在与重命名列相同的ALTER TABLE语句中重新定义这些表达式。
  • 视图和存储的程序引用了重命名的列。 您必须手动更改这些对象的定义以引用新的列名称。




要对表格中的列重新排序,请在CHANGE或MODIFY操作中使用FIRST和AFTER。


ALTER ... SET DEFAULT或ALTER ... DROP DEFAULT分别指定列的新默认值或删除旧的默认值。 如果删除旧的默认值并且列可以为NULL,则新的默认值为NULL。 如果列不能为NULL,MySQL将按照第11.7节“数据类型默认值”中所述分配默认值。



主键和索引


DROP PRIMARY KEY丢弃主键。 如果没有主键,则会发生错误。 有关主键(尤其是InnoDB表)的性能特征的信息,请参见第8.3.2节“主键优化”。


如果将一个UNIQUE INDEX或PRIMARY KEY添加到表中,MySQL会将其存储在任何非唯一索引之前,以便尽早检测重复键。


DROP INDEX删除索引。 这是标准SQL的MySQL扩展。 请参见第13.1.25节“DROP INDEX语法”。 要确定索引名称,请使用SHOW INDEX FROM tbl_name。


某些存储引擎允许您在创建索引时指定索引类型。 index_type说明符的语法是USING type_name。 有关USING的详细信息,请参见第13.1.14节“CREATE INDEX语法”。 首选位置在列表之后。 支持在列列表之前使用该选项将在未来的MySQL版本中被删除。



index_option值为索引指定其他选项。 有关允许的index_option值的详细信息,请参见第13.1.14节“CREATE INDEX语法”。


RENAME INDEX old_index_name TO new_index_name重命名索引。 这是标准SQL的MySQL扩展。 表的内容保持不变。 old_index_name必须是表中未被同一ALTER TABLE语句删除的现有索引的名称。 new_index_name是新的索引名称,在应用更改后,它不能在结果表中复制索引的名称。 索引名称不能是PRIMARY。



如果在MyISAM表上使用ALTER TABLE,则所有非唯一索引都将在单独的批处理中创建(与REPAIR TABLE相同)。 当你有很多索引时,这应该使ALTER TABLE更快。


外键


FOREIGN KEY和REFERENCES子句由InnoDB和NDB存储引擎支持,它们实现ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name](...)REFERENCES ...(...)。



对于ALTER TABLE,与CREATE TABLE不同,ADD FOREIGN KEY忽略index_name(如果给定)并使用自动生成的外键名称。 作为解决方法,请包含CONSTRAINT子句以指定外键名称:


ADD CONSTRAINT name FOREIGN KEY (....) ...



重要:

MySQL默默地忽略内联REFERENCES规范,其中引用被定义为列规范的一部分。 MySQL只接受定义为单独FOREIGN KEY规范一部分的REFERENCES子句。



注意:

分区的InnoDB表不支持外键。 此限制不适用于NDB表,包括由[LINEAR] KEY明确分区的那些表。



MySQL服务器和NDB集群都支持使用ALTER TABLE来删除外键:


ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;


在ALTER TABLE语句中添加和删除外键支持ALTER TABLE ... ALGORITHM = INPLACE,但不支持ALTER TABLE ... ALGORITHM = COPY。


MySQL服务器和NDB集群都支持使用ALTER TABLE来删除外键:

ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;



在ALTER TABLE语句中添加和删除外键支持ALTER TABLE ... ALGORITHM = INPLACE,但不支持ALTER TABLE ... ALGORITHM = COPY。



服务器禁止更改可能导致引用完整性丢失的外键列。 它还禁止更改可能不安全的列的数据类型。 例如,将VARCHAR(20)更改为VARCHAR(30)是允许的,但将其更改为VARCHAR(1024)不行,因为它会更改存储各个值所需的长度字节数。 解决方法是在更改列定义和ALTER TABLE ... ADD FOREIGN KEY之前使用ALTER TABLE ... DROP FOREIGN KEY。



ALTER TABLE tbl_name RENAME new_tbl_name更改内部生成的外键约束名称和包含字符串“tbl_name_ibfk_”以反映新表名称的用户定义外键约束名称。 InnoDB将包含字符串“tbl_name_ibfk_”的外键约束名称解释为内部生成的名称。


变更 字符集

要将表默认字符集和所有字符列(CHAR,VARCHAR,TEXT)更改为新字符集,请使用如下语句:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;



要避免上述类型的数据类型更改,请勿使用CONVERT TO CHARACTER SET。 相反,使用MODIFY更改单个列。 例如:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;

ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;



如果指定CONVERT TO CHARACTER SET二进制文件,则CHAR,VARCHAR和TEXT列将转换为其对应的二进制字符串类型(BINARY,VARBINARY,BLOB)。 这意味着列不再具有字符集属性,并且后续的CONVERT TO操作不适用于它们。


如果在CONVERT TO CHARACTER SET操作中charset_name为DEFAULT,则使用由character_set_database系统变量命名的字符集。



警告:

CONVERT TO操作转换原始字符集和命名字符集之间的列值。 如果你在一个字符集中有一列(比如latin1),但这个存储的值实际上使用了一些其他不兼容的字符集(如utf8),那么这不是你想要的。 在这种情况下,您必须为每个这样的列执行以下操作:


ALTER TABLE t1 CHANGE c1 c1 BLOB;

ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;



要仅更改表格的默认字符集,请使用以下语句:

ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;


单词DEFAULT是可选的。 默认字符集是如果您未为稍后添加到表中的列指定字符集时使用的字符集(例如,使用ALTER TABLE ... ADD列)。



放弃并导入InnoDB表空间


可以使用DISCARD TABLESPACE和IMPORT TABLESPACE选项丢弃并导入在其自己的每个表文件表空间中创建的InnoDB表。 这些选项可用于从备份中导入每个文件表空间的表空间,或者将每个文件表的表空间从一个数据库服务器复制到另一个数据库服务器。



MYISAM 表的行顺序


ORDER BY使您能够按特定顺序创建具有行的新表。 此选项主要用于知道您在大多数时间以特定顺序查询行时。 在对表格进行重大更改后使用此选项,您可能会获得更高的性能。 在某些情况下,如果表按您希望稍后订购的列顺序排列,则可能会使MySQL的排序更容易。


注意:

插入和删除后,表不会保持指定的顺序。



ORDER BY语法允许为排序指定一个或多个列名称,其中每个列名称可以选择跟随ASC或DESC以分别指示升序或降序排序顺序。 默认值是升序。 只有列名可以作为排序标准; 任意表达式是不允许的。 这个子句应该在任何其他子句之后给出。


ORDER BY对InnoDB表没有意义,因为InnoDB总是根据聚集索引对表行进行排序。


在分区表上使用时,ALTER TABLE ... ORDER BY仅对每个分区内的行进行排序。



分区选项

partition_options表示可以与分区表一起使用的选项,用于重新分区,添加,删除,放弃,导入,合并和拆分分区以及执行分区维护。



ALTER TABLE语句可能包含PARTITION BY或REMOVE PARTITIONING子句作为其他alter规范的补充,但PARTITION BY或REMOVE PARTITIONING子句必须在任何其他规范后面指定。 由于刚刚列出的选项不能与其他更改规范结合在一个ALTER TABLE中,所以 ADD PARTITION, DROP PARTITION, DISCARD PARTITION, IMPORT PARTITION, COALESCE PARTITION,REORGANIZE PARTITION, EXCHANGE PARTITION, ANALYZE PARTITION, CHECK PARTITION, REPAIR PARTITION 选项 在单个分区上运行。


在MySQL 5.7.6之前,分区的InnoDB表使用MyISAM采用的通用ha_partition分区处理程序和其他存储引擎,而不提供它们自己的分区处理程序; 在MySQL 5.7.6和更高版本中,这些表是使用InnoDB存储引擎自己的(或“本地”)分区处理程序创建的。 从MySQL 5.7.9开始,您可以使用ALTER TABLE ... UPGRADE PARTITIONING将在MySQL 5.7.6或更早版本中创建的InnoDB表(即使用ha_partition创建的表)升级到InnoDB本地分区处理程序。 (bug#76734,bug#20727344)此ALTER TABLE语法不接受任何其他选项,并且一次只能在单个表上使用。 您还可以在MySQL 5.7.9或更高版本中使用mysql_upgrade将较旧的分区InnoDB表升级到本地分区处理程序。


13.1.11 CREATE DATABASE 语法

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [create_specification] ...


create_specification:

[DEFAULT] CHARACTER SET [=] charset_name

| [DEFAULT] COLLATE [=] collation_name



CREATE DATABASE用给定的名字创建一个数据库。 要使用此语句,您需要数据库的CREATE特权。 CREATE SCHEMA是CREATE DATABASE的同义词。


如果数据库存在并且您没有指定IF NOT EXISTS,则会发生错误。



在具有活动的LOCK TABLES语句的会话中不允许CREATE DATABASE。


create_specification选项指定数据库特征。 数据库特征存储在数据库目录的db.opt文件中。


MySQL中的数据库实现为包含与数据库中的表对应的文件的目录。 由于数据库最初创建时没有表,因此CREATE DATABASE语句仅在MySQL数据目录和db.opt文件下创建一个目录。


如果您在数据目录下手动创建目录(例如,使用mkdir),服务器将其视为数据库目录,并显示在SHOW DATABASES的输出中。



13.1.18 CREATE TABLE 语法


CREATE TABLE使用给定的名称创建一个表。 您必须具有该表的CREATE权限。


默认情况下,使用InnoDB存储引擎在默认数据库中创建表。 如果表存在,没有默认数据库,或者数据库不存在,则会发生错误。




13.1.18.2 通过 CREATE TABLE 创建的文件


MySQL通过数据库目录中的.frm表格格式(定义)文件来表示每个表格。 表的存储引擎也可能创建其他文件。


对于以文件为单位的表空间或常规表空间创建的InnoDB表,表数据和关联的索引存储在数据库目录中的ibd文件中。 当在系统表空间中创建InnoDB表时,表数据和索引存储在表示系统表空间的ibdata *文件中。 innodb_file_per_table选项控制默认情况下是在每个文件表空间还是系统表空间中创建表。 无论innodb_file_per_table设置如何,TABLESPACE选项都可用于将表放入每个表文件的文件表空间,常规表空间或系统表空间中。


对于MyISAM表,存储引擎会创建数据和索引文件。 因此,对于每个MyISAM表tbl_name,有三个磁盘文件。


tbl_name.frm 表格式(定义)文件

tbl_name.MYD 数据文件

tbl_name.MYI 索引文件




13.1.18.3 Create TEMPORARY table 语法


创建表时可以使用TEMPORARY关键字。 TEMPORARY表仅在当前会话中可见,并在会话关闭时自动删除。 这意味着两个不同的会话可以使用相同的临时表名称而不会相互冲突,也不会使用相同名称的现有非TEMPORARY表冲突。 (在删除临时表之前隐藏现有表。)


除了与TEMPORARY关键字一起使用外,CREATE TABLE会导致隐式提交。 请参见第13.3.3节“导致隐式提交的语句”。



TEMPORARY表与数据库(方案)的关系非常松散。 删除数据库不会自动删除在该数据库中创建的任何TEMPORARY表。 另外,如果您在CREATE TABLE语句中使用数据库名称限定表名,则可以在不存在的数据库中创建TEMPORARY表。 在这种情况下,对表的所有后续引用都必须使用数据库名称进行限定。


要创建临时表,您必须具有CREATE TEMPORARY TABLES特权。 会话创建临时表后,服务器不会在该表上执行进一步的特权检查。 创建会话可以对表执行任何操作,例如DROP TABLE,INSERT,UPDATE或SELECT。


这种行为的一个含义是即使当前用户没有权限创建它们,会话也可以操纵它的临时表。 假设当前用户没有CREATE TEMPORARY TABLES特权,但能够执行一个定义者上下文存储过程,该过程使用具有CREATE TEMPORARY TABLES并创建临时表的用户的权限执行。 在执行过程时,会话将使用定义用户的权限。 过程返回后,有效权限将恢复为当前用户的权限,该权限仍可以看到临时表并对其执行任何操作。



13.1.18.4 CREATE TABLE .... LIKE 语法


使用CREATE TABLE ... LIKE根据另一个表的定义(包括原始表中定义的所有列属性和索引)创建一个空表:


CREATE TABLE new_tbl LIKE orig_tbl;


该副本是使用与原始表格相同版本的表格存储格式创建的。 原始表上需要SELECT权限。



LIKE 关键字只能对于基础表,不能用于视图


重要:

当LOCK TABLES语句生效时,您不能执行CREATE TABLE或CREATE TABLE ... LIKE。


CREATE TABLE ... LIKE与CREATE TABLE进行相同的检查,不仅仅复制.frm文件。 这意味着如果当前的SQL模式与创建原始表时的有效模式不同,则表定义可能被认为对新模式无效,并且语句将失败。


对于CREATE TABLE ... LIKE,目标表保留了原始表中生成的列信息。


CREATE TABLE ... LIKE不保留为原始表或任何外键定义指定的DATA DIRECTORY或INDEX DIRECTORY表选项。


如果原始表是TEMPORARY表,CREATE TABLE ... LIKE不保留TEMPORARY。 要创建TEMPORARY目标表,请使用CREATE TEMPORARY TABLE ... LIKE。




13.1.18.5 CREATE TABLE ... SELECT 语法


您可以通过在CREATE TABLE语句末尾添加一条SELECT语句来创建另一个表:


CREATE TABLE new_tbl [AS] SELECT * FROM orig_tbl;



MySQL为SELECT中的所有元素创建新列。 例如:


mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,

PRIMARY KEY (a), KEY(b))

ENGINE=MyISAM SELECT b,c FROM test2;



这将创建一个包含三列a,b和c的MyISAM表。 ENGINE选项是CREATE TABLE语句的一部分,不应在SELECT之后使用; 这会导致语法错误。 其他CREATE TABLE选项(如CHARSET)也是如此。



请注意,SELECT语句中的列将附加到表的右侧,而不会与其重叠。 以下面的例子:


mysql> SELECT * FROM foo;

+---+

| n |

+---+

| 1 |

+---+

mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM bar;

+------+---+

| m | n |

+------+---+

| NULL | 1 |

+------+---+

1 row in set (0.00 sec)



对于表foo中的每一行,行插入bar中的是foo的值和新列的默认值。


在由CREATE TABLE ... SELECT产生的表中,仅在CREATE TABLE部分中命名的列首先出现。 在这两个部分命名的列或仅在SELECT部分的列在后面。 SELECT列的数据类型也可以通过指定CREATE TABLE部分中的列来重写。


如果在将数据复制到表时发生任何错误,它会自动删除并且不会创建。


您可以在SELECT by IGNORE或REPLACE之前指出如何处理重复唯一键值的行。 使用IGNORE时,丢弃在唯一键值上复制现有行的行。 使用REPLACE,新行将替换具有相同唯一键值的行。 如果既未指定IGNORE也未指定REPLACE,则重复唯一键值会导致错误。 有关更多信息,请参阅IGNORE关键字和严格SQL模式的比较。




由于不能总是确定底层SELECT语句中的行的顺序,因此CREATE TABLE ... IGNORE SELECT和CREATE TABLE ... REPLACE SELECT语句被标记为对基于语句的复制而言不安全。 这些语句在使用基于语句的模式时会在错误日志中产生警告,并在使用MIXED模式时使用基于行的格式写入二进制日志。


CREATE TABLE ... SELECT不会自动为您创建任何索引。 这是故意的,尽可能灵活。 如果你想在创建的表中有索引,你应该在SELECT语句之前指定它们:

mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;



对于CREATE TABLE ... SELECT,目标表不保留有关选定源表中的列是否为生成列的信息。 语句的SELECT部分不能将值分配给目标表中的生成列。


数据类型可能会发生一些转换。 例如,AUTO_INCREMENT属性不会保留,并且VARCHAR列可以成为CHAR列。 被重置的属性为NULL(或NOT NULL),和具有这些属性的列,CHARACTER SET,COLLATION,COMMENT和DEFAULT子句。


使用CREATE TABLE ... SELECT创建表时,请确保在查询中别名任何函数调用或表达式。 如果您不这样做,则CREATE语句可能会失败或导致不需要的列名称。

CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;


您还可以在创建的表中明确指定列的数据类型:



CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;



对于CREATE TABLE ... SELECT,如果给出IF NOT EXISTS并且目标表存在,则不会将任何内容插入到目标表中,并且不会记录该语句。


为确保二进制日志可用于重新创建原始表,MySQL在CREATE TABLE ... SELECT过程中不允许并发插入。


您不能在语句中使用FOR UPDATE作为SELECT的一部分,例如CREATE TABLE new_table SELECT ... FROM old_table ....如果尝试这样做,则语句失败。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3118229/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42295