公司软件出问题了,症状是数据库表有个字段,本来是存储的以逗号分隔的数据ID,数据ID通常是6位整数,这个字段本来是存储了上千个ID的,但是公司同事突然告诉我,本来可以查询到上千条数据,现在只能查到几十条了。我一听,吓坏了,因为同事告诉我,这是软件更新后才出现的,以为是我更新软件出的问题,但是我仔细想想,与之相关的代码我都没改呀!到底咋回事呢?

打开网易新闻 查看精彩图片

初听到这个事情,我感觉我要尽快找出原因,否则这个锅我背定了!

最开始我以为是数据显示出了问题,意思就是ID的数量没变,只是查询的时候出了问题,但是,这个猜想很快就被我否定了,因为我直接查询数据库,发现数据库里存储的ID数量就那么几十条。

现在可以肯定的是,数据丢了!

但是,我很确定,我没有改与之相关的任何代码,并且也翻了代码库的日志,发现近期我们公司所有程序员都没有动与之相关的代码。

查到这里,我就奇怪了,难道是有人动了数据库,直接在数据库里删的数据吗?但是,如果仅仅是删数据库,为什么还留那么几十条呢?

然后,我就发现了一个规律,因为这张表里的数据不止一行,我发现所有行的这一列数据的ID个数都是一样的!

这就奇怪了,难道是数据在存储的时候被截断了吗?

刚开始,我还没想通,于是检查了存储ID列表的代码,发现没有问题。

因为存储的ID是在选择数据以后,单独把ID拎出来组成一个以逗号分隔的字符串的,因此,我又重新选择了数据,大概有上千条吧,然后保存了数据。

接着,我就再到数据库里去看,然后我惊讶地发现,我明明存储的是上千条数据ID,但是到了数据库里,就变成了几十条了。

我不信邪,对代码进行了调试,发现我选择多少数据,以逗号分隔格式化后就是多少数据,但是只要执行完Sql语句,这些数据就变成了几十条了。这种情况说明,至少在代码层面是没有问题的,问题可能出现在数据库。

然后我突然灵光一闪,看了下表设计,发现该表用来存储ID的字段类型竟然是nvarchar,长度为255!

这下,什么事情都说清楚了,但是,我明明记得这个字段的类型是text!但凡懂点数据库的人都知道,想要存储大长度的字符串,只能使用text,或者像SqlServer这样使用nvarchar(max),其他数据库我就不知道了!

很显然,有人动了数据库!

我很确定我没有动过数据库,那么到底是谁动的呢?问了一圈,也没有人承认,既然没有人承认,那我只能装作不知道了!

于是,我把字段类型改了以后,让同事重新试试,结果发现功能正常了!

没过多久,我在代码库里发现有一个同事上传了一个新项目,该项目是独立于我们公司现有软件的,相当于一个后台管理系统,数据库用得跟我们主软件是一个数据库,但是区别就是ORM不同!

这个项目本来我是知道的,也就是最近立项的项目,但是,写这个项目的程序员把代码上传到代码库里我是不知道的。

本来就是纯好奇,想拉下来看看写得怎么样,但是,无意之中却让我看到了不该看的东西!

前面说了,我们公司主软件和新项目使用的ORM不同,主软件使用的是EntityFramework,他写的新项目使用的是FreeSql。

用过FreeSql的程序员都知道,FreeSql是有一个自动同步表结构的特性字段的,而正好,上面说的那个出问题的字段的那个所在表,在他的项目里也使用了该特性。

于是,我就看了下他定义的字段,发现他标明了字段类型为text,并且,对每个字段的类型和长度都做了标记。

开始,我以为我多想了,但是一看日志,发现他的这些标记恰恰就是上面说的那张表出问题以后不久才上传的!而之前这个字段就是普通的string类型,我查看了下FreeSql关于string类型在数据库类型中的定义,发现正好是nvarchar(255)!

所以,事情到这里算是真相大白了吧,FreeSql的自动同步表结构的特性,即使在查询时,也会进行表结构的同步,虽然他代码还没写到“增删改”那一步,但是仅仅是查询,其实就已经足以让数据库表有所变动了!

结语

最后,虽然知道了真相,但是念他年纪大,软件出现的问题不算严重,所以,我就当作没看见,毕竟,这个篓子谁也不愿意捅!

但我估计,通过这件事情,他也算长了记性吧!