CREATETABLE {表名} ({字段名} {字段类型} [NOTNULL] [DEFAULT {默认值}], ...); -- CREATE TABLE test (id int NOT NULL, name text, age smallint); -- CREATE TABLE test (id int DEFAULT 0, name text, age smallint);
1 2 3 4
ALTERTABLE {表名} MODIFY COLUMN {字段名} {字段类型} [NOTNULL] [DEFAULT {默认值}] -- ALTER TABLE test MODIFY COLUMN id int NOT NULL; -- 设置为非空 -- ALTER TABLE test MODIFY COLUMN id int DEFAULT 0; -- 设置默认值 0 -- ALTER TABLE test MODIFY COLUMN id int; -- 设置为空且无默认值
注意: 主键不能去除非空约束。BLOB / TEXT / GEOMETRY / JSON 不能设置默认值。在 ALTER TABLE 时设置和移除非空值与默认值都使用 MODIFY COLUMN。
外键
什么是外键
外键是一种重要的约束,用于保证联结表的数据安全性。外键保证用于联结的键在外表中始终存在。
我们经常会使用下面的方式进行联结:
1
SELECT*FROM Movies;
1
SELECT*FROM MovieExec;
1 2 3 4 5 6 7 8 9 10 11 12 13
SELECT title, year, length, movieType, studioName, name AS execName FROM Movies LEFTJOIN MovieExec ON producerC = cert;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+--------------------------+------+--------+-----------+----------------+-----------+ | title | year | length | movieType | studioName | producerC | +--------------------------+------+--------+-----------+----------------+-----------+ | Empire Strikes Back | 1980 | 111 | drama | Fox | 555 | | My people,My country | 2019 | 158 | feature | huaxia | 100 | | Gone With the Wind | 1938 | 238 | drama | MGM | 123 | | Logan's run | 1977 | 120 | drama | MGM | 888 | | Pretty Woman | 1990 | 119 | drama | Disney | 999 | | Star Trek | 1979 | NULL | sciFic | Paramount | 444 | | Star Trek: Nemesis | 2002 | 116 | sciFic | Paramount | 321 | | Star Wars | 1977 | 124 | sciFic | Fox | 555 | | Terms of Endearment | 1983 | 132 | drama | MGM | 123 | | The Man Who Wasn't There | 2001 | 116 | comedy | USA Entertainm | 777 | | The Usual Suspects | 1995 | 106 | drama | MGM | 999 | +--------------------------+------+--------+-----------+----------------+-----------+
1 2 3 4 5 6 7 8 9 10 11
+-------------------+-------------+------+-----------+ | name | address | cert | netWorth | +-------------------+-------------+------+-----------+ | Huangjianxin | NULL | 100 | NULL | | Calvin Coolidge | Fast Lane | 123 | 20000000 | | Merv Griffin | Riot Rd. | 199 | 112000000 | | Stephen Spielberg | 123 ET road | 222 | 100000000 | | Ted Turner | Turner Av. | 333 | 125000000 | | George Lucas | Oak Rd. | 555 | 200000000 | | Jane Fonda | Turner Av. | 567 | 200000000 | +-------------------+-------------+------+-----------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+--------------------------+------+--------+-----------+----------------+-----------------+ | title | year | length | movieType | studioName | execName | +--------------------------+------+--------+-----------+----------------+-----------------+ | Empire Strikes Back | 1980 | 111 | drama | Fox | George Lucas | | My people,My country | 2019 | 158 | feature | huaxia | Huangjianxin | | Gone With the Wind | 1938 | 238 | drama | MGM | Calvin Coolidge | | Logan's run | 1977 | 120 | drama | MGM | NULL | | Pretty Woman | 1990 | 119 | drama | Disney | NULL | | Star Trek | 1979 | NULL | sciFic | Paramount | NULL | | Star Trek: Nemesis | 2002 | 116 | sciFic | Paramount | NULL | | Star Wars | 1977 | 124 | sciFic | Fox | George Lucas | | Terms of Endearment | 1983 | 132 | drama | MGM | Calvin Coolidge | | The Man Who Wasn't There | 2001 | 116 | comedy | USA Entertainm | NULL | | The Usual Suspects | 1995 | 106 | drama | MGM | NULL | +--------------------------+------+--------+-----------+----------------+-----------------+
ALTERTABLE Movies DROPCONSTRAINT {约束名}; -- ALTER TABLE Movies DROP CONSTRAINT foreignProducerC;
外键约束下行为
外键约束下有很强的约束,不满足约束将导致操作失败。另外,外键还有一些额外的行为。
创建外键时
约束
主字段中元素必须均包含于外字段元素(外键约束)
外字段必须已经创建索引,通常外字段是外表的主键
行为
主字段自动创建索引
创建外键约束
删除外键时
行为
不会删除自动创建的主字段索引
删除外键约束
在主表插入或修改记录
约束
操作后将满足外键约束
在外表删除或修改记录
约束
操作后将满足外键约束
索引
什么是索引
在使用查询语句时,常常使用 WHERE 子句进行筛选,但对于一般的字段,使用逐行判断的方法进行筛选,这种筛选效率低下。索引的本质是用于加速字段筛选的数据结构。字段使用索引后,可以在对数时间内查找需要的值。
通过创建索引,在数据量很大时有显著的查询效率提升,但在频繁插入和修改时,效率下降明显。
为什么索引的数据结构是 B+ 树
刚刚说了索引是一种数据结构,那么为什么选择 B+ 树?我们要先从 B 树讲起。
B 树是一棵多路搜索平衡树,每个节点有多个值和多个子节点。与二叉树不同的是,B 树通过在同一节点存放多个值,拥有更小的树深。虽然 B 树在一个节点存放多个值弱化了二叉搜索,但连续存储使得内存访问更加高效(局部性原理)。数据库的数据存储在磁盘中,与内存不同的是,磁盘中的 IO 操作远比内存中的 IO 慢,此时局部性原理显得比二叉搜索更为重要。B 树具有阶的概念,即在一个节点最多存放几个值,其实就是对局部性原理与二叉搜索性质的权衡。下图是一棵 B 树:
B+ 树是对 B 树的优化,在 B 树中使用连续访问相对低效且不稳定,B+ 树即在 B 树的基础上建立后继索引,当进行区间询问时,效率就会有显著提升。B+ 树中的阶数由系统分页大小决定,例如分页大小为 16KB 时,阶数通常设置为 1000 左右。下图是一棵 B+ 树:
创建和删除索引
创建索引
1
CREATE INDEX {索引名} ON {表名}({字段名});
如果要对 BLOB / TEXT 等变长类型创建索引,必须指定用于创建索引的长度。可以对联合键创建索引。
下面是使用索引提速的示例:
1
SELECTCOUNT(*) FROM test;
1
SELECT*FROM test WHERE name="zhaoliu";
1
CREATE INDEX indexName ON test(name(4));
1
SELECT*FROM test WHERE name="zhaoliu";
1 2 3 4 5 6
+----------+ | COUNT(*) | +----------+ | 511232 | +----------+ 1 row in set (0.05 sec)
1 2 3 4 5 6 7 8
+-------+---------+------+ | id | name | age | +-------+---------+------+ | 23435 | zhaoliu | 35 | | 23436 | zhaoliu | 44 | | 23890 | zhaoliu | 35 | +-------+---------+------+ 3 rows in set (0.12 sec)