mysql 层_MySQL:MySQL层比较函数调用

博客探讨了在MySQL中使用from_unixtime()函数进行日期比较时出现的一个意外情况,即字符串和日期类型的比较。通过创建表并查看源码,证实了MySQL在比较时会进行类型转换,导致预期结果与实际不符。这个问题提醒我们在数据库操作中需要注意数据类型的正确使用和转换。

---

###一、问题来源

最近遇到一个日期比较的问题如下:

```

root@localhost:test:10:25:48>select from_unixtime(1596680255);

+---------------------------+

| from_unixtime(1596680255) |

+---------------------------+

| 2020-08-06 10:17:35 |

+---------------------------+

1 row in set (0.00 sec)

root@localhost:test:10:25:52>select from_unixtime(1596680255,'%Y-%m-%d') < '2020-08-1';

+----------------------------------------------------+

| from_unixtime(1596680255,'%Y-%m-%d') < '2020-08-1' |

+----------------------------------------------------+

| 1 |

+----------------------------------------------------+

1 row in set (2.70 sec)

root@localhost:test:10:25:59>select from_unixtime(1596680255) < '2020-08-1';

+-----------------------------------------+

| from_unixtime(1596680255) < '2020-08-1' |

+-----------------------------------------+

| 0 |

+-----------------------------------------+

1 row in set (2.36 sec)

```

按理来说from_unixtime(1596680255,'%Y-%m-%d') < '2020-08-1' 应该是false才对,但是返回为true,因此怀疑为字符串比较的方式

###二、问题验证

首先关闭gtid通过create table as 来验证一下字段类型如下:

```

create table testit951

as

select from_unixtime(1596678161,'%Y-%m-%d') as "tt"

create table testit952

as

select from_unixtime(1596678161) as "tt"

```

通过这种方式发现两种建表字段为varchar和datetime类型。通过源码验证可以看到如下:

```

Breakpoint 5, Arg_comparator::compare_string (this=0x7fffe40167c0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/item_cmpfunc.cc:1672

1672 if ((res1= (*a)->val_str(&value1)))

(gdb) c

Continuing.

Breakpoint 4, Arg_comparator::compare_datetime (this=0x7fffe40164c8) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/item_cmpfunc.cc:1509

1509 THD *thd= current_thd;

(gdb) c

Continuing.

```

可以看到内部通过了string和datetime两种类型来比较。因此得到证明。最后留下比较函数的位置:

Item_cmpfunc.cc

![image.png](https://upload-images.jianshu.io/upload_images/7398834-9a3fa87743742dad.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-2714077/,如需转载,请注明出处,否则将追究法律责任。

这段内容是一个 Python 类的内部属性字典(`__dict__`)的输出,它展示了类 `MysqlConnect` 的所有**类级别的属性和方法**。我们可以逐项解析它的含义: --- ### 输出内容解释: ```python { '__module__': '__main__', 'password': '123456', 'port': 3306, '__init__': <function MysqlConnect.__init__ at 0x105044ea0>, 'select': <function MysqlConnect.select at 0x10567bf60>, '__dict__': <attribute '__dict__' of 'MysqlConnect' objects>, '__weakref__': <attribute '__weakref__' of 'MysqlConnect' objects>, '__doc__': None } ``` #### 详细说明: 1. **`'__module__': '__main__'`** - 表示这个类定义在哪个模块中。 - `__main__` 表示该类是在当前运行的脚本中定义的,而不是从其他模块导入的。 2. **`'password': '123456'` 和 `'port': 3306`** - 这两个是**类属性**,属于类 `MysqlConnect`,不是某个实例的私有属性。 - 所有实例都可以访问它们,也可以通过类名直接调用:`MysqlConnect.password`。 3. **`'__init__': <function ...>`** - 构造函数,用于初始化一个新创建的实例。 - 当你使用 `MysqlConnect()` 创建对象时,Python 会自动调用这个方法。 4. **`'select': <function ...>`** - 自定义的方法,可以在实例上调用,例如:`conn.select()`。 - 它是一个**实例方法**,第一个参数必须是 `self`,指向调用它的实例。 5. **`'__dict__': <attribute ...>`** - 是类实例的一个属性,它保存了实例的所有**实例属性**。 - 你可以通过 `instance.__dict__` 查看实例变量的键值对。 6. **`'__weakref__': <attribute ...>`** - 支持弱引用机制,允许不增加引用计数地引用对象。 - 主要用于优化内存管理,避免循环引用导致内存泄漏。 7. **`'__doc__': None`** - 表示这个类没有文档字符串(docstring)。 - 如果你在类开头添加注释,如: ```python class MysqlConnect(): """这是一个MySQL连接类""" ``` 那么 `__doc__` 就会变成 `"这是一个MySQL连接类"`。 --- ### 示例代码演示 ```python class MysqlConnect: password = '123456' port = 3306 def __init__(self): self.ip = '127.0.0.1' self.user_account = 'root' def select(self): print('查询语句') # 查看类的属性字典 print(MysqlConnect.__dict__) ``` #### 输出说明: - 显示的是整个类结构的元信息,包括类属性、方法等; - 不包含实例属性(比如 `ip` 和 `user_account`),因为这些只存在于具体的实例中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值