表的介绍
- 表是关系数据库的核心
- 表 = 关系
- 表是记录的集合
- 二维表格模型易于人的理解
- MySQL 默认存储引擎都是基于行存储
- 每行记录都是基于列进行组织的
select * from table_name limit 1;
表是数据的集合,集合是无序的,上面的 SQL 语句的意思是:从表(集合)中随机选出一条数据,结果是不确定的,不能简单的认为是取出第一条数据。
select * from table_name order by col_name limit 1;
只有通过 order by 排序之后取出的数据,才是确定的。
创建表结构
官网文档:https://dev.mysql.com/doc/refman/5.7/en/create-table.html
临时表的创建
--
-- mysql 5.7.9
--
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.9-log |
+-----------+
1 row in set (0.00 sec)
mysql> use burn_test;
Database changed
mysql> create temporary table temp_a(a int);
Query OK, 0 rows affected (0.01 sec)
mysql> show create table temp_a\G
*************************** 1. row ***************************
Table: temp_a
Create Table: CREATE TEMPORARY TABLE `temp_a` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 -- 使用的是innodb
1 row in set (0.00 sec)
--
-- mysql 5.6.27
--
mysql> select version();
+------------+
| version() |
+------------+
| 5.6.27-log |
+------------+
1 row in set (0.00 sec)
mysql> create temporary table temp_a_56(a int);
Query OK, 0 rows affected (0.06 sec)
mysql> show create table temp_a_56\G
*************************** 1. row ***************************
Table: temp_a_56
Create Table: CREATE TEMPORARY TABLE `temp_a_56` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 -- 5.6 也是innodb
1 row in set (0.00 sec)
-----
--
-- 终端1 MySQL 5.7.9
--
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.9-log |
+-----------+
1 row in set (0.00 sec)
mysql> show processlist\G
*************************** 1. row ***************************
Id: 10 -- 当前ID 是 10
User: root
Host: localhost
db: burn_test
Command: Query
Time: 0
State: starting
Info: show processlist -- 当前终端执行
*************************** 2. row ***************************
Id: 12
User: root
Host: localhost
db: NULL
Command: Sleep
Time: 328
State:
Info: NULL
*************************** 3. row ***************************
Id: 13
User: root
Host: localhost
db: burn_test
Command: Sleep
Time: 16
State:
Info: NULL
3 rows in set (0.00 sec)
mysql> insert into temp_a values(123);
Query OK, 1 row affected (0.00 sec)
mysql> select * from temp_a;
+------+
| a |
+------+
| 123 |
+------+
1 row in set (0.00 sec)
--
-- 终端2 MySQL 5.7.9
--
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.9-log |
+-----------+
1 row in set (0.00 sec)
mysql> show processlist\G
*************************** 1. row ***************************
Id: 10
User: root
Host: localhost
db: burn_test
Command: Sleep
Time: 75
State:
Info: NULL
*************************** 2. row ***************************
Id: 12
User: root
Host: localhost
db: NULL
Command: Sleep
Time: 403
State:
Info: NULL
*************************** 3. row ***************************
Id: 13 -- 当前 ID 是 13
User: root
Host: localhost
db: burn_test
Command: Query
Time: 0
State: starting
Info: show processlist -- 当前终端执行
3 rows in set (0.00 sec)
mysql> use burn_test;
Database changed
mysql> show tables;
Empty set (0.00 sec) -- 从其他终端登录的用户(session)无法看到temp_a这个临时表
----
--
-- 临时表 和 普通表 同名问题
--
mysql> create table test_1 (a int); -- 创建一张普通的表叫做 test_1
Query OK, 0 rows affected (0.16 sec)
mysql> insert into test_1 values(23);
Query OK, 1 row affected (0.03 sec)
mysql> insert into test_1 values(24);
Query OK, 1 row affected (0.03 sec)
mysql> select * from test_1;
+------+
| a |
+------+
| 23 | -- 可以看到插入的数据
| 24 |
+------+
2 rows in set (0.00 sec)
mysql> create temporary table test_1 (a int); -- 创建一种和test_1 同名的临时表
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_1 values(1000); -- 插入一个 不一样的值
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_1;
+------+
| a |
+------+
| 1000 | -- 只能搜索到 临时表中的数据
+------+
1 row in set (0.00 sec)
mysql> create temporary table if not exists table_name (a int); -- 使用if not exists进行判断
- 临时表是 SESSION 级别的, 当前用户 logout 或者其他用户登录上来,是无法看到这张表的。
- 当临时表和普通表同名时,当前用户只能看到同名的临时表。
- 创建表时带上 if not exists 进行表的存在性检查;同时建议在临时表的表名前面加上统一的 prefix。
临时表的作用
临时表主要的作用是给当前登录的用户存储临时数据或者临时结果的,不要和 SQL 优化器在排序过程中内部帮你创建的临时表相混淆。
比如在存储过程中,可以用来存储临时数据,存储过程执行结束后,释放临时表。
临时表的存储引擎
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.9-log |
+-----------+
1 row in set (0.00 sec)
mysql> show variables like "default%tmp%";
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
| default_tmp_storage_engine | InnoDB | -- 5.7.9 的临时表默认存储引擎就是 InnoDB
+----------------------------+--------+
1 row in set (0.00 sec)
mysql> select version();
+------------+
| version() |
+------------+
| 5.6.27-log |
+------------+
1 row in set (0.00 sec)
mysql> show variables like "default%tmp%";
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
| default_tmp_storage_engine | InnoDB | -- 5.6.27 的临时表默认存储引擎也是 InnoDB
+----------------------------+--------+
1 row in set (0.00 sec)
-- 5.6 之前用的是MyISAM
临时表存储位置
--
-- mysql 5.7
--
mysql> system ls -l /tmp # 使用system 可以解析执行linux shell命令
total 20
drwxr-xr-x. 4 mysql mysql 4096 Dec 2 10:06 mysql_data
srwxrwxrwx. 1 mysql mysql 0 Dec 2 21:20 mysql.sock_56
srwxrwxrwx. 1 mysql mysql 0 Dec 2 20:51 mysql.sock_57
-rw-------. 1 mysql mysql 5 Dec 2 20:51 mysql.sock_57.lock
-rw-r-----. 1 mysql mysql 8554 Dec 2 22:04 #sqlf18_a_0.frm -- temp_1 的表结构
mysql> system ls -l /data/mysql_data/5.7/ | grep ib
-rw-r-----. 1 mysql mysql 879 Dec 2 20:47 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12582912 Dec 2 22:21 ibdata1
-rw-r-----. 1 mysql mysql 134217728 Dec 2 22:20 ib_logfile0
-rw-r-----. 1 mysql mysql 134217728 Dec 2 21:33 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 Dec 2 22:33 ibtmp1 -- 这个是我们的表结构对应的数据
mysql> show variables like "innodb_temp%";
+----------------------------+-----------------------+
| Variable_name | Value |
+----------------------------+-----------------------+
| innodb_temp_data_file_path | ibtmp1:12M:autoextend |
+----------------------------+-----------------------+
1 row in set (0.00 sec)
-----
--
-- mysql 5.6
--
mysql> system ls -l /tmp
total 68
drwxr-xr-x. 4 mysql mysql 4096 Dec 2 10:06 mysql_data
srwxrwxrwx. 1 mysql mysql 0 Dec 2 21:20 mysql.sock_56
srwxrwxrwx. 1 mysql mysql 0 Dec 2 20:51 mysql.sock_57
-rw-------. 1 mysql mysql 5 Dec 2 20:51 mysql.sock_57.lock
-rw-rw----. 1 mysql mysql 8554 Dec 2 22:38 #sql13f3_7_0.frm -- 表结构
-rw-rw----. 1 mysql mysql 49152 Dec 2 22:38 #sql13f3_7_0.ibd -- 表数据
-- 5.6.27 中没有 innodb_temp_data_file_path 变量
mysql> show variables like "innodb_temp%";
Empty set (0.00 sec)
mysql> show variables like "%innodb%temp%";
Empty set (0.00 sec)
- MySQL 5.7.9 把临时表结构放在 tmpdir,而数据表数据放在 datadir
- MySQL 5.6.27 把临时表结构和表数据都放在 tmpdir
查看表结构
mysql> show create table test_1\G -- 表结构
*************************** 1. row ***************************
Table: test_1
Create Table: CREATE TABLE `test_1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
mysql> desc test_1\G -- 表的描述,描述二维表信息
*************************** 1. row ***************************
Field: a
Type: int(11)
Null: YES
Key:
Default: NULL
Extra:
1 row in set (0.00 sec)
mysql> show table status like "test_1"\G -- 看表结构的元数据信息
*************************** 1. row ***************************
Name: test_1
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 2
Avg_row_length: 4096
Data_length: 8192
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2015-12-02 22:20:19
Update_time: 2015-12-02 22:20:44
Check_time: NULL
Collation: utf8mb4_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
更新表结构
ALTER TABLE 官方文档:https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
mysql> alter table test_1 add column b char(10); -- 添加列 b
Query OK, 0 rows affected (0.25 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from test_1;
+------+------+
| a | b |
+------+------+
| 23 | NULL |
| 24 | NULL |
+------+------+
2 rows in set (0.00 sec)
mysql> alter table test_1 drop column b; -- 删除列 b
Query OK, 0 rows affected (0.27 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from test_1;
+------+
| a |
+------+
| 23 |
| 24 |
+------+
2 rows in set (0.00 sec)
注意,当表记录很大的时候,ALTER TABLE 会很耗时,影响性能。
MySQL 早期版本在执行 ALTER TABLE 的时候会锁住整张表,5.6 以后可以执行 Online DDL 操作,以提高性能,参考官方文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html,查看哪些操作可以执行 Online DDL。
Online DDL 表示在执行一些 DDL 操作的时候,表不会被锁住,不会阻塞应用,应用仍然可以执行读写操作。
- DDL(Data Definition Language):数据定义语言,管理表和索引结构。DDL 的最基本是 CREATE、ALTER、RENAME、DROP 和 TRUNCATE 语句。
- DML(Data Manipulation Language):数据操纵语言,是 SQL 用于添加、更新和删除数据的子集。
作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/bboou6 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。