MySQL常用增删改查

来源:互联网 发布:java文件上传到服务器 编辑:程序博客网 时间:2024/05/18 20:04


以下所有提到的新版本,均在mysql 5.7之后,目前5.7均支持。




===============================      一、数据库操作      ============================================
 
1、查看数据库


SHOW DATABASES;
 
# 默认数据库:
 mysql - 用户权限相关数据
 test - 用于用户测试数据
 information_schema - MySQL本身架构相关数据
 performance_schemamysql性能相关数据
 sys 可视化维护管理相关
 
2、创建数据库
 
# utf-8 编码
CREATE DATABASE test DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
CREATE DATABASE test DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci;


# gbk 编码
CREATE DATABASE test DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;
 
# utf8mb4 编码
CREATE DATABASE test DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;


修改数据库字符集
alter DATABASE test DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;




3、用户管理
 
# 创建用户
create user 'lzj'@'10.10.%' identified by 'mysql';


# 删除用户
drop user 'lzj'@'10.10.%';
delete from mysql.user(清空用户表)


# 修改用户
rename user 'lzj'@'10.10.%'; to 'dba'@'%';


# 修改密码
set password for 'dba'@'%' = Password('mysql')


#新版本MySQL:
set password for 'dba'@'%'='mysql';

#创建用户授权一起:(新版本这种方式将被放弃)
grant all on *.* to 'db2'@'%' identified by 'mysql';


PS:用户权限相关数据保存在mysql数据库的user表中,所以也可以直接对其进行操作(不建议)


#新版本5.7MYSQL修改密码:
update mysql.user set authentication_string=password('zabbix') where user='zabbix';

mariadb及5.6以下:
update mysql.user set password=password('zabbix') where user='zabbix';
 
# 查看当前用户
select user();
# 查看所有用户
select host,user from mysql.user;

# 人性化显示所有用户
SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;




5、授权管理


 # 查看用户的所有权限
show grants for 'nick'@'%';
或者:
mysql> show grants for 'test';
+-------------------------------------------+
| Grants for test@%                         |
+-------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' |
+-------------------------------------------+
1 row in set (0.36 sec)


#用户授权
grant all on *.* to 'test'@'%';flush privileges;

#回收权限
revoke select on *.* from 'test'@'%';
 
 
#对于目标数据库以及内部其他:
test.* 表示test库下所有表
test.sys 表示test库下sys表
test.del_id 表示test库下,del_id是存储过程。
*.* 表示所有库下所有表


#对于用户和IP:
'test'@'192.168.1.164'表示test用户只能在192.168.1.164的IP地址才能访问
'test'@'192.168.1.%'表示test用户只能在192.168.1网段下才能访问。
'test'@'%' 表示test用户可以在任意网段访问(不包括localhost,127.0.0.1)
'test'@'localhost'或是'test'@'127.0.0.1'表示test用户只能在MySQL服务器本地访问


#子网掩码配置法
    grant all on *.* to 'test'@'192.168.200.0/255.255.255.0' identified by 'test123';


#所有权限
all privileges(简写all)除grant,revoke外的所有权限。
select 查询
insert 插入
update 更改
drop 删除
delete 删除
usage 无访问权限
alter 管理命令:修改,例如alter table
alter routine 修改存储过程,alter procedure和drop procedure
create temporary tables创建临时表。
create user 创建用户
create view 创建视图
execute 一般用户执行存储过程,使用call也可以
file 使用select .. into outfile 和load data infile
grant option 授权权限,grant和revoke
index 索引权限,create index,drop index,alter table  XXX drop,alter table XXX add
lock tables 锁表权限
show databasesshow数据库权限
process show进程权限,例如:show processlist,show full processlist。
reload 使用flush,加载
shutdown 关闭命令,mysqladmin shutdown
super 具有change master to ,kill,logs,purge,master,set global,还容许mysqladmin调试登录
replication client可以使用SHOW MASTER STATUS和SHOW SLAVE STATUS命令,也就是说这个用于授予账户监视Replication状况的权限
replication slave复制必须的权限。




===================================      二、表操作  =================================================
 
1、创建表
 
# 基本语法:
CREATE TABLE `sys_dict` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
 `type` smallint(6) unsigned DEFAULT NULL COMMENT '类型',
 `type_label` varchar(32) DEFAULT NULL COMMENT '类型名称',
 `key` int(10) unsigned DEFAULT NULL COMMENT '键',
 `value` varchar(32) DEFAULT NULL COMMENT '值',
 `remark` varchar(128) DEFAULT NULL COMMENT '备注',
 PRIMARY KEY (`id`),
 KEY `index_sys_dict_type` (`type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=64 DEFAULT CHARSET=utf8 COMMENT='数据字典';


#常用约束 
not null                # 不可以为空
default 1               # 默认值为1
auto_increment   # 自增
primary key         # 主键
constraint fk_test foreign key fk_column references emp(id)    # 外键
 
注意:1、对于自增列,必须是索引(含主键)。
      2、对于自增可以设置步长和起始值。


主键,一种特殊的唯一索引,不允许有空值,如果主键使用单个列,则它的值必须唯一,如果是多列,则其组合必须唯一。
外键,一个特殊的索引,只能是指定内容。


#修改引擎:
alter TABLE t_reinforce_vote ENGINE=innodb;

#添加备注:
alter TABLE t_reinforce_vote COMMENT='投票选项表';

#修改字符集:
alter TABLE t_reinforce_vote DEFAULT CHARSET=utf8;


2、删除表
drop table 表名
 
3、清空表
 
# 表还存在,表内容清空
delete from 表名
truncate table 表名
 
4、修改表
 
# 添加列:
    ALTER TABLE `t_information`
ADD COLUMN `star_ids` varchar(255) NULL DEFAULT NULL COMMENT '明星ID集合' AFTER `continent`,
ADD COLUMN `star_names` varchar(255) NULL DEFAULT NULL COMMENT '明星名字集合' AFTER `star_ids`;

ALTER TABLE `t_information`
ADD COLUMN `qq` varchar(255) NULL DEFAULT NULL first;
  
# 删除列:
        ALTER TABLE `t_information` drop column star_ids;

# 修改列:
修改列类型,列名不变
        alter table t_information modify column star_ids varchar(255) NULL DEFAULT NULL COMMENT '明星ID集合';

利用这个特点,可以用来重新调整列的顺序。
alter table t_information modify column star_ids varchar(255) NULL DEFAULT NULL AFTER continent;


#修改列名:
alter table t_ad_stat_minute change column `palyend` `playend` bigint(11) DEFAULT '0' COMMENT '播放结束';

# 添加主键:
        alter table t_information add primary key(star_ids);

# 删除主键:
        alter table t_information drop primary key;
        alter table t_information modify star_ids int, drop primary key;
 
# 添加外键:
        alter table 从表 add constraint 外键名称(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);
alter table t_information_sns add constraint FK_sns_t_information foreign key t_information_sns(id) references t_information(id);

# 删除外键:
        alter table 表名 drop foreign key 外键名称;
alter table t_information_sns drop foreign key FK_sns_t_information;
 
# 修改默认值:
      ALTER TABLE 表名 ALTER 字段 SET DEFAULT 1000;
 alter table t_reinforce_vote alter id set default '1';
 
# 删除默认值:
      ALTER TABLE 表名 ALTER 字段 DROP DEFAULT;
 alter table t_reinforce_vote alter id drop default;
 
# 更改表名(修改表名)


rename table `t_reinforce_vote` to `t_reinforce`;
 
#更改库名,修改库名
rename table old.t_reinforce to new.t_reinforce;
修改所有表名。
 
 
 
========================================      三、表内容操作    =========================================================
 
1、增
 
# 插入单条数据
        insert into 表 (列名,列名...) values (值,值,值...)

# 插入多条数据
       insert into 表 (列名,列名...) values (值,值,值...),(值,值,值...)
  
# 插入另一条语句的查询结果
        insert into 表 (列名,列名...) select 列名,列名... from 表
insert into t_reinforce select id,name from t_reinforce_vote where id=2;
 
2、删


delete from 表;
delete from 表 where id=1;
 
多表关联删除
1    delete from t1 where 条件
2    delete t1 from t1 where 条件
3    delete t1 from t1,t2 where 条件
4    delete t1,t2 from t1,t2 where 条件


简单用delete语句无法进行多表删除数据操作,不过可以建立级联删除,在两个表之间建立级联删除关系,
则可以实现删除一个表的数据时,同时删除另一个表中相关的数据。


1、从数据表t1中把那些id值在数据表t2里有匹配的记录全删除掉
DELETE t1 FROM t1,t2 WHERE t1.id=t2.id 或 DELETE FROM t1 USING t1,t2 WHERE t1.id=t2.id

2、从数据表t1里在数据表t2里没有匹配的记录查找出来并删除掉   
DELETE t1 FROM t1 LEFT JOIN T2 ON t1.id=t2.id WHERE t2.id IS NULL 
或 DELETE FROM t1,USING t1 LEFT JOIN T2 ON t1.id=t2.id WHERE t2.id IS NULL


3、 从两个表中找出相同记录的数据并把两个表中的数据都删除掉
DELETE MV,Track FROM MV LEFT JOIN Track ON MV.mvid=Track.trkid WHERE MV.mvid=1
DELETE t1,t2 from MV as t1 LEFT JOIN Track as t2 ON t1.id=t2.id WHERE t1.id=25
如果使用了别名的方式,那么上下一致都用别名。


 3、改
 
update t_reinforce set name='nick' where id>1;
update t_reinforce set name='nick',vote=40 where id>10;


#表关联更新
UPDATE Track INNER JOIN MV
ON Track.trkid=MV.mvid
SET Track.is_show=MV.is_show
WHERE trkid<6


等同于


UPDATE Track,MV
SET Track.is_show=MV.is_show
WHERE Track.trkid=MV.mvid and trkid<6


根据结果集进行update更新操作


原表信息
表1:am_favorites_4


af_user_id af_tag_idaf_content_id af_content_type
374 0535522 3
374 0535522 3
374 89535522 3


表2:am_tag_user_4


atu_user_id atu_tag_idatu_num
374 09
374 899


根据am_favorites_4更新am_tag_user_4表

更新结果:am_tag_user_4


atu_user_id atu_tag_idatu_num
374 07
374 898




UPDATE am_tag_user_4 tag
INNER JOIN am_favorites_4 fav
ON tag.atu_tag_id=fav.af_tag_id and tag.atu_user_id=fav.af_user_id
INNER JOIN (SELECT  af_user_id,af_tag_id,count(*) as cnt
FROM am_favorites_4,am_tag_user_4
where atu_tag_id=af_tag_id and atu_user_id=af_user_id and af_content_id = 535522 and af_content_type=3 and af_user_id=374
group by af_user_id,af_tag_id) AS T1
ON tag.atu_tag_id=T1.af_tag_id and tag.atu_user_id=T1.af_user_id
SET tag.atu_num=tag.atu_num- T1.cnt




4、查


select * from 表
select * from 表 where id > 1
select nid,name,gender as gg from 表 where id > 1


多表关联:


内连接:
select * from T1, T3 where T1.userid = T3.userid
(其实这样的结果等同于select * from T1 inner join T3 on T1.userid=T3.userid )。


左连接:
select * from T1 left outer join T2 on T1.userid = T2.userid


右连接:
select * from T1 right outer join T2 on T1.userid = T2.userid


全连接:
select * from T1 full outer join T2 on T1.userid = T2.userid


 
6、通配符


"_" 匹配单个字符,"\_" 匹配"_"
"%" 匹配任意个字符,包括零个字符。
sql模式下的匹配,缺省是忽略大小写的,并且sql模式下的模糊匹配不能使用“=”或”!=”,而使用 like 或 not like.
SELECT * FROM user WHERE u_name LIKE '%t_';
SELECT * FROM user WHERE u_name LIKE '_n%';


正则模式匹配:
当使用正则匹配时,使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它们是同义词)。


正则表达式:
"." 匹配任何单个的字符。
"[...]" 匹配在方括号内的任何字符。
"[abc]" 则匹配”a”、”b”或者”c”,
"[a-z]"匹配任何小写字母,
"[0-9]"匹配任何数字。
"*" 匹配零个或多个在它前面的东西。
“x*”匹配任何数量的“x”字符,
"[0-9]*"匹配的任何数量的数字,
".*"匹配任何数量的任何东西。

正则表达式是区分大小写的,但是如果你希望,你能使用一个字符类匹配大写和小写。
"[aA]"匹配小写或大写的“a”,
"[a-zA-Z]"匹配两种写法的任何字母。
如果它出现在被测试值的任何地方,模式就匹配(只要他们匹配整个值,SQL模式匹配)。
为了定位一个模式以便它必须匹配被测试值的开始或结尾,在模式开始处使用“^”或在模式的结尾用“$”。


SELECT * FROM user WHERE u_name LIKE '^n%';
SELECT * FROM user WHERE u_name LIKE '_n^';


也可以使用“{n}”“重复n次”操作符重写先前的查询:
SELECT * FROM user WHERE u_name REGEXP 'b{2}$';


如果我就真的要查%或者_,怎么办呢?使用escape,转义字符后面的%或_就不作为通配符了,注意前面没有转义字符的%和_仍然起通配符作用


select username from gg_user where username like '%xiao/_%' escape '/';   
select username from gg_user where username like '%xiao/%%' escape '/';


 
7、限制
 
语法:select * from 表 limit 9,5;


 
8、排序
 
语法:select * from 表 order by 列1 desc,列2 asc
 


 
9、分组
 
语法:select num from 表 group by num
 
select ring_id from t_fan_posts_star 
where is_top=0 
and is_recommend=0 
and is_cream=0 
GROUP BY ring_id
HAVING count(ring_id)>500 ORDER BY ring_id;

注:group by 必须在where之后,order by之前。
 


11、组合
 
语法:union、union all




 
 =============================================     四、其它命令  =================================    
 
1、查看建表语句
show create table user;


 
2、查看表结构
 
desc user;
 
3、查看是否走索引
 
explain select * from 表名 where name ='nick' \G 


用此命令查看是否sql语句是否还有优化的余地


 
 
================================================  五、数据类型  ==========================================    


 1、数字类型:
 
整数类型        字节       范围(有符号)      范围(无符号)          用途 
TINYINT        1字节        (-128,127)          (0,255)            小整数值 
SMALLINT       2字节     (-32768,32767)        (0,65535)         大整数值 
MEDIUMINT      3字节   (-8388608,8388607) (0,16777215)      大整数值 
INT或INTEGER   4字节   (-2147483648,2147483647) (0,4294967295)   大整数值 
BIGINT         8字节   (-9233372036854775808,9223372036854775807) (0,18446744073709551615) 极大整数值 
FLOAT          4字节   (-3.402823466E+38,1.175494351E-38),0,(1.175494351E-38,3.402823466351E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度浮点数值 
DOUBLE         8字节 (1.7976931348623157E+308,2.2250738585072014E-308),0,(2.2250738585072014E-308,1.7976931348623157E+308) 0,(2.225073858507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度浮点数值 
DECIMAL 对DECIMAL(M,D)其中M表示十进制数字总的个数,D表示小数点后面数字的位数。如果M>D,为M+2否则为D+2
M的默认取值为10,D默认取值为0。如果创建表时,某字段定义为decimal类型不带任何参数,等同于decimal(10,0)。带一个参数时,D取默认值。
M的取值范围为1~65,取0时会被设为默认值,超出范围会报错。
D的取值范围为0~30,而且必须<=M,超出范围会报错。
所以,很显然,当M=65,D=0时,可以取得最大和最小值。


指定一个字段的类型为 INT(6),
就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。
需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。


salary DECIMAL(5,2) 5表示的是位数总和,2是小数位数,也就是整数部分是3位数。
如果存储时,整数部分超出了范围(如上面的例子中,添加数值为1000.01),MySql就会报错,不允许存这样的值。
如果存储时,小数点部分若超出范围,就分以下情况:
    若四舍五入后,整数部分没有超出范围,则只警告,但能成功操作并四舍五入删除多余的小数位后保存。如999.994实际被保存为999.99。
    若四舍五入后,整数部分超出范围,则MySql报错,并拒绝处理。如999.995和-999.995都会报错。


float(M,D): “(M,D)”表示该值一共显示M位整数,其中D位位于小数点后面。例如,定义为FLOAT(7,4)的一个列可以显示为-999.9999。
MySQL保存值时进行四舍五入,因此如果在FLOAT(7,4)列内插入999.00009,近似结果是999.0001。
FLOAT和DOUBLE中的M和D的取值默认都为0,即除了最大最小值,不限制位数。


M取值范围为0~255。FLOAT只保证6位有效数字的准确性,所以FLOAT(M,D)中,M<=6时,数字通常是准确的。
如果M和D都有明确定义,其超出范围后的处理同decimal。


D取值范围为0~30,同时必须<=M。double只保证16位有效数字的准确性,所以DOUBLE(M,D)中,M<=16时,数字通常是准确的。
如果M和D都有明确定义,其超出范围后的处理同decimal。


2、BIT位运算

    BIT数据类型可用来保存位字段值。BIT(M)类型允许存储M位值。M范围为1~64,默认为1。
    BIT其实就是存入二进制的值,类似010110。
    如果存入一个BIT类型的值,位数少于M值,则左补0.
    如果存入一个BIT类型的值,位数多于M值,MySQL的操作取决于此时有效的SQL模式:
    如果模式未设置,MySQL将值裁剪到范围的相应端点,并保存裁减好的值。
    如果模式设置为traditional(“严格模式”),超出范围的值将被拒绝并提示错误,并且根据SQL标准插入会失败。
    下面是官方示例:
mysql> CREATE TABLE t (b BIT(8));
mysql> INSERT INTO t SET b = b'11111111';
mysql> INSERT INTO t SET b = b'1010';
mysql> INSERT INTO t SET b = b'0101';
mysql> SELECT b+0, BIN(b+0), OCT(b+0), HEX(b+0) FROM t;
+------+----------+----------+----------+
| b+0  | BIN(b+0) | OCT(b+0) | HEX(b+0) |
+------+----------+----------+----------+
|  255 | 11111111 | 377      | FF       |
|   10 | 1010     | 12       | A        |
|    5 | 101      | 5        | 5        |
+------+----------+----------+----------+


3.字符串


MySQL 提供了8个基本的字符串类型,分别:CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和SET等多种字符串类型。


  字符串类型     字节大小         描述及存储需求
    CHAR         0-255字节          定长字符串 
    VARCHAR      0-255字节          变长字符串 
    TINYBLOB     0-255字节        不超过 255 个字符的二进制字符串 
    TINYTEXT     0-255字节        短文本字符串 
    BLOB         0-65535字节      二进制形式的长文本数据 
    TEXT         0-65535字节      长文本数据 
    MEDIUMBLOB   0-16777215字节 二进制形式的中等长度文本数据 
    MEDIUMTEXT   0-16777215字节 中等长度文本数据 
    LOGNGBLOB    0-4294967295字节 二进制形式的极大文本数据 
    LONGTEXT     0-4294967295字节 极大文本数据
    VARBINARY(M)                   允许长度0-M个字节的定长字节符串,值的长度+1个字节
    BINARY(M)                      允许长度0-M个字节的定长字节符串


CHAR 和 VARCHAR 类型


CHAR 类型用于定长字符串,这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。
CHAR 类型可以使用 BINARY 修饰符。当用于比较运算时,这个修饰符使 CHAR 以二进制方式参于运算,而不是以传统的区分大小写的方式。
VARCHAR是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MYSQL 数据库处理
这个指示器的方式:CHAR 把这个大小视为值的大小,长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度
(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。
VARCHAR 类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。
VARCHAR 类型在使用 BINARY 修饰符时与 CHAR 类型完全相同。


TEXT 和 BLOB 类型
  对于字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小,它们都有不同的子类型。
这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。
TEXT 和 BLOB 类型在分类和比较上存在区别。BLOB 类型区分大小写,而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。
比指定类型支持的最大范围大的值将被自动截短。




4、日期和时间类型

 在处理日期和时间类型的值时,MySQL 带有 5 个不同的数据类型可供选择。它们可以被分成简单的日期、时间类型,和混合日期、时间类型。
根据要求的精度,子类型在每个分类型中都可以使用,并且 MySQL 带有内置功能可以把多样化的输入格式变为一个标准格式。


 类型     大小(字节)     范围               格式          用途 
 DATE       4        1000-01-01/9999-12-31 YYYY-MM-DD    日期值 
 TIME       3        '-838:59:59'/'838:59:59' HH:MM:SS    时间值或持续时间 
 YEAR       1         1901/2155               YYYY       年份值 
 DATETIME   8       1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值 
 TIMESTAMP  4       1970-01-01 00:00:00/2037 年某时 YYYYMMDD HHMMSS 混合日期和时间值,时间戳


 DATE、TIME 和 YEAR 类型
  MySQL 用 DATE 和 YEAR 类型存储简单的日期值,使用 TIME 类型存储时间值。这些类型可以描述为字符串或不带分隔符的整数序列。
如果描述为字符串,DATE 类型的值应该使用连字号作为分隔符分开,而 TIME 类型的值应该使用冒号作为分隔符分开。
  需要注意的是,没有冒号分隔符的 TIME 类型值,将会被 MySQL 理解为持续的时间,而不是时间戳。


MySQL 还对日期的年份中的两个数字的值,或是 SQL 语句中为 YEAR 类型输入的两个数字进行最大限度的通译。
因为所有 YEAR 类型的值必须用 4 个数字存储。MySQL 试图将 2 个数字的年份转换为 4 个数字的值。
把在 00-69 范围内的值转换到 2000-2069 范围内。把 70-99 范围内的值转换到 1970-1979 之内。
如果 MySQL 自动转换后的值并不符合我们的需要,请输入 4 个数字表示的年份。


DATEYIME 和 TIMESTAMP 类型


  除了日期和时间数据类型,MySQL 还支持 DATEYIME 和 TIMESTAMP 这两种混合类型。它们可以把日期和时间作为单个的值进行存储。
这两种类型通常用于自动存储包含当前日期和时间的时间戳,并可在需要执行大量数据库事务和需要建立一个调试和审查用途的
审计跟踪的应用程序中发挥良好作用。如果我们对 TIMESTAMP 类型的字段没有明确赋值,或是被赋与了 null 值。
MySQL 会自动使用系统当前的日期和时间来填充它。


 复合类型
  MySQL 还支持两种复合数据类型 ENUM 和 SET,它们扩展了 SQL 规范。虽然这些类型在技术上是字符串类型,但是可以被视为不同的数据类型。
一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。


ENUM 类型字段可以从集合中取得一个值或使用 null 值,除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。
另外如果插入值的大小写与集合中值的大小写不匹配,MySQL 会自动使用插入值的大小写转换成与集合中大小写一致的值。
   ENUM 类型在系统内部可以存储为数字,并且从 1 开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素,
   其中一个元素被 MySQL 保留,用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。
MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。
这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。


SET 类型
 SET 类型与 ENUM 类型相似但不相同。SET 类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是
任何试图在 SET 类型字段中插入非预定义的值都会使MySQL 插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录,
MySQL 将会保留合法的元素,除去非法的元素。


 一个 SET 类型最多可以包含 64 项元素。在 SET 元素中值被存储为一个分离的“位”序列,这些“位”表示与它相对应的元素。
“位”是创建有序元素集合的一种简单而有效的方式。并且它还去除了重复的元素,所以 SET 类型中不可能包含两个相同的元素。
希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。

原创粉丝点击