如何解决mysql enum 类型字段的插入问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决mysql enum 类型字段的插入问题相关的知识,希望对你有一定的参考价值。

根据用户定义的枚举值与分片节点映射文件,直接定位目标分片。

    用户在rule.xml中配置枚举值文件路径和分片索引是字符串还是数字,DBLE在启动时会将枚举值文件加载到内存中,形成一个映射表

    在DBLE的运行过程中,用户访问使用这个算法的表时,WHERE子句中的分片索引值会被提取出来,直接查映射表得到分片编号

    与MyCat的类似分片算法对比

    中间件

    DBLE

    MyCat

    分片算法种类    enum 分区算法    分片枚举    

    两种中间件的枚举分片算法使用上无差别。

    开发注意点

    【分片索引】1. 整型数字(可以为负数)或字符串((不含=和换行符)

    【分片索引】2. 枚举值之间不能重复

    Male=0Male=1

    或者

    123=1123=2

    会导致分片策略加载出错

    【分片索引】3. 不同枚举值可以映射到同一个分片上

    Mr=0Mrs=1Miss=1Ms=1123=0

    运维注意点

    【扩容】1. 增加枚举值无需数据再平衡

    【扩容】2. 增加一个枚举值的分片数量数时,需要对局部数据进行迁移

    【缩容】1. 减少枚举值需要数据再平衡

    【缩容】2. 减少一个枚举值的分片数量数时,需要对局部数据进行迁移

    配置注意点

    【配置项】1. 在 rule.xml 中,可配置项为 <property name="defaultNode"> 、<property name="mapFile"> 和 <property name="type"> 

    【配置项】2. 在 rule.xml 中配置 <property name="defaultNode"> 标签,非必须配置项,不配置该项的话,用户的分片索引值没落在 mapFile 定义的范围时,DBLE 会报错;若需要配置,必须为非负整数,用户的分片索引值没落在 mapFile 定义的范围时,DBLE 会路由至这个值的 mysql 分片

    【配置项】3. 在 rule.xml 中配置 <property name="mapFile"> 标签,范围映射文件的路径:若在映射文件在 DBLE_HOME/conf 或其中,则可以使用相对路径的形式配置,例如,映射文件是 DBLE_HOME/conf/map/table_map.txt 时,配置值就可以简写为 map/table_map.txt;映射文件在 DBLE_HOME/conf 目录以外时,需要使用绝对路径,但这种做法需要考虑用户权限等问题,因此不建议把映射文件放在 DBLE_HOME/conf 外。

    【配置项】4. 编辑 mapFile 所配置的文件

    记录格式为:<枚举值>=<分片编号>

    枚举值可以是整型数字,或任意字符(除了=和换行符),分片编号必须是非负整型数字,记录之间以换行分隔,一行仅能有一条记录,枚举值不能够是“DEFAULT_NODE”这个字符串,允许以“//”和“#”在行首来注释该行

    【配置项】5. 在 rule.xml 中配置 <property name="type"> 标签;type 必须为整型;取值为 0 时,mapFile 的<枚举值>必须为整型;取值为非 0 时,mapFile 的<枚举值>可以是任意字符(除了=和换行符)

参考技术A mysql装好后,有一个mysql数据库配置向导的,打开一个一个的点下一步,到编码选择里,选“日本语”那个选项,就是让mysql默认用utf-8编码。试试。

MySQL中的set和enum

MYSQL中 ENUM 类型的详细解释

  ENUM类型
    ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举。

    在下列某些情况下,值也可以是空串("") 或 NULL:

    如果将一个无效值插入一个 ENUM (即,一个不在允许值列表中的字符串),空字符串将作为一个特殊的错误值被插入。事实上,这个字符串有别于一个"普通的"空字符串,因为这个字符串有个数字索引值为 0。稍后有更详细描述。
如果一个 ENUM 被声明为 NULL,NULL 也是该列的一个合法值,并且该列的缺省值也将为 NULL 。如果一个 ENUM 被声明为 NOT NULL,该列的缺省值将是该列表所允许值的第一个成员。
  每个枚举值均有一个索引值:

  在列说明中列表值所允许的成员值被从 1 开始编号。
  空字符串错误值的索引值为 0。这就意味着,你可以使用下面所示的 SELECT 语句找出被赋于无效 ENUM值的记录行。
    mysql> SELECT * FROM tbl_name WHERE enum_col=0;
    NULL 值的索引值为 NULL。

换个枚举最大可以有 65535 个成员值。

从 MySQL 3.23.51 开始,当表被创建时,ENUM 值尾部的空格将会自动删除。

  当为一个 ENUM 列赋值时,字母的大小写是无关紧要的。然而,以后从列中检索出来的值的大小写却是匹配于创建表时所指定的允许值。

  如果在一个数字语境中检索一个ENUM,列值的索引值将被返回。例如,你可以像这样使用数字值检索一个 ENUM 列:

  mysql> SELECT enum_col+0 FROM tbl_name;
  如果将一个数字存储到一个 ENUM 中,数字被当作为一个索引值,并且存储的值是该索引值所对应的枚举成员。(但是,这在 LOAD DATA 将不能工作,因为它视所有的输入均为字符串。) 在一个   ENUM 字符串中存储数字是不明智的,因为它可能会打乱思维。

  ENUM 值依照列规格说明中的列表顺序进行排序。(换句话说,ENUM 值依照它们的索引号排序。)举例来说,对于 ENUM("a", "b") "a" 排在 "b" 后,但是对于 ENUM("b", "a") , "b" 却排在 "a" 之前。空字符串排在非空字符串前,NULL 值排在其它所有的枚举值前。为了防止意想不到的结果,建议依照字母的顺序定义 ENUM 列表。也可以通过使用 GROUP BY CONCAT(col) 来确定该以字母顺序排序而不是以索引值。

  如果希望得到一个 ENUM 列的所有可能值,可以使用 SHOW COLUMNS FROM table_name LIKE enum_colum

 

set,enum的数据类型都是字符串类型的对象,其中set最多可以包含64个元素,并且可以任意取到集合中的元素。而enum则是只能取到集合中的木一个元素,最多包含65536个元素,也就是说set是多项选择,enum是单项选择了。

 1 MariaDB [stu149]> create table db_set(
 2     -> set1 set(x,y,z) not null,
 3     -> enum1 enum(one,two,three) not null);
 4 Query OK, 0 rows affected (0.25 sec)
 5 
 6 MariaDB [stu149]> desc db_set;
 7 +-------+---------------------------+------+-----+---------+-------+
 8 | Field | Type                      | Null | Key | Default | Extra |
 9 +-------+---------------------------+------+-----+---------+-------+
10 | set1  | set(x,y,z)          | NO   |     | NULL    |       |
11 | enum1 | enum(one,two,three) | NO   |     | NULL    |       |
12 +-------+---------------------------+------+-----+---------+-------+
13 2 rows in set (0.01 sec)
14 
15 MariaDB [stu149]> insert into db_set values(1,3),(1,4),(4,1);
16 Query OK, 3 rows affected, 1 warning (0.09 sec)
17 Records: 3  Duplicates: 0  Warnings: 1
18 
19 MariaDB [stu149]> select * from db_set;
20 +------+-------+
21 | set1 | enum1 |
22 +------+-------+
23 | x    | three |
24 | x    |       |
25 | z    | one   |
26 +------+-------+
27 3 rows in set (0.00 sec)
28 
29 MariaDB [stu149]> insert into db_set values(2,0);
30 Query OK, 1 row affected, 1 warning (0.08 sec)
31 
32 MariaDB [stu149]> insert into db_set values(3,2);
33 Query OK, 1 row affected (0.05 sec)
34 
35 MariaDB [stu149]> select * from db_set;
36 +------+-------+
37 | set1 | enum1 |
38 +------+-------+
39 | x    | three |
40 | x    |       |
41 | z    | one   |
42 | y    |       |
43 | x,y  | two   |
44 +------+-------+
45 5 rows in set (0.00 sec)
46 
47 MariaDB [stu149]> insert into db_set values(2,6);
48 Query OK, 1 row affected, 1 warning (0.14 sec)
49 
50 MariaDB [stu149]> select * from db_set;
51 +------+-------+
52 | set1 | enum1 |
53 +------+-------+
54 | x    | three |
55 | x    |       |
56 | z    | one   |
57 | y    |       |
58 | x,y  | two   |
59 | y    |       |
60 +------+-------+
61 6 rows in set (0.00 sec)

 

 

set类型中对于超出它能表示的范围的,就用二进制来加去:

set元素  十进制    二进制

‘x‘     1      0001

‘y‘     2      0010

‘z‘     4      0100

enum类型超出自己能表示的范围,就附空值了:

enym元素   索引  

null      null 

""        0

"one"      1

"two"      2

"three"      3

 

以上是关于如何解决mysql enum 类型字段的插入问题的主要内容,如果未能解决你的问题,请参考以下文章

mysql表的enum类型字段

MySQL中的enum类型有啥优点

sql enum类型

如何在mysqlworkbench的表的某一字段类型是enum

关于MySQL的检查约束不生效的问题

MySQL中 enum 插入的时候注意事项