这是第十五次ㄚ琪自我练习的结果,咦,上一次不是最后一次吗?没啦,有关我的认证经验你可以看大型资料库管理系统-专业级(MySQL 5.0)测验认证受挫,这里我就不多讲了,只专注在如何帮大家精进你的MySQL能力。
[adsense][/adsense]
这一次的测试50题,答对46题得92分,错4题扣4分,总计得分88分。
这是MySQL 5实力养成暨评量里的1-17.‘下列关于关联式资料库的叙述,何者不正确?’
答案:(C) 表格内的资料不可以重复
这一题看来只要有中文阅读力加上一般的资料库基础就可以答题,看来是我们阅读能力有问题
这是MySQL 5实力养成暨评量里的3-75.‘SQL指令中,使用DROP指令无法删除下列何者?’
答案:(A) 资料目录
这一题本应该是简单的,但是粗心还是错了,也可能是不熟ALTER TABLE的叙述吧,我们重新复习一下,手册可以看MySQL 5.7 Reference Manual :: 13 SQL Statement Syntax :: 13.1 Data Definition Statements :: 13.1.6 ALTER TABLE Syntax,中文的部份看MySQL 5.1参考手册 :: 13. SQL语句语法::13.1. 数据定义语句::13.1.2. ALTER TABLE语法
转译繁体中文于下:
ALTER [IGNORE] TABLE tbl_name
alter_specification [, alter_specification] ...
alter_specification:
ADD [COLUMN] column_definition [FIRST | AFTER col_name ]
| ADD [COLUMN] (column_definition,...)
| ADD INDEX [index_name] [index_type] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
PRIMARY KEY [index_type] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
UNIQUE [index_name] [index_type] (index_col_name,...)
| ADD [FULLTEXT|SPATIAL] [index_name] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
| ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] old_col_name column_definition
[FIRST|AFTER col_name]
| MODIFY [COLUMN] column_definition [FIRST | AFTER col_name]
| DROP [COLUMN] col_name
| DROP PRIMARY KEY
| DROP INDEX index_name
| DROP FOREIGN KEY fk_symbol
| DISABLE KEYS
| ENABLE KEYS
| RENAME [TO] new_tbl_name
| ORDER BY col_name
| CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
| [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name]
| DISCARD TABLESPACE
| IMPORT TABLESPACE
| table_options
| partition_options
| ADD PARTITION partition_definition
| DROP PARTITION partition_names
| COALESCE PARTITION number
| REORGANIZE PARTITION partition_names INTO (partition_definitions)
| ANALYZE PARTITION partition_names
| CHECK PARTITION partition_names
| OPTIMIZE PARTITION partition_names
| REBUILD PARTITION partition_names
| REPAIR PARTITION partition_names
ALTER TABLE用于更改原有资料表的结构。例如,您可以增加或删除栏位,建立或取消索引,更改原有栏位的型态,或重新命名栏位或资料表。您还可以更改资料表的评注和资料表的型态。
允许进行的变更中,许多子句的语法与CREATE TABLE中的子句的语法相近。其中包括table_options修改,选项有ENGINE, AUTO_INCREMENT和AVG_ROW_LENGTH等。请见13.1.5节,“CREATE TABLE语法”。
储存引擎不支援有些操作,如果进行这些操作,会出现警告。使用SHOW WARNINGS可以显示出这些警告。请参见13.5.4.22节,“SHOW WARNINGS语法”。
如果您使用ALTER TABLE更改栏位规约,但是DESCRIBE tbl_name提示您栏位规约并没有改变,则可能是因为MySQL忽略了您所做的更改。忽略更改的原因见13.1.5.1节,“沉寂的列规格变更”。例如,如果您试图把VARCHAR栏位更改为CHAR栏位,此时,如果资料表包含其它长度可变的栏位,则MySQL仍会使用VARCHAR。
ALTER TABLE运行时会对原资料表进行临时复制,在副本上进行更改,然后删除原资料表,再对新资料表进行重命名。在执行ALTER TABLE时,其它用户可以阅读原资料表,但是对资料表的更新和修改的操作将被延迟,直到新资料表生成为止。新资料表生成后,这些更新和修改讯息会自动转移到新资料表上。
注意,如果您在执行ALTER TABLE时使用除了RENAME以外的选项,则MySQL会建立一个临时资料表。即使资料并不需要进行复制(例如当您更改栏位的名称时),MySQL也会这么操作。对于MyISAM资料表,您可以通过把myisam_sort_buffer_size系统变数设置到一个较高的值,来加快重新建立索引(该操作是变更过程中速度最慢的一部分)的速度。
· 要使用ALTER TABLE,您需要获得资料表的ALTER, INSERT和CREATE权限。
· IGNORE是MySQL相对于标准SQL的延伸。如果在新资料表中有重复关键字,或者当STRICT模式启动后出现警告,则使用IGNORE控制ALTER TABLE的运行。如果没有指定IGNORE,当重复关键字错误发生时,复制操作被放弃,返回前一步骤。如果指定了IGNORE,则对于有重复关键字的行,只使用第一行,其它有冲突的行被删除。并且,对错误值进行修正,使之尽量接近正确值。
· 您可以在一个ALTER TABLE语句里写入多个ADD, ALTER, DROP和CHANGE子句,中间用逗号分开。这是MySQL相对于标准SQL的延伸。在标准SQL中,每个ALTER TABLE语句中每个子句只允许使用一次。例如,在一个语句中取消多个栏位:
· mysql> ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
· CHANGE col_name, DROP col_name和DROP INDEX是MySQL相对于标准SQL的延伸。
· MODIFY是Oracle对ALTER TABLE的延伸。
· COLUMN只是自选项目,可以忽略。
· 如果您使用ALTER TABLE tbl_name RENAME TO new_tbl_name并且没有其它选项,则MySQL只对与table tbl_name相对应的档案进行重命名。不需要建立一个临时资料表。(您也可以使用RENAME TABLE语句对资料表进行重命名。请参见13.1.9节,“RENAME TABLE语法”。)
· column_definition子句使用与CREATE TABLE中的ADD和CHANGE子句相同的语法。注意,此语法包括栏位名称,而不只是栏位型态。请参见13.1.5节,“CREATE TABLE语法”。
· 您可以使用CHANGE old_col_name column_definition子句对栏位进行重命名。重命名时,需给定旧的和新的栏位名称和栏位当前的型态。例如:要把一个INTEGER列的名称从a变更到b,您需要如下操作:
· mysql> ALTER TABLE t1 CHANGE a b INTEGER;
如果您想要更改栏位的型态而不是名称, CHANGE语法仍然要求旧的和新的栏位名称,即使旧的和新的栏位名称是一样的。例如:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
您也可以使用MODIFY来改变栏位的型态,此时不需要重命名:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
· 如果您使用CHANGE或MODITY缩短栏位长时,栏位中存在有索引,并且缩短后的栏位长小于索引长度,则MySQL会自动缩短索引的长度。
· 当您使用CHANGE或MODIFY更改栏位的型态时,MySQL会尽量把原有的栏位值转化为新的型态。
· 您可以使用FIRST或AFTER col_name在一个资料表行中的某个特定位置新增栏位。预设把栏位新增到最后。您也可以在CHANGE或MODIFY语句中使用FIRST和AFTER。
· AFTER COLUMN用于指定栏位的新预设值,或删除旧的预设值。如果旧的预设值被删除同时栏位值为NULL,则新的预设值为NULL。如果栏位值不能为NULL,MySQL会指定一个预设值,请参见13.1.5节,“CREATE TABLE语法”。
· DROP INDEX用于取消索引。这是MySQL相对于标准SQL的延伸。请参见13.1.7节,“DROP INDEX语法”。
· 如果栏位从资料表中被取消了,则这些栏位也从相应的索引中被取消。如果组成一个索引的所有栏位均被取消,则该索引也被取消。
· 如果一个资料表只包含一栏位,则此栏位不能被取消。如果您想要取消资料表,应使用DROP TABLE。
· DROP PRIMAY DEY用于取消主索引。注释:在MySQL较早的版本中,如果没有主索引,则DROP PRIMARY KEY会取消资料表中的第一个UNIQUE索引。在MySQL 5.1中不会出现这种情况。如果在MySQL 5.1中对没有主键的资料表使用DROP PRIMARY KEY,则会出现错误讯息。
如果您向资料表中新增UNIQUE KEY或PRIMARY KEY,则UNIQUE KEY或PRIMARY KEY会被储存在非唯一索引之前,这样MySQL就可以尽早地检查出重复关键字。
· ORDER BY用于在建立新资料表时,让各行按一定的顺序排列。注意,在插入和删除后,资料表不会仍保持此顺序。当您知道多数情况下您会按照特定的顺序查询各行时,可以使用这个选项;在对资料表进行了大的改动后,通过使用此选项,您可以提高查询效率。在有些情况下,如果资料表按栏位排序,对于MySQL来说,排序可能会更简单。
· 如果您对一个MyISAM资料表使用ALTER TABLE,则所有非唯一索引会被建立到一个单独的批里(和REPAIR TABLE相同)。当您有许多索引时,这样做可以使ALTER TABLE的速度更快。
这项功能可以明确激活。ALTER TABLE…DISABLE KEYS让MySQL停止更新MyISAM资料表中的非唯一索引。然后使用ALTER TABLE … ENABLE KEYS重新建立丢失的索引。进行此操作时,MySQL采用一种特殊的算法,比一个接一个地插入关键字要快很多。因此,在进行成批插入操作前先使关键字禁用可以大大地加快速度。使用ALTER TABLE … DISABLE KEYS除了需要获得以前提到的权限以外,还需要获得INDEX权限。
· Innodb储存引擎支援FOREIGN KEY和REFERENCES子句。Innodb储存引擎执行ADD [CONSTRAINT [symbol]] FOREIGN KEY (…) REFERENCES … (…)。请参见15.2.6.4节,“FOREIGN KEY约束”。对于其它储存引擎,这些子句会被分析,但是会被忽略。对于所有的储存引擎,CHECK子句会被分析,但是会被忽略。请参见13.1.5节,“CREATE TABLE语法”。接受这些子句但又忽略子句的原因是为了提高相容性,以便更容易地从其它SQL伺服器中导入代码,并运行应用程式,建立带参考资料的资料表。请参见1.8.5节,“MySQL与标准SQL的差别”。
· InnoDB支援使用ALTER TABLE来取消外部键:
· ALTER TABLE yourtablename DROP FOREIGN KEY fk_symbol;
要了解更多讯息,请参见15.2.6.4节,“FOREIGN KEY约束”。
· ALTER TABLE忽略DATA DIRECTORY和INDEX DIRECTORY资料表选项。
· 如果您想要把资料表预设的字元编码和所有字元栏位(CHAR, VARCHAR, TEXT)改为新的字元编码,应使用如下语句:
· ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
警告:前面的操作转换了字元编码之间的栏位型态。如果您有一栏位使用一种字元编码(如latin1),但是储存的值实际上使用了其它的字元编码(如utf8),这种情况不是您想要的。此时,您必须对这样的栏位进行以下操作。
ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
这种方法能够实现此功能的原因是,当您转换到BLOB栏位或从BLOB栏位转换过来时,并没有发生转换。
如果您指定CONVERT TO CHARACTER SET为二进制,则TEXT栏位被转换到相应的二进制字串型态(BINARY, VARBINARY, BLOB)。这意味着这些栏位将不再有字元编码,接下来的CONVERT TO操作也将不适用于这些栏位。
要仅仅改变一个资料表的预设字元编码,应使用此语句:
ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;
词语DEFAULT为自选项。如果您在向资料表中新增一个新栏位时(例如,使用ALTER TABLE…ADD column)没有指定字元编码,则此时使用的字元编码为预设字元编码。
警告:ALTER TABLE…DEFAULT CHARACTER SET和ALTER TABLE…CHARACTER SET是等价的,只用于更改预设的资料表字元编码。
· 如果InnoDB资料表在建立时,使用了.ibd档案中的自己的资料表空间,则这样的档案可以被删除和导入。使用此语句删除.ibd档案:
· ALTER TABLE tbl_name DISCARD TABLESPACE;
此语句用于删除当前的.ibd档案,所以应首先确认您有一个备份。如果在资料表空间被删除后尝试打开资料表格,则会出现错误。
要把备份的.ibd档案还原到资料表中,需把此档案复制到资料库目录中,然后书写此语句:
ALTER TABLE tbl_name IMPORT TABLESPACE;
· 使用mysql_info() C API函数,您可以了解有多少记录已被复制,以及(当使用IGNORE时)有多少记录由于重复关键字的原因已被删除。请参见25.2.3.34节,“mysql_info()”。
· ALTER TABLE也可以用于对带分区的资料表进行重新分区,功能包括新增、取消、合并和拆分各分区,还可以用于进行分区维护。
对带分区的资料表使用partition_options子句和ALTER TABLE可以对资料表进行重新分区,使用时依据partition_options定义的分区方法。本子句以PARTITION BY为开头,然后使用与用于CREATE TABLE的partition_options子句一样的语法和规则(要了解详细讯息,请参见13.1.5节,“CREATE TABLE语法”)。注释:MySQL 5.1伺服器目前接受此语法,但是不实际执行;等MySQL 5.1开发出来后,将执行此语法。
用于ALTER TABLE ADD PARTITION的partition_definition子句支援用于CREATE TABLE语句的partition_definition子句的同样名称的选项。(要了解语法和介绍,请参见13.1.5节,“CREATE TABLE语法”。)例如,假设您有一个按照以下方式建立的带分区的资料表:
CREATE TABLE t1 (
id INT,
year_col INT
)
PARTITION BY RANGE (year_col) (
PARTITION p0 VALUES LESS THAN (1991),
PARTITION p1 VALUES LESS THAN (1995),
PARTITION p2 VALUES LESS THAN (1999)
);
您可以在资料表中增加一个新的分区p3,该分区用于储存小于2002的值。新增方法如下:
ALTER TABLE t1 ADD PARTITION p3 VALUES LESS THAN (2002);
注释:您不能使用ALTER TABLE向一个没有进行分区的资料表新增分区。
DROP PARTITION用于取消一个或多个RANGE或LIST分区。此命令不能用于HASH或KEY 分区;用于这两个分区时,应使用COALESCE PARTITION(见后)。如果被取消的分区其名称栏位于partition_names清单中,则储存在此分区中的资料也被取消。例如,如果以前已定义的资料表t1,您可以采用如下方法取消名称为p0和p1的分区:
ALTER TABLE DROP PARTITION p0, p1;
ADD PARTITION和DROP PARTITION目前不支援IF [NOT] EXISTS。也不可能对一个分区或一个已分区的资料表进行重命名。如果您希望对一个分区进行重命名,您必须取消分区,再重新建立;如果您希望对一个已分区的资料表进行重新命名,您必须取消所有分区,然后对资料表进行重命名,再新增被取消的分区。
COALESCE PARTITION可以用于使用HASH或KEY进行分区的资料表,以便使用number来减少分区的数目。例如,假设您使用下列方法建立了资料表t2:
CREATE TABLE t2 (
name VARCHAR (30),
started DATE
)
PARTITION BY HASH(YEAR(started))
PARTITIONS (6);
您可以使用以下命令,把t2使用的分区的数目由6个减少到4个:
ALTER TABLE t2 COALESCE PARTITION 2;
包含在最后一个number分区中的资料将被合并到其余的分区中。在此情况下,分区4和分区5将被合并到前4个分区中(编号为0、1、2和3的分区)。
如果要更改部分分区,但不更改所有的分区,您可以使用REORGANIZE PARTITION。这个命令有多种使用方法:
o 把多个分区合并为一个分区。通过把多个分区的名称列入partition_names清单,并为partition_definition提供一个单一的定义,可以实现这个功能。
o 把一个原有的分区拆分为多个分区。通过为partition_names命名一个分区,并提供多个partition_definitions,可以实现这个功能。
o 更改使用VALUES LESS THAN定义的分区子集的范围或更改使用VALUES IN定义的分区子集的值清单。
注释:对于没有明确命名的分区,MySQL会自动提供预设名称p0, p1, p2等。
要了解有关ALTER TALBE…REORANIZE PARTITION命令的详细讯息,请参见18.3节,“分区管理”。
· 多个附加子句用于提供分区维护和修补功能。这些功能与用于非分区资料表的功能类似。这些功能由CHECK TABLE和REPAIR TABLE等命令(这些命令不支援用于分区资料表)执行。这些子句包括ANALYZE PARTITION, CHECK PARTITION, OPTIMIZE PARTITION, REBUILD PARTITION和REPAIR PARTITION.每个选项均为一个partition_names子句,包括一个或多个分区名称。需要更改的资料表中必须已存在这些分区。多个分区名称用逗号分隔。要了解更多讯息,或要了解举例说明,请参见18.3.3节,“分区维护”。
以下例子展示了ALTER TABLE的使用。首先展示资料表t1。资料表t1采用如下方法建立:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
把资料表t1重新命名为t2:
mysql> ALTER TABLE t1 RENAME t2;
把栏位a从INTERGER更改为TINYINT NOT NULL(名称保持不变),并把栏位b从CHAR(10)更改为CHAR(20),同时把栏位b重新命名为栏位c:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
新增一个新的TIMESTAMP栏位,名称为d:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
在栏位d和栏位a中新增索引:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);
删除栏位c:
mysql> ALTER TABLE t2 DROP COLUMN c;
新增一个新的AUTO_INCREMENT整数栏位,名称为c:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> ADD PRIMARY KEY (c);
注意我们为c编制了索引(作为PRIMARY KEY),因为AUTO_INCREMENT栏位必须编制索引。同时我们定义c为NOT NULL,因为主键栏位不能为NULL。
当您新增一个AUTO_INCREMENT栏位时,栏位值被自动地按序号填入。对于MyISAM资料表,您可以在ALTER TABLE之前执行SET INSERT_ID=value来设置第一个序号,也可以使用AUTO_INCREMENT=value资料表选项来设置。请参见13.5.3节,“SET语法”。
如果值大于AUTO_INCREMENT栏位中的最大值,则您可以使用用于InnoDB资料表的ALTER TALBE…AUTO_INCREMENT=value资料表选项,来为新行设置序号。如果值小于栏位中当前的最大值,不会出现错误讯息,当前的序列值也不改变。
使用MyISAM资料表时,如果您不更改AUTO_INCREMENT栏位,则序列号不受影响。如果您取消一个AUTO_INCREMENT栏位,然后新增另一个AUTO_INCREMENT栏位,则序号重新排列,从1开始。
这是MySQL 5实力养成暨评量里的3-47.‘SQL语法中,哪一个符号代表单一长度的任意字元?’
答案:(C) _
也是粗心题,因为看成是任意长度。


