楼主: Amygo

[原创] MySQL数据类型:ENUM、SET、BOOL/BOOLEAN、TINYINT特性介绍

[复制链接]
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
31#
 楼主| 发表于 2019-6-4 11:32 | 只看该作者
c)修改枚举类型字段定义的默认值,且新默认值不在枚举列表中
  1. root@localhost : mysqlops 02:39:15> ALTER TABLE mysqlops_set_enum MODIFY Work_Option enum(‘DBA’,‘SA’,‘C++’,‘JavaScript’,‘NA’,‘QA’,‘Java’,‘other’,’’) NOT NULL DEFAULT ‘iphone’;

  2. ERROR 1067 (42000): Invalid default value for ‘Work_Option’
复制代码

小结:
若是给枚举类型字段指定的默认值,没有在枚举类型值域列表中出现,则会出现SQL语法错误,导致SQL语句执行失败。


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
32#
 楼主| 发表于 2019-6-4 11:33 | 只看该作者
d)修改枚举类型字段定义,尾部追加枚举元素
  1. root@localhost : mysqlops 02:39:27> ALTER TABLE mysqlops_set_enum MODIFY Work_Option enum(‘DBA’,‘SA’,‘C++’,‘JavaScript’,‘NA’,‘QA’,‘Java’,‘PHP’,‘other’,’’,‘Python’) NOT NULL DEFAULT ‘DBA’;
  2. Query OK, 0 rows affected (0.00 sec)
  3. Records: 0 Duplicates: 0 Warnings: 0
复制代码

小结:
为枚举类型字段的值域列表增加枚举元素,若是尾部追加的方式,则不需要表级锁,可以非常快就可以完成DDL变更。

使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
33#
 楼主| 发表于 2019-6-4 11:34 | 只看该作者
e)修改枚举类型字段定义,调整枚举元素的顺序
  1. root@localhost : mysqlops 02:38:10> SELECT * FROM mysqlops_set_enum WHERE Work_Option=1 LIMIT 1;

  2. ±---------±------------±------------------+

  3. | ID | Work_Option | Work_City |

  4. ±---------±------------±------------------+

  5. | 12017252 | DBA | guangzhou,tianjin |

  6. ±---------±------------±------------------+

  7. 1 row in set (3.22 sec)



  8. root@localhost : mysqlops 02:39:39> ALTER TABLE mysqlops_set_enum MODIFY Work_Option enum(‘JavaScript’,‘DBA’,‘SA’,‘C++’,‘NA’,‘QA’,‘Java’,‘PHP’,‘other’,’’,‘Python’) NOT NULL DEFAULT ‘DBA’;

  9. Query OK, 20017251 rows affected (2 min 10.75 sec)

  10. Records: 20017251 Duplicates: 0 Warnings: 0



  11. root@localhost : mysqlops 02:42:01> SELECT * FROM mysqlops_set_enum WHERE Work_Option=1 LIMIT 1;

  12. ±---------±------------±------------------+

  13. | ID | Work_Option | Work_City |

  14. ±---------±------------±------------------+

  15. | 12017252 | DBA | guangzhou,tianjin |

  16. ±---------±------------±------------------+

  17. 1 row in set (3.22 sec)
复制代码

小结:
对枚举类型字段的值域列表元素顺序进行调整,会发现:
i.将需要表级锁和重见数据存储表的方式,完成枚举类型字段表的结构调整;
ii.枚举类型字段值域列表中受影响元素的存储顺序编号发生变化;
iii.数据库表枚举类型字段中存储的数据是枚举类型元素的编号,枚举类型元素顺序编号发生变化时,对应存储的数据序号也需要跟着发生变化;


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
34#
 楼主| 发表于 2019-6-4 11:37 | 只看该作者
f)修改枚举类型字段定义,删除某个枚举元素
  1. root@localhost : mysqlops 02:05:24> SELECT COUNT() FROM mysqlops_set_enum WHERE Work_Option=’’;

  2. ±---------+

  3. | COUNT() |

  4. ±---------+

  5. | 4017251 |

  6. ±---------+

  7. 1 row in set (5.00 sec)



  8. root@localhost : mysqlops 02:05:40> SELECT * FROM mysqlops_set_enum limit 6000000,1;

  9. ±--------±------------±----------+

  10. | ID | Work_Option | Work_City |

  11. ±--------±------------±----------+

  12. | 6000001 | PHP | dalian |

  13. ±--------±------------±----------+

  14. 1 row in set (1.38 sec)



  15. root@localhost : mysqlops 02:06:55> SELECT COUNT() FROM mysqlops_set_enum WHERE Work_Option=‘PHP’;

  16. ±---------+

  17. | COUNT() |

  18. ±---------+

  19. | 2000000 |

  20. ±---------+

  21. 1 row in set (5.11 sec)



  22. root@localhost : mysqlops 02:45:40> ALTER TABLE mysqlops_set_enum MODIFY Work_Option enum(‘JavaScript’,‘DBA’,‘SA’,‘C++’,‘NA’,‘QA’,‘Java’,‘other’,’’,‘Python’) NOT NULL DEFAULT ‘DBA’;

  23. Query OK, 20017251 rows affected, 65535 warnings (2 min 11.71 sec)

  24. Records: 20017251 Duplicates: 0 Warnings: 2000000



  25. root@localhost : mysqlops 02:54:01> SHOW WARNINGS;

  26. ±--------±-----±-------------------------------------------------------+

  27. | Level | Code | Message |

  28. ±--------±-----±-------------------------------------------------------+

  29. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017252 |

  30. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017253 |

  31. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017254 |

  32. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017255 |

  33. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017256 |

  34. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017257 |

  35. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017258 |

  36. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017259 |

  37. | Warning | 1265 | Data truncated for column ‘Work_Option’ at row 4017260 |



  38. root@localhost : mysqlops 02:56:18> SELECT COUNT() FROM mysqlops_set_enum WHERE Work_Option=’’;

  39. ±---------+

  40. | COUNT() |

  41. ±---------+

  42. | 6017251 |

  43. ±---------+

  44. 1 row in set (4.68 sec)



  45. root@localhost : mysqlops 02:56:48> SELECT * FROM mysqlops_set_enum WHERE ID=6000001;

  46. ±--------±------------±----------+

  47. | ID | Work_Option | Work_City |

  48. ±--------±------------±----------+

  49. | 6000001 | | dalian |

  50. ±--------±------------±----------+

  51. 1 row in set (0.00 sec)
复制代码

小结:
对于枚举类型字段中已存储某枚举元素的数据,再删除枚举类型ENUM字段值域列表中某个枚举值,则会出现:
I.存在多少条要删除的枚举值记录数,就会产生多少条警告信息(注:警告信息最大值65535条);
II.被删除枚举值对应的字段的记录值,会发生截断,并且用空字符串值填充;


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
35#
 楼主| 发表于 2019-6-4 11:38 | 只看该作者
g)上述DDL变更操作之后的表结构
  1. <p>root@localhost : mysqlops 02:57:30> SHOW CREATE TABLE mysqlops_set_enum\G</p><p>*************************** 1. row ***************************</p><p>Table: mysqlops_set_enum</p><p>Create Table: CREATE TABLE mysqlops_set_enum (</p><p>ID int(11) NOT NULL AUTO_INCREMENT,</p><p>Work_Option enum(‘JavaScript’,‘DBA’,‘SA’,‘C++’,‘NA’,‘QA’,‘Java’,‘other’,’’,‘Python’) NOT NULL DEFAULT ‘DBA’,</p><p>Work_City set(‘shanghai’,‘beijing’,‘hangzhou’,‘shenzhen’,‘guangzhou’,‘xiamen’,‘tianjin’,‘qingdao’,‘dalian’,‘xian’,‘other’) NOT NULL DEFAULT ‘shanghai’,</p><p>PRIMARY KEY (ID)</p><p>) ENGINE=InnoDB AUTO_INCREMENT=20017252 DEFAULT CHARSET=utf8</p><p>1 row in set (0.00 sec)</p><p></p>
复制代码


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
36#
 楼主| 发表于 2019-6-6 17:12 | 只看该作者
(四)枚举类型ENUM字段数据库索引创建与删除

a)枚举类型字段无创建索引条件的SQL语句执行计划
root@localhost : mysqlops 03:40:35> EXPLAIN SELECT * FROM mysqlops_set_enum WHERE Work_Option=4 LIMIT 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: mysqlops_set_enum
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 20017710
Extra: Using where
1 row in set (0.00 sec)
小结:
MySQL数据库枚举类型字段没有显式创建索引信息时,即使符合MySQL数据库使用索引条件要求的SQL语句,也无索引信息可用,也即MySQL数据库枚举类型字段值域列表中的存储序列编号,无法做到替代索引的作用,也即依然需要显式创建数据库索引,加速数据查找速度。
---------------------
作者:Amy—go


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
37#
 楼主| 发表于 2019-6-6 17:12 | 只看该作者
b)为枚举类型字段创建索引
root@localhost : mysqlops 03:40:59> ALTER TABLE mysqlops_set_enum ADD INDEX idx_Work_Option_enum(Work_Option);
Query OK, 0 rows affected (1 min 14.31 sec)
Records: 0 Duplicates: 0 Warnings: 0
小结:
mysql数据库枚举类型字段上创建普通索引,也是需要表级锁、创建临时表等方式实现,并没有什么内部特殊的机制可使用。


使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
38#
 楼主| 发表于 2019-6-6 17:13 | 只看该作者
c)枚举类型字段有索引条件的SQL语句执行计划
root@localhost : mysqlops 03:42:53> EXPLAIN SELECT * FROM mysqlops_set_enum WHERE Work_Option=4 LIMIT 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: mysqlops_set_enum
type: ref
possible_keys: idx_Work_Option_enum
key: idx_Work_Option_enum
key_len: 1
ref: const
rows: 3927162
Extra: Using where
1 row in set (0.00 sec)
小结:
mysql数据库枚举类型字段创建索引之后,若是根据枚举类型字段进行数据查找,且WHERE子句符合正确写法和枚举值所占比例符合使用索引的要求,即可根据索引数据完成数据查找。

使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
39#
 楼主| 发表于 2019-6-6 17:13 | 只看该作者
d)删除枚举类型字段上的索引
root@localhost : mysqlops 03:44:22> ALTER TABLE mysqlops_set_enum DROP INDEX idx_Work_Option_enum;
Query OK, 0 rows affected (0.80 sec)
Records: 0 Duplicates: 0 Warnings: 0
小结:
MySQL5.5.X版本数据库对于普通索引的删除操作,还是非常好的支持,并不需要创建临时表等操作,对于枚举类型字段上的索引也是同样适用的,关于这方面的文章可参考MySQL 5.5版本对普通索引增删性能的优化。

使用道具 举报

回复
论坛徽章:
2
现任管理团队成员
日期:2020-02-20 02:10:00版主1段
日期:2020-02-20 02:10:12
40#
 楼主| 发表于 2019-6-6 17:13 | 只看该作者
(五)总结
通过上述对MySQL数据库表枚举类型字段的定义属性和索引方面的DDL变更操作,观察对枚举类型字段存储的数据影响,可以得出下列结论:
a)MySQL数据库枚举类型字段与其他数据类型一样,进行DDL变更操作可能产生的影响;
b)MySQL数据库枚举类型字段的DDL变更操作,属于枚举类型字段特有的内容:
I.枚举类型字段的枚举数据值域列表,以尾部追加枚举元素值的方式,不会出现锁表等;
II.枚举类型字段的枚举数据值域列表中,若是调整枚举类型枚举元素值的顺序,不会导致数据库表存储的数据出现错乱对照关系,数据库表存储数值会发生更新,以及需要锁表等操作;
III.删除枚举类型字段的枚举数据值域列表中,某个枚举元素值,会导致数据库表已存储的数据行出现截断,以及需要锁表等操作;
IV.枚举类型字段内部的枚举数据与存储序号之间的对照关系,不会能起到MySQL数据库表索引的功能;
V.枚举类型字段存储的数据值,则是枚举类型枚举元素的序列编号,而不是真实的字符串数据,而是通过其内部对照表的方式转换而实现的;

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表