表的介绍

  • 表是关系数据库的核心
  • 表 = 关系
  • 表是记录的集合
  • 二维表格模型易于人的理解
  • MySQL 默认存储引擎都是基于行存储
  • 每行记录都是基于列进行组织的
  1. select * from table_name limit 1;

表是数据的集合,集合是无序的,上面的 SQL 语句的意思是:从表(集合)中随机选出一条数据,结果是不确定的,不能简单的认为是取出第一条数据。

  1. select * from table_name order by col_name limit 1;

只有通过 order by 排序之后取出的数据,才是确定的。

创建表结构

官网文档:https://dev.mysql.com/doc/refman/5.7/en/create-table.html

临时表的创建

  1. --
  2. -- mysql 5.7.9
  3. --
  4. mysql> select version();
  5. +-----------+
  6. | version() |
  7. +-----------+
  8. | 5.7.9-log |
  9. +-----------+
  10. 1 row in set (0.00 sec)
  11. mysql> use burn_test;
  12. Database changed
  13. mysql> create temporary table temp_a(a int);
  14. Query OK, 0 rows affected (0.01 sec)
  15. mysql> show create table temp_a\G
  16. *************************** 1. row ***************************
  17. Table: temp_a
  18. Create Table: CREATE TEMPORARY TABLE `temp_a` (
  19. `a` int(11) DEFAULT NULL
  20. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 -- 使用的是innodb
  21. 1 row in set (0.00 sec)
  22. --
  23. -- mysql 5.6.27
  24. --
  25. mysql> select version();
  26. +------------+
  27. | version() |
  28. +------------+
  29. | 5.6.27-log |
  30. +------------+
  31. 1 row in set (0.00 sec)
  32. mysql> create temporary table temp_a_56(a int);
  33. Query OK, 0 rows affected (0.06 sec)
  34. mysql> show create table temp_a_56\G
  35. *************************** 1. row ***************************
  36. Table: temp_a_56
  37. Create Table: CREATE TEMPORARY TABLE `temp_a_56` (
  38. `a` int(11) DEFAULT NULL
  39. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 -- 5.6 也是innodb
  40. 1 row in set (0.00 sec)
  41. -----
  42. --
  43. -- 终端1 MySQL 5.7.9
  44. --
  45. mysql> select version();
  46. +-----------+
  47. | version() |
  48. +-----------+
  49. | 5.7.9-log |
  50. +-----------+
  51. 1 row in set (0.00 sec)
  52. mysql> show processlist\G
  53. *************************** 1. row ***************************
  54. Id: 10 -- 当前ID 10
  55. User: root
  56. Host: localhost
  57. db: burn_test
  58. Command: Query
  59. Time: 0
  60. State: starting
  61. Info: show processlist -- 当前终端执行
  62. *************************** 2. row ***************************
  63. Id: 12
  64. User: root
  65. Host: localhost
  66. db: NULL
  67. Command: Sleep
  68. Time: 328
  69. State:
  70. Info: NULL
  71. *************************** 3. row ***************************
  72. Id: 13
  73. User: root
  74. Host: localhost
  75. db: burn_test
  76. Command: Sleep
  77. Time: 16
  78. State:
  79. Info: NULL
  80. 3 rows in set (0.00 sec)
  81. mysql> insert into temp_a values(123);
  82. Query OK, 1 row affected (0.00 sec)
  83. mysql> select * from temp_a;
  84. +------+
  85. | a |
  86. +------+
  87. | 123 |
  88. +------+
  89. 1 row in set (0.00 sec)
  90. --
  91. -- 终端2 MySQL 5.7.9
  92. --
  93. mysql> select version();
  94. +-----------+
  95. | version() |
  96. +-----------+
  97. | 5.7.9-log |
  98. +-----------+
  99. 1 row in set (0.00 sec)
  100. mysql> show processlist\G
  101. *************************** 1. row ***************************
  102. Id: 10
  103. User: root
  104. Host: localhost
  105. db: burn_test
  106. Command: Sleep
  107. Time: 75
  108. State:
  109. Info: NULL
  110. *************************** 2. row ***************************
  111. Id: 12
  112. User: root
  113. Host: localhost
  114. db: NULL
  115. Command: Sleep
  116. Time: 403
  117. State:
  118. Info: NULL
  119. *************************** 3. row ***************************
  120. Id: 13 -- 当前 ID 13
  121. User: root
  122. Host: localhost
  123. db: burn_test
  124. Command: Query
  125. Time: 0
  126. State: starting
  127. Info: show processlist -- 当前终端执行
  128. 3 rows in set (0.00 sec)
  129. mysql> use burn_test;
  130. Database changed
  131. mysql> show tables;
  132. Empty set (0.00 sec) -- 从其他终端登录的用户(session)无法看到temp_a这个临时表
  133. ----
  134. --
  135. -- 临时表 普通表 同名问题
  136. --
  137. mysql> create table test_1 (a int); -- 创建一张普通的表叫做 test_1
  138. Query OK, 0 rows affected (0.16 sec)
  139. mysql> insert into test_1 values(23);
  140. Query OK, 1 row affected (0.03 sec)
  141. mysql> insert into test_1 values(24);
  142. Query OK, 1 row affected (0.03 sec)
  143. mysql> select * from test_1;
  144. +------+
  145. | a |
  146. +------+
  147. | 23 | -- 可以看到插入的数据
  148. | 24 |
  149. +------+
  150. 2 rows in set (0.00 sec)
  151. mysql> create temporary table test_1 (a int); -- 创建一种和test_1 同名的临时表
  152. Query OK, 0 rows affected (0.00 sec)
  153. mysql> insert into test_1 values(1000); -- 插入一个 不一样的值
  154. Query OK, 1 row affected (0.00 sec)
  155. mysql> select * from test_1;
  156. +------+
  157. | a |
  158. +------+
  159. | 1000 | -- 只能搜索到 临时表中的数据
  160. +------+
  161. 1 row in set (0.00 sec)
  162. mysql> create temporary table if not exists table_name (a int); -- 使用if not exists进行判断
  • 临时表是 SESSION 级别的, 当前用户 logout 或者其他用户登录上来,是无法看到这张表的。
  • 当临时表和普通表同名时,当前用户只能看到同名的临时表。
  • 创建表时带上 if not exists 进行表的存在性检查;同时建议在临时表的表名前面加上统一的 prefix。

临时表的作用

临时表主要的作用是给当前登录的用户存储临时数据或者临时结果的,不要和 SQL 优化器在排序过程中内部帮你创建的临时表相混淆。

比如在存储过程中,可以用来存储临时数据,存储过程执行结束后,释放临时表。

临时表的存储引擎

  1. mysql> select version();
  2. +-----------+
  3. | version() |
  4. +-----------+
  5. | 5.7.9-log |
  6. +-----------+
  7. 1 row in set (0.00 sec)
  8. mysql> show variables like "default%tmp%";
  9. +----------------------------+--------+
  10. | Variable_name | Value |
  11. +----------------------------+--------+
  12. | default_tmp_storage_engine | InnoDB | -- 5.7.9 的临时表默认存储引擎就是 InnoDB
  13. +----------------------------+--------+
  14. 1 row in set (0.00 sec)
  15. mysql> select version();
  16. +------------+
  17. | version() |
  18. +------------+
  19. | 5.6.27-log |
  20. +------------+
  21. 1 row in set (0.00 sec)
  22. mysql> show variables like "default%tmp%";
  23. +----------------------------+--------+
  24. | Variable_name | Value |
  25. +----------------------------+--------+
  26. | default_tmp_storage_engine | InnoDB | -- 5.6.27 的临时表默认存储引擎也是 InnoDB
  27. +----------------------------+--------+
  28. 1 row in set (0.00 sec)
  29. -- 5.6 之前用的是MyISAM

临时表存储位置

  1. --
  2. -- mysql 5.7
  3. --
  4. mysql> system ls -l /tmp # 使用system 可以解析执行linux shell命令
  5. total 20
  6. drwxr-xr-x. 4 mysql mysql 4096 Dec 2 10:06 mysql_data
  7. srwxrwxrwx. 1 mysql mysql 0 Dec 2 21:20 mysql.sock_56
  8. srwxrwxrwx. 1 mysql mysql 0 Dec 2 20:51 mysql.sock_57
  9. -rw-------. 1 mysql mysql 5 Dec 2 20:51 mysql.sock_57.lock
  10. -rw-r-----. 1 mysql mysql 8554 Dec 2 22:04 #sqlf18_a_0.frm -- temp_1 的表结构
  11. mysql> system ls -l /data/mysql_data/5.7/ | grep ib
  12. -rw-r-----. 1 mysql mysql 879 Dec 2 20:47 ib_buffer_pool
  13. -rw-r-----. 1 mysql mysql 12582912 Dec 2 22:21 ibdata1
  14. -rw-r-----. 1 mysql mysql 134217728 Dec 2 22:20 ib_logfile0
  15. -rw-r-----. 1 mysql mysql 134217728 Dec 2 21:33 ib_logfile1
  16. -rw-r-----. 1 mysql mysql 12582912 Dec 2 22:33 ibtmp1 -- 这个是我们的表结构对应的数据
  17. mysql> show variables like "innodb_temp%";
  18. +----------------------------+-----------------------+
  19. | Variable_name | Value |
  20. +----------------------------+-----------------------+
  21. | innodb_temp_data_file_path | ibtmp1:12M:autoextend |
  22. +----------------------------+-----------------------+
  23. 1 row in set (0.00 sec)
  24. -----
  25. --
  26. -- mysql 5.6
  27. --
  28. mysql> system ls -l /tmp
  29. total 68
  30. drwxr-xr-x. 4 mysql mysql 4096 Dec 2 10:06 mysql_data
  31. srwxrwxrwx. 1 mysql mysql 0 Dec 2 21:20 mysql.sock_56
  32. srwxrwxrwx. 1 mysql mysql 0 Dec 2 20:51 mysql.sock_57
  33. -rw-------. 1 mysql mysql 5 Dec 2 20:51 mysql.sock_57.lock
  34. -rw-rw----. 1 mysql mysql 8554 Dec 2 22:38 #sql13f3_7_0.frm -- 表结构
  35. -rw-rw----. 1 mysql mysql 49152 Dec 2 22:38 #sql13f3_7_0.ibd -- 表数据
  36. -- 5.6.27 中没有 innodb_temp_data_file_path 变量
  37. mysql> show variables like "innodb_temp%";
  38. Empty set (0.00 sec)
  39. mysql> show variables like "%innodb%temp%";
  40. Empty set (0.00 sec)
  • MySQL 5.7.9 把临时表结构放在 tmpdir,而数据表数据放在 datadir
  • MySQL 5.6.27 把临时表结构和表数据都放在 tmpdir

查看表结构

  1. mysql> show create table test_1\G -- 表结构
  2. *************************** 1. row ***************************
  3. Table: test_1
  4. Create Table: CREATE TABLE `test_1` (
  5. `a` int(11) DEFAULT NULL
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  7. 1 row in set (0.00 sec)
  8. mysql> desc test_1\G -- 表的描述,描述二维表信息
  9. *************************** 1. row ***************************
  10. Field: a
  11. Type: int(11)
  12. Null: YES
  13. Key:
  14. Default: NULL
  15. Extra:
  16. 1 row in set (0.00 sec)
  17. mysql> show table status like "test_1"\G -- 看表结构的元数据信息
  18. *************************** 1. row ***************************
  19. Name: test_1
  20. Engine: InnoDB
  21. Version: 10
  22. Row_format: Dynamic
  23. Rows: 2
  24. Avg_row_length: 4096
  25. Data_length: 8192
  26. Max_data_length: 0
  27. Index_length: 0
  28. Data_free: 0
  29. Auto_increment: NULL
  30. Create_time: 2015-12-02 22:20:19
  31. Update_time: 2015-12-02 22:20:44
  32. Check_time: NULL
  33. Collation: utf8mb4_general_ci
  34. Checksum: NULL
  35. Create_options:
  36. Comment:
  37. 1 row in set (0.00 sec)

更新表结构

ALTER TABLE 官方文档:https://dev.mysql.com/doc/refman/5.7/en/alter-table.html

  1. mysql> alter table test_1 add column b char(10); -- 添加列 b
  2. Query OK, 0 rows affected (0.25 sec)
  3. Records: 0 Duplicates: 0 Warnings: 0
  4. mysql> select * from test_1;
  5. +------+------+
  6. | a | b |
  7. +------+------+
  8. | 23 | NULL |
  9. | 24 | NULL |
  10. +------+------+
  11. 2 rows in set (0.00 sec)
  12. mysql> alter table test_1 drop column b; -- 删除列 b
  13. Query OK, 0 rows affected (0.27 sec)
  14. Records: 0 Duplicates: 0 Warnings: 0
  15. mysql> select * from test_1;
  16. +------+
  17. | a |
  18. +------+
  19. | 23 |
  20. | 24 |
  21. +------+
  22. 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 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。