首页 数据库 mysql教程 要慎用mysql的enum字段的原因_MySQL

要慎用mysql的enum字段的原因_MySQL

Jun 01, 2016 pm 01:06 PM
enum mysql

PHP低级编程的兄弟是这样来看这个问题的,我作下笔录如下,期望能客观的理解这个enum字段的优点及缺点:

膘哥观点:
    enum有优点。但个人觉得。。。缺点更多,客观的讲:优点主要是在建数据 库的时候就可以把一些值给规范好。缺点是。。enum不适合PHP。主要是PHP是弱类型,如:你insert into ..... set a= 1,你没法知道你是想 a= '1' 还是 a= 1(a='1'是插入值1,a=1是插入enum的第一个值,尤其php弱类型的,如果int的,很少有人在sql里加双引号。),这是PHP和mysql 在使用enum 最大的问题。所以。。安心点啦。干脆点直接tinyint。

单曲观点:
    我觉得没什么优点,对数字型的enum,简直就是梦魇,boolean  tinyint(1) 0,1 status  tinyint(1)  1,2,3,4,5,6..tinyint欢淫你~~。如:audit_result enum(1,2,3),set audit_result = 1;...容易出现膘哥所说的混淆。

简单观点:
   少用,一般都是用tinyint替代。

天枫观点:
   我觉得除了状态直观  没什么优点,我一般直接int,tinyint([1or2or3]) 到底有啥区别?(后面会简单探讨下,这里面的1or2or3区别。)

中庸观点:
   a=1是插入enum的第一个值,尤其php弱类型的,如果int的,很少有人在sql里加双引号,基本上是不加引号的。

竖琴螺观点:
   六种情况就:tinyint(1)  -1,-2,1,2,3,4

上面各种观点重点集中在PHP这种弱类型语言对引号不重视,程序员不写容易引起插入的语句不是自己想要的结果的问题,容易出现int时没有用引号导致插入了新值而不是定的那个值:

表结构如下: 

CREATE TABLE `enum2tinyint` ( 
 `switchs` enum('none','success','fail','delete','skip','1') DEFAULT NULL, 
 `switch` tinyint(1) NOT NULL, 
 KEY `switchs` (`switchs`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
登录后复制


正常带引号插入enum:

INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES ('1', '1'); 
1 1 

登录后复制

PHP的弱类型问题,特别是对int类型的情况,实践如下:
如果没有带引号插入enum字段后如下(是第一个值none):

INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES (1, '1'); 
none 1 
登录后复制

如果没有带引号插入enum字段后如下(是第2个值success):

INSERT INTO `test`.`enum2tinyint` (`switchs`, `switch`) VALUES (2, '1'); 
success 1 
登录后复制


结论:要插入enum的值,字段必须加引号,不加引号当然是数字,数字就是key,不是value。

规劝:
1)enum是整型这样的错误很容易发生,尤其是php弱类型的,一般新来一个人,没注意enum类型,就会犯错。
2)数据库说明清楚的话,或者可选择的全是字符串的话,还没什么,但是里面有数字,难免有新手犯错,养成加引号的习惯很重要。

最终结论:
历史原因,要把enum改成tinyint程序改动太大了,用了的没必要改·~,以后新建的时候,尽量使用tinyint就好。
这种字段的重复内容过多的,索引建不建,关系不大,这种在mysql叫索引的势太低,其查询效果不太好:(英文是这么翻译的:https://justwinit.cn/post/1405/)。
————————————————————————————————————————————————————————————————————
tinyint(1)和tinyint(4)一样的,都是-127到128或者0到256。unsigned属性全是正,和c语言unsigned int有点类似:
tinyint(1)   -128 ~ 127
tinyint(1) unsigned  0 ~ 255

为何表示的最大正数比最小负数的绝对值少1呢?
第一位是符号位,1表示负数
所以负数可以到128,正数只能到127
-128正127
如:0111 1111  正数  ,负数 1111 1111

提问:

Mysql里int(1)和int(11)差别很大的,mysql的int,有个属性 ,UNSIGNED ZEROFILL  后面的ZEROFILL,就是有定义的位数不够则用零补齐对齐一下(这儿可能涉及到索引的性能罢):int,  长度(M)=5, 属性=UNSIGNED ZEROFILL(无符号,用0来填充位数),00001,00002。

但这个tinyint呢,tinyint(1)和tinyint(4)一样的?

看这文章后:http://www.bitsCN.com/article/53424.htm

我估计:mysql这块对一个字节不像int这种四个字节要进行对其前部分进行部分字节索引,如果说tinyint(1)和tinyint(4)是一样的表示范围情况下,但mysql对tinyint数字长度位数作了可设置的限定,从理论上说其存在硬盘里的字节是不一样才是合乎逻辑的,这块估计还是为了对字节进行对齐方便索引等,以提升效率为主罢,l如:ike keyword%    索引有效,如果统一对齐,索引效果会不会更好呢?我也只是猜测。
————————————————————————————————————————————————————————————————————

在网上找了下这个enum的mysql的大体实现如下:

一)enum的存储原理我仔细查看了下手册。是这样的:
在建立这个字段时,我们会给他规定一个范围比如enum('a','b','c'),这时mysql内部会建立一张hash结构的map表,类似:0000 -> a,0001 -> b,0002 -> c。
当我插入一条数据,此字段的值位a或b或c时,他存储在里面的不是这个字符,而是对应他的索引,也就是那个0000或0001或0002。
同样,enum在mysql手册上的说明:
ENUM('value1','value2',...)
1或2个字节,取决于枚举值的个数(最多65,535个值)
除非enum的个数超过了一定数量,否则他所占的存储空间也总是1字节。

二)tinyint:
类型  字节  最小值  最大值
      (带符号的/无符号的)  (带符号的/无符号的)
TINYINT  1  -128  127
他的最小存储所占空间也是1字节。

最后,Enum,既然要用它,就不必要使用什么0,1,2来代替实际的字符串了。甚至中文字符串。他并不会对数据库性能进行多余开销。因为对于它来说,你使用'0','1','2'和'张三','李四','王五'数据表所占的存储空间一样。但是考虑到我们实际应用时数据需要从db服务器回传到web app,所以在网络传输时,当然还是尽可能的传输小数据比较好。所以如果很在意这些,还是不用它好了。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP 的大数据结构处理技巧 PHP 的大数据结构处理技巧 May 08, 2024 am 10:24 AM

大数据结构处理技巧:分块:分解数据集并分块处理,减少内存消耗。生成器:逐个产生数据项,无需加载整个数据集,适用于无限数据集。流:逐行读取文件或查询结果,适用于大文件或远程数据。外部存储:对于超大数据集,将数据存储在数据库或NoSQL中。

如何在 PHP 中使用 MySQL 备份和还原? 如何在 PHP 中使用 MySQL 备份和还原? Jun 03, 2024 pm 12:19 PM

在PHP中备份和还原MySQL数据库可通过以下步骤实现:备份数据库:使用mysqldump命令转储数据库为SQL文件。还原数据库:使用mysql命令从SQL文件还原数据库。

如何优化 PHP 中的 MySQL 查询性能? 如何优化 PHP 中的 MySQL 查询性能? Jun 03, 2024 pm 08:11 PM

可以通过以下方式优化MySQL查询性能:建立索引,将查找时间从线性复杂度降至对数复杂度。使用PreparedStatements,防止SQL注入并提高查询性能。限制查询结果,减少服务器处理的数据量。优化连接查询,包括使用适当的连接类型、创建索引和考虑使用子查询。分析查询,识别瓶颈;使用缓存,减少数据库负载;优化PHP代码,尽量减少开销。

如何使用 PHP 插入数据到 MySQL 表中? 如何使用 PHP 插入数据到 MySQL 表中? Jun 02, 2024 pm 02:26 PM

如何将数据插入MySQL表中?连接到数据库:使用mysqli建立与数据库的连接。准备SQL查询:编写一个INSERT语句以指定要插入的列和值。执行查询:使用query()方法执行插入查询,如果成功,将输出一条确认消息。

如何使用 PHP 创建 MySQL 表? 如何使用 PHP 创建 MySQL 表? Jun 04, 2024 pm 01:57 PM

使用PHP创建MySQL表需要以下步骤:连接到数据库。创建数据库(如果不存在)。选择数据库。创建表。执行查询。关闭连接。

如何在 PHP 中使用 MySQL 存储过程? 如何在 PHP 中使用 MySQL 存储过程? Jun 02, 2024 pm 02:13 PM

要在PHP中使用MySQL存储过程:使用PDO或MySQLi扩展连接到MySQL数据库。准备调用存储过程的语句。执行存储过程。处理结果集(如果存储过程返回结果)。关闭数据库连接。

如何修复 MySQL 8.4 上的 mysql_native_password 未加载错误 如何修复 MySQL 8.4 上的 mysql_native_password 未加载错误 Dec 09, 2024 am 11:42 AM

MySQL 8.4(截至 2024 年的最新 LTS 版本)中引入的主要变化之一是默认情况下不再启用“MySQL 本机密码”插件。此外,MySQL 9.0完全删除了这个插件。 此更改会影响 PHP 和其他应用程序

oracle数据库和mysql的区别 oracle数据库和mysql的区别 May 10, 2024 am 01:54 AM

Oracle数据库和MySQL都是基于关系模型的数据库,但Oracle在兼容性、可扩展性、数据类型和安全性方面更胜一筹;而MySQL则侧重速度和灵活性,更适合小到中等规模的数据集。①Oracle提供广泛的数据类型,②提供高级安全功能,③适合企业级应用程序;①MySQL支持NoSQL数据类型,②安全性措施较少,③适合小型到中等规模应用程序。

See all articles