Rust中的ORM探索 Diesel库(3):源码解析-MySQL数据类型与Rust数据类型对应关系
介绍
在上文中,我们学习Diesel简单的CRUD操作。例子中创建的数据表中的数据类型也比较简单,接下来我们看一下MySQL中的数据类型和Rust数据类型的对应关系。
创建数据库
在上文中,我们执行migration时,Diesel CLI会根据数据库的表结构,生成diesel::table!宏来表示数据表的各个字段类型,并存放到schema.rs文件中。
另外我们也可以通过命令 diesel print-schema 打印表的schema

为了验证一下,MySQL数据格式和Rust数据格式,我们尝试创建一个migration all_types
在up.sql中,编写创建数据表的代码
- i1~i6是整数类型,f1~f3是浮点类型,t1~t6是文本类型,d1~d4是日期时间类型,o1~o2是ENUM和SET,b1~b2是二进制类型。
执行migration命令
生成的schema.rs文件中,会有报错。

排查原因:MySQL中有Mediumint类型,但Diesel的sqltype中,没有定义Mediumint类型。我们考虑使用其他类型代替。
阅读源码
为了更好的确定数据类型的对应关系,下面我们阅读一下源码。
Bool
MySQL中,创建布尔类型时,数据类型使用 BOOLEAN ,对应到 schema.rs文件中是strcut Bool,models.rs文件中类型为 bool。
- 注意,虽然使用的BOOLEAN类型,但是MySQL的表结构中,该字段的类型是Tinyint(1)
TINYINT
数据类型TINYINT,对应到 schema.rs文件中是Tinyint,models.rs文件中类型为 i8
SMALLINT
数据类型SMALLINT,对应到 schema.rs文件中是Smallint,models.rs文件中类型为 i16
INTEGER(INT)
数据类型INT,对应到 schema.rs文件中是Integer,models.rs文件中类型为 i32
BIGINT
数据类型BIGINT,对应到 schema.rs文件中是Bigint,models.rs文件中类型为 i64
FLOAT
数据类型FLOAT,对应到 schema.rs文件中是Float,models.rs文件中类型为 f32
DOUBLE
数据类型DOUBLE,对应到 schema.rs文件中是Double,models.rs文件中类型为 f64
DECIMAL
数据类型DECIMAL,对应到 schema.rs文件中是Decimal,models.rs文件中类型是bigdecimal::BigDecimal。这里需要将diesel的 numeric feature启用,并且在项目中添加bigdecimal库。
TEXT
数据类型TEXT、VARCHAR、CHAR、TINYTEXT、MEDIUMTEXT、LONGTEXT,对应到 schema.rs文件中都可以使用Text,也可以使用同名的结构体,models.rs文件中类型是String。
BINARY
数据类型BINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、VARBINARY、BIT,对应到 schema.rs文件中都可以使用Binary,也可以使用同名的结构体,models.rs文件中类型是Vec<u8>。
- 在rust中,表示二进制数据,统一都使用Vec<u8>
DATE
数据类型DATE,对应到 schema.rs文件中是Date,models.rs文件中类型有多种选择,如可以使用time::Date。这里需要将diesel的 time feature启用,并且在项目中添加time库。
TIME
数据类型TIME,对应到 schema.rs文件中是Time,models.rs文件中类型有多种选择,如可以使用time::Time。这里需要将diesel的 time feature启用,并且在项目中添加time库。
TIMESTAMP
数据类型TIMESTAMP,对应到 schema.rs文件中是Timestamp,models.rs文件中类型有多种选择,如可以使用time::OffsetDateTime。这里需要将diesel的 time feature启用,并且在项目中添加time库。
DATETIME
数据类型DATETIME,对应到 schema.rs文件中是Datetime,models.rs文件中类型有多种选择,如可以使用time::OffsetDateTime。这里需要将diesel的 time feature启用,并且在项目中添加time库。
Nullable特征
Nullable对应MySQL中的可为空属性, 如可为空的INT类型,在schema.rs文件中使用Nullable<Integer>表示,在models.rs中使用Option<i32>表示
Unsigned特征
Unsigned对应MySQL中的无符号特征, 如无符号的INT类型,在schema.rs文件中使用Unsigned<Integer>表示,在models.rs中使用u32表示。
- 注意,并不是所有的数值类型,在diesel中都实现了Unsigned,通过源码查看。只有整数类型实现了Unsigned。因此使用时应避免浮点数使用Unsigned。
类型对应表
| MySQL类型 | schema.rs中 | models.rs中 | |
|---|---|---|---|
| 非空 | BOOLEAN | Bool | bool |
| 可为空 | BOOLEAN | Nullable<Bool> | Option<bool> |
| 有符合非空 | TINYINT | Tinyint | i8 |
| 有符合可为空 | TINYINT | Nullable<Tinyint> | Option<i8> |
| 无符号非空 | TINYINT | Unsigned<Tinyint> | u8 |
| 无符号可为空 | TINYINT | Nullable<Unsigned<Tinyint>> | Option<u8> |
| 有符合非空 | SMALLINT | Smallint | i16 |
| 有符合可为空 | SMALLINT | Nullable<Smallint> | Option<i16> |
| 无符号非空 | SMALLINT | Unsigned<Smallint> | u16 |
| 无符号可为空 | SMALLINT | Nullable<Unsigned<Smallint>> | Option<u16> |
| 有符合非空 | INTEGER | Integer | i32 |
| 有符合可为空 | INTEGER | Nullable<Integer> | Option<i32> |
| 无符号非空 | INTEGER | Unsigned<Integer> | u32 |
| 无符号可为空 | INTEGER | Nullable<Unsigned<Integer>> | Option<u32> |
| 有符合非空 | BIGINT | Bigint | i64 |
| 有符合可为空 | BIGINT | Nullable<Bigint> | Option<i64> |
| 无符号非空 | BIGINT | Unsigned<Bigint> | u64 |
| 无符号可为空 | BIGINT | Nullable<Unsigned<Bigint>> | Option<u64> |
| 非空 | FLOAT | Float | f32 |
| 可为空 | FLOAT | Nullable<Float> | Option<f32> |
| 非空 | DOUBLE | Double | f64 |
| 可为空 | DOUBLE | Nullable<Double> | Option<f64> |
| 非空 | DECIMAL | Decimal | bigdecimal::BigDecimal |
| 可为空 | DECIMAL | Nullable<Decimal> | Option<bigdecimal::BigDecimal> |
| 非空 | TEXT | Text | String |
| 可为空 | TEXT | Nullable<Text> | Option<String> |
| 非空 | VARCHAR | Varchar | String |
| 可为空 | VARCHAR | Nullable<Varchar> | Option<String> |
| 非空 | CHAR | Char | String |
| 可为空 | CHAR | Nullable<Char> | Option<String> |
| 非空 | TINYTEXT | Tinytext | String |
| 可为空 | TINYTEXT | Nullable<Tinytext> | Option<String> |
| 非空 | MEDIUMTEXT | Mediumtext | String |
| 可为空 | MEDIUMTEXT | Nullable<Mediumtext> | Option<String> |
| 非空 | LONGTEXT | Longtext | String |
| 可为空 | LONGTEXT | Nullable<Longtext> | Option<String> |
| 非空 | BINARY | Binary | Vec<u8> |
| 可为空 | BINARY | Nullable<Binary> | Option<Vec<u8>> |
| 非空 | TINYBLOB | Tinyblob | Vec<u8> |
| 可为空 | TINYBLOB | Nullable<Tinyblob> | Option<Vec<u8>> |
| 非空 | BLOB | Blob | Vec<u8> |
| 可为空 | BLOB | Nullable<Blob> | Option<Vec<u8>> |
| 非空 | MEDIUMBLOB | Mediumblob | Vec<u8> |
| 可为空 | MEDIUMBLOB | Nullable<Mediumblob> | Option<Vec<u8>> |
| 非空 | LONGBLOB | Longblob | Vec<u8> |
| 可为空 | LONGBLOB | Nullable<Longblob> | Option<Vec<u8>> |
| 非空 | VARBINARY | Varbinary | Vec<u8> |
| 可为空 | VARBINARY | Nullable<Varbinary> | Option<Vec<u8>> |
| 非空 | BIT | Bit | Vec<u8> |
| 可为空 | BIT | Nullable<Bit> | Option<Vec<u8>> |
| 非空 | DATE | Date | time::Date |
| 可为空 | DATE | Nullable<Date> | Option<time::Date> |
| 非空 | TIME | Time | time::Time |
| 可为空 | TIME | Nullable<Time> | Option<time::Time> |
| 非空 | TIMESTAMP | Timestamp | time::OffsetDateTime |
| 可为空 | TIMESTAMP | Nullable<Timestamp> | Option<time::OffsetDateTime> |
| 非空 | DATETIME | Datetime | time::OffsetDateTime |
| 可为空 | DATETIME | Nullable<Datetime> | Option<time::OffsetDateTime> |
总结
至此,已经将MySQL中的数据类型和rust中数据类型进行了对应。同时我们在使用时,应尽量避免使用diesel中不支持的类型和属性,如MySQL中的 MEDIUMINT类型、无符号的FLOAT类型。
本文来自博客园,作者:Spanner,转载请注明原文链接:https://www.cnblogs.com/spanner/p/18670276

浙公网安备 33010602011771号