数据表管理文法
本节内容包括数据表的 schema 相关的文法,包括数据表本身的增删改以及索引的增减等。注意本节内容除非有特殊说明,否则在正常执行时均不对输出进行要求。对于可能涉及到建立索引的指令(包括建立索引、建立主键约束、建立 UNIQUE 约束等)需要显示所消耗的时间。
create_table
根据指定的 field_list
创建名为 Identifier
的空表。输出内容不做要求。
注意 field_list
中是逗号隔开的若干 field
,每个 field
都包含有三种语句:
normal_field
:用于创建新的列,这里不做赘述。但你应当保证逻辑的严密性,考虑到同名列、默认值类型等细节问题。primary_key_field
:用于创建主键约束,详见后文 alter_table_add_pk 部分的说明。foreign_key_field
:用于创建外键约束,详见后文 alter_table_add_foreign_key 部分的说明。
drop_table
删除当前数据库中名为 Identifier
的现有数据表,包括其元信息与所有行数据。
describe_table
显示当前数据库中名为 Identifier
的现有数据表的信息,输出的格式和内容应遵循《0.3 前端约定》一节的规定。
load_table
加载路径为 String
的(csv)文件,并将数据导入当前数据库名为 Identifier
的数据表中。
alter_add_index
在当前数据库中名为(前一个) Identifier
的现有表中创建一个新的索引,这个索引建在 identifiers
这些(一或多)列上,这个索引或许会被手动命名为(后一个) Identifier
,如果没有则你应该为它自动生成名字。
注意虽然这里没有给索引命名,但同一张表中不应该有同名索引(即不能在相同列上建两次索引)。进一步考虑到联合索引的相关问题,你应该维护一个包含 identifiers
元组的索引名。
例如,无论你的底层实现是怎样的,就上层管理而言, (course_id)
、(course_id, course_number)
、(course_number, course_id)
是三个不同的索引,它们可以同时存在,各自被删除。
另外还应考虑到索引可能是自动创建的,例如添加主键约束、UNIQUE
约束时自动创建了索引,在这些情况下你有两种处理思路:
-
手动创建的索引与自动创建的索引互不干扰,它们同时存在,都可以发挥作用,删除时各自分别考虑。例如你可能先在列
id
上建了索引,又为该列添加了主键约束,之后删除了id
上的索引,那么此时删除操作正常执行,但主键约束仍然存在,id
上自动创建的索引也仍然存在。 -
自动创建的索引会复用或覆盖手动创建的索引,当有约束带来被自动创建的索引时,不能手动删除对应索引,当约束被删除时,相应索引随即被删除。例如你可能先在列
id
上建了索引,又为id
建了主键约束,此时不能手动删除id
上的索引,如果删除了主键约束则id
上的索引亦被删除。
两种处理方式都是可以接受的,
alter_drop_index
在当前数据库中名为 Identifier
的现有表中删除建立在 identifiers
这些(一或多)列上的索引。
注意一个因其他约束而存在的索引是不能被删除,例如主键约束、UNIQUE
约束等,此时应该给出报错并拒绝执行指令。
alter_table_drop_pk
在当前数据库中名为(前一个) Identifier
的现有表中删除现有主键约束。后一个 Identifier
表示主键名,考虑到如果存在主键,则一定唯一,因此可以不给定主键名。
alter_table_drop_foreign_key
在当前数据库中名为(前一个) Identifier
的现有表中删除名为(后一个) Identifier
的现有外键约束。
alter_table_add_pk
在当前数据库中中名为(前一个) Identifier
的现有表中创建名为(后一个) Identifier
的新主键约束,约束建立在 identifiers
这些(一或多)列。
由于主键的唯一性,主键约束名通常是可以省略的。你可以根据自己的设计需求或理念来决定是否要求给出主键名,测例默认没有加。
注意创建主键时如果对应列没有索引,则应当自动创建索引。
alter_table_add_foreign_key
在当前数据库中中名为(前一个) Identifier
的现有表中创建名为(后一个) Identifier
的新外键约束,约束建立在(前一个) identifiers
这些(一或多)列上,关联到当前数据库的名为(后一个) Identifier
的现有表的(后一个)identifiers
的(一或多)列上。
注意一般外键需要一个名字以便进行删除操作,如果没有指定名字则应该自动生成一个以完成删除操作。
不同于索引,外键应用名字进行区分,即可能存在名为 fk1
与 fk2
的两个内容(即从何列关联到了何列)一样的外键,但这并不是考查内容,验收测例并不包含这种情况。
注意我们约定创建外键所指向的列必须是主键,如果不是也应该给出报错信息并拒绝执行。
外键与隐式索引
对于创建外键的列是否会自动创建隐式索引的问题,在 SQL 规范中没有明确要求,一些常用 DBMS 如 SQL Server 不会自动创建索引,而 MySQL 则会创建。对此我们不做强制要求,但是出于自动化测试时的性能考虑,建议你统一加上以节约时间。若如此做,你需要考虑在已有隐式索引的情况下又被创建显式索引应该如何处理等,合理即可,但不能让你的程序崩溃。
alter_table_add_unique
在当前数据库中名为(前一个) Identifier
的现有表中创建一个新的名为(后一个)Identifier
的 UNIQUE
约束,这个约束建在 identifiers
这些(一或多)列上,如果没有指定约束名则应该自动生成一个以便进行删除操作。
UNIQUE 约束的实现效果相当于创建了索引并要求不得重复,和主键约束相比 UNIQUE 约束允许 NULL。此外,UNIQUE 是一种特殊的 INDEX,删除 UNIQUE 也应该使用 alter_drop_index
。
注意这是选做内容。