掌握 MySQL 的数据类型

知道了表是由不同数据类型的列组成的,然后填充了一行一行的数据。

当我们要创建表的时候,就要根据业务需求,选择合适的数据类型。比如在实战项目中,文章表就是由下面这些不同数据类型的字段定义的。

目前用到了 bigint、tinyint、varchar、int、timestamp 等数据类型,这些数据类型到底该如何选择呢?就需要我们提前先了解清楚,MySQL 到底支持哪些数据类型,以及每种数据类型的特点是什么。

整数类型

上面提到的 bigint、tinyint、int 都是整数类型,MySQL 支持的整数类型如下:

smallint 和 mediuint 这两种类型很少用到,一般我们用的是 tinyint、int、bigint 这三种类型。

比如说技术派中 article 表的文章类型字段 article_type,就是用 tinyint 类型定义的,因为文章类型只有 1(博文)、2(问答)种,所以用 tinyint 就足够了。

再比如说状态 status 字段,也是用 tinyint 类型定义的,因为状态我们只有 0(未发布)、1(发布)两种。

以及 deleted 字段,也是用 tinyint 类型定义的,因为删除状态一般只有 0(未删除)、1(已删除)两种。

那像 int 一般用于用户的年龄啊、库存数量啊、评论数量啊、点赞数量啊等等。

技术派中 article 表的 offical_stat(官方推荐状态)、topping_stat(置顶状态)、cream_stat(加精状态)用了 int 类型,其实不太合理,应该用 tinyint 类型就足够了。暂时也就懒得改了。

bigint 我们用到了表的主键上,这也是一种比较常见的做法,尤其是当预计数量超过 int 的最大值(21 亿)时,但是就技术派目前的数量来看,用 int 就足够了。

在做大宗期货交易的订单时,一开始用的是 int 类型,后来还真的出现了超出 int 范围的情况,所以后来改成了 bigint 类型。

bigint 的最大值是 9223372036854775807,也就是 922 亿亿,这个数字非常非常大,往往到这个数量级的都要做分库分表了。

另外,对于主键的数据类型选择,不同的业务场景有不同的需求,如果需要确保跨多个数据库或者系统唯一性,那么 UUID 或者雪花算法生成的 ID 会更合适。

UUID 不依赖于数据库的自增特性,非常适合分布式系统,但是 UUID 会占用更多的存储空间(CHAR(36) 或 VARCHAR(36)),而且不是递增的,会导致索引的性能下降。

有符号和无符号

整型数据类型还可以选择有符号和无符号,有符号就是可以存储正数和负数,无符号就是只能存储正数。默认为有符号,也就是不用指定。

比如说 int 类型,如果是有符号的,那么范围是 -2147483648 到 2147483647,如果是无符号的,那么范围是 0 到 4294967295。

无符号的情况下,要特别注意和 Java 数据类型的对应关系

我们都知道,Java 中的int范围是 -2147483648 到 2147483647。那如果 MySQL 选择的 int 类型是无符号的,范围就超出了 Java 的 int 类型范围了。

这时候,为了避免出现不兼容的情况,Java 的数据类型要选择 long 类型。当然了,在数据库实体(POJO)中,要用包装类型Long类型。

像自增 ID,肯定是无符号的,所以我们会在定义的时候将其设置为 unsigned,比如说技术派项目中的 article 表。

int(10) 和 int

注意,上图中我们在定义 id 的时候,设置的数据类型是 int(10),和 int 有什么区别呢?

这其实是一道不错的面试题,比如说面试官可能会问你,int(10) 和 int(11) 有什么区别?

如果之前没有了解过的话,可能一下子就懵了。其实这个和存储空间没有关系,只是用来规定显示宽度的。

我们来创建这样一张测试表,包含四个字段,一个是主键 ID,一个是 int(10),一个是 int(11),另外一个是 int。

CREATE TABLE `test` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`int10` int(10) NOT NULL,`int11` int(11) NOT NULL,`int` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里的反引号 \` 是为了避免关键字冲突。

然后我们插入一条数据,看看结果。

INSERT INTO `test` (`int10`, `int11`, `int`) VALUES (1234567890, 1234567890, 1234567890);

似乎没有什么区别

我们来看一下 MySQL 官方对 int(M) 的解释。

M indicates the maximum display width for integer types.

也就是说,int(M) 只是规定了显示宽度对于存储空间和范围没有影响。通常与 ZEROFILL 一起使用,这样会在数字前面补 0,直到达到 M 位数。

If ZEROFILL is specified, the column will be zero-filled to the specified width for numeric types.

我们来修改一下之前的表结构,将 int(10) 和 int(11) 改成 int(10) ZEROFILL 和 int(11) ZEROFILL。

CREATE TABLE `test` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`int10` int(10) ZEROFILL NOT NULL,

`int11` int(11) ZEROFILL NOT NULL,

`int` int NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

再插入一条同样的数据(10 位),看看结果。

INSERT INTO `test` (`int10`, `int11`, `int`) VALUES (1234567890, 1234567890, 1234567890);

结果如下所示:

可以看到,int(10) ZEROFILL 和 int 都是正常显示,而 int(11) ZEROFILL 在数字前面补了 0,这是因为 1234567890 不足我们规定的 11 位,所以前面补了 0。

也就是说,没有指定 ZEROFILL 的话,int(M) 和 int 是一样的;指定了 ZEROFILL 的话,就会在数字前面补 0,直到达到 M 位数。

浮点数类型

浮点数类型包括 float 和 double,它们的取值范围我从来没有记住过(😂),太难记了。

它们之间的区别是存储空间不同,float 是 4 字节,double 是 8 字节。既然存储空间不同,肯定表示的范围也就不同,double 占用的空间大,所以精度上也更加准确。

定点数类型

实际工作当中,浮点数其实并不常用,因为很容易出现精度丢失的问题,尤其是一些涉及到货币值时,所以我们一般会选择定点数类型。

记得之前在对接微信支付的时候,微信支付的金额是用 int 类型表示的,单位是分,也就是说 1 元是 100 分。这样做的好处是,避免了浮点数精度丢失的问题。

定点数类型包括 decimal 和 numeric,网上有说 decimal 的存储空间是定长的,而 numeric 的存储空间是变长的,但是我在 MySQL 官方文档上并没有找到相关的信息。

换句话说,在 MySQL 中,decimal 和 numeric 是等价的,没有区别。

例如,我们可以这样定义一个定点数类型的字段

CREATE TABLE `test` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`price` decimal(10, 2) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

声明 decimal(10, 2) 意味着 price 最多有 10 位数,包括小数点后的 2 位

也就是说,decimal(M, D) 中的 M 表示总的位数,D 表示小数点后的位数。

定点数之所以比浮点数精确,是因为定点数会按照小数点把数字分成两部分,整数部分和小数部分,而浮点数是按照科学计数法来存储的。

比方说对于十进制小数 123.456,定点数会把它存储为 123 和 456 两部分,而浮点数会把它存储为 。

大家都知道,计算机存储的是二进制,遇到小数的时候就容易表示不精确,比如说 0.1 在二进制中是无限循环的。

使用 binaryconvert 可以查看 0.1 在二进制中的表示。

但存储整数就完全没问题,0 的二进制表示就是 00,1 的二进制表示就是 01,2 的二进制表示就是 10,3 的二进制表示就是 11,4 的二进制表示就是 0100,以此类推(逢二进一)。

回到定点数上,对于定点数 decimal(M, D),M 的取值范围是 1 到 255,D 的取值范围是 0 到 30;且 M 必须大于等于 D。

那 MySQL 是如何存储 decimal(16, 4) 这个定点数的呢?

可以选择字符串的存储方式,每个数字占用一个字符的位置,比如说数值 123.4567,直接存储为字符串 "123.4567"。

但这种方式对于计算机来说,并不高效,毕竟计算机的底层仍然是通过二进制来实现存储的。那怎么办呢?

对于 decimal(16, 4),MySQL 会将其拆解为两部分,整数部分和小数部分,然后采用二进制压缩存储的方式来存储

①、整数部分:有 12 位数字(16-4=12),每组 9 位十进制数字可以被压缩存储在 4 个字节的二进制格式中(因为 )。如果整数部分少于 9 位数字,它将占用足够存储该数值的最小字节数。

②、小数部分:有 4 位数字,同样可以通过压缩的二进制格式存储。4 位十进制数字可以压缩到 2 字节内(因为 )。

每组中包含的十进制数字位数不同,所需的存储空间也不同,具体见下表:

所以 decimal(16, 4) 共需要占用 8 个字节的存储空间:

  1. 第 1 组包含 3 个十进制,需要 2 个字节;
  2. 第 2 组包含 9 个十进制,需要 4 个字节;
  3. 第 3 组包含 4 个十进制,需要 2 个字节。

我们拿 1234567890.1234 举例:

①、整数部分 1234567890,可以分组为 1 和 234567890,分别占用 1 个字节和 4 个字节。

②、小数部分 1234,可以分组为 1234,占用 2 个字节。

Java 与 decimal 对应的数据类型是 BigDecimal,常用在金融领域。

日期和时间类型

日期和时间类型包括 year、date、time、datetime、timestamp。

  1. year 类型用于存储年份,范围是 1901 到 2155,占用 1 个字节。
  2. date 类型用于存储日期,范围是 1000-01-01 到 9999-12-31,占用 3 个字节。
  3. time 类型用于存储时间,范围是 -838:59:59[.000000] 到 838:59:59[.000000],占用 3 字节 + 小数秒的存储空间
  4. datetime 类型用于存储日期和时间,范围是 1000-01-01 00:00:00[.000000] 到 9999-12-31 23:59:59[.999999],占用 5字节+小数秒的存储空间。
  5. timestamp 类型用于存储时间戳,范围是 1970-01-01 00:00:01[.000000] 到 2038-01-19 03:14:07[.999999],占用 4 字节 + 小数秒的存储空间。

datetime 和 timestamp 是最常用的两个类型,新手经常会搞混,不知道到底该使用哪一个

  1. datetime 是存储的是实际的时间不会受到时区的影响适用于需要存储较宽时间范围的日期和时间数据,或者数据不需要考虑时区变化的场景,如出生日期
  2. timestamp 是存储的是 UTC(Coordinated Universal Time,一个时间标准)时间,可以根据时区进行转换特别适合记录数据的创建时间和修改时间等需要考虑时区的场景。

举例来说,我们把 2024-02-02 11:12:13 存储到 datetime 类型的字段中,那么无论在哪个时区,都是 2024-02-02 11:12:13。

而 timestamp 要求存储的是时间戳,存储之前,要先计算从 1970-01-01 00:00:00 起到某个时间节点的秒数,比如说 2024-02-02 11:12:13 对应的时间戳是 1706843533000。

那这个时间戳在 UTC+8(北京时间)时区下,就是 2024-02-02 11:12:13在 UTC-5(纽约)时区下就是 2024-02-01 20:12:13,在 UTC+1(伦敦)时区下,就是 2024-02-02 03:12:13。

在技术派项目中,article 表的 create_time 和 update_time 字段就是 timestamp 类型的。

注意到 timestamp 类型的字段,还有一个属性 DEFAULT CURRENT_TIMESTAMP,这是设置默认值的,也就是说,如果插入数据的时候没有指定 create_time 和 update_time 的值,那么就会自动填充当前时间。这是 MySQL 5.6 之后的新特性。

ON UPDATE CURRENT_TIMESTAMP 是设置更新时间的,也就是说,如果更新数据的时候没有指定 update_time 的值,那么就会自动填充当前时间。

通过 select CURRENT_TIMESTAMP 可以查看当前时间。

也就是说,我们在插入数据和更新数据的时候,不需要手动填充 create_time 和 update_time 的值,MySQL 会自动帮我们填充。

对应的 Java 数据类型是 java.util.Date。

技术派实战项目中用 MyBatis-Plus 作为持久层框架,它扩展了 MyBatis,而 MyBatis 会自动将 timestamp 类型的字段映射为 java.util.Date 类型,由 DateTypeHandler 实现。

字符串类型

字符串类型包括 char、varchar、tinytext、text、mediumtext、longtext。

①、char(M),固定 M 个字符长度,最多 255 个字符,如果省略掉 M,默认为 1。

②、varchar(M),可变 M 个字符长度,最多 65535 个字符,但实际上存不了这么多,因为需要额外两个字节来存储长度(字符数小于 255 时使用一个字节),除此之外,字符集、存储引擎有关。

下表展示了 char(4) 和 varchar(4) 在单字节字符集(latin1)下的不同。

latin1 是单字节字符集,一个字符占用 1 个字节

由此可以看出,char 类型是固定长度的,不足的地方会用空格填充,而 varchar 类型是可变长度的;当超过指定长度时,都会截断。

重点:

也就是说,当我们不确定字段的长度时,应该使用 varchar 类型。这样可以节省一定的存储空间。

实际工作中,char 确定也非常少用,项目中用的都是 varchar 类型。

③、文本类型,最常用的就是 longtext类型,比如说技术派项目中 article 表的 content 字段就是 longtext 类型的。

内容是 markdown 格式的字符,所以 longtext 足够用了,来看一下它们的存储空间:

  1. tinytext,最多 255个字节。
  2. text,最多 65,535 个字节,相当于 64KB。
  3. mediumtext,最多16,777,215  个字节,相当于 16MB。
  4. longtext,最多 4,294,967,295 个字节,相当于 4GB。

那其实除了上面提到的这几种字符类型,还有 enum 和 set 类型。

  1. enum 类型,用于存储枚举类型,比如说性别字段,只有男和女两种,就可以用 enum 类型。
  2. set 类型,用于存储集合类型,比如说文章标签字段,可以有多个标签,就可以用 set 类型

通过下面这个例子,我们可以看到 enum 和 set 类型的定义方式。

CREATE TABLE `test` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`gender` enum('男', '女') NOT NULL,

`tags` set('Java', 'Python', 'Go', 'C++') NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入两条数据,看看结果。

INSERT INTO `test` (`gender`, `tags`) VALUES ('男', 'Java,Python');

INSERT INTO `test` (`gender`, `tags`) VALUES ('女', 'Go,C++');

当然了,这两个类型在实际工作中并不常用,比如说 enum 类型,可以通过 tinyint 配合Java中的枚举来实现。

这样会更加灵活,枚举中的 code 和表中的字段值对应枚举中的 desc 就可以定义为枚举的描述。

至于 set,同样可以通过一对多的关系来实现,比如说文章和标签的关系,可以通过一张文章表和一张标签表来实现。

这样修改起来会更加容易,比如说哪天 Go 标签想更改为 Golang 标签,我只需要改一下 tag 表就可以了,文章表不需要做任何修改。

二进制类型

二进制类型通常用来存储图片、音频、视频等二进制文件,MySQL 提供了多种二进制类型来满足不同的存储要求,包括 binary、varbinary、tinyblob、blob、mediumblob、longblob。

binary 和 varbinary 类型适合存储需要精确字节长度的二进制数据,比如说 MD5 值等

  1. binary:固定长度的二进制,最多 255 个字节。
  2. varbinary:可变长度的二进制,最多 65535 个字节

blob(Binary Large OBject)类型适合存储大型二进制数据,比如说图片、音频、视频等。

  1. tinyblob:最多 255个字节。
  2. blob:最多65535 个字节,相当于 64KB。
  3. mediumblob:最多16777215 个字节,相当于 16MB。
  4. longblob:最多4294967295 个字节,相当于 4GB。

不过在实际工作中,我们很少直接存储二进制文件,而是存储文件的路径,然后通过路径来访问文件。

文件本身通过 OSS(Object Storage Service)等对象存储服务来存储,数据库只存储文件的元数据,比如说文件名、文件大小、文件类型等。

这样做的好处是,可以减少数据库的存储压力,提高数据库的性能,而且还可以实现文件的分布式存储。

像技术派中的 article 表,就有一个 picture 字段,用来存储文章的封面图片,这个字段是 varchar 类型的,存储的就图片的路径。

小结

关于 MySQL 的数据类型,这一节我们就先讲到这里,总结一下:

  1. 整数类型包括 tinyint、smallint、mediuint、int、bigint,可以选择有符号和无符号。
  2. 浮点数类型包括 float 和 double,double 的精度更高。
  3. 定点数类型包括 decimal 和 numeric,用于存储货币值等精度要求高的数据。
  4. 日期和时间类型包括 year、date、time、datetime、timestamp,datetime 适用于不需要考虑时区变化的场景,timestamp 适用于需要考虑时区变化的场景。
  5. 字符串类型包括 char、varchar、tinytext、text、mediumtext、longtext,char 是固定长度的,varchar 是可变长度的,文本类型适合存储大型文本数据。
  6. 二进制类型包括 binary、varbinary、tinyblob、blob、mediumblob、longblob,适合存储图片、音频、视频等二进制文件。

在实际工作中,我们要根据业务需求,选择合适的数据类型,避免浪费存储空间,提高数据库性能。

另外,还要注意数据库和 Java 数据类型的对应关系,避免出现不兼容的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3+ts+vite使用mock数据

安装以下命令 npm i vite-plugin-mock --save-dev npm i mockjs --save-dev 在根路径下创建mock文件夹 mock\user.ts const menuList [{path: /system,component: Layout,name: system,meta: {title: 系统管理,icon: Setting,roles: [sys:manage]},children: [{path: /depar…

Java中使用poi+poi-tl实现根据模板导出word文档

场景 若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出: 若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出_若依导出前端获得到后端的execl流之后怎么操作-CSDN博客 上面讲的是Excel的导出,如果是需要根据w…

即插即用篇 | YOLOv8 引入 MHSA 注意力机制 | 《Bottleneck Transformers for Visual Recognition》

论文名称:《Bottleneck Transformers for Visual Recognition》 论文地址:https://arxiv.org/pdf/2101.11605.pdf 文章目录 1 原理2 源代码3 添加方式4 模型 yaml 文件template-backbone.yamltemplate-small.yamltemplate-large.yamltemplate-neck.yaml

Mac 重新安装系统

Mac 重新安装系统 使用可引导安装器重新安装(可用于安装非最新的 Mac OS,系统降级,需要清除所有数据) 插入制作好的可引导安装器(U盘或者移动固态硬盘),如何制作可引导安装器将 Mac 关机将 Ma…

排序——冒泡排序

冒泡排序的基本思想 从前往后&#xff08;或从后往前&#xff09;两两比较相邻元素的值&#xff0c;若为逆序&#xff08;即 A [ i − 1 ] < A [ i ] A\left [ i-1\right ]<A\left [ i\right ] A[i−1]<A[i]&#xff09;&#xff0c;则交换它们&#xff0c;直到序列…

标准PoE交换机、非标准PoE交换机和非PoE交换机三者到底有何区别?

目录 前言&#xff1a; 一、标准PoE交换机 1.1 工作原理 1.2 应用场景 1、视频监控 2、无线接入点 3、IP电话 1.3 优势 1、简化布线 2、简化安装 3、提高可靠性 二、非标准PoE交换机 2.1 工作原理 2.2 应用场景 1、无线路由器 2、IP电话 3、数据中心 2.3 优势…

c++面试三 -- 智能指针--7000字

一、智能指针 C 中的智能指针是一种用于管理动态分配的内存的对象&#xff0c;它们可以自动进行内存管理&#xff0c;避免内存泄漏和悬挂指针等问题。 1. 悬挂指针 悬挂指针&#xff08;dangling pointer&#xff09;是指在程序中仍然存在但已经不再指向有效内存地址的指针。悬…

IO多路复用 poll模型

poll 是一种在 Linux 系统中进行 I/O 多路复用的模型&#xff0c;它与 select 类似&#xff0c;但具有一些不同之处。poll 允许监视的文件描述符数量不受限制&#xff0c;而不像 select 有一定的限制。 基本概念&#xff1a; poll 函数&#xff1a; 通过 poll 函数&#xff0c…

队列的结构概念和实现

文章目录 一、队列的结构和概念二、队列的实现三、队列的实现函数四、队列的思维导图 一、队列的结构和概念 什么是队列&#xff1f; 队列就是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 如上图所示&#x…

【比较mybatis、lazy、sqltoy、mybatis-flex操作数据】操作批量新增、分页查询(二)

orm框架使用性能比较 环境&#xff1a; idea jdk17 spring boot 3.0.7 mysql 8.0比较mybatis、lazy、sqltoy、mybatis-flex操作数据 测试条件常规对象 orm 框架是否支持xml是否支持 Lambda对比版本mybatis☑️☑️3.5.4sqltoy☑️☑️5.2.98lazy✖️☑️1.2.4-JDK17-SNAPS…

Vue+SpringBoot打造天然气工程运维系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程 12.2.2 流程 22.3 各角色功能2.3.1 系统管理员功能2.3.2 用户服务部功能2.3.3 分公司&#xff08;施工单位&#xff09;功能2.3.3.1 技术员角色功能2.3.3.2 材料员角色功能 2.3.4 安…

Zabbix企业运维监控工具

Zabbix企业级监控方案 常见监控软件介绍 Cacti Cacti是一套基于 PHP、MySQL、SNMP 及 RRD Tool 开发的监测图形分析工具&#xff0c;Cacti 是使用轮询的方式由主服务器向设备发送数据请求来获取设备上状态数据信息的,如果设备不断增多,这个轮询的过程就非常的耗时&#xff0…

sql注入less46作业三

采用报错注入 updatexml(XML_document,XPath_string,new_value) 一共可以接收三个参数&#xff0c;报错位置在第二个参数。 ?sort1 and updatexml(1,concat(0x7e,database(),0x7e),1)-- #查询库名 ?sort1 and updatexml(1,concat(0x7e,(select group_concat(table_name) fr…

[每周一更]-(第89期):开源许可证介绍

开源代码本就是一种共享精神&#xff0c;一种大无畏行为&#xff0c;为了发扬代码的魅力&#xff0c;创造更多的价值&#xff0c;让爱传递四方&#xff0c;让知识惠及更多人&#xff1b; 写文章也是一种共享精神&#xff0c;让知识传播出去。 介绍下开源中不同许可证的内容限…

初学Vue总结

0 Vue概述 问题&#xff1a;我们已经学过了htmlCssjavascript,可以开发前端页面了&#xff0c;但会发现&#xff0c;效率太低了。那么&#xff0c;有没有什么工具可以提高我们的开发效率&#xff0c;加快开发速度呢&#xff1f; 他来了&#xff0c;他来了&#xff0c;他大佬似…

Spring注解之json 数据处理

目录 1. 过滤 json 数据 2. 格式化 json 数据 3. 扁平化对象 1. 过滤 json 数据 JsonIgnoreProperties 作用在类上用于过滤掉特定字段不返回或者不解析。 //生成json时将userRoles属性过滤 JsonIgnoreProperties({"userRoles"}) public class User { ​private S…

线性规划在多种问题形式下的应用

线性规划的用处非常的广泛&#xff0c;这主要是因为很多类型的问题是可以通过转化的方式转化为线性规划的问题。例如需要再图论中寻找起始点到给定的点的最短路径问题&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 假设要计算从节点0到节点…

springboot配置多数据源以及事务问题

一、背景以及为什么需要学习 在高并发的项目中,单数据库已无法承载大数据量的访问,因此需要使用多个数据库进行对数据的读写分离,此外就是在微服化的今天,我们在项目中可能采用各种不同存储,因此也需要连接不同的数据库,居于这样的背景,这里简单分享实现的思路以及实现…

点亮城市名片丨计讯物联智慧灯杆系统在通讯基地的成功应用

项目背景 在国家新型城镇化大背景下&#xff0c;十四五规划纲要强调“加快数字化发展&#xff0c;建设数字中国”&#xff0c;明确提出“以数字化助推城乡发展和治理模式创新”&#xff0c;全面提高城市的运行效率和宜居程度。 项目概况 为满足灯杆灯光亮度的远程智能管理、对…

记录 android studio 通过安装NDK 编译C文件,得到需要的so文件

只怪自己太健忘&#xff0c;每次网上查了一圈&#xff0c;搞定后&#xff0c;再遇到又发现不会操作了&#xff0c;特此记下 不废话直接上步骤 &#xff08;1&#xff09; 进入AS的settinging如下界面 &#xff08;2&#xff09;选中图片箭头两个文件 进行下载 &#xff08;…