目录
本章介绍 MySQL支持 的 SQL 语句 的语法 。
MySQL 8.0支持原子数据定义语言(DDL)语句。 此功能称为 原子DDL 。 原子DDL语句将与DDL操作关联的数据字典更新,存储引擎操作和二进制日志写入组合到单个原子事务中。 即使服务器在操作期间停止,也会提交事务,并将适用的更改保留到数据字典,存储引擎和二进制日志中,或者回滚事务。
通过在MySQL 8.0中引入MySQL数据字典,可以实现Atomic DDL。 在早期的MySQL版本中,元数据存储在元数据文件,非事务性表和存储引擎特定的字典中,这需要中间提交。 MySQL数据字典提供的集中式事务元数据存储消除了这一障碍,使得将DDL语句操作重组为原子事务成为可能。
原子DDL功能在本节的以下主题中描述:
原子DDL功能支持表和非表DDL语句。
与表相关的DDL操作需要存储引擎支持,而非表DDL操作则不需要。
目前,只有
InnoDB
存储引擎支持原子DDL。
受支持的表DDL语句包括
CREATE
,
ALTER
和
DROP
对数据库,表,表和索引,以及语句
TRUNCATE
TABLE
声明。
支持的非表DDL语句包括:
原子DDL功能不支持以下语句:
与表相关的DDL语句涉及除以外的存储引擎
InnoDB
。
CREATE
SERVER
,
ALTER
SERVER
和
DROP
SERVER
语句。
原子DDL语句的特征包括以下内容:
元数据更新,二进制日志写入和存储引擎操作(如果适用)将合并为单个事务。
在DDL操作期间,SQL层没有中间提交。
适用时:
数据字典,例程,事件和UDF高速缓存的状态与DDL操作的状态一致,这意味着更新高速缓存以反映DDL操作是成功完成还是回滚。
DDL操作中涉及的存储引擎方法不执行中间提交,并且存储引擎将自身注册为DDL事务的一部分。
存储引擎支持DDL操作的重做和回滚,这在DDL操作的 Post-DDL 阶段执行。
DDL操作的可见行为是原子的,这会更改某些DDL语句的行为。 请参阅 DDL语句行为中的更改 。
原子或其他DDL语句隐式结束当前会话中处于活动状态的任何事务,就好像您
COMMIT
在执行语句之前
完成了
一样。
这意味着DDL语句不能在另一个事务中,在事务控制语句中执行
START TRANSACTION ...
COMMIT
,或者与同一事务中的其他语句结合使用。
本节介绍由于引入原子DDL支持而导致的DDL语句行为的更改。
DROP
TABLE
如果所有命名表都使用原子DDL支持的存储引擎,则操作是完全原子的。
该语句要么成功删除所有表,要么回滚。
DROP
TABLE
如果命名表不存在,并且未进行任何更改(无论存储引擎如何),则会失败并显示错误。
以下示例演示了此行为更改,其中
DROP
TABLE
语句失败,因为命名表不存在:
mysql>CREATE TABLE t1 (c1 INT);
mysql>DROP TABLE t1, t2;
ERROR 1051(42S02):未知表'test.t2' MySQL的>SHOW TABLES;
+ ---------------- + | Tables_in_test | + ---------------- + | t1 | + ---------------- +
在引入原子DDL之前,
DROP
TABLE
报告指定表的错误,该错误不存在但成功存在于已存在的命名表中:
mysql>CREATE TABLE t1 (c1 INT);
mysql>DROP TABLE t1, t2;
ERROR 1051(42S02):未知表'test.t2' MySQL的>SHOW TABLES;
空集(0.00秒)
由于行为的这种变化,
DROP
TABLE
MySQL 5.7主服务器上
的部分完成
语句在MySQL 8.0从服务器上复制时失败。
要避免此故障情形,请
IF
EXISTS
在
DROP
TABLE
语句中
使用
语法
以防止对不存在的表发生错误。
DROP
DATABASE
如果所有表都使用原子DDL支持的存储引擎,则为atomic。
该语句要么成功删除所有对象,要么回滚。
但是,从文件系统中删除数据库目录最后发生,并且不是原子事务的一部分。
如果由于文件系统错误或服务器暂停而导致数据库目录的删除失败,
DROP
DATABASE
则不会回滚事务。
对于不使用原子DDL支持的存储引擎的表,表删除发生在原子
DROP
TABLE
或
DROP
DATABASE
事务之外。
这样的表删除被单独写入二进制日志,这在中断
DROP
TABLE
或
DROP
DATABASE
操作
的情况下将存储引擎,数据字典和二进制日志之间的差异限制为最多一个表
。
对于删除多个表的操作,不使用原子DDL支持的存储引擎的表将在执行之前删除。
CREATE
TABLE
,
ALTER
TABLE
,
RENAME
TABLE
,
TRUNCATE
TABLE
,
CREATE TABLESPACE
,和
DROP
TABLESPACE
对使用原子DDL支持的存储引擎表执行的操作要么完全提交或如果服务器的操作时停止回滚。
在早期的MySQL版本中,这些操作的中断可能会导致存储引擎,数据字典和二进制日志之间的差异,或者留下孤立文件。
RENAME
TABLE
如果所有命名表都使用原子DDL支持的存储引擎,则操作只是原子操作。
DROP VIEW
如果命名视图不存在且未进行任何更改,则会失败。
在此示例中演示了行为更改,其中
DROP
VIEW
语句失败,因为命名视图不存在:
mysql>CREATE VIEW test.viewA AS SELECT * FROM t;
mysql>DROP VIEW test.viewA, test.viewB;
ERROR 1051(42S02):未知表'test.viewB' MySQL的>SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
+ ---------------- + ------------ + | Tables_in_test | Table_type | + ---------------- + ------------ + | viewA | 查看| + ---------------- + ------------ +
在引入原子DDL之前,
DROP
VIEW
为命名视图返回一个错误,该错误不存在但成功存在于存在的命名视图中:
mysql>CREATE VIEW test.viewA AS SELECT * FROM t;
mysql>DROP VIEW test.viewA, test.viewB;
ERROR 1051(42S02):未知表'test.viewB' MySQL的>SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
空集(0.00秒)
不再允许部分执行帐户管理声明。 帐户管理语句对所有命名用户成功或回滚,如果发生错误则无效。 在早期的MySQL版本中,为多个用户命名的帐户管理语句可能对某些用户成功,而对其他用户则失败。
在此示例中演示了行为更改,其中第二个
CREATE
USER
语句返回错误但失败,因为它无法对所有命名用户成功。
mysql>CREATE USER userA;
mysql>CREATE USER userA, userB;
ERROR 1396(HY000):'userA'@'%'的操作CREATE USER失败 MySQL的>SELECT User FROM mysql.user WHERE User LIKE 'user%';
+ ------- + | 用户| + ------- + | userA | + ------- +
在引入原子DDL之前,第二个
CREATE USER
语句为命名用户返回一个错误,该错误不存在但成功存在的命名用户:
mysql>CREATE USER userA;
mysql>CREATE USER userA, userB;
ERROR 1396(HY000):'userA'@'%'的操作CREATE USER失败 MySQL的>SELECT User FROM mysql.user WHERE User LIKE 'user%';
+ ------- + | 用户| + ------- + | userA | | userB | + ------- +
由于行为的这种变化,MySQL 5.7主服务器上部分完成的帐户管理语句在MySQL 8.0从服务器上复制时会失败。
要避免此故障情形,请
在帐户管理语句中
使用
IF EXISTS
或
IF NOT EXISTS
语法,以防止与命名用户相关的错误。
目前,只有
InnoDB
存储引擎支持原子DDL。
不支持原子DDL的存储引擎免于DDL原子性。
涉及豁免存储引擎的DDL操作仍然能够引入操作中断或仅部分完成时可能发生的不一致。
要支持重做和回滚DDL操作,
InnoDB
请将DDL日志写入
mysql.innodb_ddl_log
表,该表是驻留在
mysql.ibd
数据字典表空间
中的隐藏数据字典表
。
要
mysql.innodb_ddl_log
在DDL操作期间
查看写入
表的
DDL日志
,请启用
innodb_print_ddl_logs
配置选项。
有关更多信息,请参阅
查看DDL日志
。
mysql.innodb_ddl_log
无论
innodb_flush_log_at_trx_commit
设置
如何,对表的
更改的重做日志
都会立即刷新到磁盘
。
立即刷新重做日志可以避免DDL操作修改数据文件的情况,但是
mysql.innodb_ddl_log
由这些操作产生的
对
表的
更改的重做日志
不会持久保存到磁盘。
这种情况可能会在回滚或恢复期间导致错误。
该
InnoDB
存储引擎分阶段执行DDL操作。
DDL操作
ALTER
TABLE
可以
在
Commit
阶段
之前多次
执行
Prepare
和
Perform
阶段
。
准备
:创建所需对象并将DDL日志写入
mysql.innodb_ddl_log
表中。
DDL日志定义了如何前滚和回滚DDL操作。
执行
:执行DDL操作。
例如,为
CREATE
TABLE
操作
执行创建例程
。
提交 :更新数据字典并提交数据字典事务。
Post-DDL
:重播并从
mysql.innodb_ddl_log
表中
删除DDL日志
。
为了确保可以安全地执行回滚而不引入不一致,在最后阶段执行文件操作,例如重命名或删除数据文件。
这一阶段还从删除的动态元数据
mysql.innodb_dynamic_metadata
的数据字典表
DROP
TABLE
,
TRUNCATE
TABLE
和该重建表其他DDL操作。
无论事务是提交还是回滚,
DDL日志都会
mysql.innodb_ddl_log
在
Post-DDL
阶段
重播并从
表中
删除
。
mysql.innodb_ddl_log
如果服务器在DDL操作期间暂停,则
DDL日志应仅保留在
表中。
在这种情况下,DDL日志将在恢复后重播并删除。
在恢复情况下,可以在重新启动服务器时提交或回滚DDL事务。
如果
在重做日志和二进制日志中存在DDL操作
的
提交
阶段
期间执行的数据字典事务,则
该操作被视为成功并且前滚。
否则,在
InnoDB
重放数据字典重做日志
时回滚不完整的数据字典事务
,并回滚DDL事务。
要
mysql.innodb_ddl_log
在涉及
InnoDB
存储引擎的
原子DDL操作期间
查看写入
数据字典表
innodb_print_ddl_logs
的DDL日志
,请启用
MySQL以将DDL日志写入
stderr
。
根据主机操作系统和MySQL配置,
stderr
可能是错误日志,终端或控制台窗口。
请参见
第5.4.2.2节“默认错误日志目标配置”
。
InnoDB
将DDL日志写入
mysql.innodb_ddl_log
表以支持重做和回滚DDL操作。
该
mysql.innodb_ddl_log
表是隐藏在
mysql.ibd
数据字典表空间
中的隐藏数据字典表
。
与其他隐藏数据字典表一样,
mysql.innodb_ddl_log
在非调试版本的MySQL中无法直接访问
该
表。
(请参见
第14.1节“数据字典模式”
。)
mysql.innodb_ddl_log
表
的结构
对应于此定义:
CREATE TABLE mysql.innodb_ddl_log( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, thread_id BIGINT UNSIGNED NOT NULL, 类型INT UNSIGNED NOT NULL, space_id INT UNSIGNED, page_no INT未签名, index_id BIGINT UNSIGNED, table_id BIGINT UNSIGNED, old_file_path VARCHAR(512)COLLATE UTF8_BIN, new_file_path VARCHAR(512)COLLATE UTF8_BIN, KEY(thread_id单) );
id
:DDL日志记录的唯一标识符。
thread_id
:为每个DDL日志记录分配一个
thread_id
,用于重播和删除属于特定DDL事务的DDL日志。
涉及多个数据文件操作的DDL事务会生成多个DDL日志记录。
type
:DDL操作类型。
类型包括
FREE
(删除索引树),
DELETE
(删除文件),
RENAME
(重命名文件)或
DROP
(从
mysql.innodb_dynamic_metadata
数据字典表中
删除元
数据)。
space_id
:表空间ID。
page_no
:包含分配信息的页面;
例如,索引树根页面。
index_id
:索引ID。
table_id
:表ID。
old_file_path
:旧的表空间文件路径。
由创建或删除表空间文件的DDL操作使用;
也用于重命名表空间的DDL操作。
new_file_path
:新的表空间文件路径。
由重命名表空间文件的DDL操作使用。
此示例演示
innodb_print_ddl_logs
如何查看
strderr
为
CREATE TABLE
操作
写入的DDL日志
。
mysql> SET GLOBAL innodb_print_ddl_logs = 1; mysql> CREATE TABLE t1(c1 INT)ENGINE = InnoDB;
[注意] [000000] InnoDB:DDL日志插入:[DDL记录:DELETE SPACE,id = 18,thread_id = 7, space_id = 5,old_file_path =。/ test / t1.ibd] [注意] [000000] InnoDB:DDL日志删除:按id 18 [注意] [000000] InnoDB:DDL日志插入:[DDL记录:REMOVE CACHE,id = 19,thread_id = 7, table_id = 1058,new_file_path = test / t1] [注意] [000000] InnoDB:DDL日志删除:按id 19 [注意] [000000] InnoDB:DDL日志插入:[DDL记录:FREE,id = 20,thread_id = 7, space_id = 5,index_id = 132,page_no = 4] [注意] [000000] InnoDB:DDL日志删除:按id 20 [注意] [000000] InnoDB:DDL log post ddl:begin for thread id:7 [注意] [000000] InnoDB:DDL日志发布ddl:end for thread id:7
ALTER {DATABASE | SCHEMA} [db_name
]alter_specification
......alter_specification
: [DEFAULT] CHARACTER SET [=]charset_name
| [DEFAULT] COLLATE [=]collation_name
| DEFAULT ENCRYPTION [=] {'Y'| 'N'}
ALTER
DATABASE
使您可以更改数据库的整体特征。
这些特征存储在数据字典中。
要使用
ALTER
DATABASE
,您需要
ALTER
数据库
的
权限。
ALTER
SCHEMA
是...的同义词
ALTER
DATABASE
。
可以从第一个语法中省略数据库名称,在这种情况下,该语句将应用于默认数据库。
该
CHARACTER SET
子句更改默认数据库字符集。
该
COLLATE
子句更改默认数据库排序规则。
第10章,
字符集,排序规则,Unicode
,讨论字符集和排序规则名称。
您可以分别使用
SHOW CHARACTER
SET
和
SHOW
COLLATION
语句
查看可用的字符集和排序规则
。
有关更多
信息,
请参见
第13.7.6.3节“显示字符集语法”
和
第13.7.6.4
节“显示字符集语法”
。
如果更改数据库的默认字符集或排序规则,则必须删除并重新创建使用数据库默认值的存储例程,以便它们使用新的默认值。 (在存储例程中,如果未明确指定字符集或排序规则,则具有字符数据类型的变量将使用数据库缺省值。请参见 第13.1.17节“创建过程和创建函数语法” 。)
DEFAULT ENCRYPTION
MySQL 8.0.16中引入的
该
子句定义了默认数据库加密,该加密由数据库中创建的表继承。
更改数据库的默认加密不会更改与架构关联的现有表的加密。
只有新创建的表才会继承默认的数据库加密。
在
ALTER
DATABASE
没有
DEFAULT
ENCRYPTION
子句的情况下
执行的
语句会保留现有的默认数据库加密。
如果
table_encryption_privilege_check
启用
该
变量,
TABLE_ENCRYPTION_ADMIN
则需要
该
权限才能指定与设置不同的默认加密
default_table_encryption
设置。
有关更多信息,请参阅
为架构和常规表空间定义加密默认值
。
改变 [DEFINER =user
] 活动event_name
[安排时间表schedule
] [完成[NOT] PRESERVE] [重命名new_event_name
] [ENABLE | 禁用| 禁止在[SLAVE] [评论'string
'] [DOevent_body
]
该
ALTER
EVENT
语句更改现有事件的一个或多个特征,而无需删除和重新创建它。
的语法的每个的
DEFINER
,
ON SCHEDULE
,
ON COMPLETION
,
COMMENT
,
ENABLE
/
DISABLE
,和
DO
条款是完全一样的当用于如
CREATE
EVENT
。
(请参见
第13.1.13节“创建事件语法”
。)
任何用户都可以更改在该用户具有该
EVENT
权限
的数据库上定义的事件
。
当用户执行成功的
ALTER
EVENT
语句时,该用户将成为受影响事件的定义者。
ALTER
EVENT
仅适用于现有事件:
的MySQL>ALTER EVENT no_such_event
>ON SCHEDULE
> ERROR 1517(HY000):未知事件'no_such_event'EVERY '2:3' DAY_HOUR;
在以下每个示例中,假设命名事件
myevent
的定义如下所示:
创造事件myevent 按照时间表 每6个小时 评论'示例评论。' 做 更新myschema.mytable SET mycol = mycol + 1;
以下语句将计划
myevent
从立即开始每六小时
更改为
每十二小时一次,从语句运行开始四小时开始:
改变事件myevent 按照时间表 每12个小时 STARTS CURRENT_TIMESTAMP + INTERVAL 4小时;
可以在单个语句中更改事件的多个特征。
此示例将执行的SQL语句更改为
myevent
删除所有记录的
语句
mytable
;
它还会更改事件的计划,使其在
ALTER
EVENT
运行
此
语句
后一天执行一次
。
改变事件myevent 按照时间表 在CURRENT_TIMESTAMP + INTERVAL 1天 做 TRUNCATE TABLE myschema.mytable;
ALTER
EVENT
仅为要更改的特征
在
语句中
指定选项
;
省略的选项保留其现有值。
这包括任何默认值
CREATE
EVENT
,例如
ENABLE
。
要禁用
myevent
,请使用以下
ALTER
EVENT
语句:
改变事件myevent 禁用;
该
ON SCHEDULE
子句可以使用涉及内置MySQL函数和用户变量的表达式来获取
它包含的
任何
timestamp
或
interval
值。
您不能在此类表达式中使用存储的例程或用户定义的函数,也不能使用任何表引用;
但是,你可以使用
SELECT FROM DUAL
。
对于这两个
ALTER
EVENT
和
CREATE
EVENT
陈述
都是如此
。
在这种情况下,特别不允许引用存储例程,用户定义函数和表,并且会因错误而失败(参见Bug#22830)。
虽然
在其
子句
ALTER
EVENT
中包含另一个
ALTER
EVENT
语句的
DO
语句似乎成功,但是当服务器尝试执行生成的已调度事件时,执行将失败并显示错误。
要重命名事件,请使用
ALTER
EVENT
语句的
RENAME TO
子句。
此语句将事件重命名
myevent
为
yourevent
:
改变事件myevent 重命名给你;
您还可以使用
ALTER EVENT ... RENAME TO ...
和
表示法
将事件移动到其他数据库
,如下所示:
db_name.event_name
ALTER EVENT olddb.myevent 重命名为newdb.myevent;
要执行前一个语句,执行它的用户必须
EVENT
同时拥有
olddb
和
newdb
数据库
的
权限
。
没有
RENAME EVENT
声明。
该值
DISABLE ON SLAVE
用于复制从站而不是
ENABLE
或
DISABLE
表示在主站上创建并复制到从站的事件,但不在从站上执行。
通常,
DISABLE ON
SLAVE
根据需要自动设置;
但是,在某些情况下,您可能需要或需要手动更改它。
有关
更多信息
,
请参见
第17.4.1.16节“调用的特性的复制”
。
改变功能func_name
[characteristic
...]characteristic
: 评论'string
' | 语言SQL | {包含SQL | 没有SQL | 读取SQL数据| 修改SQL DATA} | SQL SECURITY {DEFINER | INVOKER}
此语句可用于更改存储函数的特征。
可以在
ALTER FUNCTION
语句中
指定多个更改
。
但是,您无法使用此语句更改存储函数的参数或正文;
要进行此类更改,您必须使用
DROP
FUNCTION
和
删除并重新创建函数
CREATE
FUNCTION
。
您必须拥有
ALTER ROUTINE
该功能
的
权限。
(该权限自动授予函数创建者。)如果启用了二进制日志记录,则该
ALTER FUNCTION
语句可能还需要该
SUPER
特权,如
第24.7节“存储程序二进制日志记录”中所述
。
更改实例instance_action
instance_action
:{ 旋转INNODB MASTER KEY | 旋转BINLOG MASTER KEY | RELOAD TLS [没有错误的错误] }
ALTER INSTANCE
定义适用于MySQL服务器实例的操作。
该声明支持以下操作:
ALTER INSTANCE ROTATE INNODB MASTER KEY
此操作将旋转用于
InnoDB
表空间加密
的主加密密钥
。
密钥轮换需要
ENCRYPTION_KEY_ADMIN
或
SUPER
特权。
要执行此操作,必须安装和配置密钥环插件。
有关说明,请参见
第6.4.4节“MySQL密钥环”
。
ALTER INSTANCE ROTATE INNODB MASTER KEY
支持并发DML。
但是,它不能与
CREATE TABLE ...
ENCRYPTION
或
同时
ALTER
TABLE ...
ENCRYPTION
运行,并且会采取锁定来防止因并发执行这些语句而引起的冲突。
如果其中一个冲突的语句正在运行,则必须先完成,然后才能继续。
ALTER INSTANCE ROTATE INNODB MASTER KEY
语句将写入二进制日志,以便它们可以在复制的服务器上执行。
有关其他
ALTER INSTANCE ROTATE INNODB MASTER
KEY
用法信息,请参见
第15.6.3.9节“InnoDB静态数据加密”
。
ALTER INSTANCE ROTATE BINLOG MASTER KEY
此操作将旋转用于二进制日志加密的二进制日志主密钥。
二进制日志主密钥的密钥轮换需要
BINLOG_ENCRYPTION_ADMIN
或
SUPER
特权。
如果
binlog_encryption
系统变量设置为,
则不能使用该语句
OFF
。
要执行此操作,必须安装和配置密钥环插件。
有关说明,请参见
第6.4.4节“MySQL密钥环”
。
ALTER INSTANCE ROTATE BINLOG MASTER KEY
操作不会写入二进制日志,也不会在复制从服务器上执行。
因此,二进制日志主密钥轮换可以在包括混合MySQL版本的复制环境中执行。
要在所有适用的主服务器和从属服务器上安排定期轮换二进制日志主密钥,可以在每台服务器上启用MySQL事件调度程序,并
ALTER INSTANCE ROTATE BINLOG
MASTER KEY
使用
CREATE EVENT
语句
发出
语句。
如果您因为怀疑当前或任何以前的二进制日志主密钥可能已被泄露而轮换二进制日志主密钥,请在每个适用的主从服务器上发出该语句,这样您就可以验证是否立即符合。
有关其他
ALTER INSTANCE ROTATE BINLOG MASTER
KEY
使用信息,包括如果进程未正确完成或由于意外服务器暂停而中断操作,请参见
第17.3.10节“加密二进制日志文件和中继日志文件”
。
此操作从定义上下文的系统变量的当前值重新配置SSL上下文。
它还会更新反映活动上下文值的状态变量。
此操作需要该
CONNECTION_ADMIN
权限。
默认情况下,
RELOAD TLS
如果配置值不允许创建新的SSL上下文
,则
操作将回滚并显示错误,并且无效。
先前的上下文值继续用于新连接。
如果
NO ROLLBACK ON ERROR
给出
了可选
子句并且无法创建新上下文,则不会发生回滚。
而是生成警告,并为新连接禁用SSL。
ALTER INSTANCE RELOAD TLS
语句不会写入二进制日志(因此不会被复制)。
SSL配置是本地的,取决于所有涉及的服务器上不一定存在的本地文件。
有关重新配置SSL上下文的其他信息,包括与上下文相关的系统和状态变量,请参阅 加密连接的服务器端运行时配置 。
ALTER LOGFILE GROUPlogfile_group
ADD UNDOFILE'file_name
' [INITIAL_SIZE [=]size
] [等待] 发动机[=]engine_name
此语句将
UNDO
名为'
file_name
'
的
文件
添加
到现有日志文件组
logfile_group
。
一个
ALTER LOGFILE GROUP
语句有一个且只有一个
ADD UNDOFILE
条款。
DROP UNDOFILE
目前不支持
任何
条款。
所有NDB Cluster Disk Data对象共享相同的命名空间。 这意味着 必须唯一地命名 每个磁盘数据对象 (而不仅仅是给定类型的每个磁盘数据对象)。 例如,您不能拥有具有相同名称的表空间和撤消日志文件,也不能具有撤消日志文件和具有相同名称的数据文件。
可选
INITIAL_SIZE
参数设置
UNDO
文件的初始大小(以字节为单位);
如果未指定,则初始大小默认为134217728(128 MB)。
您可以选择
size
使用一个字母的缩写,一个数量级,类似于中使用的那些
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.16节“CREATE LOGFILE GROUP语法”
):
ALTER LOGFILE GROUP lg_3 添加UNDOFILE'under_10.dat' INITIAL_SIZE = 32M ENGINE = NDBCLUSTER;
当
ALTER LOGFILE GROUP
与
ENGINE = NDBCLUSTER
(替代地
ENGINE = NDB
)一起使用时,
UNDO
在每个NDB集群数据节点上创建日志文件。
您可以
UNDO
通过查询
INFORMATION_SCHEMA.FILES
表
来验证
文件是否已创建并获取有关它们的信息
。
例如:
mysql>SELECT FILE_NAME, LOGFILE_GROUP_NUMBER, EXTRA
- >FROM INFORMATION_SCHEMA.FILES
- >WHERE LOGFILE_GROUP_NAME = 'lg_3';
+ ------------- + ---------------------- + ------------ ---- + | FILE_NAME | LOGFILE_GROUP_NUMBER | 额外| + ------------- + ---------------------- + ------------ ---- + | 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行(0.01秒)
(参见 第25.11节“INFORMATION_SCHEMA文件表” 。)
用于的内存
UNDO_BUFFER_SIZE
来自全局池,其大小由
SharedGlobalMemory
数据节点配置参数
的值确定
。
这包括通过设置
InitialLogFileGroup
数据节点配置参数
对此选项隐含的任何默认值
。
ALTER LOGFILE GROUP
仅适用于NDB Cluster的磁盘数据存储。
有关更多信息,请参见
第22.5.13节“NDB集群磁盘数据表”
。
更改程序proc_name
[characteristic
...]characteristic
: 评论'string
' | 语言SQL | {包含SQL | 没有SQL | 读取SQL数据| 修改SQL DATA} | SQL SECURITY {DEFINER | INVOKER}
此语句可用于更改存储过程的特征。
可以在
ALTER PROCEDURE
语句中
指定多个更改
。
但是,您无法使用此语句更改存储过程的参数或主体;
要进行此类更改,您必须使用
DROP
PROCEDURE
和
删除并重新创建该过程
CREATE
PROCEDURE
。
您必须拥有
ALTER ROUTINE
该过程
的
特权。
默认情况下,该权限自动授予过程创建者。
可以通过禁用
automatic_sp_privileges
系统变量
来更改此行为
。
请参见
第24.2.2节“存储例程和MySQL特权”
。
更改服务器server_name
选项(option
[,option
] ...)
更改服务器信息
,调整
server_name
CREATE
SERVER
语句中
允许的任何选项
。
mysql.servers
表中
的相应字段会相应
更新。
此声明需要该
SUPER
权限。
例如,要更新
USER
选项:
ALTER SERVER的选项(USER'sally');
ALTER SERVER
导致隐式提交。
请参见
第13.3.3节“导致隐式提交的语句”
。
ALTER SERVER
无论正在使用的日志记录格式如何,都不会写入二进制日志。
ALTER TABLEtbl_name
[alter_specification
[,alter_specification
] ...] [partition_options
]alter_specification
:table_options
| 添加[栏目] [第一个| 之后]col_name
column_definition
col_name
| 添加[栏目](,...)col_name
column_definition
| 添加{INDEX | KEY} [index_name
] [index_type
](key_part
,...)[index_option
] ...... | ADD {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name
] (key_part
,......)[index_option
] ...... | 添加[CONSTRAINT [symbol
]] PRIMARY KEY [index_type
](key_part
,...) [index_option
] ...... | ADD [CONSTRAINT [symbol
]] UNIQUE [INDEX | KEY] [index_name
] [index_type
](key_part
,...) [index_option
] ...... | 添加[CONSTRAINT [symbol
]]外键 [index_name
](col_name
,...)reference_definition
| ADDcheck_constraint_definition
| DROP CHECKsymbol
| 更改检查symbol
[NOT]强制执行 | 算法[=] {DEFAULT | INSTANT | INPLACE | COPY} | ALTER [COLUMN]col_name
{SET DEFAULTliteral
| DROP DEFAULT} | ALTER INDEXindex_name
{VISIBLE | 无形} | 更改[栏目] [第一|后]old_col_name
new_col_name
column_definition
col_name
| [DEFAULT] CHARACTER SET [=]charset_name
[COLLATE [=]collation_name
] | 转换为字符集charset_name
[COLLATEcollation_name
] | {DISABLE | ENABLE} KEYS | {DISCARD | IMPORT} TABLESPACE | DROP [COLUMN]col_name
| DROP {INDEX | KEY}index_name
| DROP PRIMARY KEY | DROP FOREIGN KEYfk_symbol
| 力 | LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE} | 修改[专栏] [第一个| 之后]col_name
column_definition
col_name
| ORDER BYcol_name
[,col_name
] ...... | RENAME COLUMNold_col_name
TOnew_col_name
| 重命名{INDEX | KEY}old_index_name
至new_index_name
| 重命名[TO | AS]new_tbl_name
| {WITHOUT | WITH}验证 | 添加分区(partition_definition
) | DROP PARTITIONpartition_names
| DISCARD PARTITION {partition_names
| ALL} TABLESPACE | IMPORT PARTITION {partition_names
| ALL} TABLESPACE | TRUNCATE PARTITION {partition_names
| 所有} | COALESCE PARTITIONnumber
| 重新划分partition_names
(partition_definitions
) |partition_name
表tbl_name
[[WITH | WITHOUT}验证]的交换分区 | 分析分区{partition_names
| 所有} | 检查分区{partition_names
| 所有} | OPTIMIZE PARTITION {partition_names
| 所有} | REBUILD PARTITION {partition_names
| 所有} | 修复分区{partition_names
| 所有} | 删除分区key_part
:{col_name
[(length
)] | (expr
)} [ASC | DESC]index_type
: 使用{BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| 与PARSERparser_name
| 评论'string
' | {VISIBLE | 无形}check_constraint_definition
: [CONSTRAINT [symbol
]] CHECK(expr
)[[NOT] ENFORCED]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
| 评论[=]'string
' | COMPRESSION [=] {'ZLIB'|'LZ4'|'NONE'} | 连接[=]'connect_string
' | {DATA | INDEX} DIRECTORY [=]'absolute path to directory
' | DELAY_KEY_WRITE [=] {0 | 1} | ENCRYPTION [=] {'Y'| 'N'} | 发动机[=]engine_name
| INSERT_METHOD [=] {NO | 第一个| 最后} | KEY_BLOCK_SIZE [=]value
| MAX_ROWS [=]value
| MIN_ROWS [=]value
| PACK_KEYS [=] {0 | 1 | 默认} | 密码[=]'string
' | ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT} | STATS_AUTO_RECALC [=] {DEFAULT | 0 | 1} | STATS_PERSISTENT [=] {DEFAULT | 0 | 1} | STATS_SAMPLE_PAGES [=]value
| TABLESPACEtablespace_name
[STORAGE {DISK | MEMORY}] | UNION [=](tbl_name
[,tbl_name
] ......)partition_options
: (见CREATE TABLE
选项)
ALTER
TABLE
改变表的结构。
例如,您可以添加或删除列,创建或销毁索引,更改现有列的类型,或重命名列或表本身。
您还可以更改特征,例如用于表的存储引擎或表注释。
要使用
ALTER
TABLE
,你需要
ALTER
,
CREATE
和
INSERT
权限表。
重命名表需要
ALTER
和
DROP
对旧表,
ALTER
,
CREATE
,和
INSERT
对新表。
在表名后面,指定要进行的更改。
如果没有给出,
ALTER
TABLE
什么都不做。
许多允许的更改的语法类似于
CREATE TABLE
语句的
子句
。
column_definition
条款使用相同的语法
ADD
和
CHANGE
作为
CREATE
TABLE
。
有关更多信息,请参见
第13.1.20节“CREATE TABLE语法”
。
该字
COLUMN
是可选的,可以省略,除了
RENAME COLUMN
(区分列重命名操作和
RENAME
表重命名操作)。
多
ADD
,
ALTER
,
DROP
,和
CHANGE
条款,允许在一个单一的
ALTER
TABLE
声明中,用逗号隔开。
这是标准SQL的MySQL扩展,每个
ALTER
TABLE
语句
只允许每个子句中的一个
。
例如,要在单个语句中删除多个列,请执行以下操作:
ALTER TABLE t2 DROP COLUMN c,DROP COLUMN d;
如果存储引擎不支持尝试的
ALTER
TABLE
操作,则可能会出现警告。
可以显示此类警告
SHOW WARNINGS
。
请参见
第13.7.6.40节“显示警告语法”
。
有关故障排除的信息
ALTER
TABLE
,请参见
第B.4.6.1节“ALTER TABLE的问题”
。
有关生成的列的信息,请参见 第13.1.9.2节“ALTER TABLE和生成的列” 。
有关用法示例,请参见 第13.1.9.3节“ALTER TABLE示例” 。
使用
mysql_info()
C API函数,您可以找出复制的行数
ALTER
TABLE
。
请参见
第28.7.7.36节“mysql_info()”
。
该
ALTER
TABLE
语句
还有其他几个方面
,本节中的以下主题对此进行了描述:
table_options
意味着可以在可以使用的一种表选项
CREATE
TABLE
语句,比如
ENGINE
,
AUTO_INCREMENT
,
AVG_ROW_LENGTH
,
MAX_ROWS
,
ROW_FORMAT
,或
TABLESPACE
。
有关所有表选项的说明,请参见
第13.1.20节“CREATE TABLE语法”
。
但是,
ALTER
TABLE
忽略
DATA
DIRECTORY
并
INDEX DIRECTORY
作为表选项给出。
ALTER
TABLE
仅允许它们作为分区选项,并要求您拥有该
FILE
权限。
使用表选项
ALTER
TABLE
提供了一种更改单个表特征的便捷方法。
例如:
如果
t1
当前不是
InnoDB
表,则此语句将其存储引擎更改为
InnoDB
:
ALTER TABLE t1 ENGINE = InnoDB;
有关
将表
切换到
InnoDB
存储引擎
时的注意
事项,
请参见
第15.6.1.3节“将表从MyISAM转换为InnoDB”
。
指定
ENGINE
子句时,
ALTER TABLE
重建表。
即使表已具有指定的存储引擎,也是如此。
在现有
表
上
运行
会执行
“
null
”
操作,该操作可用于对
表
进行碎片整理
,如
第15.11.4节“对表进行碎片整理”中所述
。
在
表
上
运行
执行相同的功能。
ALTER
TABLE
tbl_name
ENGINE=INNODBInnoDB
ALTER
TABLE
InnoDB
ALTER TABLE
tbl_name
FORCEInnoDB
ALTER
TABLE
并
使用
在线DDL
。
有关更多信息,请参见
第15.12节“InnoDB和在线DDL”
。
tbl_name
ENGINE=INNODBALTER TABLE
tbl_name
FORCE
尝试更改表的存储引擎的结果受所需存储引擎是否可用以及
NO_ENGINE_SUBSTITUTION
SQL模式
设置的影响
,如
第5.1.11节“服务器SQL模式”中所述
。
为防止意外丢失数据,
ALTER TABLE
不能用于将表的存储引擎更改为
MERGE
或
BLACKHOLE
。
要更改
InnoDB
表以使用压缩行存储格式:
ALTER TABLE t1 ROW_FORMAT = COMPRESSED;
该
ENCRYPTION
子句启用或禁用表的页级数据加密
InnoDB
。
必须安装密钥环插件并将其配置为启用加密。
如果
table_encryption_privilege_check
启用
该
变量,
TABLE_ENCRYPTION_ADMIN
则需要使用具有
ENCRYPTION
与默认架构加密设置不同的设置
的
子句
的
权限
。
在MySQL 8.0.16之前,
ENCRYPTION
仅在更改驻留在每个表文件表空间中的表时才支持
该
子句。
从MySQL 8.0.16开始,
ENCRYPTION
对于驻留在一般表空间中的表也支持
该
子句。
对于驻留在常规表空间中的表,表和表空间加密必须匹配。
如果没有明确指定
ENCRYPTION
子句,
则不允许通过将表移动到不同的表空间或更改存储引擎来更改表加密
。
从MySQL 8.0.16开始,
如果表使用不支持加密的存储引擎,则
指定
ENCRYPTION
一个值不是
'N'
或
''
不允许
的
子句
。
此前,该条款被接受。
尝试
ENCRYPTION
使用不支持加密的存储引擎在启用加密的模式中
创建没有
子句
的表
也是不允许的。
有关更多信息,请参见 第15.6.3.9节“InnoDB静态数据加密” 。
要重置当前的自动增量值:
ALTER TABLE t1 AUTO_INCREMENT = 13;
您无法将计数器重置为小于或等于当前正在使用的值的值。
对于两者
InnoDB
和
MyISAM
,如果该值小于或等于
AUTO_INCREMENT
列中当前的最大值,则将该值重置为当前最大
AUTO_INCREMENT
列值加1。
要更改默认表格字符集:
ALTER TABLE t1 CHARACTER SET = utf8;
另请参阅 更改字符集 。
添加(或更改)表注释:
ALTER TABLE t1 COMMENT ='新表评论';
ALTER TABLE
与
TABLESPACE
选项一起
使用
可
InnoDB
在现有
通用表空间
,
每表文件表
空间和
系统表空间
之间
移动
表
。
请参阅
使用ALTER TABLE在表空间之间移动表
。
ALTER TABLE ... TABLESPACE
即使
TABLESPACE
属性未从其先前值更改,
操作也始终会导致完整表重建
。
ALTER TABLE ... TABLESPACE
语法不支持将表从临时表空间移动到持久表空间。
不支持
该
DATA DIRECTORY
子句,但
CREATE TABLE
... TABLESPACE
不支持
该
子句,
ALTER TABLE ... TABLESPACE
如果指定则忽略
该
子句
。
有关该
TABLESPACE
选项
的功能和限制的详细信息
,请参阅
CREATE TABLE
。
MySQL NDB Cluster 8.0支持设置
NDB_TABLE
用于控制表的分区平衡(片段计数类型),从任何副本读取,完全复制或这些的任意组合的选项,作为
ALTER TABLE
语句
的表注释的一部分
以相同的方式至于
CREATE TABLE
,如本例所示:
ALTER TABLE t1 COMMENT =“NDB_TABLE = READ_BACKUP = 0,PARTITION_BALANCE = FOR_RA_BY_NODE”;
请记住,
ALTER TABLE ... COMMENT
...
丢弃该表的任何现有注释。
有关
其他信息和示例,
请参阅
设置NDB_TABLE选项
。
要验证表选项是否按预期更改,请使用
SHOW CREATE TABLE
或查询
INFORMATION_SCHEMA.TABLES
表。
ALTER
TABLE
使用以下算法之一处理操作:
COPY
:对原始表的副本执行操作,并将表数据从原始表逐行复制到新表。
不允许并发DML。
INPLACE
:操作避免复制表数据,但可能会重建表。
可以在操作的准备和执行阶段期间简要地对表进行独占元数据锁定。
通常,支持并发DML。
INSTANT
:操作仅修改数据字典中的元数据。
在准备和执行期间,不会在表上采用独占元数据锁,并且表数据不受影响,从而使操作立即生效。
允许并发DML。
(在MySQL 8.0.12中引入)
该
ALGORITHM
条款是可选的。
如果
ALGORITHM
省略
该
子句,MySQL将使用
支持它的
ALGORITHM=INSTANT
存储引擎和
ALTER
TABLE
子句。
否则,
ALGORITHM=INPLACE
使用。
如果
ALGORITHM=INPLACE
不支持,
ALGORITHM=COPY
则使用。
指定
ALGORITHM
子句需要操作将指定的算法用于支持它的子句和存储引擎,否则将失败并返回错误。
指定
ALGORITHM=DEFAULT
与省略该
ALGORITHM
子句
相同
。
ALTER
TABLE
使用该
COPY
算法的操作等待修改表的其他操作完成。
对表副本应用更改后,将复制数据,删除原始表,并将表副本重命名为原始表的名称。
在
ALTER
TABLE
执行操作时,原始表可由其他会话读取(不久之后会注明)。
ALTER
TABLE
操作开始
后启动的表的更新和写入将
停止,直到新表准备就绪,然后自动重定向到新表。
除非是a,否则表的临时副本将在原始表的数据库目录中创建
RENAME TO
将表移动到驻留在不同目录中的数据库的操作。
前面提到的异常是
ALTER
TABLE
块在准备从表和表定义高速缓存中清除过时的表结构时读取(而不仅仅是写入)。
此时,它必须获得独占锁。
为此,它等待当前读者完成,并阻止新的读写。
ALTER TABLE
使用该
COPY
算法
的
操作
可防止并发DML操作。
仍然允许并发查询。
也就是说,表复制操作总是至少包括
LOCK=SHARED
(允许查询但不是DML)
的并发限制
。
您可以
LOCK
通过指定
进一步限制支持该
子句的
操作的并发性
LOCK=EXCLUSIVE
,从而阻止DML和查询。
有关更多信息,请参阅
并发控制
。
要强制将
COPY
算法用于
ALTER
TABLE
不使用
该
算法的
操作,请指定
ALGORITHM=COPY
或启用
old_alter_table
系统变量。
如果
old_alter_table
设置与
ALGORITHM
具有非其他值
的
子句
之间存在冲突
DEFAULT
,则该
ALGORITHM
子句优先。
对于
InnoDB
表,
在驻留在
共享表空间中
的表上
ALTER
TABLE
使用该
COPY
算法
的
操作
可以增加
表
空间使用的空间量。
此类操作需要与表中的数据和索引一样多的额外空间。
对于驻留在共享表空间中的表,操作期间使用的额外空间不会释放回操作系统,因为它是驻留在
每个表文件表
空间中的表。
有关在线DDL操作的空间要求的信息,请参见 第15.12.3节“在线DDL空间要求” 。
ALTER TABLE
支持该
INPLACE
算法的
操作
包括:
ALTER TABLE
InnoDB
在线DDL
功能
支持的操作
。
请参见
第15.12.1节“在线DDL操作”
。
重命名表格。
MySQL重命名与表对应的文件
tbl_name
而不进行复制。
(您也可以使用该
RENAME
TABLE
语句重命名表。请参见
第13.1.36节“RENAME TABLE语法”
。)专门为重命名表授予的权限不会迁移到新名称。
必须手动更改它们。
仅修改表元数据的操作。 这些操作是立即的,因为服务器不接触表内容。 仅元数据操作包括:
重命名列。
更改列的默认值(
NDB
表
除外
)。
通过将新枚举或集成员添加到
有效成员值列表
的
末尾
来
修改
ENUM
或
SET
列
的定义
,只要数据类型的存储大小不会更改。
例如,将成员添加到
具有8个成员
的
列会将每个值所需的存储空间从1个字节更改为2个字节;
这需要一个表副本。
在列表中间添加成员会导致重新编号现有成员,这需要表副本。
SET
更改空间列的定义以删除该
SRID
属性。
(添加或更改
SRID
属性确实需要重建,并且无法在适当的位置完成,因为服务器必须验证所有值都具有指定的SRID值。)
从MySQL 8.0.14开始,在这些条件适用时更改列字符集:
从MySQL 8.0.14开始,在适用这些条件时更改生成的列:
对于
InnoDB
表,修改生成的存储列但不更改其类型,表达式或可为空性的语句。
对于非
InnoDB
表,修改生成的存储列或虚拟列但不更改其类型,表达式或可为空性的语句。
An example of such a change is a change to the column comment.
Renaming an index.
Adding or dropping a secondary index, for
InnoDB
and
NDB
tables. See
Section 15.12.1,
“Online DDL Operations”.
For NDB
tables, operations that
add and drop indexes on variable-width columns. These
operations occur online, without table copying and without
blocking concurrent DML actions for most of their duration.
See Section 22.5.14,
“Online Operations with ALTER TABLE in NDB Cluster”.
Modifying index visibility with an ALTER
INDEX
operation.
Column modifications of tables containing generated columns
that depend on columns with a DEFAULT
value
if the modified columns are not involved in the generated
column expressions. For example, changing the
NULL
property of a separate column can be
done in place without a table rebuild.
ALTER TABLE
operations that support the
INSTANT
algorithm include:
Adding a column. This feature is referred to as “Instant
ADD COLUMN
”. Limitations apply. See
Section 15.12.1,
“Online DDL Operations”.
Adding or dropping a virtual column.
Adding or dropping a column default value.
Modifying the definition of an
ENUM
or
SET
column.
The same
restrictions apply as described above for
ALGORITHM=INSTANT
.
Changing the index type.
Renaming a table. The same restrictions apply as described
above for ALGORITHM=INSTANT
.
For more information about operations that support
ALGORITHM=INSTANT
, see
Section 15.12.1,
“Online DDL Operations”.
ALTER TABLE
upgrades MySQL 5.5
temporal columns to 5.6 format for ADD COLUMN
,
CHANGE COLUMN
, MODIFY
COLUMN
, ADD INDEX
, and
FORCE
operations. This conversion cannot be
done using the INPLACE
algorithm because the
table must be rebuilt, so specifying
ALGORITHM=INPLACE
in these cases results in an
error. Specify ALGORITHM=COPY
if necessary.
If an ALTER TABLE
operation on a multicolumn
index used to partition a table by KEY
changes
the order of the columns, it can only be performed using
ALGORITHM=COPY
.
The WITHOUT VALIDATION
and WITH
VALIDATION
clauses affect whether
ALTER TABLE
performs an in-place
operation for
virtual generated
column modifications. See
Section 13.1.9.2,
“ALTER TABLE and Generated Columns”.
NDB Cluster 8.0 supports online operations using the same
ALGORITHM=INPLACE
syntax used with the standard
MySQL Server. See
Section 22.5.14,
“Online Operations with ALTER TABLE in NDB Cluster”, for more
information.
ALTER TABLE
with DISCARD ... PARTITION
... TABLESPACE
or IMPORT ... PARTITION ...
TABLESPACE
does not create any temporary tables or
temporary partition files.
ALTER TABLE
with ADD
PARTITION
, DROP PARTITION
,
COALESCE PARTITION
, REBUILD
PARTITION
, or REORGANIZE PARTITION
does not create temporary tables (except when used with
NDB
tables); however, these
operations can and do create temporary partition files.
ADD
or DROP
operations for
RANGE
or LIST
partitions are
immediate operations or nearly so. ADD
or
COALESCE
operations for HASH
or KEY
partitions copy data between all
partitions, unless LINEAR HASH
or
LINEAR KEY
was used; this is effectively the
same as creating a new table, although the ADD
or COALESCE
operation is performed partition by
partition. REORGANIZE
operations copy only
changed partitions and do not touch unchanged ones.
For MyISAM
tables, you can speed up index
re-creation (the slowest part of the alteration process) by
setting the
myisam_sort_buffer_size
system
variable to a high value.
For ALTER
TABLE
operations that
support it, you can use the LOCK
clause to
control the level of concurrent reads and writes on a table while
it is being altered. Specifying a non-default value for this
clause enables you to require a certain amount of concurrent
access or exclusivity during the alter operation, and halts the
operation if the requested degree of locking is not available.
Only LOCK = DEFAULT
is permitted for operations
that use ALGORITHM=INSTANT
. The other
LOCK
clause parameters are not applicable.
The parameters for the LOCK
clause are:
LOCK = DEFAULT
Maximum level of concurrency for the given
ALGORITHM
clause (if any) and
ALTER TABLE
operation: Permit concurrent
reads and writes if supported. If not, permit concurrent reads
if supported. If not, enforce exclusive access.
LOCK = NONE
If supported, permit concurrent reads and writes. Otherwise, an error occurs.
LOCK = SHARED
If supported, permit concurrent reads but block writes. Writes
are blocked even if concurrent writes are supported by the
storage engine for the given ALGORITHM
clause (if any) and ALTER TABLE
operation.
If concurrent reads are not supported, an error occurs.
LOCK = EXCLUSIVE
实施独家访问。
即使存储引擎支持给定
ALGORITHM
子句(如果有)和
ALTER TABLE
操作的
并发读/写,也会执行此
操作。
用于
ADD
向表中添加新列,以及
DROP
删除现有列。
是标准SQL的MySQL扩展。
DROP
col_name
要在表格行中的特定位置添加列,请使用
FIRST
或
。
默认是最后添加列。
AFTER
col_name
如果表只包含一列,则无法删除该列。
如果您打算删除表,请改用该
DROP
TABLE
语句。
如果从表中删除列,则列也将从它们所属的任何索引中删除。
如果删除构成索引的所有列,则也会删除索引。
如果使用
CHANGE
或
MODIFY
缩短列上存在索引的列,并且结果列长度小于索引长度,MySQL会自动缩短索引。
对于
ALTER TABLE ... ADD
,如果列具有使用非确定性函数的表达式默认值,则该语句可能会产生警告或错误。
有关详细信息,请参见
第17.1.3.6节“使用GTID进行复制的限制”
。
在
CHANGE
,
MODIFY
,
RENAME COLUMN
,和
ALTER
条款允许的名称和现有列的定义被改变。
它们具有以下比较特征:
CHANGE
:
可以重命名列并更改其定义,或两者。
具有比
MODIFY
或
更多的能力
RENAME COLUMN
,但是以某些操作的便利性为代价。
CHANGE
如果不重命名,则需要将列命名两次,如果仅重命名,则需要重新指定列定义。
使用
FIRST
或
AFTER
可以重新排序列。
MODIFY
:
可以更改列定义但不能更改其名称。
比
CHANGE
不更改列定义更改列定义
更方便
。
使用
FIRST
或
AFTER
可以重新排序列。
RENAME COLUMN
:
可以更改列名但不能更改其定义。
比重
CHANGE
命名列而不更改其定义
更方便
。
ALTER
:仅用于更改列默认值。
CHANGE
是标准SQL的MySQL扩展。
MODIFY
并且
RENAME COLUMN
是Oracle兼容性的MySQL扩展。
要更改列以更改其名称和定义,请使用
CHANGE
,指定旧名称和新名称以及新定义。
例如,重命名
INT NOT
NULL
从塔
a
到
b
并改变其定义为使用
BIGINT
的数据类型,同时保留
NOT NULL
属性,操作如下:
ALTER TABLE t1 CHANGE ab BIGINT NOT NULL;
要更改列定义但不更改其名称,请使用
CHANGE
或
MODIFY
。
使用时
CHANGE
,语法需要两个列名,因此必须指定两次相同的名称才能保持名称不变。
例如,要更改列的定义
b
,请执行以下操作:
ALTER TABLE t1 CHANGE bb INT NOT NULL;
MODIFY
更改定义而不更改名称更方便,因为它只需要列名称一次:
ALTER TABLE t1 MODIFY b INT NOT NULL;
要更改列名但不更改其定义,请使用
CHANGE
或
RENAME COLUMN
。
使用时
CHANGE
,语法需要列定义,因此要保持定义不变,必须重新指定列当前具有的定义。
例如,要重命名
INT NOT NULL
的列
b
到
a
,这样做:
ALTER TABLE t1 CHANGE ba INT NOT NULL;
RENAME COLUMN
更改名称而不更改定义更方便,因为它只需要旧名称和新名称:
ALTER TABLE t1 RENAME COLUMN b TO a;
通常,您不能将列重命名为表中已存在的名称。
但是,有时情况并非如此,例如当您交换名称或将其移动一个循环时。
如果表具有名为
a
,,
b
和的
列
c
,则这些是有效的操作:
- 交换a和b ALTER TABLE t1 RENAME COLUMN a TO b, RENAME COLUMN b TO a; - 通过循环“旋转”a,b,c ALTER TABLE t1 RENAME COLUMN a TO b, RENAME COLUMN b TO c, RENAME COLUMN c TO a;
对于使用
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.11节“服务器SQL模式”
)。
如果使用
CHANGE
或
MODIFY
缩短列上存在索引的列,并且结果列长度小于索引长度,MySQL会自动缩短索引。
对于由
CHANGE
or
RENAME COLUMN
重命名的
列
,MySQL会自动将这些引用重命名为重命名的列:
引用旧列的索引,包括不可见索引和禁用
MyISAM
索引。
引用旧列的外键。
对于由
CHANGE
or
RENAME COLUMN
重命名的
列
,MySQL不会自动将这些引用重命名为重命名的列:
生成的列和分区表达式,用于引用重命名的列。
您必须使用
CHANGE
在与
ALTER
TABLE
重命名列的语句
相同的
语句中
重新定义此类表达式
。
引用重命名列的视图和存储程序。 您必须手动更改这些对象的定义以引用新列名称。
要重新排序表中的列,请使用
FIRST
and
AFTER
in
CHANGE
或
MODIFY
operations。
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.27节“DROP INDEX语法”
。
要确定索引名称,请使用
。
SHOW INDEX FROM
tbl_name
某些存储引擎允许您在创建索引时指定索引类型。
index_type
说明符
的语法
是
。
有关详细信息
,请参见
第13.1.15节“CREATE INDEX语法”
。
首选位置在列列表之后。
在将来的MySQL版本中,将删除在列列表之前使用该选项的支持。
USING
type_name
USING
index_option
values指定索引的其他选项。
USING
就是这样一个选择。
有关允许
index_option
值的
详细信息
,请参见
第13.1.15节“CREATE INDEX语法”
。
RENAME INDEX
重命名索引。
这是标准SQL的MySQL扩展。
表的内容保持不变。
old_index_name
TO
new_index_name
old_index_name
必须是表中未被同一
ALTER
TABLE
语句
删除的现有索引的名称
。
new_index_name
是新索引名称,在应用更改后,不能复制结果表中索引的名称。
索引名称都不能
PRIMARY
。
如果
ALTER
TABLE
在
MyISAM
表
上使用
,则所有非唯一索引都在单独的批处理中创建(至于
REPAIR
TABLE
)。
ALTER
TABLE
当你有很多索引时,
这应该会
快得多。
对于
MyISAM
表,可以显式控制密钥更新。
使用
ALTER TABLE ... DISABLE
KEYS
要告诉MySQL停止更新非唯一索引。
然后使用
ALTER TABLE ... ENABLE KEYS
重新创建缺失的索引。
MyISAM
使用比逐个插入密钥快得多的特殊算法来做到这一点,因此在执行批量插入操作之前禁用密钥应该会带来相当大的加速。
除了前面提到
ALTER TABLE ... DISABLE KEYS
的
INDEX
权限之外,
使用还
需要
特权。
虽然非唯一索引被禁用,它们将被忽略语句,如
SELECT
和
EXPLAIN
,否则会使用它们。
在
ALTER
TABLE
声明之后,可能需要运行
ANALYZE
TABLE
以更新索引基数信息。
请参见
第13.7.6.22节“SHOW INDEX语法”
。
该
ALTER INDEX
操作允许索引可见或不可见。
优化程序不使用不可见索引。
索引可见性的修改适用于主键以外的索引(显式或隐式)。
此功能是存储引擎中性(支持任何引擎)。
有关更多信息,请参见
第8.3.12节“不可见索引”
。
在
FOREIGN KEY
和
REFERENCES
条款由支持
InnoDB
和
NDB
存储引擎,它实现
。
请参见
第15.6.1.5节“InnoDB和FOREIGN KEY约束”
。
对于其他存储引擎,将解析子句但忽略这些子句。
ADD [CONSTRAINT
[
symbol
]] FOREIGN KEY
[index_name
] (...) REFERENCES ...
(...)
对于
ALTER
TABLE
不像
CREATE
TABLE
,
ADD FOREIGN
KEY
忽略了
index_name
如果给,并使用自动生成的外键的名称。
作为解决方法,请包含
CONSTRAINT
指定外键名称
的
子句:
添加约束外name
键(......)......
MySQL默默地忽略内联
REFERENCES
规范,其中引用被定义为列规范的一部分。
MySQL仅接受
REFERENCES
作为单独
FOREIGN KEY
规范的
一部分定义的子句
。
分区
InnoDB
表不支持外键。
此限制不适用于
NDB
表,包括那些明确分区的表
[LINEAR] KEY
。
有关更多信息,请参见
第23.6.2节“分区与存储引擎相关的限制”
。
MySQL Server和NDB Cluster都支持使用
ALTER
TABLE
删除外键:
ALTER TABLEtbl_name
DROP FOREIGN KEYfk_symbol
;
ALTER TABLE
支持
在同一
语句中
添加和删除外键
ALTER
TABLE ...
ALGORITHM=INPLACE
但不支持
ALTER
TABLE ...
ALGORITHM=COPY
。
服务器禁止更改可能导致参照完整性丢失的外键列。
解决方法是
ALTER
TABLE
... DROP FOREIGN KEY
在更改列定义之前和
ALTER
TABLE ... ADD FOREIGN KEY
之后使用。
禁止更改的示例包括:
对可能不安全的外键列的数据类型的更改。
例如,
允许
更改
VARCHAR(20)
为
VARCHAR(30)
,但将其更改
VARCHAR(1024)
为不是因为这会更改存储单个值所需的长度字节数。
禁止将
NULL
列
更改
NOT
NULL
为非严格模式,以防止将
NULL
值
转换
为默认的非
NULL
值,在引用的表中没有相应的值。
在严格模式下允许该操作,但如果需要任何此类转换,则会返回错误。
ALTER TABLE
更改内部生成的外键约束名称和以字符串
“
tbl_name
RENAME
new_tbl_name
tbl_name
_ibfk_
”
开头
以反映新表名称的
用户定义的外键约束名称
。
InnoDB
将以字符串
“
tbl_name
_ibfk_
”
开头的外键约束名称解释
为内部生成的名称。
在MySQL 8.0.16之前,
ALTER
TABLE
仅允许以下限制版本的
CHECK
约束添加语法,该语法被解析并被忽略:
添加检查(expr
)
从MySQL 8.0.16开始,
ALTER
TABLE
允许
CHECK
添加,删除或更改现有表的约束:
添加新约束:
ALTER TABLEtbl_name
ADD CONSTRAINT [symbol
] CHECK(expr
)[[NOT] ENFORCED];
约束语法元素的含义与for相同
CREATE
TABLE
。
请参见
第13.1.20.7节“检查约束”
。
删除名为的现有约束
symbol
:
ALTER TABLEtbl_name
DROP CHECKsymbol
;
更改是否
symbol
强制执行
现有约束
:
ALTER TABLEtbl_name
ALTER CHECKsymbol
[NOT] ENFORCED;
在
DROP CHECK
和
ALTER
CHECK
条款是MySQL的扩展标准SQL。
如果表更改导致违反强制
CHECK
约束,则会发生错误并且不会修改表。
发生错误的操作示例:
尝试将该
AUTO_INCREMENT
属性
添加
到
CHECK
约束中
使用的列
。
尝试添加强制
CHECK
约束或强制执行
非强制
约束
CHECK
,现有行违反约束条件。
尝试修改,重命名或删除
CHECK
约束中
使用的列
,除非该约束也在同一语句中删除。
例外:如果
CHECK
约束仅引用单个列,则删除列会自动删除约束。
ALTER TABLE
更改内部生成的和用户定义的
tbl_name
RENAME
new_tbl_name
CHECK
约束名称,以字符串
“
tbl_name
_chk_
”
开头
以反映新的表名。
MySQL
CHECK
将以字符串
“
tbl_name
_chk_
”
开头的约束名称
解释
为内部生成的名称。
要更改默认的表字符集和所有字符列(
CHAR
,
VARCHAR
,
TEXT
)到一个新的字符集,使用这样的语句:
ALTER TABLEtbl_name
CONVERT TO CHARACTER SETcharset_name
;
该语句还会更改所有字符列的排序规则。
如果指定no
COLLATE
子句指示要使用的排序规则,则该语句将对字符集使用默认排序规则。
如果此排序规则不适合预期的表使用(例如,如果它将从区分大小写的排序规则更改为不区分大小写的排序规则),请明确指定排序规则。
对于具有的数据类型的列
VARCHAR
或一个
TEXT
种类,
CONVERT TO
CHARACTER SET
改变了数据类型必须确保新列足够长,以尽可能多的字符存储为原始列。
例如,一
TEXT
列有两个长度字节,用于存储列中值的字节长度,最大值为65,535。
对于
latin1
TEXT
列,每个字符都需要一个字节,因此该列最多可以存储65,535个字符。
如果将列转换为
utf8
,则每个字符最多可能需要三个字节,最大可能长度为3×65,535 = 196,605字节。
该长度不适合
TEXT
列的长度字节,因此MySQL将数据类型转换为
MEDIUMTEXT
,这是长度字节可以记录值196,605的最小字符串类型。
同样,
VARCHAR
列可能会转换为
MEDIUMTEXT
。
要避免更改刚才描述的类型的数据类型,请不要使用
CONVERT TO CHARACTER SET
。
相反,用于
MODIFY
更改单个列。
例如:
ALTER TABLE t MODIFY latin1_text_col文本字符集utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M
)CHARACTER SET utf8;
如果您指定
CONVERT TO CHARACTER SET binary
的
CHAR
,
VARCHAR
和
TEXT
列转换为它们相应的二进制字符串类型(
BINARY
,
VARBINARY
,
BLOB
)。
这意味着列不再具有字符集,后续
CONVERT TO
操作将不适用于它们。
如果
charset_name
是
DEFAULT
在一个
CONVERT TO CHARACTER
SET
操作中,由命名的字符集
character_set_database
被用于系统变量。
该
CONVERT TO
操作转换原始字符集和命名字符集之间的列值。
如果你在一个字符集中有一个列(如
),
那么
这
不是
你想要的,
latin1
但存储的值实际上使用了一些其他不兼容的字符集(如
utf8
)。
在这种情况下,您必须为每个此类列执行以下操作:
ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
这样做的原因是当您转换为
BLOB
列
或从
列
转换时没有转换
。
要仅更改 表 的 默认 字符集,请使用以下语句:
ALTER TABLEtbl_name
DEFAULT CHARACTER SETcharset_name
;
这个词
DEFAULT
是可选的。
如果未指定稍后添加到表中的列的字符集(例如,with
ALTER TABLE ... ADD
column
)
,则默认字符集是使用的字符集
。
当
foreign_key_checks
系统变量启用,这是默认设置,字符集转换是不允许的,其中包括在一个外键约束使用的字符串列的表。
解决方法是
foreign_key_checks
在执行字符集转换之前
禁用
。
在重新启用之前,必须对外键约束中涉及的两个表执行转换
foreign_key_checks
。
如果
foreign_key_checks
在仅转换其中一个表后
重新启用
,则
由于在这些操作期间发生的隐式转换,
ON DELETE
CASCADE
或
ON UPDATE CASCADE
操作可能会破坏引用表中的数据(Bug#45290,Bug#74816)。
一个
InnoDB
在自己创建的表
文件的每个表的
表空间可以被丢弃,并使用进口
DISCARD TABLESPACE
和
IMPORT
TABLESPACE
选项。
这些选项可用于从备份导入每个表的文件表空间,或者将每个表的文件表空间从一个数据库服务器复制到另一个数据库服务器。
请参见
第15.6.3.7节“将表空间复制到另一个实例”
。
ORDER BY
使您能够以特定顺序创建包含行的新表。
当您知道在大多数时间以特定顺序查询行时,此选项很有用。
通过在对表进行重大更改后使用此选项,您可以获得更高的性能。
在某些情况下,如果表格由您想要稍后订购的列按顺序排列,则可能会使MySQL更容易排序。
插入和删除后,表不会保持指定的顺序。
ORDER BY
语法允许为排序指定一个或多个列名,每个列名可选地可以分别跟随
ASC
或
DESC
指示升序或降序排序。
默认为升序。
只允许列名作为排序标准;
不允许使用任意表达式。
该条款应在任何其他条款之后最后给出。
ORDER BY
对
InnoDB
表
没有意义,
因为
InnoDB
总是根据
聚簇索引
对表行进行排序
。
在分区表上使用时,
ALTER TABLE ... ORDER
BY
仅对每个分区中的行进行排序。
partition_options
表示可以与分区表一起使用的选项,用于重新分区,添加,删除,丢弃,导入,合并和拆分分区,以及执行分区维护。
这是可能的
ALTER
TABLE
语句包含一个
PARTITION BY
或
REMOVE PARTITIONING
子句中,除其他更改规格,但
PARTITION
BY
还是
REMOVE PARTITIONING
子句必须最后任何其他规格后指定。
的
ADD
PARTITION
,
DROP PARTITION
,
DISCARD PARTITION
,
IMPORT
PARTITION
,
COALESCE PARTITION
,
REORGANIZE PARTITION
,
EXCHANGE
PARTITION
,
ANALYZE PARTITION
,
CHECK PARTITION
,和
REPAIR
PARTITION
选项不能与其他单一更改规格组合
ALTER TABLE
,因为选择刚上市就单个分区的行为。
有关分区选项的更多信息,请参见
第13.1.20节“CREATE TABLE语法”
和
第13.1.9.1节“ALTER TABLE分区操作”
。
有关
ALTER TABLE ...
EXCHANGE PARTITION
语句的
信息和示例
,请参见
第23.3.3节“使用表交换分区和子分区”
。
与分区相关的子句
ALTER
TABLE
可以与分区表一起用于重新分区,添加,删除,丢弃,导入,合并和拆分分区,以及执行分区维护。
只需
在分区表上
使用
partition_options
子句,
ALTER
TABLE
就可以根据定义的分区方案对表进行重新分区
partition_options
。
此子句始终
PARTITION BY
以及适用于该
partition_options
子句
的相同语法和其他规则
开始
CREATE
TABLE
(有关更多详细信息,请参见
第13.1.20节“CREATE TABLE语法”
),并且还可用于对现有表进行分区。尚未分区。
例如,考虑如下所示定义的(非分区)表:
CREATE TABLE t1( id INT, year_col INT );
通过此语句
HASH
,可以使用
id
列作为分区键
将此表分区
为8个分区:
改编表t1 哈希分区(id) PARTITIONS 8;
MySQL支持一个
ALGORITHM
选项
[SUB]PARTITION BY [LINEAR] KEY
。
ALGORITHM=1
在计算分区中行的位置时,服务器使用与MySQL 5.1相同的密钥散列函数;
ALGORITHM=2
表示服务器使用默认为
KEY
MySQL 5.5及更高版本中的
新
分区表
实现和使用的密钥散列函数
。
(使用MySQL 5.5及更高版本中使用的密钥散列函数创建的分区表不能由MySQL 5.1服务器使用。)不指定该选项与使用具有相同的效果
ALGORITHM=2
。
此选项主要用于升级或降级时
[LINEAR] KEY
MySQL 5.1和更高版本MySQL版本之间的分区表,或者用于创建
可在MySQL 5.1服务器上使用的MySQL 5.5或更高版本服务器上
KEY
或
LINEAR KEY
之上
分区的表
。
使用
ALTER TABLE
... PARTITION BY
语句
产生的
表必须遵循与
使用
语句创建的规则相同的规则
CREATE TABLE ...
PARTITION BY
。
这包括管理表可能具有的任何唯一键(包括任何主键)与分区表达式中使用的列之间的关系的规则,如
第23.6.1节“分区键,主键和独特的钥匙“
。
CREATE TABLE ... PARTITION BY
指定分区数
的
规则也适用于
ALTER TABLE ... PARTITION BY
。
该
partition_definition
子句
ALTER TABLE ADD PARTITION
支持与语句的同名子句相同的选项
CREATE
TABLE
。
(有关
语法和说明,
请参见
第13.1.20节“CREATE TABLE语法”
。)假设您创建了分区表,如下所示:
CREATE TABLE t1( id INT, year_col INT ) 按范围划分(year_col)( 分数p0值低于(1991), 分区p1值低于(1995), 分区p2值低于(1999) );
您可以
p3
向此表
添加新分区
,以存储小于以下值的值
2002
:
更改表t1添加分区(分区p3值小于(2002));
DROP PARTITION
可用于删除一个或多个
RANGE
或
LIST
分区。
这种说法不能使用
HASH
或
KEY
分区;
相反,使用
COALESCE
PARTITION
(见本节后面部分)。
存储在
partition_names
列表中
指定的已删除分区中的任何数据都将被
丢弃。
例如,根据
t1
先前定义
的表
,您可以删除命名的分区
p0
,
p1
如下所示:
ALTER TABLE t1 DROP PARTITION p0,p1;
DROP PARTITION
不适用于使用
NDB
存储引擎的
表
。
请参见
第23.3.1节“RANGE和LIST分区的管理”
和
第22.1.7节“NDB集群的已知限制”
。
ADD PARTITION
并且
DROP
PARTITION
目前不支持
IF
[NOT] EXISTS
。
在
DISCARD
PARTITION ... TABLESPACE
和
IMPORT
PARTITION ... TABLESPACE
选项延长
传输表空间
功能个别
InnoDB
表分区。
每个
InnoDB
表分区都有自己的表空间文件(
.ibd
文件)。
可
传输表空间
功能可以轻松地将表空间从正在运行的MySQL服务器实例复制到另一个正在运行的实例,或者在同一实例上执行还原。
这两个选项都使用逗号分隔的一个或多个分区名称列表。
例如:
更改表t1 DISCARD PARTITION p2,p3 TABLESPACE;
更改表t1导入分区p2,p3 TABLESPACE;
在子分区表上
运行时
DISCARD
PARTITION ... TABLESPACE
,
IMPORT
PARTITION ... TABLESPACE
允许分区和子分区名称。
指定分区名称时,将包括该分区的子分区。
可
传输表空间
功能还支持复制或还原分区
InnoDB
表(所有分区一次)。
有关其他信息,请参见
第15.6.3.7节“将表空间复制到另一个实例”
,以及
第15.6.3.7.1节“可传输表空间示例”
。
支持分区表的重命名。
您可以使用间接重命名单个分区
ALTER TABLE
... REORGANIZE PARTITION
;
但是,此操作会复制分区的数据。
要从选定分区中删除行,请使用该
TRUNCATE PARTITION
选项。
此选项采用一个或多个逗号分隔的分区名称列表。
考虑一下
t1
这个语句创建的表:
CREATE TABLE t1( id INT, year_col INT ) 按范围划分(year_col)( 分数p0值低于(1991), 分区p1值低于(1995), 分区p2值低于(1999), 分区p3的价值低于(2003年), 分区p4价值低于(2007年) );
要从分区中删除所有行
p0
,请使用以下语句:
ALTER TABLE t1 TRUNCATE PARTITION p0;
刚才显示的语句与以下
DELETE
语句
具有相同的效果
:
DELETE FROM t1 WHERE year_col <1991;
截断多个分区时,分区不必是连续的:这可以大大简化分区表上的删除操作,否则
WHERE
如果使用
DELETE
语句
,则需要非常复杂的
条件
。
例如,此语句删除分区中的所有行,
p1
并且
p3
:
ALTER TABLE t1 TRUNCATE PARTITION p1,p3;
DELETE
这里显示了
一个等效
语句:
从t1 WHERE中删除 (year_col> = 1991 AND year_col <1995) 要么 (year_col> = 2003 AND year_col <2007);
如果使用
ALL
关键字代替分区名称列表,则该语句将作用于所有表分区。
TRUNCATE PARTITION
只是删除行;
它不会改变表本身或其任何分区的定义。
要验证行是否已删除,请
INFORMATION_SCHEMA.PARTITIONS
使用以下查询
检查
表:
SELECT PARTITION_NAME,TABLE_ROWS 来自INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME ='t1';
COALESCE PARTITION
可以与分区的表一起使用,
HASH
或者
KEY
减少分区数
number
。
假设您已创建表
t2
,如下所示:
创建表t2( 名称VARCHAR(30), 开始日期 ) 哈希分区(年(开始)) 分数6;
要将使用的分区数
t2
从6减少到4,请使用以下语句:
更改表t2 COALESCE PARTITION 2;
最后一个
number
分区中
包含的数据
将合并到其余分区中。
在这种情况下,分区4和5将合并到前4个分区(编号为0,1,2和3的分区)中。
要更改分区表使用的部分但不是全部分区,可以使用
REORGANIZE
PARTITION
。
可以通过以下几种方式使用此语句:
将一组分区合并到一个分区中。
这是通过在
partition_names
列表中
命名多个分区
并为其提供单个定义来完成的
partition_definition
。
将现有分区拆分为多个分区。
通过为单个分区命名
partition_names
并提供多个
分区来完成此任务
partition_definitions
。
更改使用定义的分区子集的范围
VALUES LESS THAN
或
使用定义的分区子集
的值列表
VALUES IN
。
对于没有明确命名的分区,MySQL的自动提供的默认名称
p0
,
p1
,
p2
,等等。
对于子分区也是如此。
有关
ALTER TABLE ... REORGANIZE PARTITION
语句的
更多详细信息和示例
,请参见
第23.3.1节“RANGE和LIST分区的管理”
。
要使用表交换表分区或子分区,请使用该
ALTER
TABLE ... EXCHANGE PARTITION
语句,即将分区或子分区中的任何现有行移动到非分区表,将非分区表中的任何现有行移动到表分区或子分区。
有关用法信息和示例,请参见 第23.3.3节“使用表交换分区和子分区” 。
有几个选项提供分区维护和修复功能,类似于通过诸如
CHECK
TABLE
和
REPAIR
TABLE
(以及分区表也支持的
语句
)
为非
分区表实现的功能;有关更多信息,请参见
第13.7.3节“表维护语句”
)。
这些措施包括
ANALYZE PARTITION
,
CHECK
PARTITION
,
OPTIMIZE PARTITION
,
REBUILD PARTITION
,和
REPAIR
PARTITION
。
这些选项中的每一个都采用
partition_names
由一个或多个分区名称组成的子句,以逗号分隔。
分区必须已存在于目标表中。
您也可以使用
ALL
关键字代替
partition_names
在这种情况下,该语句作用于所有表分区。
有关更多信息和示例,请参见
第23.3.4节“分区维护”
。
InnoDB
目前不支持按分区优化;
ALTER TABLE ...
OPTIMIZE PARTITION
导致整个表重建和分析,并发出适当的警告。
(Bug#11751825,Bug#42822)要解决此问题,请使用
ALTER TABLE ... REBUILD
PARTITION
而
ALTER TABLE ... ANALYZE
PARTITION
不是。
在
ANALYZE PARTITION
,
CHECK
PARTITION
,
OPTIMIZE PARTITION
,和
REPAIR PARTITION
选项不支持未分区表。
REMOVE PARTITIONING
使您可以删除表的分区,而不会影响表或其数据。
此选项可以与其他
ALTER
TABLE
选项
结合使用,
例如用于添加,删除或重命名列或索引的选项。
使用该
ENGINE
选项
ALTER
TABLE
可更改表使用的存储引擎,而不会影响分区。
目标存储引擎必须提供自己的分区处理程序。
只有
InnoDB
和
NDB
存储引擎有本机分区处理程序;
NDB
MySQL 8.0目前不支持。
这是可能的
ALTER
TABLE
语句包含一个
PARTITION BY
或
REMOVE PARTITIONING
子句中,除其他更改规格,但
PARTITION
BY
还是
REMOVE PARTITIONING
子句必须最后任何其他规格后指定。
的
ADD PARTITION
,
DROP
PARTITION
,
COALESCE PARTITION
,
REORGANIZE PARTITION
,
ANALYZE
PARTITION
,
CHECK PARTITION
,和
REPAIR PARTITION
选项不能与其他单一更改规格组合
ALTER
TABLE
,因为选择刚上市就单个分区的行为。
有关更多信息,请参见
第13.1.9.1节“ALTER TABLE分区操作”
。
只有以下任一选项的单个实例可以在给定的使用
ALTER
TABLE
声明:
PARTITION BY
,
ADD
PARTITION
,
DROP PARTITION
,
TRUNCATE PARTITION
,
EXCHANGE
PARTITION
,
REORGANIZE PARTITION
,或
COALESCE PARTITION
,
ANALYZE
PARTITION
,
CHECK PARTITION
,
OPTIMIZE PARTITION
,
REBUILD
PARTITION
,
REMOVE PARTITIONING
。
例如,以下两个语句无效:
ALTER TABLE t1 ANALYZE PARTITION p1,ANALYZE PARTITION p2; ALTER TABLE t1 ANALYZE PARTITION p1,CHECK PARTITION p2;
在第一种情况下,您可以
使用单个语句同时
分析分区
p1
和
p2
表,
t1
并使用单个
ANALYZE PARTITION
选项列出要分析的两个分区,如下所示:
ALTER TABLE t1 ANALYZE PARTITION p1,p2;
在第二种情况下,不可能
同时在同一个表的不同分区上
执行
ANALYZE
和
CHECK
操作。
相反,您必须发出两个单独的语句,如下所示:
ALTER TABLE t1 ANALYZE PARTITION p1; ALTER TABLE t1检查分区p2;
REBUILD
子分区目前不支持操作。
所述
REBUILD
关键字被明确地与子分区不允许,并且使得
ALTER TABLE
如果这样用失败,错误。
CHECK PARTITION
REPAIR
PARTITION
当要检查或修复的分区包含任何重复的键错误时
,
操作失败。
有关这些语句的更多信息,请参见 第23.3.4节“分区维护” 。
ALTER TABLE
允许生成的列操作是
ADD
,
MODIFY
,和
CHANGE
。
可以添加生成的列。
CREATE TABLE t1(c1 INT); 更改表t1添加列c2 INT始终作为(c1 + 1)存储;
可以修改生成列的数据类型和表达式。
创建表t1(c1 INT,c2 INT始终作为(c1 + 1)存储); 更改表t1修改栏c2 TINYINT始终作为(c1 + 5)存储;
如果没有其他列引用它们,则可以重命名或删除生成的列。
创建表t1(c1 INT,c2 INT始终作为(c1 + 1)存储); 更改表t1更改c2 c3 INT始终作为(c1 + 1)存储; ALTER TABLE t1 DROP COLUMN c3;
虚拟生成的列不能更改为存储的生成列,反之亦然。 要解决此问题,请删除该列,然后使用新定义添加该列。
创建表t1(c1 INT,c2 INT始终为(c1 + 1)VIRTUAL); ALTER TABLE t1 DROP COLUMN c2; 更改表t1添加列c2 INT始终作为(c1 + 1)存储;
非生成列可以更改为已存储但不是虚拟生成列。
CREATE TABLE t1(c1 INT,c2 INT); 更改表t1修改栏c2 INT始终作为(c1 + 1)存储;
存储但不是虚拟生成的列可以更改为非生成列。 存储的生成值将成为非生成列的值。
创建表t1(c1 INT,c2 INT始终作为(c1 + 1)存储); ALTER TABLE t1 MODIFY COLUMN c2 INT;
ADD COLUMN
不是存储列的就地操作(不使用临时表),因为表达式必须由服务器评估。
对于存储的列,索引更改将在适当的位置完成,并且表达式更改不会就位。
列注释的更改已就位。
对于非分区表,
ADD COLUMN
以及
DROP COLUMN
虚拟列的就地操作。
但是,无法在与其他
ALTER
TABLE
操作
组合的情况下执行添加或删除虚拟列
。
对于分区表,
ADD COLUMN
并且
DROP COLUMN
不是虚拟列的就地操作。
InnoDB
支持虚拟生成列上的二级索引。
在虚拟生成列上添加或删除辅助索引是就地操作。
有关更多信息,请参见
第13.1.20.10节“二级索引和生成的列”
。
将
VIRTUAL
生成的列添加到表中或进行修改时,无法确保生成的列表达式计算的数据不会超出列的范围。
这可能导致返回不一致的数据和意外失败的语句。
允许控制是否对此类列,
ALTER TABLE
支持
WITHOUT VALIDATION
和
WITH
VALIDATION
子句
进行验证
:
使用
WITHOUT VALIDATION
(默认情况下,如果未指定none子句),将执行就地操作(如果可能),不检查数据完整性,并且语句更快完成。
但是,如果值超出范围,稍后从表中读取可能会报告列的警告或错误。
用
WITH VALIDATION
,
ALTER
TABLE
复制表。
如果发生超出范围或任何其他错误,则语句失败。
由于执行了表副本,因此语句需要更长时间。
WITHOUT VALIDATION
并且
WITH
VALIDATION
只有被允许
ADD
COLUMN
,
CHANGE COLUMN
和
MODIFY COLUMN
操作。
否则,
ER_WRONG_USAGE
会发生错误。
如果表达式求值导致截断或向函数提供不正确的输入,则
ALTER
TABLE
语句将终止并显示错误,并拒绝DDL操作。
ALTER TABLE
更改列的默认值
的
语句
col_name
还可能更改引用列使用
col_name
的生成列表达式的值,这可能会更改引用该列的生成列表达式的值
。
因此,
如果任何生成的列表达式使用,则更改列定义的操作会导致表重建
。
DEFAULT(
col_name
)ALTER TABLE
DEFAULT()
从
t1
如下所示创建
的表开始
:
CREATE TABLE t1(INTEGER,b CHAR(10));
要将表重命名
t1
为
t2
:
ALTER TABLE t1 RENAME t2;
若要更改列
a
从
INTEGER
给
TINYINT NOT
NULL
(名字一样),并更改列
b
从
CHAR(10)
到
CHAR(20)
以及来自重命名
b
到
c
:
ALTER TABLE t2修改TINYINT NOT NULL,更改bc CHAR(20);
要添加
TIMESTAMP
名为
的新
列
d
:
ALTER TABLE t2 ADD d TIMESTAMP;
要添加对列的索引
d
和
UNIQUE
对列索引
a
:
ALTER TABLE t2 ADD INDEX(d),ADD UNIQUE(a);
要删除列
c
:
ALTER TABLE t2 DROP COLUMN c;
要添加
AUTO_INCREMENT
名为
的新
整数列
c
:
ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, 添加主要密钥(c);
我们索引
c
(作为a
PRIMARY
KEY
)因为
AUTO_INCREMENT
列必须被索引,并且我们声明
c
为
NOT NULL
因为主键列不能
NULL
。
对于
NDB
表,还可以更改用于表或列的存储类型。
例如,考虑
NDB
如下所示创建
的
表:
MySQL的> CREATE TABLE t1 (c1 INT) TABLESPACE ts_1 ENGINE NDB;
查询OK,0行受影响(1.27秒)
要将此表转换为基于磁盘的存储,可以使用以下
ALTER
TABLE
语句:
MySQL的>ALTER TABLE t1 TABLESPACE ts_1 STORAGE DISK;
查询正常,0行受影响(2.99秒) 记录:0重复:0警告:0 MySQL的>SHOW CREATE TABLE t1\G
*************************** 1。排******************** ******* 表:t1 创建表:CREATE TABLE`t1`( `c1` int(11)DEFAULT NULL )/ *!50100 TABLESPACE ts_1存储盘* / ENGINE = ndbcluster DEFAULT CHARSET = latin1 1排(0.01秒)
最初创建表时,没有必要引用表空间;
但是,表空间必须由以下引用
ALTER
TABLE
:
MySQL的>CREATE TABLE t2 (c1 INT) ts_1 ENGINE NDB;
查询正常,0行受影响(1.00秒) mysql> ERROR 1005(HY000):无法创建表'c。#sql-1750_3'(错误号:140) mysql>ALTER TABLE t2 STORAGE DISK;
ALTER TABLE t2 TABLESPACE ts_1 STORAGE DISK;
查询OK,0行受影响(3.42秒) 记录:0重复:0警告:0 MySQL的>SHOW CREATE TABLE t2\G
*************************** 1。排******************** ******* 表:t1 创建表:CREATE TABLE`t2`( `c1` int(11)DEFAULT NULL )/ *!50100 TABLESPACE ts_1存储盘* / ENGINE = ndbcluster DEFAULT CHARSET = latin1 1排(0.01秒)
要更改单个列的存储类型,您可以使用
ALTER TABLE ... MODIFY [COLUMN]
。
例如,假设您使用以下
CREATE
TABLE
语句
创建具有两列的NDB Cluster Disk Data表
:
mysql>CREATE TABLE t3 (c1 INT, c2 INT)
- >TABLESPACE ts_1 STORAGE DISK ENGINE NDB;
查询OK,0行受影响(1.34秒)
要将列
c2
从基于磁盘的存储
更改
为内存存储,请在ALTER TABLE语句使用的列定义中包含STORAGE MEMORY子句,如下所示:
MySQL的> ALTER TABLE t3 MODIFY c2 INT STORAGE MEMORY;
查询正常,0行受影响(3.14秒)
记录:0重复:0警告:0
您可以通过
STORAGE DISK
类似的方式
使用内存中的列到基于磁盘的列
。
列
c1
使用基于磁盘的存储,因为这是表的缺省值(由
STORAGE DISK
语句中的
表级
子句
确定
CREATE
TABLE
)。
但是,列
c2
使用内存存储,这可以在SHOW的输出中看到
CREATE
TABLE
:
MySQL的> SHOW CREATE TABLE t3\G
*************************** 1。排******************** *******
表:t3
创建表:CREATE TABLE`t3`(
`c1` int(11)DEFAULT NULL,
`c2` int(11)/ *!50120 STORAGE MEMORY * / DEFAULT NULL
)/ *!50100 TABLESPACE ts_1存储磁盘* / ENGINE = ndbcluster DEFAULT CHARSET = latin1
1排(0.02秒)
添加
AUTO_INCREMENT
列时,列值将自动填入序列号。
对于
MyISAM
表,您可以通过执行
之前
或使用
表选项
来设置第一个序列号
。
SET
INSERT_ID=
value
ALTER TABLE
AUTO_INCREMENT=
value
对于
MyISAM
表,如果不更改
AUTO_INCREMENT
列,则序列号不受影响。
如果删除
AUTO_INCREMENT
列然后添加另一
AUTO_INCREMENT
列,则从1开始重新排序数字。
使用复制时,向
AUTO_INCREMENT
表中
添加
列可能不会在从属和主服务器上生成相同的行顺序。
发生这种情况是因为行的编号顺序取决于用于表的特定存储引擎以及插入行的顺序。
如果在主站和从站上具有相同的顺序很重要,则必须在分配
AUTO_INCREMENT
号码
之前对行进行排序
。
假设您要向
AUTO_INCREMENT
表中
添加一
列
t1
,以下语句将生成一个
与
列
t2
相同
t1
但具有
AUTO_INCREMENT
列
的新表
:
CREATE TABLE t2(id INT AUTO_INCREMENT PRIMARY KEY) SELECT * FROM t1 ORDER BY col1,col2;
这假设表
t1
有列
col1
和
col2
。
这组语句还将生成一个
与添加
列
t2
相同
的新表
:
t1
AUTO_INCREMENT
CREATE TABLE t2 LIKE t1; ALTER TABLE t2 ADD id INT AUTO_INCREMENT PRIMARY KEY; INSERT INTO t2 SELECT * FROM t1 ORDER BY col1,col2;
为了保证主服务器和从服务器上的相同顺序
,
必须在
子句中
引用
所有
列
。
t1
ORDER BY
无论用于创建和填充具有
AUTO_INCREMENT
列
的副本的方法如何
,最后一步是删除原始表,然后重命名副本:
DROP TABLE t1; ALTER TABLE t2 RENAME t1;
仅ALTER [UNDO] TABLESPACE NDB: {ADD | DROP} DATAFILE' 'tablespace_name
file_name
[INITIAL_SIZE [=]尺寸] [等待] InnoDB和NDB: [仅限 RENAME TOtablespace_name
] InnoDB: [SET {ACTIVE | INACTIVE}] [ENCRYPTION [=] {'Y'| 'N'}] InnoDB和NDB: [ENGINE [=]engine_name
]
此语句与
NDB
和
InnoDB
表空间一起使用。
它可用于向
NDB
表空间
添加新数据文件或从
表空间
删除数据文件
。
它还可用于重命名NDB Cluster Disk Data表空间,重命名
InnoDB
常规表空间,加密
InnoDB
常规表空间或将
InnoDB
undo表空间
标记
为活动或非活动。
UNDO
MySQL 8.0.14中引入
的
关键字与该
SET {ACTIVE|INACTIVE}
子句一起
使用,
以将
InnoDB
撤消表空间
标记
为活动或非活动。
有关更多信息,请参见
第15.6.3.4节“撤消表空间”
。
该
ADD DATAFILE
变量使您可以
NDB
使用
INITIAL_SIZE
子句
指定
磁盘数据表空间
的初始大小
,其中
size
以字节为单位进行测量;
默认值为134217728(128 MB)。
您可以选择
size
使用一个字母的缩写,一个数量级,类似于中使用的那些
my.cnf
。
通常,这是字母
M
(兆字节)或
G
(千兆字节)之一。
在32位系统上,支持的最大值为
INITIAL_SIZE
4294967296(4 GB)。
(Bug#29186)
INITIAL_SIZE
是明确的四舍五入的
CREATE
TABLESPACE
。
创建数据文件后,其大小无法更改;
但是,您可以使用其他
ALTER TABLESPACE ... ADD DATAFILE
语句
将更多数据文件添加到NDB表空间
。
当
ALTER TABLESPACE ... ADD DATAFILE
与使用
ENGINE = NDB
中,每个群集的数据节点上创建的数据文件,但在仅生成一个行
INFORMATION_SCHEMA.FILES
表。
有关详细信息,请参阅此表的说明以及
第22.5.13.1节“NDB集群磁盘数据对象”
。
表空间
ADD DATAFILE
不支持
InnoDB
。
使用
DROP DATAFILE
与
ALTER
TABLESPACE
下降的数据文件“
file_name
从NDB表”。
您不能从任何表正在使用的表空间中删除数据文件;
换句话说,数据文件必须为空(不使用扩展数据块)。
请参见
第22.5.13.1节“NDB集群磁盘数据对象”
。
此外,要删除的任何数据文件必须先前已使用
CREATE
TABLESPACE
或
添加到表空间
ALTER
TABLESPACE
。
表空间
DROP
DATAFILE
不支持
InnoDB
。
WAIT
被解析但被忽略。
它旨在用于未来的扩展。
该
ENGINE
子句指定了表空间使用的存储引擎,已弃用,将在以后的版本中删除。
表空间存储引擎是数据字典已知的,使该
ENGINE
子句过时。
如果指定了存储引擎,则它必须与数据字典中定义的表空间存储引擎匹配。
engine_name
与
NDB
表空间
兼容
的唯一值
是
NDB
和
NDBCLUSTER
。
RENAME TO
autocommit
无论
autocommit
设置
如何,
都以
模式
隐式执行操作
。
甲
RENAME TO
操作不能同时被执行
LOCK
TABLES
或者
FLUSH TABLES
WITH READ
LOCK
是在驻留在表空间的表的效果。
在重命名表空间时,驻留在通用表空间中的表采用 独占 元数据锁 ,这可防止并发DDL。 支持并发DML。
CREATE TABLESPACE
需要
该
权限才能重命名
InnoDB
常规表空间。
该
ENCRYPTION
子句启用或禁用
InnoDB
常规表空间或
mysql
系统表空间的
页级数据加密
。
MySQL 8.0.13中引入了对通用表空间的加密支持。
mysql
MySQL 8.0.16中引入
了对
系统表空间的
加密支持
。
必须先安装并配置密钥环插件,然后才能启用加密。
从MySQL 8.0.16开始,如果
table_encryption_privilege_check
启用了
该
变量,
TABLE_ENCRYPTION_ADMIN
则需要
使用
权限来更改具有与
ENCRYPTION
设置不同
的
子句设置
的常规表空间
default_table_encryption
。
如果表空间中的任何表属于使用定义的模式,则对通用表空间启用加密会失败
DEFAULT
ENCRYPTION='N'
。
同样,如果通用表空间中的任何表属于定义的模式,则禁用加密会失败
DEFAULT
ENCRYPTION='Y'
。
该
DEFAULT
ENCRYPTION
模式选项在MySQL 8.0.16介绍。
如果
ALTER
TABLESPACE
在通用表空间上执行
的
语句不包含
ENCRYPTION
子句,则表空间将保留其当前加密状态,而不管
default_table_encryption
设置
如何
。
对通用表空间或
mysql
系统表空间进行加密时,驻留在表空间中的所有表都将被加密。
同样,在加密表空间中创建的表也是加密的。
INPLACE
在更改
ENCRYPTION
通用表空间或
mysql
系统表空间
的
属性
时使用
该
算法
。
该
INPLACE
算法允许驻留在表空间中的表上的并发DML。
并发DDL被阻止。
有关更多信息,请参见 第15.6.3.9节“InnoDB静态数据加密” 。
改变 [ALGORITHM = {UNDEFINED | MERGE | 不是Temptable}] [DEFINER =user
] [SQL SECURITY {DEFINER | INVOKER}] 查看view_name
[(column_list
)] 如select_statement
[WITH [CASCADED | 本地]检查选项]
此语句更改必须存在的视图的定义。
语法是类似于对
CREATE
VIEW
见
第13.1.23,“CREATE VIEW语法”
)。
此语句需要
视图的权限
CREATE VIEW
和
DROP
特权,以及
SELECT
语句中
引用的每个列的某些特权
。
ALTER
VIEW
仅允许定义者或用户提供
SET_USER_ID
或
SUPER
特权。
创建{数据库| SCHEMA} [如果不存在]db_name
[create_specification
] ......create_specification
: [DEFAULT] CHARACTER SET [=]charset_name
| [DEFAULT] COLLATE [=]collation_name
| DEFAULT ENCRYPTION [=] {'Y'| 'N'}
CREATE
DATABASE
创建具有给定名称的数据库。
要使用此语句,您需要
CREATE
数据库
的
权限。
CREATE
SCHEMA
是...的同义词
CREATE
DATABASE
。
如果数据库存在且您未指定,则会发生错误
IF NOT EXISTS
。
CREATE
DATABASE
在具有活动
LOCK
TABLES
语句
的会话中不允许
。
create_specification
options指定数据库特征。
数据库特征存储在数据字典中。
该
CHARACTER SET
子句指定默认数据库字符集。
该
COLLATE
子句指定默认的数据库排序规则。
第10章,
字符集,排序规则,Unicode
,讨论字符集和排序规则名称。
DEFAULT ENCRYPTION
MySQL 8.0.16中引入的
该
子句定义了默认数据库加密,该加密由数据库中创建的表继承。
如果
DEFAULT ENCRYPTION
未指定
该
子句,则该
default_table_encryption
设置将定义默认数据库加密。
如果
table_encryption_privilege_check
启用
该
变量,
TABLE_ENCRYPTION_ADMIN
则需要
该
权限才能指定与设置不同的默认加密
default_table_encryption
设置。
有关更多信息,请参阅
为架构和常规表空间定义加密默认值
。
MySQL中的数据库实现为包含与数据库中的表对应的文件的目录。
由于最初创建数据库时没有表,因此该
CREATE
DATABASE
语句仅在MySQL数据目录下创建一个目录。
第9.2节“模式对象名称”
中给出了允许的数据库名称的规则
。
如果数据库名称包含特殊字符,则数据库目录的名称包含这些字符的编码版本,如
第9.2.3节“标识符到文件名的映射”中所述
。
在MySQL 8.0中不支持通过在 数据目录下手动创建目录(例如,使用 mkdir )来 创建数据库目录 。
您还可以使用 mysqladmin 程序创建数据库。 请参见 第4.5.2节“ mysqladmin - 管理MySQL服务器的客户端” 。
创建 [DEFINER =user
] 事件 [IF NOT EXISTS]event_name
按照时间表schedule
[完成[NOT] PRESERVE] [ENABLE | 禁用| 禁止在[SLAVE] [评论'string
'] 做event_body
;schedule
: ATtimestamp
[+ INTERVALinterval
] ...... | 每个interval
[开始timestamp
[+间隔interval
] ...] [结束timestamp
[+ INTERVALinterval
] ...]interval
:quantity
{年| QUARTER | 月| 一天| 小时| 分钟| 周| 第二| YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
此语句创建并计划新事件。 除非启用了事件计划程序,否则该事件将不会运行。 有关检查事件调度程序状态并在必要时启用它的信息,请参见 第24.4.2节“事件调度程序配置” 。
CREATE
EVENT
需要对
EVENT
要在其中创建事件的模式
的
权限。
如果该
DEFINER
子句存在,则所需的权限取决于
user
值,如
第24.6节“存储对象访问控制”中所述
。
有效
CREATE
EVENT
声明
的最低要求
如下:
关键字
CREATE EVENT
加上事件名称,它唯一标识数据库模式中的事件。
一个
ON SCHEDULE
子句,用于确定事件执行的时间和频率。
一个
DO
子句,包含要由事件执行的SQL语句。
这是最小
CREATE
EVENT
语句
的示例
:
创造事件myevent 在CURRENT_TIMESTAMP + INTERVAL 1小时的时间表 做 更新myschema.mytable SET mycol = mycol + 1;
前一个语句创建一个名为的事件
myevent
。
此事件在创建后执行一次 - 通过运行SQL语句,该语句将
myschema.mytable
表的
mycol
列
的值递增
1。
在
event_name
必须与64个字符的最大长度一个有效的MySQL标识符。
事件名称是不区分大小写,所以你不能有两个名为事件
myevent
,并
MyEvent
在同一个模式。
通常,管理事件名称的规则与存储例程的名称相同。
请参见
第9.2节“架构对象名称”
。
事件与架构相关联。
如果没有指示模式作为其一部分
event_name
,则假定默认(当前)模式。
要在特定模式中创建事件,请使用
语法
使用模式限定事件名称
。
schema_name
.event_name
该
DEFINER
子句指定在事件执行时检查访问权限时要使用的MySQL帐户。
如果
DEFINER
子句,该
user
值应被指定为一个MySQL帐户
,
或
。
允许的
值取决于您拥有的权限,如
第24.6节“存储对象访问控制”中所述
。
有关事件安全性的其他信息,另请参阅该部分。
'
user_name
'@'host_name
'CURRENT_USER
CURRENT_USER()
user
如果
DEFINER
省略
该
子句,则默认定义者是执行该
CREATE
EVENT
语句
的用户
。
这与
DEFINER = CURRENT_USER
明确
指定相同
。
在事件正文中,该
CURRENT_USER
函数返回用于在事件执行时检查权限的帐户,即
DEFINER
用户。
有关事件中用户审计的信息,请参见
第6.2.22节“基于SQL的帐户活动审计”
。
IF NOT EXISTS
具有相同的含义为
CREATE
EVENT
为
CREATE
TABLE
:如果命名的事件
event_name
已经在相同的模式存在,不采取任何行动,而不会出现错误。
(但是,在这种情况下会产生警告。)
该
ON SCHEDULE
子句确定
event_body
事件
的
定义
时间,频率和持续时间
。
该子句采用以下两种形式之一:
AT
用于一次性事件。
它指定事件仅在给定的日期和时间执行一次,该日期和时间
timestamp
timestamp
必须包括日期和时间,或者必须是解析为datetime值的表达式。
您可以
为此目的
使用
DATETIME
或
TIMESTAMP
类型
的值
。
如果日期是过去的,则会发出警告,如下所示:
MySQL的>SELECT NOW();
+ --------------------- + | 现在()| + --------------------- + | 2006-02-10 23:59:01 | + --------------------- + 1排(0.04秒) mysql>CREATE EVENT e_totals
- >ON SCHEDULE AT '2006-02-10 23:59:00'
- >DO INSERT INTO test.totals VALUES (NOW());
查询正常,0行受影响,1警告(0.00秒) MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:注意 代码:1588 消息:事件执行时间是过去而完全没有 PRESERVE已经确定。事件在此之后立即被删除 创建。
CREATE
EVENT
无论出于何种原因本身无效的语句 - 失败并出现错误。
您可以使用
CURRENT_TIMESTAMP
指定当前日期和时间。
在这种情况下,事件一旦创建就会起作用。
要创建一个相对于当前日期和时间在某个时间点发生的事件 - 例如短语
“
从现在起三周
”所表达的事件
- 您可以使用optional子句
。
该
部分由两部分组成,即数量和时间单位,并遵循
时间间隔中
描述的语法规则
,但在定义事件时不能使用任何涉及微秒的单位关键字。
对于一些间隔类型,可以使用复杂的时间单位。
例如,
“
两分十秒
”
可以表示为
。
+
INTERVAL
interval
interval
+
INTERVAL '2:10' MINUTE_SECOND
您还可以组合间隔。
例如,
AT
CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY
相当于
“
从现在开始的三周和两天
”
。
这样一个条款的每一部分都必须以
+ INTERVAL
。
要定期重复操作,请使用
EVERY
子句。
该
EVERY
关键字后跟一个关键字
interval
的前一个讨论中所描述的
AT
关键字。
(
+ INTERVAL
是
不
与所用
EVERY
。)例如,
EVERY 6
WEEK
是指
“
每六周
”
。
虽然
+ INTERVAL
条款中不允许使用
EVERY
条款,但您可以使用相同的复杂时间单位
+
INTERVAL
。
一个
EVERY
子句可以包含一个可选的
STARTS
条款。
STARTS
后跟一个
timestamp
值,
该
值指示动作应该何时开始重复,并且还可以
用于指定
“
从现在起
”
的时间量
。
例如,
意思是
“
每三个月,从现在开始一周
”
。
同样,你可以表达
“
每两个星期,开始6小时15分钟从现在开始
”
的
。
未指定
与使用相同
+ INTERVAL
interval
EVERY 3 MONTH STARTS CURRENT_TIMESTAMP +
INTERVAL 1
WEEK
EVERY 2 WEEK STARTS CURRENT_TIMESTAMP
+ INTERVAL '6:15' HOUR_MINUTE
STARTS
STARTS
CURRENT_TIMESTAMP
- 也就是说,为事件指定的操作在创建事件后立即开始重复。
一个
EVERY
子句可以包含一个可选的
ENDS
条款。
该
ENDS
关键字后跟
timestamp
告诉MySQL时,该事件应停止重复值。
你也可以
用
;
例如,
相当于
“
每十二小时,从现在开始三十分钟,从现在开始四周后
”
。
不使用
意味着事件继续无限期执行。
+ INTERVAL
interval
ENDS
EVERY 12 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS
CURRENT_TIMESTAMP + INTERVAL 4 WEEK
ENDS
ENDS
支持与复杂时间单位相同的语法
STARTS
。
您可以
在
条款中
使用
STARTS
,
ENDS
或两者都使用
EVERY
。
如果重复事件未在其调度间隔内终止,则结果可能是同时执行事件的多个实例。
如果这是不合需要的,您应该建立一个机制来防止同时发生。
例如,您可以使用
GET_LOCK()
函数,或行或表锁定。
该
ON SCHEDULE
子句可以使用涉及内置MySQL函数和用户变量的表达式来获取
它包含的
任何
timestamp
或
interval
值。
您不能在此类表达式中使用存储函数或用户定义函数,也不能使用任何表引用;
但是,你可以使用
SELECT FROM DUAL
。
对于这两个
CREATE
EVENT
和
ALTER
EVENT
陈述
都是如此
。
在这种情况下,特别不允许引用存储函数,用户定义函数和表,并且失败并出现错误(参见Bug#22830)。
在时代
ON SCHEDULE
条款使用当前会话解释
time_zone
值。
这成为事件时区;
也就是说,用于事件调度的时区,它在执行时在事件中生效。
这些时间将转换为UTC并与
mysql.event
表中
的事件时区一起存储
。
这使得事件执行能够按照定义继续执行,而不管服务器时区或夏令时效果的任何后续更改。
有关事件时间表示的其他信息,请参见
第24.4.4节“事件元数据”
。
另请参见
第13.7.6.18节“显示事件语法”
和
第25.10节“INFORMATION_SCHEMA事件表”
。
通常,一旦事件过期,它会立即被删除。
您可以通过指定来覆盖此行为
ON
COMPLETION PRESERVE
。
使用
ON COMPLETION NOT
PRESERVE
仅仅使默认的非持久行为显式化。
您可以创建一个事件,但使用该
DISABLE
关键字
阻止它处于活动状态
。
或者,您可以使用
ENABLE
显式默认状态,该状态是活动的。
这最有用
ALTER
EVENT
(参见
第13.1.3节“ALTER EVENT语法”
)。
第三个值也可能代替
ENABLE
或
出现
DISABLE
;
DISABLE ON SLAVE
设置为复制从站上事件的状态,以指示事件是在主服务器上创建并复制到从服务器,但不在从服务器上执行。
请参见
第17.4.1.16节“调用调用的功能”
。
您可以使用
COMMENT
子句
为事件提供注释
。
comment
可以是您希望用于描述事件的任何最多64个字符的字符串。
注释文本是字符串文字,必须用引号括起来。
该
DO
子句指定事件携带的操作,并由SQL语句组成。
几乎任何可以在存储例程中使用的有效MySQL语句也可以用作已调度事件的操作语句。
(请参见
第C.1节“存储程序的限制”
。)例如,以下事件
每小时
e_hourly
删除
sessions
一次表中的
所有行
,其中此表是
site_activity
模式的
一部分
:
e_hourly创造活动 按照时间表 每一个小时 评论'每小时清理一次会议表。' 做 从site_activity.sessions中删除;
MySQL存储在
sql_mode
创建或更改事件时生效
的
系统变量设置,并始终使用此设置执行事件,
而不管事件开始执行时当前服务器SQL模式如何
。
一个
CREATE
EVENT
包含一个声明
ALTER
EVENT
它在声明中
DO
条款似乎是成功的;
但是,当服务器尝试执行生成的预定事件时,执行将失败并显示错误。
在事件中使用时,
诸如
SELECT
或
SHOW
仅返回结果集的
语句
不起作用;
这些输出不会发送到MySQL监视器,也不会存储在任何地方。
但是,你可以使用语句,如
SELECT
...
INTO
与
INSERT INTO ...
SELECT
该商店的结果。
(有关后者的实例,请参阅本节中的下一个示例。)
事件所属的模式是
DO
子句
中表引用的默认模式
。
必须使用正确的模式名称限定对其他模式中的表的任何引用。
与存储例程一样,您可以使用
和
关键字
在
DO
子句中
使用复合语句语法
,如下所示:
BEGIN
END
分隔符| 创造事件e_daily 按照时间表 每一天 评论'保存会话总数,然后每天清理表' 做 开始 INSERT INTO site_activity.totals(时间,总计) SELECT CURRENT_TIMESTAMP,COUNT(*) 来自site_activity.sessions; 从site_activity.sessions中删除; 结束| 分隔符;
此示例使用该
delimiter
命令更改语句分隔符。
请参见
第24.1节“定义存储的程序”
。
在事件中,可以使用更复杂的复合语句,例如存储例程中使用的语句。 此示例使用局部变量,错误处理程序和流控制构造:
分隔符| 创造事件e 按照时间表 每隔5秒 做 开始 DECLARE v INTEGER; DECLARE CONTINUE HANDLER开始SQLEXCEPTION开始; SET v = 0; WHILE v <5 DO 插入t1值(0); 更新t2 SET s1 = s1 + 1; SET v = v + 1; 结束时间; 结束| 分隔符;
无法直接将参数传递给事件或从事件传递参数; 但是,可以使用事件中的参数调用存储的例程:
创建事件e_call_myproc 按照时间表 在CURRENT_TIMESTAMP + INTERVAL 1天 请致电myproc(5,27);
如果事件的定义者具有足以设置全局系统变量的特权(请参见 第5.1.9.1节“系统变量特权” ),则事件可以读取和写入全局变量。 由于授予此类特权可能会导致滥用,因此必须特别注意这样做。
通常,在存储例程中有效的任何语句都可以用于事件执行的操作语句。 有关存储例程中允许的语句的更多信息,请参见 第24.2.1节“存储的例程语法” 。 您可以将事件创建为存储例程的一部分,但事件不能由另一个事件创建。
该
CREATE FUNCTION
语句用于创建存储函数和用户定义函数(UDF):
有关创建存储函数的信息,请参见 第13.1.17节“创建过程和创建函数语法” 。
有关创建用户定义函数的信息,请参见 第13.7.4.1节“用户定义函数的CREATE FUNCTION语法” 。
创建[UNIQUE | FULLTEXT | 空间]索引index_name
[index_type
] ONtbl_name
(key_part
,...) [index_option
] [algorithm_option
|lock_option
] ......key_part
:{col_name
[(length
)] | (expr
)} [ASC | DESC]index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| 与PARSERparser_name
| 评论'string
' | {VISIBLE | 无形}index_type
: 使用{BTREE | HASH}algorithm_option
: ALGORITHM [=] {DEFAULT | INPLACE | 复制}lock_option
: LOCK [=] {DEFAULT | 没有| 共享| 独家}
通常,您在创建表本身时在表上创建所有索引
CREATE
TABLE
。
请参见
第13.1.20节“CREATE TABLE语法”
。
对于
InnoDB
表,其中主键确定数据文件中行的物理布局,
此指南尤其重要
。
CREATE
INDEX
使您可以向现有表添加索引。
CREATE
INDEX
映射到一个
ALTER
TABLE
语句来创建索引。
请参见
第13.1.9节“ALTER TABLE语法”
。
CREATE
INDEX
不能用来创造
PRIMARY KEY
;
使用
ALTER
TABLE
来代替。
有关索引的更多信息,请参见
第8.3.1节“MySQL如何使用索引”
。
InnoDB
支持虚拟列上的二级索引。
有关更多信息,请参见
第13.1.20.10节“二级索引和生成的列”
。
innodb_stats_persistent
启用
该
设置
后,在该表上创建索引后
运行
表
的
ANALYZE
TABLE
语句
InnoDB
。
表单的索引规范
创建具有多个关键部分的索引。
索引键值是通过连接给定关键部分的值而形成的。
例如
指定与由索引关键字值从多列索引
,
和
。
(
key_part1
,
key_part2
, ...)(col1, col2, col3)
col1
col2
col3
甲
key_part
规格可以与结束
ASC
或
DESC
以指定的索引值是否被存储在升序或降序。
如果未给出订单说明符,则默认值为升序。
ASC
并且
DESC
不允许
HASH
索引。
在MySQL 8.0.12的,
ASC
而
DESC
不是允许
SPATIAL
索引。
以下部分描述了该
CREATE
INDEX
语句的
不同方面
:
对于字符串列,可以创建仅使用列值的前导部分
的索引
,使用
语法指定索引前缀长度:
col_name
(length
)
前缀
必须
用于指定
BLOB
和
TEXT
关键零部件。
此外,
BLOB
和
TEXT
列可以只对索引
InnoDB
,
MyISAM
和
BLACKHOLE
表。
前缀
限制
以字节为单位。
然而,前缀
长度
在索引规范
CREATE
TABLE
,
ALTER
TABLE
和
CREATE INDEX
语句解释为非二进制串类型的字符数(
CHAR
,
VARCHAR
,
TEXT
)和二进制串类型的字节数(
BINARY
,
VARBINARY
,
BLOB
)。
在为使用多字节字符集的非二进制字符串列指定前缀长度时,请考虑这一点。
前缀支持和前缀长度(支持的位置)取决于存储引擎。
例如,对于
InnoDB
使用
REDUNDANT
或
COMPACT
行格式的
表,
前缀最长可达767字节
。
对于
InnoDB
使用
DYNAMIC
或
COMPRESSED
行格式的
表,
前缀长度限制为3072字节
。
对于
MyISAM
表,前缀长度限制为1000个字节。
该
NDB
存储引擎不支持前缀(见
第22.1.7.6,“在NDB簇不支持或缺失的功能”
)。
如果指定的索引前缀超过最大列数据类型大小,
CREATE
INDEX
则按如下方式处理索引:
对于非唯一索引,要么发生错误(如果启用了严格的SQL模式),要么索引长度减少到最大列数据类型大小,并产生警告(如果未启用严格SQL模式)。
对于唯一索引,无论SQL模式如何都会发生错误,因为减少索引长度可能会导致插入不符合指定唯一性要求的非唯一条目。
此处显示的语句使用列的前10个字符创建索引
name
(假设它
name
具有非二进制字符串类型):
CREATE INDEX part_of_name ON customer(name(10));
如果列中的名称通常在前10个字符中不同,则使用此索引执行的查找不应比使用从整个
name
列
创建的索引慢得多
。
此外,使用索引的列前缀可以使索引文件更小,这可以节省大量磁盘空间并且还可以加快
INSERT
操作。
阿
“
正常
”
索引索引列值或者列值的前缀。
例如,在下表中,给定
t1
行
的索引条目
包括完整
col1
值和
col2
由前10个字符组成的
值的前缀
:
CREATE TABLE t1( col1 VARCHAR(10), col2 VARCHAR(20), INDEX(col1,col2(10)) );
MySQL 8.0.13及更高版本支持索引表达式值而不是列或列前缀值的功能键部分。 使用功能键部件可以索引未直接存储在表中的值。 例子:
CREATE TABLE t1(col1 INT,col2 INT,INDEX func_index((ABS(col1)))); CREATE INDEX idx1 ON t1((col1 + col2)); CREATE INDEX idx2 ON t1((col1 + col2),(col1-col2),col1); ALTER TABLE t1 ADD INDEX((col1 * 40)DESC);
具有多个关键部分的索引可以混合非功能和功能关键部分。
ASC
并
DESC
支持功能关键部件。
功能关键部件必须遵守以下规则。 如果关键部件定义包含不允许的构造,则会发生错误。
在索引定义中,将表达式括在括号内,以将它们与列或列前缀区分开来。 例如,这是允许的; 表达式括在括号内:
INDEX((col1 + col2),(col3-col4))
这会产生错误; 表达式不包含在括号内:
INDEX(col1 + col2,col3 - col4)
功能键部分不能仅由列名组成。 例如,这是不允许的:
INDEX((col1),(col2))
相反,将关键部分写为非功能性关键部分,不带括号:
INDEX(col1,col2)
功能键部分表达式不能引用列前缀。
有关解决方法,请参阅的讨论
SUBSTRING()
,并
CAST()
在本节后面。
外键规范中不允许使用功能关键部件。
对于
CREATE
TABLE ... LIKE
,目标表保留原始表中的功能键部分。
功能索引实现为隐藏的虚拟生成列,具有以下含义:
每个功能键部分都计入表列总数的限制; 请参见 第C.10.4节“表列数和行大小的限制” 。
功能键部件继承适用于生成列的所有限制。 例子:
对于功能关键部件,仅允许生成列允许的功能。
不允许使用子查询,参数,变量,存储函数和用户定义的函数。
有关适用限制的更多信息,请参见 第13.1.20.9节“创建表和生成的列” 和 第13.1.9.2节“更改表和生成的列” 。
虚拟生成列本身不需要存储。 索引本身占用的存储空间与任何其他索引一样。
UNIQUE
支持包含功能键部分的索引。
但是,主键不能包含功能键部分。
主键需要存储生成的列,但功能键部分实现为虚拟生成列,而不是存储生成列。
SPATIAL
和
FULLTEXT
索引不能有功能关键部分。
如果表中不包含主键,
InnoDB
则会自动将第一个
UNIQUE NOT
NULL
索引提升为主键。
UNIQUE NOT NULL
具有功能键部分的索引
不支持此
功能。
如果存在重复索引,则非功能性索引会发出警告。 包含功能键部件的索引没有此功能。
要删除功能键部件引用的列,必须首先删除索引。 否则,会发生错误。
虽然非功能性关键部件支持前缀长度规范,但这对于功能关键部件是不可能的。
解决方案是使用
SUBSTRING()
(或
CAST()
,如本节后面所述)。
对于包含
SUBSTRING()
要在查询中使用
的
函数
的功能键部分
,该
WHERE
子句必须包含
SUBSTRING()
相同的参数。
在以下示例中,只有第二个
SELECT
能够使用索引,因为这是
SUBSTRING()
与索引规范匹配的
参数的唯一查询
:
CREATE TABLE tbl( col1 LONGTEXT, INDEX idx1((SUBSTRING(col1,1,10))) ); SELECT * FROM tbl WHERE SUBSTRING(col1,1,9)='123456789'; SELECT * FROM tbl WHERE SUBSTRING(col1,1,10)='1234567890';
功能键部件支持索引无法索引的值,例如
JSON
值。
但是,必须正确地完成这一操作才能达到预期的效果。
例如,此语法不起作用:
CREATE TABLE员工( 数据JSON, INDEX((data - >>'$。name')) );
语法失败,因为:
该
->>
运营商转变成
JSON_UNQUOTE(JSON_EXTRACT(...))
。
JSON_UNQUOTE()
返回数据类型为的值,
LONGTEXT
因此为隐藏生成的列分配相同的数据类型。
MySQL不能
LONGTEXT
在关键部分
索引
没有前缀长度的列,并且在功能键部分中不允许使用前缀长度。
要索引
JSON
列,您可以尝试使用以下
CAST()
函数:
CREATE TABLE员工( 数据JSON, INDEX((CAST(data - >>'$。name'AS CHAR(30)))) );
为隐藏的生成列分配
VARCHAR(30)
数据类型,可以对其进行索引。
但是这种方法在尝试使用索引时会产生一个新问题:
CAST()
返回带有排序规则的字符串
utf8mb4_0900_ai_ci
(服务器默认排序规则)。
JSON_UNQUOTE()
返回带有排序规则的字符串
utf8mb4_bin
(硬编码)。
因此,前面的表定义中的索引表达式
WHERE
与以下查询中
的
子句表达式
之间存在排序规则不匹配
:
SELECT * FROM employees WHERE data - >>'$。name'='James';
不使用索引,因为查询中的表达式和索引不同。
为了支持这种方案的功能键部分,优化自动去除
CAST()
寻找一个指数时使用,但
只有
当索引表达式的排序规则匹配查询表达式。
对于具有要使用的功能键部分的索引,以下两个解决方案中的任何一个都有效(尽管它们在某种程度上有所不同):
解决方案1.为索引表达式分配相同的排序规则
JSON_UNQUOTE()
:
CREATE TABLE员工( 数据JSON, INDEX idx((CAST(data - >>“$。name”AS CHAR(30))COLLATE utf8mb4_bin)) ); 插入员工价值观 ('{“name”:“james”,“salary”:9000}'), ('{“name”:“詹姆斯”,“薪水”:10000}'), ('{“name”:“Mary”,“salary”:12000}'), ('{“name”:“Peter”,“salary”:8000}'); SELECT * FROM employees WHERE data - >>'$。name'='James';
该
->>
操作是一样的
JSON_UNQUOTE(JSON_EXTRACT(...))
,并
JSON_UNQUOTE()
返回与归类的字符串
utf8mb4_bin
。
因此,比较区分大小写,只有一行匹配:
+ ------------------------------------ + | 数据| + ------------------------------------ + | {“name”:“James”,“薪水”:10000} | + ------------------------------------ +
解决方案2.在查询中指定完整表达式:
CREATE TABLE员工( 数据JSON, INDEX idx((CAST(data - >>“$。name”AS CHAR(30)))) ); 插入员工价值观 ('{“name”:“james”,“salary”:9000}'), ('{“name”:“詹姆斯”,“薪水”:10000}'), ('{“name”:“Mary”,“salary”:12000}'), ('{“name”:“Peter”,“salary”:8000}'); SELECT * FROM employees WHERE CAST(data - >>'$。name'AS CHAR(30))='James';
CAST()
返回带有排序规则的字符串
utf8mb4_0900_ai_ci
,因此比较不区分大小写且两行匹配:
+ ------------------------------------ + | 数据| + ------------------------------------ + | {“name”:“james”,“salary”:9000} | | {“name”:“James”,“薪水”:10000} | + ------------------------------------ +
请注意,尽管优化程序支持
CAST()
使用索引生成的列
自动剥离
,但以下方法不起作用,因为它会生成带有和不带索引的不同结果(Bug#27337092):
MySQL的>CREATE TABLE employees (
data JSON,
generated_col VARCHAR(30) AS (CAST(data->>'$.name' AS CHAR(30)))
);
查询正常,0行受影响,1警告(0.03秒) MySQL的>INSERT INTO employees (data)
VALUES ('{"name": "james"}'), ('{"name": "James"}');
查询正常,2行受影响,1警告(0.01秒) 记录:2个重复:0警告:1 MySQL的>SELECT * FROM employees WHERE data->>'$.name' = 'James';
+ ------------------- + --------------- + | 数据| generated_col | + ------------------- + --------------- + | {“name”:“James”} | 詹姆斯| + ------------------- + --------------- + 1排(0.00秒) MySQL的>ALTER TABLE employees ADD INDEX idx (generated_col);
查询正常,0行受影响,1警告(0.03秒) 记录:0重复:0警告:1 MySQL的>SELECT * FROM employees WHERE data->>'$.name' = 'James';
+ ------------------- + --------------- + | 数据| generated_col | + ------------------- + --------------- + | {“name”:“james”} | 詹姆斯| | {“name”:“James”} | 詹姆斯| + ------------------- + --------------- + 2行(0.01秒)
一个
UNIQUE
索引创建的约束,使得该指数的所有值必须是不同的。
如果您尝试添加具有与现有行匹配的键值的新行,则会发生错误。
如果为
UNIQUE
索引中的列
指定前缀值
,则列值必须在前缀长度内是唯一的。
一个
UNIQUE
索引,可以多次
NULL
进行,可以包含列的值
NULL
。
如果表具有
由具有整数类型的单个列组成的索引
PRIMARY KEY
或
UNIQUE NOT NULL
索引,则可以使用它
_rowid
来引用
SELECT
语句中
的索引列
,如下所示:
_rowid
PRIMARY
KEY
如果存在
PRIMARY
KEY
由单个整数列组成
的
列,则
引用该
列。
如果有,
PRIMARY KEY
但它不包含单个整数列,
_rowid
则不能使用。
否则,
如果该索引由单个整数列组成
,则
_rowid
引用第一个
UNIQUE NOT NULL
索引中的列。
如果第一个
UNIQUE NOT NULL
索引不包含单个整数列,
_rowid
则不能使用。
FULLTEXT
索引仅支持
InnoDB
和
MyISAM
表格,并且可以只包括
CHAR
,
VARCHAR
和
TEXT
列。
索引总是发生在整个列上;
不支持列前缀索引,如果指定,则忽略任何前缀长度。
有关
操作的详细信息,
请参见
第12.9节“全文搜索功能”
。
在
MyISAM
,
InnoDB
,
NDB
,和
ARCHIVE
存储引擎支持空间列,比如
POINT
和
GEOMETRY
。
(
第11.5节“空间数据类型”
描述了空间数据类型。)但是,空间列索引的支持因引擎而异。
根据以下规则,空间列上的空间和非空间索引可用。
空间列上的空间索引具有以下特征:
在空间列非空间索引(与创建
INDEX
,
UNIQUE
或
PRIMARY KEY
)具有以下特征:
在关键部件列表之后,可以给出索引选项。
的
index_option
值可以是任何以下的:
KEY_BLOCK_SIZE [=]
value
对于
MyISAM
表,
KEY_BLOCK_SIZE
可以选择指定用于索引键块的大小(以字节为单位)。
该值被视为提示;
如有必要,可以使用不同的尺寸。
KEY_BLOCK_SIZE
为单个索引定义指定
的
值将覆盖表级
KEY_BLOCK_SIZE
值。
KEY_BLOCK_SIZE
InnoDB
表
的索引级别不支持
。
请参见
第13.1.20节“CREATE TABLE语法”
。
index_type
某些存储引擎允许您在创建索引时指定索引类型。 例如:
CREATE TABLE查找(id INT)ENGINE = MEMORY; CREATE INDEX id_index ON lookup(id)USING BTREE;
表13.1“每个存储引擎的索引类型”
显示了不同存储引擎支持的允许索引类型值。
如果列出了多个索引类型,则在没有给出索引类型说明符时,第一个是缺省值。
表中未列出的存储引擎不支持
index_type
索引定义中
的
子句。
该
index_type
子句不能用于
FULLTEXT INDEX
或(在MySQL 8.0.12之前)
SPATIAL INDEX
规范。
全文索引实现依赖于存储引擎。
空间索引实现为R树索引。
如果指定的索引类型对于给定的存储引擎无效,但引擎可以使用另一种索引类型而不影响查询结果,则引擎将使用可用类型。
解析器识别
RTREE
为类型名称。
从MySQL 8.0.12开始,仅允许
SPATIAL
索引使用。
在8.0.12之前,
RTREE
无法为任何存储引擎指定。
BTREE
索引由
NDB
存储引擎实现为T树索引。
对于
NDB
表列的
索引
,
USING
只能为唯一索引或主键指定
该
选项。
USING HASH
阻止创建有序索引;
否则,在
NDB
表
上创建唯一索引或主键会
自动导致创建有序索引和散列索引,每个索引都对同一列索引进行索引。
对于包含
NULL
表的一列
或多
列的
唯一索引,
NDB
哈希索引只能用于查找文字值,这意味着
IS [NOT] NULL
条件需要对表进行完整扫描。
一种解决方法是确保
NULL
在这样的表上
使用一个或多个
列
的唯一索引
始终以包含有序索引的方式创建;
也就是说,避免
USING HASH
在创建索引时使用。
如果指定的索引类型对于给定的存储引擎无效,但引擎可以使用另一种索引类型而不影响查询结果,则引擎将使用可用类型。
解析器识别
RTREE
为类型名称,但目前无法为任何存储引擎指定。
index_type
在
不推荐使用
该
子句
之前
使用该
选项
;
在将来的MySQL版本中将删除对此位置中选项的使用的支持。
如果
在较早和较晚的位置都给出了
一个
选项,则最终选项适用。
ON
tbl_name
index_type
TYPE
被认为是的同义词
。
但是,
是首选形式。
type_name
USING
type_name
USING
下表显示了支持该
index_type
选项
的存储引擎的索引特征
。
表13.2 InnoDB存储引擎索引特征
指数类 | 索引类型 | 存储NULL值 | 允许多个NULL值 | IS NULL扫描类型 | IS NOT NULL扫描类型 |
---|---|---|---|---|---|
首要的关键 | BTREE |
没有 | 没有 | N / A | N / A |
独特 | BTREE |
是 | 是 | 指数 | 指数 |
键 | BTREE |
是 | 是 | 指数 | 指数 |
FULLTEXT |
N / A | 是 | 是 | 表 | 表 |
SPATIAL |
N / A | 没有 | 没有 | N / A | N / A |
表13.3 MyISAM存储引擎索引特征
指数类 | 索引类型 | 存储NULL值 | 允许多个NULL值 | IS NULL扫描类型 | IS NOT NULL扫描类型 |
---|---|---|---|---|---|
首要的关键 | BTREE |
没有 | 没有 | N / A | N / A |
独特 | BTREE |
是 | 是 | 指数 | 指数 |
键 | BTREE |
是 | 是 | 指数 | 指数 |
FULLTEXT |
N / A | 是 | 是 | 表 | 表 |
SPATIAL |
N / A | 没有 | 没有 | N / A | N / A |
表13.4 MEMORY存储引擎索引特征
指数类 | 索引类型 | 存储NULL值 | 允许多个NULL值 | IS NULL扫描类型 | IS NOT NULL扫描类型 |
---|---|---|---|---|---|
首要的关键 | BTREE |
没有 | 没有 | N / A | N / A |
独特 | BTREE |
是 | 是 | 指数 | 指数 |
键 | BTREE |
是 | 是 | 指数 | 指数 |
首要的关键 | HASH |
没有 | 没有 | N / A | N / A |
独特 | HASH |
是 | 是 | 指数 | 指数 |
键 | HASH |
是 | 是 | 指数 | 指数 |
表13.5 NDB存储引擎索引特征
指数类 | 索引类型 | 存储NULL值 | 允许多个NULL值 | IS NULL扫描类型 | IS NOT NULL扫描类型 |
---|---|---|---|---|---|
首要的关键 | BTREE |
没有 | 没有 | 指数 | 指数 |
独特 | BTREE |
是 | 是 | 指数 | 指数 |
键 | BTREE |
是 | 是 | 指数 | 指数 |
首要的关键 | HASH |
没有 | 没有 | 表(见注1) | 表(见注1) |
独特 | HASH |
是 | 是 | 表(见注1) | 表(见注1) |
键 | HASH |
是 | 是 | 表(见注1) | 表(见注1) |
表注意:
1.
USING HASH
阻止创建隐式有序索引。
WITH PARSER
parser_name
此选项只能用于
FULLTEXT
索引。
如果全文索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。
InnoDB
并
MyISAM
支持全文解析器插件。
有关详细信息,请参阅
全文分析器插件
和
第29.2.4.4节“编写全文分析器插件”
。
COMMENT
'
string
'
索引定义可以包含最多1024个字符的可选注释。
该
MERGE_THRESHOLD
索引页面可以被配置为使用单独的索引
中的条款
声明。
例如:
index_option
COMMENT
CREATE INDEX
CREATE TABLE t1(id INT); CREATE INDEX id_index ON t1(id)COMMENT'MERGE_THRESHOLD = 40';
如果索引页的页面满百分比低于
MERGE_THRESHOLD
删除行时或更新操作缩短行时
的
值,则
InnoDB
尝试将索引页与相邻索引页合并。
默认
MERGE_THRESHOLD
值为50,这是以前的硬编码值。
MERGE_THRESHOLD
也可以使用
CREATE TABLE
和
ALTER
TABLE
语句
在索引级别和表级别定义
。
有关更多信息,请参见
第15.8.11节“配置索引页的合并阈值”
。
VISIBLE
,
INVISIBLE
指定索引可见性。 默认情况下,索引是可见的。 优化程序不使用不可见索引。 索引可见性的规范适用于除主键之外的索引(显式或隐式)。 有关更多信息,请参见 第8.3.12节“不可见索引” 。
ALGORITHM
并且
LOCK
可以赋予子句以影响表复制方法和在修改索引时读写表的并发级别。
它们与
ALTER
TABLE
声明
具有相同的含义
。
有关更多信息,请参见
第13.1.9节“ALTER TABLE语法”
NDB Cluster
ALGORITHM=INPLACE
使用与标准MySQL服务器
相同的
语法
支持在线操作
。
有关
更多信息
,
请参见
第22.5.14节“使用NDB簇中的ALTER TABLE进行联机操作”
。
CREATE LOGFILE GROUPlogfile_group
ADD UNDOFILE'undo_file
' [INITIAL_SIZE [=]initial_size
] [UNDO_BUFFER_SIZE [=]undo_buffer_size
] [REDO_BUFFER_SIZE [=]redo_buffer_size
] [NODEGROUP [=]nodegroup_id
] [等待] [评论[=]'string
'] 发动机[=]engine_name
此语句创建一个
名为“
”
logfile_group
的单个
UNDO
文件
的新日志文件组
undo_file
。
一个
CREATE LOGFILE GROUP
语句有一个且只有一个
ADD UNDOFILE
条款。
有关日志文件组命名的规则,请参见
第9.2节“架构对象名称”
。
所有NDB Cluster Disk Data对象共享相同的命名空间。 这意味着 必须唯一地命名 每个磁盘数据对象 (而不仅仅是给定类型的每个磁盘数据对象)。 例如,您不能拥有具有相同名称的表空间和日志文件组,或者具有相同名称的表空间和数据文件。
在任何给定时间,每个NDB群集实例只能有一个日志文件组。
可选
INITIAL_SIZE
参数设置
UNDO
文件的初始大小;
如果未指定,则默认为
128M
(128兆字节)。
可选
UNDO_BUFFER_SIZE
参数设置
UNDO
缓冲区用于日志文件组的大小;
其缺省值
UNDO_BUFFER_SIZE
是
8M
(8兆字节);
此值不能超过可用的系统内存量。
这两个参数都以字节为单位指定。
您可以选择使用一个字母的缩写来跟随其中一个或两个,其数量级类似于
my.cnf
。
通常,这是字母之一
M
(兆字节)或
G
(千兆字节)。
用于的内存
UNDO_BUFFER_SIZE
来自全局池,其大小由
SharedGlobalMemory
数据节点配置参数
的值确定
。
这包括通过设置
InitialLogFileGroup
数据节点配置参数
对此选项隐含的任何默认值
。
允许的最大值为
UNDO_BUFFER_SIZE
629145600(600 MB)。
在32位系统上,支持的最大值为
INITIAL_SIZE
4294967296(4 GB)。
(Bug#29186)
允许的最小值为
INITIAL_SIZE
1048576(1 MB)。
该
ENGINE
选项确定此日志文件组要使用
engine_name
的存储引擎,该存储引擎是存储引擎的名称。
在MySQL 8.0中,这必须是
NDB
(或
NDBCLUSTER
)。
如果
ENGINE
未设置,MySQL将尝试使用
default_storage_engine
服务器系统变量(以前
storage_engine
)
指定的引擎
。
在任何情况下,如果引擎未指定为
NDB
or
NDBCLUSTER
,则该
CREATE
LOGFILE GROUP
语句似乎成功但实际上无法创建日志文件组,如下所示:
mysql>CREATE LOGFILE GROUP lg1
- >ADD UNDOFILE 'undo.dat' INITIAL_SIZE = 10M;
查询正常,0行受影响,1警告(0.00秒) MySQL的>SHOW WARNINGS;
+ ------- + ------ + ---------------------------------- -------------------------------------------------- ------------ + | 等级| 代码| 消息| + ------- + ------ + ---------------------------------- -------------------------------------------------- ------------ + | 错误| 1478 | 表存储引擎'InnoDB'不支持创建选项'TABLESPACE或LOGFILE GROUP' | + ------- + ------ + ---------------------------------- -------------------------------------------------- ------------ + 1排(0.00秒) mysql> ERROR 1529(HY000):无法删除LOGFILE GROUPDROP LOGFILE GROUP lg1 ENGINE = NDB;
mysql>CREATE LOGFILE GROUP lg1
- >ADD UNDOFILE 'undo.dat' INITIAL_SIZE = 10M
- >ENGINE = NDB;
查询OK,0行受影响(2.97秒)
CREATE LOGFILE GROUP
当一个非
NDB
存储引擎被命名,但似乎成功
时
,该
语句实际上没有返回错误
这一事实
是我们希望在未来的NDB Cluster版本中解决的一个已知问题。
REDO_BUFFER_SIZE
,
NODEGROUP
,
WAIT
,和
COMMENT
被分析,但是被忽略,所以有在MySQL 8.0没有影响。
这些选项旨在用于将来的扩展。
使用时
ENGINE [=] NDB
,
UNDO
会在每个群集数据节点上创建
日志文件组和关联的
日志文件。
您可以
UNDO
通过查询
INFORMATION_SCHEMA.FILES
表
来验证
文件是否已创建并获取有关它们的信息
。
例如:
mysql>SELECT LOGFILE_GROUP_NAME, LOGFILE_GROUP_NUMBER, EXTRA
- >FROM INFORMATION_SCHEMA.FILES
- >WHERE FILE_NAME = 'undo_10.dat';
+ -------------------- + ---------------------- + ----- ----------- + | LOGFILE_GROUP_NAME | LOGFILE_GROUP_NUMBER | 额外| + -------------------- + ---------------------- + ----- ----------- + | lg_3 | 11 | CLUSTER_NODE = 3 | | lg_3 | 11 | CLUSTER_NODE = 4 | + -------------------- + ---------------------- + ----- ----------- + 2行(0.06秒)
CREATE LOGFILE GROUP
仅适用于NDB Cluster的磁盘数据存储。
请参见
第22.5.13节“NDB集群磁盘数据表”
。
创建 [DEFINER =user
] 程序sp_name
([proc_parameter
[,...]]) [characteristic
...]routine_body
创建 [DEFINER =user
] 功能sp_name
([func_parameter
[,...]]) 退货type
[characteristic
...]routine_body
proc_parameter
: [IN | OUT | 进出 ]param_name
type
func_parameter
:param_name
type
type
:Any valid MySQL data type
characteristic
: 评论'string
' | 语言SQL | [NOT]决定因素 | {包含SQL | 没有SQL | 读取SQL数据| 修改SQL DATA} | SQL SECURITY {DEFINER | INVOKER}routine_body
:Valid SQL routine statement
这些语句创建存储的例程。
默认情况下,例程与默认数据库关联。
要将例程与给定数据库显式关联,请
db_name.sp_name
在创建时
指定名称
。
该
CREATE FUNCTION
语句还在MySQL中用于支持UDF(用户定义的函数)。
请参见
第29.4节“向MySQL添加新函数”
。
UDF可以被视为外部存储功能。
存储函数与UDF共享其命名空间。
有关
描述服务器如何解释对不同类型函数的引用的规则
,
请参见
第9.2.4节“函数名称解析和解析”
。
要调用存储过程,请使用该
CALL
语句(请参见
第13.2.1节“CALL语法”
)。
要调用存储的函数,请在表达式中引用它。
该函数在表达式求值期间返回一个值。
CREATE PROCEDURE
并
CREATE FUNCTION
要求
CREATE ROUTINE
特权。
如果该
DEFINER
子句存在,则所需的权限取决于
user
值,如
第24.6节“存储对象访问控制”中所述
。
如果启用了二进制日志记录,则
CREATE FUNCTION
可能需要该
SUPER
特权,如
第24.7节“存储程序二进制日志记录”中所述
。
默认情况下,MySQL的自动授权
ALTER ROUTINE
和
EXECUTE
权限,以常规的创造者。
可以通过禁用
automatic_sp_privileges
系统变量
来更改此行为
。
请参见
第24.2.2节“存储例程和MySQL特权”
。
的
DEFINER
和
SQL SECURITY
子句指定的安全上下文,在程序执行时检查访问权限的情况下,如在本节后面所述使用。
如果例程名称与内置SQL函数的名称相同,则会发生语法错误,除非在定义例程或稍后调用例程时在名称和以下括号之间使用空格。 因此,请避免将现有SQL函数的名称用于您自己的存储例程。
在
IGNORE_SPACE
SQL模式适用于内置的功能,而不是保存的程序。
无论是否
IGNORE_SPACE
启用
,始终允许在存储的例程名称后面有空格
。
括号内的参数列表必须始终存在。
如果没有参数,
()
则应使用
空参数列表
。
参数名称不区分大小写。
IN
默认情况下,
每个参数都是
参数。
要为参数指定其他方式,请使用关键字
OUT
或
INOUT
参数名称之前。
将参数指定为
IN
,
OUT
或
INOUT
仅对a有效
PROCEDURE
。
对于a
FUNCTION
,参数始终被视为
IN
参数。
一个
IN
参数传送一个值的过程。
该过程可能会修改该值,但过程返回时调用程序看不到修改。
一个
OUT
参数传送从过程返回给调用者的值。
它的初始值
NULL
在过程中,当过程返回时,调用者可以看到它的值。
一个
INOUT
参数是由呼叫者初始化,可以由程序进行修改,并且由所述方法制备的任何变化是可见的呼叫者时,过程返回。
对于每个
OUT
或
INOUT
参数,在
CALL
调用过程
的
语句中
传递用户定义的变量,
以便在过程返回时获取其值。
如果要调用从另一个存储过程或函数内的过程中,你也可以通过常规的参数或局部常规变量作为
OUT
或
INOUT
参数。
如果要调用从一个触发器中的过程中,你也可以通过
作为
或
参数。
NEW.
col_name
OUT
INOUT
有关未处理条件对过程参数的影响的信息,请参见 第13.6.7.8节“条件处理和OUT或INOUT参数” 。
在例程中准备的语句中不能引用例程参数; 请参见 第C.1节“存储程序的限制” 。
以下示例显示了一个使用
OUT
参数
的简单存储过程
:
MySQL的>delimiter //
mysql>CREATE PROCEDURE simpleproc (OUT param1 INT)
- >BEGIN
- >SELECT COUNT(*) INTO param1 FROM t;
- >END//
查询正常,0行受影响(0.00秒) MySQL的>delimiter ;
MySQL的>CALL simpleproc(@a);
查询正常,0行受影响(0.00秒) MySQL的>SELECT @a;
+ ------ + | @a | + ------ + | 3 | + ------ + 1排(0.00秒)
该示例使用
MySQL的
客户机
delimiter
命令语句从定界符改变
;
到
//
当正在定义的过程。
这使得
;
过程体中使用
的
分隔符能够传递到服务器,而不是由
mysql
本身
解释
。
请参见
第24.1节“定义存储的程序”
。
该
RETURNS
条款只能为a
FUNCTION
强制规定。
它表示函数的返回类型,函数体必须包含一个
语句。
如果
语句返回不同类型的值,则将该值强制转换为正确的类型。
例如,如果函数
在
子句中
指定了一个
或
值
,但该
语句返回一个整数,则该函数返回的值是
成员集
的相应
成员
的字符串
。
RETURN
value
RETURN
ENUM
SET
RETURNS
RETURN
ENUM
SET
以下示例函数接受一个参数,使用SQL函数执行操作,并返回结果。
在这种情况下,不必使用,
delimiter
因为函数定义不包含内部
;
语句分隔符:
mysql>CREATE FUNCTION hello (s CHAR(20))
mysql>RETURNS CHAR(50) DETERMINISTIC
- >RETURN CONCAT('Hello, ',s,'!');
查询正常,0行受影响(0.00秒) MySQL的>SELECT hello('world');
+ ---------------- + | 你好('世界')| + ---------------- + | 你好,世界!| + ---------------- + 1排(0.00秒)
可以声明参数类型和函数返回类型以使用任何有效的数据类型。
COLLATE
如果前面有
CHARACTER SET
规范,
则可以使用
该
属性
。
它
routine_body
由一个有效的SQL例程语句组成。
这可以是一个简单的语句,如
SELECT
or
INSERT
,或者是使用
BEGIN
和
编写的复合语句
END
。
复合语句可以包含声明,循环和其他控制结构语句。
第13.6节“复合语句语法”中
描述了这些语句的
语法
。
实际上,存储函数倾向于使用复合语句,除非正文包含单个
RETURN
语句。
MySQL允许例程包含DDL语句,例如
CREATE
和
DROP
。
MySQL还允许存储过程(但不是存储函数)包含SQL事务语句,如
COMMIT
。
存储的函数可能不包含执行显式或隐式提交或回滚的语句。
SQL标准不要求支持这些语句,该标准规定每个DBMS供应商可以决定是否允许它们。
返回结果集的语句可以在存储过程中使用,但不能在存储的函数中使用。
这项禁令包括
SELECT
不具有的声明
条款等语句,如
,
和
。
对于可以在函数定义时确定以返回结果集的语句,会
发生错误(
)。
对于只能在运行时确定以返回结果集的语句,会
发生错误(
)。
INTO
var_list
SHOW
EXPLAIN
CHECK TABLE
Not allowed to return a result set from a
function
ER_SP_NO_RETSET
PROCEDURE %s can't return a result set in the
given
context
ER_SP_BADSELECT
USE
不允许存储例程中的语句。
调用例程时,将
执行
隐式
(并在例程终止时撤消)。
导致例程在执行时具有给定的默认数据库。
应使用适当的数据库名称限定对除例程缺省数据库之外的数据库中的对象的引用。
USE
db_name
有关存储例程中不允许的语句的其他信息,请参见 第C.1节“存储程序的限制” 。
有关从具有MySQL接口的语言编写的程序中调用存储过程的信息,请参见 第13.2.1节“CALL语法” 。
MySQL
sql_mode
在创建或更改例程时
存储有效的
系统变量设置,并始终使用此设置执行例程,
而不管例程开始执行时当前服务器SQL模式如何
。
在评估参数并将结果值分配给例程参数之后,将从调用者的SQL模式切换到例程的SQL模式。 如果在严格SQL模式下定义例程但在非严格模式下调用它,则不会在严格模式下为常规参数分配参数。 如果要求在严格SQL模式下分配传递给例程的表达式,则应调用具有严格模式的例程。
该
COMMENT
特性是MySQL扩展,可用于描述存储的例程。
此信息由
SHOW CREATE
PROCEDURE
和
SHOW CREATE
FUNCTION
语句
显示
。
该
LANGUAGE
特性表示其中例行程序语言编写。
服务器忽略了这个特性;
仅支持SQL例程。
的例程被认为是
“
确定性的
”
,如果它总是产生相同的结果对于相同的输入参数,并且
“
不确定性
”
否则。
如果
例程定义中
既未
给出
也
DETERMINISTIC
未
NOT
DETERMINISTIC
给出,则默认为
NOT DETERMINISTIC
。
要声明函数是确定性的,必须
DETERMINISTIC
明确
指定
。
对例程性质的评估基于
创建者
的
“
诚实
”
:MySQL不会检查声明的例程
DETERMINISTIC
是否没有产生非确定性结果的语句。
但是,错误地说明例程可能会影响结果或影响性能。
声明非确定性例程
DETERMINISTIC
可能会导致优化程序选择错误的执行计划,从而导致意外结果。
声明确定性例程
NONDETERMINISTIC
可能会导致不使用可用的优化,从而降低性能。
如果启用了二进制日志记录,则该
DETERMINISTIC
特性会影响MySQL接受的例程定义。
请参见
第24.7节“存储程序二进制日志记录”
。
包含
NOW()
函数(或其同义词)或
RAND()
不确定
的例程
,但它可能仍然是复制安全的。
对于
NOW()
,二进制日志包括时间戳并正确复制。
RAND()
只要在执行例程期间只调用一次,也可以正确复制。
(您可以将例程执行时间戳和随机数种子视为主服务器和从服务器上相同的隐式输入。)
几个特征提供了关于例程使用数据的性质的信息。 在MySQL中,这些特征仅供参考。 服务器不使用它们来约束允许例程执行的语句类型。
所述
SQL SECURITY
特性可以是
DEFINER
或
INVOKER
以指定的安全上下文;
也就是说,例程是使用例程
DEFINER
子句中
指定的帐户的权限
还是使用调用它的用户执行。
此帐户必须具有访问与例程关联的数据库的权限。
默认值为
DEFINER
。
调用例程的用户必须拥有该
EXECUTE
特权,
DEFINER
如果例程在definer安全上下文中执行,则
必须具有该
帐户
的
特权
。
该
DEFINER
子句指定在常规执行时检查具有该
SQL SECURITY
DEFINER
特征的
例程的访问权限时要使用的MySQL帐户
。
如果
DEFINER
子句,该
user
值应被指定为一个MySQL帐户
,
或
。
允许的
值取决于您拥有的权限,如
第24.6节“存储对象访问控制”中所述
。
有关存储的例程安全性的其他信息,另请参阅该部分。
'
user_name
'@'host_name
'CURRENT_USER
CURRENT_USER()
user
如果
DEFINER
省略
该
子句,则默认定义者是执行
CREATE
PROCEDURE
or
CREATE
FUNCTION
语句
的用户
。
这与
DEFINER = CURRENT_USER
明确
指定相同
。
在使用
SQL SECURITY DEFINER
特征
定义的存储例程的主体内
,该
CURRENT_USER
函数返回例程的
DEFINER
值。
有关存储例程中的用户审计的信息,请参见
第6.2.22节“基于SQL的帐户活动审计”
。
请考虑以下过程,该过程显示
mysql.user
系统表中
列出的MySQL帐户数量的计数
:
CREATE DEFINER ='admin'@'localhost'PROCEDURE account_count() 开始 SELECT'帐号数:',COUNT(*)FROM mysql.user; 结束;
无论哪个用户定义
该过程,都会为该过程分配
DEFINER
帐户
'admin'@'localhost'
。
无论哪个用户调用它,它都以该帐户的权限执行(因为默认的安全特性是
DEFINER
)。
该过程成功或失败取决于调用者是否具有该
EXECUTE
特权并
'admin'@'localhost'
具有
SELECT
该
mysql.user
表
的
特权
。
现在假设该过程是使用以下
SQL
SECURITY INVOKER
特征
定义的
:
CREATE DEFINER ='admin'@'localhost'PROCEDURE account_count() SQL安全调查员 开始 SELECT'帐号数:',COUNT(*)FROM mysql.user; 结束;
该过程仍具有
DEFINER
的
'admin'@'localhost'
,但在这种情况下,它与调用用户的权限执行。
因此,该过程成功或失败取决于调用者是否具有该
EXECUTE
特权以及
SELECT
该
mysql.user
表
的
特权
。
服务器处理例程参数的数据类型,使用
DECLARE
或函数返回值
创建的本地例程变量
,如下所示:
检查分配的数据类型不匹配和溢出。 转换和溢出问题会导致警告或严格SQL模式中的错误。
只能分配标量值。
例如,诸如
SET x = (SELECT 1, 2)
无效
的陈述
。
对于字符数据类型,if
CHARACTER SET
包含在声明中,使用指定的字符集及其默认排序规则。
如果该
COLLATE
属性也存在,则使用该排序规则而不是默认排序规则。
如果
CHARACTER SET
和
COLLATE
不存在,则使用在例程创建时有效的数据库字符集和排序规则。
为避免服务器使用数据库字符集和排序规则,请
为字符数据参数
提供显式
CHARACTER SET
和
COLLATE
属性。
如果更改数据库缺省字符集或排序规则,则必须删除并重新创建使用数据库缺省值的存储例程,以便它们使用新的缺省值。
该数据库字符集和校对规则由的值给出
character_set_database
和
collation_database
系统变量。
有关更多信息,请参见
第10.3.3节“数据库字符集和排序规则”
。
创建服务器server_name
外部数据包装wrapper_name
选项(option
[,option
] ...)option
: {主持人character-literal
| 数据库character-literal
| 用户character-literal
| 密码character-literal
| SOCKETcharacter-literal
| 所有者character-literal
| PORTnumeric-literal
}
此语句创建用于
FEDERATED
存储引擎
的服务器的定义
。
该
CREATE
SERVER
语句
servers
在
mysql
数据库
的
表中
创建一个新行
。
此声明需要该
SUPER
权限。
本
应该是唯一的参考服务器。
服务器定义在服务器范围内是全局的,无法将服务器定义限定为特定数据库。
server_name
最大长度为64个字符(超过64个字符的名称被静默截断),并且不区分大小写。
您可以将名称指定为带引号的字符串。
server_name
它
是一个标识符,可以用单引号引用。
wrapper_name
对于每个,
您必须指定字符文字或数字文字。
字符文字是UTF-8,最大长度为64个字符,默认为空(空)字符串。
字符串文字被静默截断为64个字符。
数字文字必须是0到9999之间的数字,默认值为0。
option
该
OWNER
选项当前未应用,并且对创建的服务器连接的所有权或操作没有影响。
该
CREATE SERVER
语句在
mysql.servers
表中
创建一个条目,
以后可以
CREATE
TABLE
在创建
FEDERATED
表
时
与
语句
一起使用
。
您指定的选项将用于填充表中的
mysql.servers
列。
该表包括
Server_name
,
Host
,
Db
,
Username
,
Password
,
Port
和
Socket
。
例如:
创建服务器 FOREIGN DATA WRAPPER mysql 选项(用户'远程',主机'198.51.100.106',数据库'测试');
请务必指定与服务器建立连接所需的所有选项。 用户名,主机名和数据库名是必需的。 也可能需要其他选项,例如密码。
创建与
FEDERATED
表
的连接时,可以使用存储在表中的数据
:
CREATE TABLE t(s1 INT)ENGINE = FEDERATED CONNECTION ='s';
有关更多信息,请参见 第16.8节“FEDERATED存储引擎” 。
CREATE SERVER
导致隐式提交。
请参见
第13.3.3节“导致隐式提交的语句”
。
CREATE SERVER
无论正在使用的日志记录格式如何,都不会写入二进制日志。
创建或替换空间参考系统 ......srid
srs_attribute
创建空间参考系统 [IF NOT EXISTS]srid
srs_attribute
...srs_attribute
:{ 名称 'srs_name
' | 定义'definition
' | 组织org_name
'IDENTIFIED BYorg_id
| 说明'description
' }srid
,org_id
:32-bit unsigned integer
此语句创建
空间参照系
(SRS)定义并将其存储在数据字典中。
可以使用该
INFORMATION_SCHEMA
ST_SPATIAL_REFERENCE_SYSTEMS
表
检查定义
。
此声明需要该
SUPER
权限。
如果既未
指定
也
OR REPLACE
未
IF NOT
EXISTS
指定,则如果已存在具有SRID值的SRS定义,则会发生错误。
使用
CREATE OR REPLACE
语法,将替换具有相同SRID值的任何现有SRS定义,除非现有表中的某些列使用SRID值。
在这种情况下,会发生错误。
例如:
MySQL的> CREATE OR REPLACE SPATIAL REFERENCE SYSTEM 4326 ...;
ERROR 3716(SR005):无法修改SRID 4326。有
至少有一列取决于它。
要标识哪个或哪些列使用SRID,请使用以下查询:
SELECT * FROM INFORMATION_SCHEMA.ST_GEOMETRY_COLUMNS WHERE SRS_ID = 4326;
使用
CREATE ... IF NOT EXISTS
语法,任何具有相同SRID值的现有SRS定义都会导致忽略新定义并发出警告。
SRID值必须在32位无符号整数的范围内,具有以下限制:
SRID 0是有效的SRID,但不能与之一起使用
CREATE SPATIAL REFERENCE
SYSTEM
。
如果该值在保留的SRID范围内,则会发出警告。 保留范围为[0,32767](由EPSG保留),[60,000,000,69,999,999](由EPSG保留)和[2,000,000,000,2,147,483,647](由MySQL保留)。 EPSG代表 欧洲石油调查组 。
用户不应在保留范围内创建具有SRID的SRS。 这样做可能会导致SRID与MySQL分发的未来SRS定义冲突,从而导致新系统提供的SRS未安装用于MySQL升级或用户定义的SRS被覆盖。
语句的属性必须满足以下条件:
属性可以按任何顺序给出,但不能多次给出属性。
在
NAME
和
DEFINITION
属性是强制性的。
该
NAME
srs_name
属性值必须是唯一的。
ORGANIZATION
org_name
和
org_id
属性值
的组合
必须是唯一的。
的
NAME
srs_name
属性值和
ORGANIZATION
org_name
属性值不能为空或开始或空白结束。
属性规范中的字符串值不能包含控制字符,包括换行符。
下表显示了字符串属性值的最大长度。
这是一个示例
CREATE SPATIAL REFERENCE
SYSTEM
声明。
为了
DEFINITION
便于阅读,
该
值在多行中重新格式化。
(对于合法的陈述,实际上必须在一行上给出该值。)
创建空间参考系统4120 姓名'希腊' 组织'EPSG'由4120识别 定义 'GEOGCS [“希腊语”,DATUM [“希腊语”,SPHEROID [“Bessel 1841”, 6377397.155,299.1528128,AUTHORITY [ “EPSG”, “7004”]], AUTHORITY [ “EPSG”, “6120”]],PRIMEM [ “格林威治”,0, AUTHORITY [ “EPSG”, “8901”]],单位[ “度”,0.017453292519943278, AUTHORITY [ “EPSG”, “9122”]],AXIS [ “纬度”,NORTH],AXIS [ “经度”,EAST] AUTHORITY [ “EPSG”, “4120”]]“;
SRS定义的语法基于 OpenGIS Implementation Specification:Coordinate Transformation Services ,Revision 1.00,OGC 01-009,2001年1月12日,第7.2节中 定义的语法 。 该规范可从 http://www.opengeospatial.org/standards/ct获得 。
MySQL将这些更改合并到规范中:
仅实施
<horz cs>
生产规则(即,地理和预计的SRS)。
有一个可选的非标准
<authority>
条款
<parameter>
。
这使得可以通过权限而不是名称来识别投影参数。
规范没有
AXIS
在
GEOGCS
空间参考系统定义中
强制
使用
子句
。
但是,如果没有
AXIS
子句,MySQL无法确定定义是否具有纬度 - 经度顺序或经度 - 纬度顺序的轴。
MySQL强制执行非标准要求,即每个
GEOGCS
定义必须包含两个
AXIS
子句。
一个必须是,
NORTH
或
SOUTH
另一个
EAST
或
WEST
。
该
AXIS
子句顺序决定的定义是否在纬度-经度顺序或经纬度顺序轴。
SRS定义可能不包含换行符。
如果SRS定义指定了投影的权限代码(建议使用),则如果定义缺少必需参数,则会发生错误。 在这种情况下,错误消息表明问题是什么。 MySQL支持的投影方法和强制参数如 表13.7“支持的空间参考系统投影方法” 和 表13.8“空间参考系统投影参数”所示 。
有关编写SRS定义为MySQL的更多信息,请参见 在MySQL 8.0地理空间参考系统 和 投影空间参照系在MySQL 8.0
下表显示了MySQL支持的投影方法。 MySQL允许未知的投影方法,但无法检查强制参数的定义,也无法将空间数据转换为未知投影或从未知投影转换空间数据。 有关每个投影如何工作的详细说明,包括公式,请参阅 EPSG指导说明7-2 。
表13.7支持的空间参考系统投影方法
EPSG代码 | 投影名称 | 强制参数(EPSG代码) |
---|---|---|
1024 | 流行的可视化伪墨卡托 | 8801,8802,8806,8807 |
1027 | Lambert Azimuthal等面积(球面) | 8801,8802,8806,8807 |
1028 | 等距圆柱形 | 8823,8802,8806,8807 |
1029 | 等距圆柱(球面) | 8823,8802,8806,8807 |
1041 | Krovak(朝北) | 8811,8833,1036,8818,8819,8806,8807 |
1042 | Krovak修改 | 8811,8833,1036,8818,8819,8806,8807,8617,8618,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035 |
1043 | Krovak改装(朝北) | 8811,8833,1036,8818,8819,8806,8807,8617,8618,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035 |
1051 | Lambert Conic Conformal(密歇根州2SP) | 8821,8822,8823,8824,8826,8827,1038 |
1052 | 哥伦比亚城市 | 8801,8802,8806,8807,1039 |
9801 | Lambert Conic Conformal(1SP) | 8801,8802,8805,8806,8807 |
9802 | Lambert Conic Conformal(2SP) | 8821,8822,8823,8824,8826,8827 |
9803 | Lambert Conic Conformal(2SP比利时) | 8821,8822,8823,8824,8826,8827 |
9804 | 墨卡托(变种A) | 8801,8802,8805,8806,8807 |
9805 | 墨卡托(变种B) | 8823,8802,8806,8807 |
9806 | 卡西尼 - 雇佣兵 | 8801,8802,8806,8807 |
9807 | 横向墨卡托 | 8801,8802,8805,8806,8807 |
9808 | 横向墨卡托(南方定向) | 8801,8802,8805,8806,8807 |
9809 | 倾斜立体 | 8801,8802,8805,8806,8807 |
9810 | 极地立体(变体A) | 8801,8802,8805,8806,8807 |
9811 | 新西兰地图网格 | 8801,8802,8806,8807 |
9812 | Hotine Oblique Mercator(变体A) | 8811,8812,8813,8814,8815,8806,8807 |
9813 | Laborde Oblique Mercator | 8811,8812,8813,8815,8806,8807 |
9815 | Hotine Oblique Mercator(变体B) | 8811,8812,8813,8814,8815,8816,8817 |
9816 | 突尼斯矿业网 | 8821,8822,8826,8827 |
9817 | Lambert Conic近共形 | 8801,8802,8805,8806,8807 |
9818 | 美国的Polyconic | 8801,8802,8806,8807 |
9819 | Krovak | 8811,8833,1036,8818,8819,8806,8807 |
9820 | Lambert Azimuthal平等区域 | 8801,8802,8806,8807 |
9822 | Albers Equal Area | 8821,8822,8823,8824,8826,8827 |
9824 | 横向墨卡托分区网格系统 | 8801,8830,8831,8805,8806,8807 |
9826 | Lambert Conic Conformal(西方定向) | 8801,8802,8805,8806,8807 |
9828 | Bonne(南方定位) | 8801,8802,8806,8807 |
9829 | 极地立体图(变体B) | 8832,8833,8806,8807 |
9830 | 极地立体(变体C) | 8832,8833,8826,8827 |
9831 | 关岛投射 | 8801,8802,8806,8807 |
9832 | 改进的Azimuthal等距离 | 8801,8802,8806,8807 |
9833 | 双曲卡西尼号战士 | 8801,8802,8806,8807 |
9834 | 朗伯圆柱等面积(球面) | 8823,8802,8806,8807 |
9835 | 朗伯圆柱面积等面积 | 8823,8802,8806,8807 |
下表显示了MySQL识别的投影参数。 识别主要由权威代码发生。 如果没有权限代码,MySQL将回退到参数名称上不区分大小写的字符串匹配。 有关每个参数的详细信息,请通过 EPSG Online Registry 中的代码进行查找 。
表13.8空间参考系统投影参数
EPSG代码 | 后备名称(由MySQL认可) | EPSG名称 |
---|---|---|
1026 | C1 | C1 |
1027 | C2 | C2 |
1028 | C3 | C3 |
1029 | C4 | C4 |
1030 | C5 | C5 |
1031 | C6 | C6 |
1032 | C7 | C7 |
1033 | C8 | C8 |
1034 | C9 | C9 |
1035 | C10 | C10 |
1036 | 方位 | 锥轴的共同纬度 |
1038 | ellipsoid_scale_factor | 椭球比例因子 |
1039 | projection_plane_height_at_origin | 投影平面原点高度 |
8617 | evaluation_point_ordinate_1 | 纵坐标1评价点 |
8618 | evaluation_point_ordinate_2 | 纵坐标评价点2 |
8801 | latitude_of_origin | 纬度自然来源 |
8802 | central_meridian | 经度来源于自然 |
8805 | 比例因子 | 天然来源的比例因子 |
8806 | false_easting | 虚假的东方 |
8807 | false_northing | 假北上 |
8811 | latitude_of_center | 投影中心的纬度 |
8812 | longitude_of_center | 投影中心的经度 |
8813 | 方位 | 初始线的方位角 |
8814 | rectified_grid_angle | 从整流到偏斜网格的角度 |
8815 | 比例因子 | 初始线上的比例因子 |
8816 | false_easting | 在投影中心东边 |
8817 | false_northing | 北投影中心 |
8818 | pseudo_standard_parallel_1 | 纬度的标准并行 |
8819 | 比例因子 | 伪标准并行的比例因子 |
8821 | latitude_of_origin | 虚假来源的纬度 |
8822 | central_meridian | 虚假出身的经度 |
8823 | standard_parallel_1,standard_parallel1 | 第一标准平行纬度 |
8824 | standard_parallel_2,standard_parallel2 | 纬度为第二标准平行 |
8826 | false_easting | 东方是错误的起源 |
8827 | false_northing | 北方在虚假的起源 |
8830 | initial_longitude | 初始经度 |
8831 | zone_width | 区域宽度 |
8832 | standard_parallel | 纬度标准平行 |
8833 | longitude_of_center | 经度 |
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 | 更换] [如]query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
{LIKEold_tbl_name
| (LIKEold_tbl_name
)}create_definition
: | {INDEX | KEY} [ ] [ ](,...)col_name
column_definition
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
]]外键 [index_name
](col_name
,...)reference_definition
|check_constraint_definition
column_definition
:data_type
[NOT NULL | NULL] [DEFAULT {literal
| (expr
)}] [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY] [评论'string
'] [收集collation_name
] [COLUMN_FORMAT {FIXED | DYNAMIC | DEFAULT}] [STORAGE {DISK | MEMORY}] [reference_definition
] [check_constraint_definition
] |data_type
[收集collation_name
] [GENERATED ALWAYS] AS(expr
) [VIRTUAL | 存储] [NOT NULL | 空值] [UNIQUE [KEY]] [[PRIMARY] KEY] [评论'string
'] [reference_definition
] [check_constraint_definition
]data_type
: (见第11章,数据类型)key_part
:{col_name
[(length
)] | (expr
)} [ASC | DESC]index_type
: 使用{BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| 与PARSERparser_name
| 评论'string
' | {VISIBLE | 无形}check_constraint_definition
: [CONSTRAINT [symbol
]] CHECK(expr
)[[NOT] ENFORCED]reference_definition
: 参考文献tbl_name
(key_part
,...) [匹配完整| 匹配部分| 匹配简单] [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: 限制| CASCADE | SET NULL | 没有动作| 默认设置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
| 评论[=]'string
' | COMPRESSION [=] {'ZLIB'|'LZ4'|'NONE'} | 连接[=]'connect_string
' | {DATA | INDEX} DIRECTORY [=]'absolute path to directory
' | DELAY_KEY_WRITE [=] {0 | 1} | ENCRYPTION [=] {'Y'| 'N'} | 发动机[=]engine_name
| INSERT_METHOD [=] {NO | 第一个| 最后} | KEY_BLOCK_SIZE [=]value
| MAX_ROWS [=]value
| MIN_ROWS [=]value
| PACK_KEYS [=] {0 | 1 | 默认} | 密码[=]'string
' | ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT} | STATS_AUTO_RECALC [=] {DEFAULT | 0 | 1} | STATS_PERSISTENT [=] {DEFAULT | 0 | 1} | STATS_SAMPLE_PAGES [=]value
| TABLESPACEtablespace_name
[STORAGE {DISK | MEMORY}] | UNION [=](tbl_name
[,tbl_name
] ......)partition_options
: 分区 {[LINEAR] HASH(expr
) | [LINEAR] KEY [ALGORITHM = {1 | 2}](column_list
) | 范围{(expr
)| COLUMNS(column_list
)} | 列表{(expr
)| COLUMNS(column_list
)}} [PARTITIONSnum
] [SUBPARTITION BY {[LINEAR] HASH(expr
) | [LINEAR] KEY [ALGORITHM = {1 | 2}](column_list
)} [SUBPARTITIONSnum
] ] [(partition_definition
[,partition_definition
] ......)]partition_definition
: 划分partition_name
[VALUES {不到{(expr
|value_list
)| MAXVALUE} | IN(value_list
)}] [[STORAGE] ENGINE [=]engine_name
] [评论[=]'string
'] [DATA DIRECTORY [=]''] [INDEX DIRECTORY [=]'
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] tablespace_name] [(subpartition_definition
[,subpartition_definition
] ......)]subpartition_definition
: SUBPARTITIONlogical_name
[[STORAGE] ENGINE [=]engine_name
] [评论[=]'string
'] [DATA DIRECTORY [=]''] [INDEX DIRECTORY [=]'
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] tablespace_name]query_expression:
选择......(Some valid select or union statement
)
CREATE
TABLE
创建一个具有给定名称的表。
您必须拥有
CREATE
该表
的
权限。
默认情况下,使用
InnoDB
存储引擎
在默认数据库中创建表
。
如果表存在,如果没有默认数据库,或者数据库不存在,则会发生错误。
有关表的物理表示的信息,请参见 第13.1.20.2节“由CREATE TABLE创建的文件” 。
CREATE TABLE
创建表时,MySQL将存储
原始
语句,包括所有规范和表选项。
有关更多信息,请参见
第13.1.20.1节“CREATE TABLE语句保留”
。
CREATE
TABLE
声明
有几个方面
,在本节的以下主题中描述:
tbl_name
可以指定表名
db_name.tbl_name
以在特定数据库中创建表。
假设数据库存在,无论是否存在默认数据库,这都有效。
如果使用带引号的标识符,请分别引用数据库和表名。
例如,写
`mydb`.`mytbl`
,不
`mydb.mytbl`
。
第9.2节“模式对象名称” 中给出了允许的表名称的规则 。
IF NOT EXISTS
如果表存在,则防止发生错误。
但是,没有验证现有表的结构与
CREATE TABLE
语句
指示的结构相同
。
您可以
TEMPORARY
在创建表时
使用该
关键字。
一个
TEMPORARY
表只在当前会话中可见,而当会话关闭时自动删除。
有关更多信息,请参见
第13.1.20.3节“CREATE TEMPORARY TABLE语法”
。
LIKE
用于
CREATE TABLE ... LIKE
根据另一个表的定义创建一个空表,包括原始表中定义的任何列属性和索引:
new_tbl
像表格一样orig_tbl
;
有关更多信息,请参见 第13.1.20.4节“CREATE TABLE ... LIKE语法” 。
[AS]
query_expression
要从另一个表创建一个表,请在
SELECT
语句末尾
添加一个
CREATE TABLE
语句:
CREATE TABLEnew_tbl
AS SELECT * FROMorig_tbl
;
有关更多信息,请参见 第13.1.20.5节“CREATE TABLE ... SELECT语法” 。
IGNORE|REPLACE
在
IGNORE
和
REPLACE
选项指示如何处理使用复制表时复制唯一键值的行
SELECT
声明。
有关更多信息,请参见 第13.1.20.5节“CREATE TABLE ... SELECT语法” 。
每个表的硬限制为4096列,但给定表的有效最大值可能更小,并取决于 第C.10.4节“表列计数和行大小限制”中 讨论的因素 。
data_type
data_type
表示列定义中的数据类型。
有关可用于指定列数据类型的语法的完整说明,以及有关每种类型的属性的信息,请参见
第11章,
数据类型
。
某些属性不适用于所有数据类型。
AUTO_INCREMENT
仅适用于整数和浮点类型。
在此之前的MySQL 8.0.13,
DEFAULT
并不适用于
BLOB
,
TEXT
,
GEOMETRY
,和
JSON
类型。
字符数据类型(
CHAR
,
VARCHAR
,的
TEXT
类型,
ENUM
,
SET
,和任何同义词)同义词)可以包括
CHARACTER SET
指定的字符的列设置。
CHARSET
是...的同义词
CHARACTER SET
。
可以使用
COLLATE
属性以及任何其他属性
指定字符集的排序规则
。
有关详细信息,请参见
第10章,
字符集,排序规则,Unicode
。
例:
CREATE TABLE t(c CHAR(20)CHARACTER SET utf8 COLLATE utf8_bin);
MySQL 8.0以字符形式解释字符列定义中的长度规范。
长度为
BINARY
和
VARBINARY
以字节
为
单位。
为
CHAR
,
VARCHAR
,
BINARY
,和
VARBINARY
列,索引可以创建仅使用列值的前导部分,使用
语法来指定一个索引前缀长度。
和
列也可以编入索引,但
必须
给出
前缀长度
。
对于非二进制字符串类型,前缀长度以字符给出,对于二进制字符串类型,以字节为单位给出。
即,索引项由所述第一的
每个列的值的字符
,
和
col_name
(length
)BLOB
TEXT
length
CHAR
VARCHAR
TEXT
列,并且所述第一
length
对每个列的值的字节
BINARY
,
VARBINARY
和
BLOB
列。
仅索引像这样的列值的前缀可以使索引文件更小。
有关索引前缀的其他信息,请参见
第13.1.15节“CREATE INDEX语法”
。