外键和其他约束

InnoDB和NDB存储引擎支持 FOREIGN KEY 和 REFERENCES 子句,这些存储引擎实现了ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (...) REFERENCES ... (...)。对于其他存储引擎,将解析子句,但忽略它们。

与CREATE TABLE不同,对于ALTER TABLE,ADD FOREIGN KEY会忽略给定的index_name,并使用自动生成的外键名。作为一种解决方案,请使用 CONSTRAINT 子句来指定外键名:

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

重要

MySQL忽略内联REFERENCES规范,其中引用被定义为列规范的一部分。MySQL只接受定义为独立外键规范一部分的REFERENCES子句。

注意

分区的InnoDB表不支持外键。这个限制不适用于NDB表,包括那些通过[LINEAR] KEY显式分区的表。

MySQL Server和NDB Cluster都支持使用ALTER TABLE来删除外键:

1. ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;

在ALTER TABLE ... ALGORITHM=INPLACE中,支持在同一ALTER TABLE语句中添加和删除外键,但是在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_nameibfk”开头的内部生成的外键约束名称和用户定义的外键约束名称,以反映新的表名。InnoDB将以字符串“tbl_nameibfk”开头的外键约束名称解释为内部生成的名称。

在MySQL 8.0.16之前,ALTER TABLE只允许以下有限版本的CHECK约束添加语法,它被解析并忽略:

1. ADD CHECK (expr)

从MySQL8.0.16开始,ALTER TABLE允许添加、删除或更改现有表的CHECK约束:

● 添加新的CHECK约束:

1. ALTER TABLE tbl_name

2. ADD CONSTRAINT [symbol] CHECK (expr) [[NOT] ENFORCED];

约束语法元素的含义与CREATE TABLE相同。

● 删除名为symbol的现有CHECK约束:

1. ALTER TABLE tbl_name

2 DROP CHECK symbol;

● 更改已存在的名为symbol的CHECK约束是否强制执行:

1. ALTER TABLE tbl_name ALTER CHECK symbol [NOT] ENFORCED;

DROP CHECK和ALTER CHECK子句是对标准SQL的MySQL扩展。

从MySQL 8.0.19开始,ALTER TABLE允许更通用的(遵从SQL标准)语法来删除和修改任何类型的现有约束,其中约束类型由约束名称决定:

● 删除已存在的名为 symbol 的约束:

1. ALTER TABLE tbl_name

2. DROP CONSTRAINT symbol;

如果启用了sql_require_primary_key系统变量,尝试删除主键会产生错误。

● 更改已存在的名为symbol的约束是否强制执行:

1. ALTER TABLE tbl_name

2. ALTER CONSTRAINT symbol [NOT] ENFORCED;

SQL标准指定所有类型的约束(主键、唯一索引、外键、检查)都属于同一个命名空间。在MySQL中,每个模式的每个约束类型都有自己的命名空间。因此,每种约束类型的名称对于每个模式都必须是唯一的,但是不同类型的约束可以具有相同的名称。当多个约束具有相同的名称时,DROP CONSTRAINT和ADD CONSTRAINT是不明确的,并且会发生错误。在这种情况下,必须使用特定于约束的语法来修改约束。例如,使用DROP PRIMARY KEY或DROP FOREIGN KEY删除主键或外键。

如果表更改导致违反强制CHECK约束,则会发生错误,并且不会修改表。发生错误的操作示例如下:

● 试图将AUTO_INCREMENT属性添加到CHECK约束中使用的列。

● 试图添加强制CHECK约束或将非强制CHECK约束改为强制约束,而这种更改会使现有行违反约束条件。

● 试图修改、重命名或删除CHECK约束中使用的列,除非该约束也在同一语句中被删除。例外:如果CHECK约束只引用一个列,删除该列将自动删除该约束。

ALTER TABLE tbl_name RENAME new_tbl_name更改内部生成的和用户定义的以字符串“tbl_namechk”开头的CHECK约束名称,以反映新的表名。MySQL将以字符串“tbl_namechk”开头的CHECK约束名称解释为内部生成的名称。

更改字符集

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

1. ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

该语句还更改所有字符列的排序规则。如果不指定COLLATE子句来指示要使用哪个排序规则,则语句将对字符集使用默认排序规则。如果此排序规则不适用于预期的表用途(例如,如果它将从区分大小写的排序规则更改为不区分大小写的排序规则),请显式指定排序规则。

对于数据类型为VARCHAR或其中一种TEXT类型的列,CONVERT TO CHARACTER SET 会根据需要更改数据类型,以确保新列足够长,可以存储与原始列一样多的字符。例如,TEXT列有两个长度字节,用于存储列中值的字节长度,最大值为65535。对于latin1 TEXT列,每个字符需要一个字节,因此该列最多可存储65535个字符。如果将列转换为utf8,则每个字符可能需要最多三个字节,最大可能长度为3×65535=196605个字节。这个长度不适合TEXT列的长度字节,因此MySQL将数据类型转换为MEDIUMTEXT,MEDIUMTEXT是长度字节可以记录值196605的最小字符串类型。类似地,VARCHAR列可以转换为MEDIUMTEXT。

若要避免对刚才描述的类型进行数据类型更改,请不要使用CONVERT To CHARACTER SET,而应使用MODIFY来更改单个列。例如:

1. ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;

2. 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操作将不会应用于它们。

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

警告

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

1. ALTER TABLE t1 CHANGE c1 c1 BLOB;

2. ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;

这样做的原因是在转换到BLOB列或从BLOB列转换时没有转换。

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

ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;

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

对于包含外键约束中使用的字符串列的表,不允许进行字符集转换。解决方法是在执行字符集转换之前禁用foreign_key_checks。在重新启用foreign_key_checks之前,必须对涉及外键约束的两个表执行转换。如果在仅转换一个表后重新启用foreign_key_checks,则由于在这些操作期间发生隐式转换,ON DELETE CASCADE或ON UPDATE CASCADE操作可能会损坏引用表中的数据。

导入InnoDB表

使用DISCARD TABLESPACE和IMPORT TABLESPACE子句,可以从备份或另一个MySQL服务器实例导入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子句,但是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中,因为刚刚列出的选项作用于各个分区。

MySQL中定义fk语句_MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句 (4)相关推荐

  1. MySQL中rename一个view对应的SQL语句

    OS:linux ubuntu 最近在对MySQL数据库开发的过程中,需要修改一个view的名字,但是找了许久才找到对应的SQL,切记不是alter,而是rename table .... 在MySQ ...

  2. mysql对所有列的数据进行修改6_MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句 (3)...

    添加和删除列 使用ADD向表中添加新列,使用DROP删除现有列.DROP col_name是对标准SQL的MySQL扩展. 若要在表行的特定位置添加列,请使用FIRST col_name 或者 AFT ...

  3. mysql更改数据语句6_MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(1)

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

  4. MySQL中特别实用的几种SQL语句

    MySQL中特别实用的几种SQL语句 文章目录 MySQL中特别实用的几种SQL语句 1. 插入或替换 2. 插入或更新 3. 插入或忽略 4. 指定数据快照或备份 5. 写入查询结果集 6. 强制使 ...

  5. mysql删除索引语句_MySQL:使用SQL语句删除所有索引

    删除所有索引 可利用ALTER TABLE或DROP INDEX语句来删除索引.这里使用ALTER TABLE,首先查询所有索引,然后拼接成删除语句,复制执行即可 #拼接删除索引的语法 SELECT ...

  6. mysql的char在java中表示为_Java学习篇之-Mysql中varchar门类总结_mysql

    java学习篇之---mysql中varchar类型总结 Mysql中varchar类型总结 今天新做一个项目,需要自己进行数据库设计,发现自己对varchar的用法还不是很熟悉,所以查阅资料总结若下 ...

  7. SQL的数据定义功能及语句:

    定义各种数据库的"对象" 模式定义 表定义 视图定义 索引定义 SQL的数据定义语句 操作对象 操作方式 创建 删除 修改   模式 CREATE SCHEMA DROP  SCH ...

  8. SQL ALTER TABLE 语句在项目中的使用

    1.在实际的项目开发过程中,之前已经创建好的实体类可能需要增加/删除字段,亦或是更改已有字段的属性,比如主键的增长策略从自增型改为UUID型,那么就会涉及到 SQL 中 alter table 语句的 ...

  9. MYSQL中如何修改类型_MySQL怎么修改字段类型?

    在MySQL中,可以通过alter table语句来修改表中一个字段的数据类型.下面本篇文章就来带大家了解一下alter table语句,介绍如何修改字段类型,希望对大家有所帮助. 在MySQL中,a ...

最新文章

  1. EEGNet: 神经网络应用于脑电信号
  2. 用 C 语言开发一门编程语言 — 跨平台的可移植性
  3. python流程控制-python简单流程控制
  4. HTML DOM Document 对象
  5. 求p1+5和p2+5等于多少?
  6. 5.fork和vfork
  7. 图解ARP协议(六)RARP与IARP:被遗忘的兄弟协议
  8. Python函数合集:68个内置函数请收好!
  9. Git常用命令——分支操作
  10. 【汇编优化】之ARM32与AARCH64指令集优化总结
  11. 51Nod-1383 整数分解为2的幂【数列】
  12. php soapenv:server.userexception,SoapFault - faultcode: 'soap:Server' faultstring
  13. VB 源码 产生任意数之间随机数,支持负数
  14. 麦咖啡设置指南------详细介绍访问保护的设置方法抵御未知病毒
  15. 如何成为优秀的技术主管-管理篇
  16. 服从还是被裁?职场人请做好这道生存选择题!
  17. ubuntu compiz 不能启动
  18. 企业微信如何建立部门?
  19. Go语言相关书籍推荐(从入门到放弃)
  20. 2-1暴力破解原理和测试流程

热门文章

  1. uda1341原理及驱动
  2. Tyvj 1039 忠诚2
  3. React 重新渲染指南
  4. 打造卓越游戏 | 2023 Google 游戏开发者峰会
  5. 2021年双流永安中学高考成绩查询,双流永安中学2020年高考升学率高不高?
  6. Android(四十二):Drawable 转 Bitmap
  7. Photoshop学习笔记之色彩学的概念与常识
  8. labview接收串口通信数据不正常的解决办法
  9. 高光谱解混(一)——高光谱分解综述:基于几何,统计和稀疏回归的方法
  10. VUE利用transition标签实现摇一摇抽签效果