当前位置: 首页 > news >正文

MySQL:MySQL8.0 JSON类型使用整理,基于用户画像的案例

摘要:MySQLJSON类型多值索引用户画像

MySQL是结构化数据存储,JSON是非结构化格式,在MySQL中使用JSON类型可以打通关系型和非关系型数据的存储之间的界限,为业务提供更好的架构选择,以下内容包括

  • (1)JSON 数据类型
  • (2)JSON类型创建插入数据
  • (3)提取JSON内字段
  • (4)JSON类型和字符串的区别
  • (5)JSON类型数据修改
  • (6)JSON类型使用索引
  • (7)JSON类型其他常用函数
  • (8)JSON ARRAY的多值索引
  • (9)基于JSON类型的用户画像设计

(1)JSON 数据类型

JSON(JavaScript Object Notation)主要用于互联网应用服务之间的数据交换。MySQL 支持JSON 对象JSON 数组两种类型,JSON 类型是从 MySQL 5.7 版本开始支持的功能,MySQL中使用JSON有以下好处

  • 无须预定义字段:字段可以无限拓展,避免了ALTER ADD COLUMN的操作,使用更加灵活
  • 处理稀疏字段:避免了稀疏字段的NULL值,避免冗余存储
  • 支持索引:相比于字符串格式的JSON,JSON类型支持索引做特定的查询优化

总体而言,JSON 类型比较适合存储一些修改较少、相对静态的数据,或者说适合存储修改较少,且容忍稀疏的聚合数据,比如存储用户的登录信息


(2)JSON类型创建插入数据
create database test default charset utf8mb4;CREATE TABLE student (id BIGINT AUTO_INCREMENT PRIMARY KEY,info JSON DEFAULT NULL
);

插入数据

mysql> INSERT student (info) VALUES ('{"sex": "F", "age": 13, "city": "beijing"}');
Query OK, 1 row affected (0.13 sec)mysql> INSERT student (info) VALUES ('{"sex": "M", "age": 14, "city": "suzhou"}');
Query OK, 1 row affected (0.10 sec)mysql> INSERT student (info) VALUES ('{"sex": "F", "age": 23, "city": "shenzhen"}');
Query OK, 1 row affected (0.20 sec)

查看数据

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+

试一下插入JSON数组

mysql> INSERT student (info) VALUES ('[1,2,3,4]');
Query OK, 1 row affected (0.12 sec)mysql> INSERT student (info) VALUES ('[{"sex": "M"},{"sex":"F", "city":"nanjing"}]');
Query OK, 1 row affected (0.11 sec)mysql> select * from student;
+----+-------------------------------------------------+
| id | info                                            |
+----+-------------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}      |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}       |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"}     |
|  4 | [1, 2, 3, 4]                                    |
|  5 | [{"sex": "M"}, {"sex": "F", "city": "nanjing"}] |
+----+-------------------------------------------------+
5 rows in set (0.00 sec)
  • 可以混合插入JSON数组和JSON对象,但是必须要符合JSON格式
  • 其中整个字符串使用单引号,键值对使用双引号,
  • JSON中可以允许有多余空格,MySQL会自动解析,输出的使用格式为符号后带有一个空格

(3)提取JSON内字段

因为支持了新的JSON类型,MySQL 配套提供了丰富的 JSON 字段处理函数,用于方便地操作 JSON 数据,最常见的就是函数 JSON_EXTRACT,它用来从 JSON 数据中提取所需要的字段内容

(1)提取JSON对象

主要是JSON_UNQUOTE和JSON_EXTRACT,JSON_EXTRACT作用是去除最外侧的双引号,JSON_EXTRACT根据键提取值

mysql> SELECT->     id,->     JSON_UNQUOTE(JSON_EXTRACT(info,"$.sex")) sex,->     JSON_UNQUOTE(JSON_EXTRACT(info,"$.age")) age,->     JSON_UNQUOTE(JSON_EXTRACT(info,"$.city")) city-> FROM student;
+----+------+------+----------+
| id | sex  | age  | city     |
+----+------+------+----------+
|  1 | F    | 13   | beijing  |
|  2 | M    | 14   | suzhou   |
|  3 | F    | 23   | shenzhen |
+----+------+------+----------+
3 rows in set (0.00 sec)

MySQL 还提供了 ->> 表达式,和上述 SQL 效果完全一样,->>也是去除最外面的引号,还有一种符号->,它也能得到提取结果但是不去除外面的符号,相当于->和JSON_EXTRACT对应

mysql> SELECT->     id,->     info->>"$.sex" sex,->     info->>"$.age" age,->     info->>"$.city" city-> FROM student;
+----+------+------+----------+
| id | sex  | age  | city     |
+----+------+------+----------+
|  1 | F    | 13   | beijing  |
|  2 | M    | 14   | suzhou   |
|  3 | F    | 23   | shenzhen |
+----+------+------+----------+
3 rows in set (0.00 sec)

如果JSON对象中查询的键不存在,则返回为NULL

mysql> SELECT->     id,->     JSON_UNQUOTE(JSON_EXTRACT(info,"$.sex")) sex,->     JSON_UNQUOTE(JSON_EXTRACT(info,"$.height")) height-> FROM student;
+----+------+--------+
| id | sex  | height |
+----+------+--------+
|  1 | F    | NULL   |
|  2 | M    | NULL   |
|  3 | F    | NULL   |
+----+------+--------+
3 rows in set (0.00 sec)
(2)提取JSON数组

先创建JSON数组类型,插入数据

mysql> CREATE TABLE student (->   id BIGINT AUTO_INCREMENT PRIMARY KEY,->   info JSON DEFAULT NULL-> );
Query OK, 0 rows affected (0.42 sec)mysql> INSERT student (info) VALUES ('[1, 2, 3, 4]');
Query OK, 1 row affected (0.09 sec)mysql> INSERT student (info) VALUES ('[2, 3, 4]');
Query OK, 1 row affected (0.08 sec)mysql> INSERT student (info) VALUES ('[3, 1, -1]');
Query OK, 1 row affected (0.13 sec)mysql> select * from student;
+----+--------------+
| id | info         |
+----+--------------+
|  1 | [1, 2, 3, 4] |
|  2 | [2, 3, 4]    |
|  3 | [3, 1, -1]   |
+----+--------------+
3 rows in set (0.00 sec)

JOSN数组通过索引取对应的值,同样是使用JSON_EXTRACT,索引从0开始

mysql> SELECT ->     JSON_EXTRACT(info, '$[0]') first-> FROM student;
+----------------------------+
| first                      |
+----------------------------+
| 1                          |
| 2                          |
| 3                          |
+----------------------------+

同样可以采用->>符号,这种方式会去除双引号,如果JSON数组内的元素是双引号字符串,显示出来的时候也会被去除引号

mysql> SELECT->     id,->     info->>"$[0]" first,->     info->>"$[1]" second-> FROM student;
+----+-------+--------+
| id | first | second |
+----+-------+--------+
|  1 | 1     | 2      |
|  2 | 2     | 3      |
|  3 | 3     | 1      |
+----+-------+--------+

可以提取数组中的多个值,此时JSON_EXTRACT后面传入多个参数,提取的顺序和输出顺序一致

mysql> SELECT id, JSON_EXTRACT(info, "$[1]", "$[0]") a FROM student;
+----+--------+
| id | a      |
+----+--------+
|  1 | [2, 1] |
|  2 | [5, 2] |
|  3 | [3, 1] |
+----+--------+
3 rows in set (0.01 sec)

如果提取的索引位置不存在则返回空

mysql> SELECT ->     id,->     info->>"$[2]" a-> FROM student;
+----+------+
| id | a    |
+----+------+
|  1 | 3    |
|  2 | 6    |
|  3 | NULL |
+----+------+
3 rows in set (0.00 sec)
(3)提取嵌套数组

嵌套数组主要是JSON数组内包含多个JSON对象或者JSON数组包含多个JSON数组,先以包含多个JSON对象为例

mysql> truncate table student;
Query OK, 0 rows affected (0.70 sec)mysql> INSERT student (info) VALUES ('[{"no":1,"ent_name":"张家港市杨舍百桥士方园艺场","score":98.2}, {"no":2,"ent_name":"昆山市朱北苗圃有限公司","score":98.2}, {"no":3,"ent_name":"苏州市吴中区临湖现代渔业发展有限公司","score":98.2}]');
Query OK, 1 row affected (0.08 sec)mysql> INSERT student (info) VALUES ('[{"no":1,"ent_name":"张家港市合力土石方挖掘服务部","score":98.1}, {"no":2,"ent_name":"中国石化销售有限公司江苏苏州养武加油站","score":97.6}, {"no":3,"ent_name":"中国石化销售有限公司江苏苏州太仓璜泾二站服务点","score":97.5}]');
Query OK, 1 row affected (0.09 sec)
mysql> select * from student;
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | info                                                                                                                                                                                                                                                                                                   |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | [{"no": 1, "score": 98.2, "ent_name": "张家港市杨舍百桥士方园艺场"}, {"no": 2, "score": 98.2, "ent_name": "昆山市朱北苗圃有限公司"}, {"no": 3, "score": 98.2, "ent_name": "苏州市吴中区临湖现代渔业发展有限公司"}]                                                                                     |
|  2 | [{"no": 1, "score": 98.1, "ent_name": "张家港市合力土石方挖掘服务部"}, {"no": 2, "score": 97.6, "ent_name": "中国石化销售有限公司江苏苏州养武加油站"}, {"no": 3, "score": 97.5, "ent_name": "中国石化销售有限公司江苏苏州太仓璜泾二站服务点"}]                                                         |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

提取嵌套数组的值,首先要找到数组中对应的对象,然后根据对象的键找值

mysql> SELECT ->     id,->     JSON_UNQUOTE(JSON_EXTRACT(info -> "$[0]", "$.ent_name")) first_ent_name-> FROM student;
+----+--------------------------------------------+
| id | first_ent_name                             |
+----+--------------------------------------------+
|  1 | 张家港市杨舍百桥士方园艺场                 |
|  2 | 张家港市合力土石方挖掘服务部               |
+----+--------------------------------------------+
2 rows in set (0.00 sec)

对比一下之前的写法则只能提取第一个数组对象,可见JSON_UNQUOTE对于内侧的引号不删除,只删除外侧的引号

mysql> SELECT ->     id,->     JSON_UNQUOTE(JSON_EXTRACT(info, "$[0]")) first-> FROM student;
+----+------------------------------------------------------------------------------------+
| id | first                                                                              |
+----+------------------------------------------------------------------------------------+
|  1 | {"no": 1, "score": 98.2, "ent_name": "张家港市杨舍百桥士方园艺场"}                 |
|  2 | {"no": 1, "score": 98.1, "ent_name": "张家港市合力土石方挖掘服务部"}               |
+----+------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

在看数组套数组的情况

mysql> INSERT student (info) VALUES ('[1, 2, [3, 4]]');
Query OK, 1 row affected (0.07 sec)mysql> select * from student;
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
+----+----------------+
1 row in set (0.00 sec)

提取其中嵌套的数组,第一个表示嵌套数据的位置索引,第二个*表示嵌套数据内取所有元素

mysql> SELECT ->     id, ->     JSON_EXTRACT(info, "$[2][*]") a-> FROM student;
+----+--------+
| id | a      |
+----+--------+
|  1 | [3, 4] |
+----+--------+
1 row in set (0.00 sec)

如果第二个参数不是*,也可以选取嵌套数据内的指定位置的元素

SELECT id, JSON_EXTRACT(info, "$[2][1]") a
FROM student;
mysql> SELECT ->     id, ->     JSON_EXTRACT(info, "$[2][1]") a-> FROM student;
+----+------+
| id | a    |
+----+------+
|  1 | 4    |
+----+------+
1 row in set (0.00 sec)
(4)提取JSON后增加过滤 / 排序条件

提取JSON后不能用新命名的字段做筛选过滤,需要调用把JSON函数或者符号再写一遍

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.00 sec)

筛选sex是F,age大于14的

mysql> SELECT ->     id, ->     info-> FROM student WHERE info->>"$.age" > 14 and info->>"$.sex" = 'F';
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
1 row in set (0.01 sec)

根据age倒序排序取第一,只要city列

mysql> SELECT ->     id, ->     info->>"$.city"-> FROM student WHERE info->>"$.age" > 14 and info->>"$.sex" = 'F';
+----+-----------------+
| id | info->>"$.city" |
+----+-----------------+
|  3 | shenzhen        |
+----+-----------------+
1 row in set (0.00 sec)

(4)JSON类型和字符串的区别

除了JSON类型支持索引之外,看一下脚本语言对于JSON类型取值和字符串是否有区别,使用pymysql连接测试

>>> import pymysql
>>> config = {"user": "root", "password": "123456", "database": "test", "host": "127.0.0.1", "port": 3306}
>>> conn = pymysql.connect(**config)
>>> cursor = conn.cursor()
>>> cursor.execute("select info from student where id = 1")
1
>>> res = cursor.fetchall()  # (('{"age": 13, "sex": "F", "city": "beijing"}',),)
>>> cursor.close()
>>> conn.close()
>>> json.loads(res[0][0])
{'age': 13, 'sex': 'F', 'city': 'beijing'}

可见结果是一个JSON格式的字符串,可以直接解析成JSON,所以脚本语言取出的JSON类型结果和字符串没有差别,就是JSON格式的字符串,另外指定JSON格式后,MySQL会对插入的字符串做检验,如果不符合JSON格式插入报错,这也是和传统Varchar或者TEXT的区别

  • JSON格式相比于Varchar,TEXT支持索引
  • JSON格式会对插入的字符串做JSON格式校验,不符合则报错
  • JSON格式的输入输出都是字符串,如果使用Varchar或者TEXT格式人工保证字符串为JSON格式,效果是一致的

(5)JSON类型数据修改

修改数据主要是JSON_SETJSON_INSERTJSON_REPLACE三个方法

  • JSON_SET:替换现有key的值,插入不存在的key的值
  • JSON_INSERT:插入不存在的key的值,已经存在的不修改
  • JSON_REPLACE:只替换已存在的key的值,不存在的不做插入

使用的时候结合update语句

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.01 sec)

JSON_SET,不存在则插入,有则替换

mysql> UPDATE student SET info = JSON_SET(info, "$.city", 'wuxi', "$.height", 123) WHERE id = 1;
Query OK, 1 row affected (0.87 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from student;
+----+--------------------------------------------------------+
| id | info                                                   |
+----+--------------------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "wuxi", "height": 123} |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}              |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"}            |
+----+--------------------------------------------------------+

JSON_INSERT,只会插入不存在的值

mysql> UPDATE student SET info = JSON_INSERT(info, "$.city", 'wuxi', "$.height", 123) WHERE id = 1;
Query OK, 1 row affected (0.11 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from student;
+----+-----------------------------------------------------------+
| id | info                                                      |
+----+-----------------------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing", "height": 123} |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}                 |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"}               |
+----+-----------------------------------------------------------+
3 rows in set (0.00 sec)

JSON_REPLACE,只会替换已有值

mysql> UPDATE student SET info = JSON_REPLACE(info, "$.city", 'wuxi', "$.height", 123) WHERE id = 1;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "wuxi"}     |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.00 sec)

删除使用JSON_REMOVE,在JSON对象中指定key删除

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "wuxi"}     |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.00 sec)mysql> UPDATE student SET info = JSON_REMOVE(info, "$.age") WHERE id = 1;
Query OK, 1 row affected (0.45 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"sex": "F", "city": "wuxi"}                |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.00 sec)

在JSON数组中指定下标删除

mysql> select * from student;
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  2 | [2, 5, 6]      |
|  3 | [1, 3]         |
+----+----------------+
3 rows in set (0.00 sec)mysql> UPDATE student SET info = JSON_REMOVE(info, "$[1]") WHERE id=2;
Query OK, 1 row affected (0.72 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from student;
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  2 | [2, 6]         |
|  3 | [1, 3]         |
+----+----------------+
3 rows in set (0.00 sec)

(6)JSON类型使用索引

当 JSON 数据量非常大,用户希望对 JSON 数据进行有效检索时,可以利用 MySQL 的函数索引功能对 JSON 中的某个字段进行索引,具体方式是先创建一个虚拟列,再对虚拟列创建索引
先看一下没有索引下,对JSON对象中某个key做条件检索的EXPLAIN计划,可见访问方式type是ALL全表扫面,使用的索引Key是NULL

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+
3 rows in set (0.00 sec)
mysql> explain select * from student where info->>"$.age" = 13;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

创建虚拟列age,并且添加普通索引,可见表新增了一列(虽然是虚拟列,但是在SELECT和脚本语言取数都能取到新增的虚拟列),重新EXPLAIN之后Type改为ref代表普通索引,使用的Key是idx_age

mysql> ALTER TABLE student ADD COLUMN age INT as (info->>"$.age");
Query OK, 0 rows affected (0.54 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> select * from student;
+----+---------------------------------------------+------+
| id | info                                        | age  |
+----+---------------------------------------------+------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |   13 |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |   14 |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |   23 |
+----+---------------------------------------------+------+
3 rows in set (0.00 sec)mysql> ALTER TABLE student ADD INDEX idx_age(age);
Query OK, 0 rows affected (0.51 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> explain select * from student where info->>"$.age" = 13;
+----+-------------+---------+------------+------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | student | NULL       | ref  | idx_age       | idx_age | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

除了普通索引,同理还可以为JSON对象的其他Key值创建唯一索引等
除了再建表之后创建虚拟列增加索引,也可以在建表的时候就为JSON类型创建索引

mysql> CREATE TABLE student (->   id BIGINT AUTO_INCREMENT PRIMARY KEY,->   info JSON DEFAULT NULL, ->   age Int as (info->>"$.age"),->   index idx_age(age)-> );

(7)JSON类型其他常用函数

除了上面的JSON_EXTRACT和JSON_UNQUOTE,常用函数如下

  • MEMBER OF:只能对JSON数组使用,返回1元素存在数组中,0元素不存在数组中
  • JSON_CONTAINS:可以对JSON数组和JSON对象使用,针对JSON数组检查一个元素或者多个元素是否存在,对于JSON对象检查指定路径下是否有某个值或者是否有某个路径(Key)
  • JSON_OVERLAP:比较两个JSON数组是否至少有一个元素一致,如果是返回1,否则返回0,如果是JSON对象,判断是否是找有一对key value一致
  • JSON_KEYS:返回JSON对象的Key,也可以是嵌套JSON对象

以上函数可以在前面加上NOT关键字就可以取反

MEMBER OF是MySQL 8.0.17新增的函数,查看元素或者子数组是否存在在JSON数组中,如果把MEMBER OF放在where条件后面则直接筛选结果是1的,可以省略写=1

mysql> select * from student;
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  2 | [2, 5, 6]      |
|  3 | [1, 3]         |
+----+----------------+
3 rows in set (0.01 sec)mysql> SELECT * FROM student WHERE 3 MEMBER OF(info);
+----+--------+
| id | info   |
+----+--------+
|  3 | [1, 3] |
+----+--------+
1 row in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_ARRAY(3, 4) MEMBER OF(info);
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
+----+----------------+
1 row in set (0.00 sec)

JSON_CONTAINS和MEMBER OF类似,但是JSON_CONTAINS可以作用与JSON对象,对于JSON数组两者也有区别,JSON_CONTAINS可以指定多个数组内的元素,相当于是且的关系,JSON_CONTAINS放在where后面默认筛选结果值是1的

mysql> select * from student;
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  2 | [2, 5, 6]      |
|  3 | [1, 3]         |
+----+----------------+
3 rows in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_CONTAINS(info, '[2, 6]');
+----+-----------+
| id | info      |
+----+-----------+
|  2 | [2, 5, 6] |
+----+-----------+
1 row in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_CONTAINS(info, '[2]');
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  2 | [2, 5, 6]      |
+----+----------------+mysql> SELECT * FROM student WHERE JSON_CONTAINS(info, '[3]');
+----+----------------+
| id | info           |
+----+----------------+
|  1 | [1, 2, [3, 4]] |
|  3 | [1, 3]         |
+----+----------------+

当JSON_CONTAINS作用与JSON对象时,需要判断某个key-value对是否存,格式是(target,value,key),在指定value的时候,数值用单引号,字符串还要在内加一层双引号

mysql> select * from student;
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  2 | {"age": 14, "sex": "M", "city": "suzhou"}   |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+mysql> SELECT * FROM student WHERE JSON_CONTAINS(info, '"F"', '$.sex');
+----+---------------------------------------------+
| id | info                                        |
+----+---------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"}  |
|  3 | {"age": 23, "sex": "F", "city": "shenzhen"} |
+----+---------------------------------------------+mysql> SELECT * FROM student WHERE JSON_CONTAINS(info, '13', '$.age');
+----+--------------------------------------------+
| id | info                                       |
+----+--------------------------------------------+
|  1 | {"age": 13, "sex": "F", "city": "beijing"} |
+----+--------------------------------------------+

JSON_OVERLAP返回两个JSON数组或者JSON对象至少有一个/对元素一致则是1,房子啊where后面筛选出存在至少一个交集的数据

mysql> SELECT * FROM student WHERE JSON_OVERLAPS(info, '[1, 5]');
+----+--------------+
| id | info         |
+----+--------------+
|  1 | [1, 2, 5]    |
|  2 | [2, 5, 6]    |
|  3 | [1, 3, 8]    |
|  4 | [1, 2, 7, 8] |
+----+--------------+
4 rows in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_OVERLAPS(info, '[1, 5, 6]');
+----+--------------+
| id | info         |
+----+--------------+
|  1 | [1, 2, 5]    |
|  2 | [2, 5, 6]    |
|  3 | [1, 3, 8]    |
|  4 | [1, 2, 7, 8] |
+----+--------------+
4 rows in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_OVERLAPS(info, '[5]');
+----+-----------+
| id | info      |
+----+-----------+
|  1 | [1, 2, 5] |
|  2 | [2, 5, 6] |
+----+-----------+
2 rows in set (0.00 sec)mysql> SELECT * FROM student WHERE JSON_OVERLAPS(info, '[9]');
Empty set (0.00 sec)

(8)JSON ARRAY的多值索引

从MySQL8.0.17开始,InnoDB支持多值索引。多值索引是在存储JSON数组的列上定义的辅助索引,对于JSON ARRAY的MEMBER OF,JSON_CONTAINS,JSON_OVERLAPS可以利用多值索引进行性能优化

mysql> select * from student;
+----+--------------+
| id | info         |
+----+--------------+
|  1 | [1, 2, 5, 9] |
|  2 | [2, 5, 6, 8] |
|  3 | [5, 3, 8, 9] |
|  4 | [1, 2, 7, 8] |
+----+--------------+
4 rows in set (0.00 sec)

先不创建多值索引,使用JSON_CONTAINS语句EXPLAIN查看执行计划

mysql> EXPLAIN SELECT * FROM student WHERE JSON_CONTAINS(info, '[5, 3]');
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

Type为全表扫描,key为NULL,下一步给表增加多值索引,注意如果这个地方改为idx_info((cast((info->"$") as unsigned array))),则后续所有的函数都要是info->"$",否则走不了索引

mysql> ALTER TABLE student ADD INDEX idx_info((cast(info as unsigned array)));
Query OK, 0 rows affected (0.57 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看建立多值索引之后的EXPLAIN计划,可见现在JSON操作函数都走了索引

mysql> EXPLAIN SELECT * FROM student WHERE 5 MEMBER OF(info);
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ref  | idx_info      | idx_info | 9       | const |    1 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)mysql> EXPLAIN SELECT * FROM student WHERE JSON_CONTAINS(info, '[5, 3]');
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | range | idx_info      | idx_info | 9       | NULL |    4 |   100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)mysql> EXPLAIN SELECT * FROM student WHERE JSON_OVERLAPS(info, '[5, 3]');
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | range | idx_info      | idx_info | 9       | NULL |    4 |   100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

(9)基于JSON类型的用户画像设计

下面基于30万级别的数据,以MySQL的JSON做用户画像的存储和查询测试,画像值已经全部处理成枚举值,不加入数值型的字段,第一步梳理用户标签,定义一张标签表,记录标签值和标签号

mysql> CREATE TABLE tags_info (->     tag_id bigint auto_increment primary key,->     tag_name varchar(255) not null,->     tag_value varchar(255) not null-> );
Query OK, 0 rows affected (0.80 sec)

插入所有的标签,预览表如下

mysql> select * from tags_info order by rand() limit 10;
+--------+--------------+--------------------+
| tag_id | tag_name     | tag_value          |
+--------+--------------+--------------------+
|     24 | 渠道名称     | 自助收银           |
|     38 | 类目范围     | 类目多样           |
|      3 | 生日月份     | 1                  |
|     35 | RFM          | 重要保持会员       |
|     11 | 生日月份     | 9                  |
|     44 | 时间偏好     | 常客               |
|     16 | 会员等级     | 员工卡             |
|     27 | 会员状态     | 沉默               |
|     25 | 渠道名称     | 闪电购             |
|     43 | 时间偏好     | 周末客             |
+--------+--------------+--------------------+

下一步构建用户画像表,标签值替换为标签ID,将一个用户的所有标签值存储为JSON ARRAY,先构建一张用户画像结果表

mysql> CREATE TABLE user_tag (->     user_id bigint not null primary key,->     user_tags JSON-> );
Query OK, 0 rows affected (0.41 sec)

插入数据查看预览结果

mysql> select * from user_tag order by rand() limit 10;
+---------+--------------------------------------+
| user_id | user_tags                            |
+---------+--------------------------------------+
|   36978 | [14, 19, 23, 25, 32, 42]             |
|   28515 | [14, 19, 23, 27, 36, 42]             |
|   28683 | [14, 19, 28]                         |
|   39368 | [14, 19, 24, 26, 36, 43]             |
|   22269 | [14, 19, 28]                         |
|   42160 | [14, 19, 23, 26, 32, 43]             |
|   22321 | [14, 17, 27, 33, 40, 43, 44, 47, 49] |
|   20407 | [14, 19, 20, 25, 34, 38, 43]         |
|   26167 | [14, 17, 23, 27, 35, 38, 43]         |
|   38082 | [14, 19, 25, 32, 42]                 |
+---------+--------------------------------------+
10 rows in set (0.00 sec)

下一步对用户画像进行标签筛选指定的人群做营销,实际上转化为SQL就是多个条件的与或非组合,看几个案例
(1)取用户等级是白银卡(17)或者银卡(20),且用户状态是活跃的(28),逻辑是(17∪20)∩28,33万里面筛选出265个人

mysql> SELECT * FROM user_tag WHERE JSON_OVERLAPS(user_tags, '[18, 17, 20]') AND JSON_CONTAINS(user_tags, '[28]') limit 5;
+---------+------------------+
| user_id | user_tags        |
+---------+------------------+
|    3201 | [14, 19, 20, 28] |
|    4183 | [14, 19, 20, 28] |
|    4554 | [14, 19, 20, 28] |
|    4890 | [14, 19, 20, 28] |
|    6334 | [14, 17, 28]     |
+---------+------------------+mysql> SELECT count(*) FROM user_tag WHERE JSON_OVERLAPS(user_tags, '[18, 17, 20]') AND JSON_CONTAINS(user_tags, '[28]');
+----------+
| count(*) |
+----------+
|      265 |
+----------+
1 row in set (0.66 sec)

(2)筛选母婴客群(47)且是周末客(43),但是过滤掉流失会员(29),逻辑是47∩43∩(not 29),最终结果筛选出11678人

mysql> SELECT * FROM user_tag WHERE JSON_CONTAINS(user_tags, '[43, 47]') AND NOT JSON_CONTAINS(user_tags, '[29]') limit 10;
+---------+----------------------------------------------+
| user_id | user_tags                                    |
+---------+----------------------------------------------+
|    3036 | [14, 17, 24, 27, 33, 37, 40, 43, 44, 47, 48] |
|    3049 | [14, 17, 27, 33, 38, 40, 43, 44, 47, 48]     |
|    3072 | [14, 19, 20, 27, 33, 37, 40, 43, 44, 47, 48] |
|    3099 | [14, 19, 21, 27, 33, 37, 40, 43, 44, 47]     |
|    3110 | [14, 15, 27, 33, 37, 40, 43, 44, 46, 47, 48] |
|    3127 | [14, 19, 20, 27, 33, 37, 40, 43, 44, 46, 47] |
|    3132 | [14, 19, 27, 33, 40, 41, 43, 44, 47]         |
|    3147 | [14, 17, 27, 34, 40, 43, 46, 47, 48]         |
|    3157 | [14, 19, 23, 26, 34, 43, 47, 48]             |
|    3160 | [14, 19, 23, 27, 34, 40, 43, 44, 47, 48]     |
+---------+----------------------------------------------+
10 rows in set (0.00 sec)mysql> SELECT count(*) FROM user_tag WHERE JSON_CONTAINS(user_tags, '[43, 47]') AND NOT JSON_CONTAINS(user_tags, '[29]');
+----------+
| count(*) |
+----------+
|    11678 |
+----------+
1 row in set (0.55 sec)

(3)筛选RFM为重要开头的高价值客户(34,35,36,37),且是微信会员(15),逻辑是(34∪35∪36∪37)∩15,最终筛选出148人

mysql> SELECT * FROM user_tag WHERE JSON_OVERLAPS(user_tags, '[34, 35, 36, 37]') AND JSON_CONTAINS(user_tags, '[15]') limit 10;
+---------+--------------------------------------------------------+
| user_id | user_tags                                              |
+---------+--------------------------------------------------------+
|    3110 | [14, 15, 27, 33, 37, 40, 43, 44, 46, 47, 48]           |
|    6990 | [14, 15, 23, 27, 34, 37, 40, 43, 44, 47, 48, 49]       |
|   11214 | [14, 15, 24, 27, 33, 37, 40, 43, 44, 47]               |
|   13447 | [0, 2, 14, 15, 27, 33, 37, 40, 43, 44, 46, 47, 48]     |
|   18356 | [14, 15, 25, 34, 38, 43]                               |
|   22016 | [1, 2, 14, 15, 27, 33, 37, 40, 43, 44, 46, 47, 48, 49] |
|   22392 | [14, 15, 23, 27, 33, 37, 40, 41, 43, 44, 48, 49]       |
|   22721 | [1, 7, 14, 15, 27, 33, 37, 40, 42, 44, 48]             |
|   22800 | [14, 15, 23, 27, 33, 37, 40, 43, 44, 48]               |
|   25122 | [14, 15, 26, 34, 37, 40, 43, 47, 48, 49]               |
+---------+--------------------------------------------------------+
10 rows in set (0.06 sec)mysql> SELECT count(*) FROM user_tag WHERE JSON_OVERLAPS(user_tags, '[34, 35, 36, 37]') AND JSON_CONTAINS(user_tags, '[15]');
+----------+
| count(*) |
+----------+
|      148 |
+----------+
1 row in set (0.75 sec)

给这张用户画像表增加一下多值索引

ALTER TABLE user_tag ADD INDEX idx_info((cast(user_tags as unsigned array)));

结果是SQL不能得到正确结果,之前能检索到人群现在检索结果为符合条件的人为0,可能是在多值索引的情况下,不能组合多个JSON函数的原因

mysql> SELECT count(*) FROM user_tag WHERE JSON_OVERLAPS(user_tags, '[34, 35, 36, 37]') AND JSON_CONTAINS(user_tags, '[15]');
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

另外在多次测试下,就算不使用JSON函数组合,单个使用JSON_CONTAINS,JSON_OVERLAPS也可能会导致索引失效,具体原因不明,如果使用NOT条件多值索引直接失效

最后编辑于:2025-02-05 20:55:48


喜欢的朋友记得点赞、收藏、关注哦!!!

相关文章:

MySQL:MySQL8.0 JSON类型使用整理,基于用户画像的案例

摘要:MySQL,JSON类型,多值索引, 用户画像 MySQL是结构化数据存储,JSON是非结构化格式,在MySQL中使用JSON类型可以打通关系型和非关系型数据的存储之间的界限,为业务提供更好的架构选择&#xff…...

Python MoviePy 视频处理全攻略:从入门到实战案例

第1章 环境安装与配置 # 案例1:安装MoviePy及FFmpeg !pip install moviepy # Windows安装FFmpeg:https://ffmpeg.org/download.html # Linux: sudo apt-get install ffmpeg# 验证安装 from moviepy.editor import * print("MoviePy版本:", __…...

30道Qt面试题(答案公布)

前五个答案 ✦ 1. Qt中常用的五大模块是哪些? Qt中常用的五大模块包括: • Qt Core:提供核心非GUI功能,如数据结构、文件操作、国际化等。 • Qt GUI:提供与平台无关的图形和基本窗口功能。 • Qt Widgets:提供用于创建传统桌面应用程序的UI组件。 • Qt Netw…...

深入解析 MySQL 数据删除操作:DELETE、TRUNCATE 与 DROP 的原理与选择

引言 在 MySQL 中,删除数据或表结构的操作看似简单,但不同操作(如 DELETE、TRUNCATE、DROP)背后的原理和适用场景差异巨大。错误选择可能导致性能问题或数据丢失!本文通过通俗的比喻、流程图和表格,带你深入理解它们的原理与差异。 DELETE 操作的原理 DELETE … IN 执…...

spring cloud gateway限流常见算法

目录 一、网关限流 1、限流的作用 1. 保护后端服务 2. 保证服务质量 (QoS) 3. 避免滥用和恶意攻击 4. 减少资源浪费 5. 提高系统可扩展性和稳定性 6. 控制不同用户的访问频率 7. 提升用户体验 8. 避免API滥用和负载过高 9. 监控与分析 10. 避免系统崩溃 2、网关限…...

华为FusionCompute虚拟化平台

一、华为FusionCompute虚拟化套件介绍 华为FusionCompute虚拟化套件是业界领先的虚拟化解决方案,能够帮助客户带来如下的价值,从而大幅提升数据中心基础设施的效率。 帮助客户提升数据中心基础设施的资源利用率;帮助客户成倍缩短业务上线周期…...

自然语言处理入门1——单词的表示和距离

随着DeepSeek的火爆,AI大模型越来越被大众所接受,我们在日常生活和工作学习中也开始越来越频繁的使用豆包、通义千问、Kimi、DeepSeek、文心一言等大模型工具了。这些大模型底层技术都是Transformer模型,属于自然语言处理范畴。 今天开始&am…...

UART(一)——UART基础

一、定义 UART(Universal Asynchronous Receiver/Transmitter)是一种广泛使用的串行通信协议,用于在设备间通过异步方式传输数据。它无需共享时钟信号,而是依赖双方预先约定的参数(如波特率)完成通信。 功能和特点 基本的 UART 系统只需三个信号即可提供稳健的中速全双工…...

【数据结构初阶第十节】队列(详解+附源码)

好久不见。。。别不开心了,听听喜欢的歌吧 必须有为成功付出代价的决心,然后想办法付出这个代价。云边有个稻草人-CSDN博客 目录 一、概念和结构 二、队列的实现 Queue.h Queue.c test.c Relaxing Time! ————————————《有没…...

确保设备始终处于最佳运行状态,延长设备的使用寿命,保障系统的稳定运行的智慧地产开源了

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。通过计算机视觉和…...

SP字体UI放大代码

代码: echo off set QT_SCALE_FACTOR放大倍数 start "" "你的SP.exe启动路径"...

信息安全之网络安全防护

信息安全之网络安全防护 先来看看计算机网络通信面临的威胁: 截获——从网络上窃听他人的通信内容中断——有意中断他人在网络上的通信篡改——故意篡改网络上传送的报文伪造——伪造信息在网络上传送 截获信息的攻击称为被动攻击,而更改信息和拒绝用…...

idea无法联网,离线安装插件

插件地址:https://plugins.jetbrains.com/ JetBrains Marketplace 如果无法进入,可以试试 配置hosts 3.163.125.103 plugins.jetbrains.com ip 变了,可以查询个最新的: https://tool.chinaz.com/speedtest/plugins.jetbrai…...

数据结构——哈希表

一、哈希表 1.1 哈希表的概念 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函…...

学习查看 linux 关于进程的文件信息 cat /proc/968/status

(1) 在 Linux 系统中,/proc 文件系统是一个伪文件系统,提供了一个接口来访问内核数据结构。/proc/[pid]/status 文件包含了关于特定进程的状态信息。当你运行 cat /proc/968/status 时,它会输出与进程 ID 为 968 的进程…...

记一次一波三折的众测SRC经历

视频教程和更多福利在我主页简介或专栏里 (不懂都可以来问我 专栏找我哦) 目录: 前言 波折一:RCE漏洞利用失败 波折二:SQL时间盲注 波折三:寻找管理后台 总结 前言 先谈个人SRC心得体会吧,我虽…...

python绘图之箱型图

箱型图(Boxplot),也称为箱线图或盒须图,是一种用于展示一组数据的分布情况的统计图表。它通过简洁的图形形式,直观地呈现数据的集中趋势、离散程度、偏态以及异常值等信息。本节我们来学习使用python绘制箱型图 # 导入…...

http 响应码影响 video 标签播放视频

背景 使用后端给的文件下载接口地址实现视频播放,但是 video 标签一直无法播放视频如下图,把接口地址放到浏览器请求能直接下载。但就是不能播放 原因 http 响应码不正确,返回201是无法播放视频200可以如下图 状态码的影响: 20…...

【ClickHouse 特性及应用场景】

Clickhouse是一个用于联机分析处理(OLAP)的列式数据库管理系统(columnar DBMS)。 传统数据库在数据大小比较小,索引大小适合内存,数据缓存命中率足够高的情形下能正常提供服务。但残酷的是,这种…...

【基础架构篇九】《DeepSeek模型版本管理:Git+MLflow集成实践》

各位在模型迭代中反复去世的炼丹师们,扔掉你们那些混乱的v1.2.3_final_fix2模型压缩包!今天我们不聊什么单纯的Git分支管理,也不讲MLflow的入门教程,而是直接掀开算法迭代的黑箱,手把手教你用"外科手术级"的版本控制方案,让模型迭代从玄学变成精准的流水线作业…...

EasyExcel 自定义头信息导出

需求:需要在导出 excel时,合并单元格自定义头信息(动态生成),然后才是字段列表头即导出数据。 EasyExcel - 使用table去写入:https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E4%BD%BF%E7%94%A8table%E…...

MySQL 之INDEX 索引(Index Index of MySQL)

MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键 key,索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引,保证数…...

Linux驱动学习(二)--字符设备

设备分类 字符设备块设备网络设备 内核结构图&#xff1a; 字符设备号 字符设备号是32位的无符号整型值 高12位&#xff1a;主设备号低20位&#xff1a;次设备号 查看设备号 cat /proc/devices 设备号构造 直接使用宏MKDEV #define MKDEV(ma,mi) (((ma) << MINORBITS…...

计算机毕业设计--基于深度学习技术(Yolov11、v8、v7、v5)算法的高效人脸检测模型设计与实现(含Github代码+Web端在线体验界面)

基于深度学习技术&#xff08;Yolov11、v8、v7、v5&#xff09;算法的高效人脸检测模型 Yolo算法应用之《基于Yolo的花卉识别算法模型设计》&#xff0c;请参考这篇CSDN作品&#x1f447; 计算机毕业设计–基于深度学习技术&#xff08;Yolov11、v8、v7、v5&#xff09;算法的…...

leetcode-414.第三大的数

leetcode-414.第三大的数 code review! 文章目录 leetcode-414.第三大的数一.题目描述二.代码提交 一.题目描述 二.代码提交 class Solution { public:int thirdMax(vector<int>& nums) {set<int> set_v(nums.begin(), nums.end());auto it set_v.rbegin()…...

使用API有效率地管理Dynadot域名,参与过期域名竞价

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…...

iOS 上自定义编译 FFmpeg

在 iOS 上自定义编译 FFmpeg 是一个复杂但非常灵活的过程。通过自定义编译,您可以选择启用或禁用特定的功能和编解码器,以满足项目的需求,同时减少二进制文件的大小。 1. 自定义编译 FFmpeg 1.1 准备工作 在开始编译之前,您需要以下工具和环境: macOS:运行编译的主机。…...

解锁 JavaScript 异步编程:Promise 链式操作、async/await 与 Promise.all 深度剖析

1.引言 在 JavaScript 的世界里,异步编程是一个核心且关键的概念。随着 Web 应用的复杂度不断提升,处理多个异步操作的需求也日益增长。传统的回调函数方式容易陷入 “回调地狱”,让代码的可读性和可维护性大打折扣。而 Promise 的出现为异步编程带来了新的曙光,后续又衍生…...

30 款 Windows 和 Mac 下的复制粘贴软件对比

在日常电脑操作中&#xff0c;复制粘贴是极为高频的操作&#xff0c;一款好用的复制粘贴软件能极大提升工作效率。以下为你详细介绍 30 款 Windows 和 Mac 下的复制粘贴软件&#xff0c;并对比它们的优缺点&#xff0c;同时附上官网下载地址&#xff0c;方便大家获取软件。 Pa…...

复现论文:DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization

论文&#xff1a;[2403.16697] DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization github: TYLfromSEU/DPStyler: DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization 论文: 这篇论文还是在PromptStyler:Prompt-driven Style Gener…...

【数据库维护】Clickhouse数据库维护关键系统表相关指标说明,支撑定位慢SQL及多实例场景下分析各实例运行情况

背景 当前使用环境上以Docker容器化部署Clickhouse服务8个实例&#xff0c;但在实际运行过程中&#xff0c;发现8个实例内存负载不均衡&#xff0c;ck-0实例在固定时间段内存会直线上升&#xff0c;直至服务报错memory exceeded max memory limit。 为排查ck-0节点内存直线上升…...

java爬虫抓取网页搜索数据

首先访问这个使用必应并搜索想要的内容 https://www.bing.com/images/search?q[把这里替换成想要的搜索内容] 按下f12来查看源码 我们可以找到a.iusc这个元素可以获取图片的源地址 注意&#xff0c;直接选中网页上的图片只能看到它的缩略图在哪。 由此可以编写出来爬虫脚本来…...

智能编程助手功能革新与价值重塑之:GitHub Copilot

引言&#xff1a; GitHub Copilot 的最新更新为开发者带来了显著变化&#xff0c;其中 Agent Mode 功能尤为引人注目。该模式能够自动识别并修复代码错误、自动生成终端命令&#xff0c;并具备多级任务推理能力&#xff0c;这使得开发者在开发复杂功能时&#xff0c;可大幅减少…...

Linux3-文件io、时间有关函数

一、前情回顾 1.当scanf输入10\n直接结束程序&#xff0c;因为scanf接收了10&#xff0c;fgets&#xff08;接收了\n结束程序&#xff09;&#xff0c; 因此可以加一个getchar();消耗一个\n。 2.fgets();所接收的\n利用buff[strlen(buff)-1]0; 二、文件io 1.目的&#xff1a…...

VScode运行C语言提示“#Include错误,无法打开源文件stdio.h”

C/C环境配置 参考&#xff1a; VS Code 配置 C/C 编程运行环境&#xff08;保姆级教程&#xff09;_vscode配置c环境-CSDN博客 基本步骤 - 安装MinGW-W64&#xff0c;其包含 GCC 编译器&#xff1a;bin目录添加到环境变量&#xff1b;CMD 中输入gcc --version或where gcc验证…...

【Linux】线程全解:概念、操作、互斥与同步机制、线程池实现

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;一、线程概念 &#x1f4d6; 回顾进程 &#x1f4d6; 引入线程 &#x1f4d6; 总结 &a…...

【第4章:循环神经网络(RNN)与长短时记忆网络(LSTM)— 4.3 RNN与LSTM在自然语言处理中的应用案例】

咱今天来聊聊在人工智能领域里,特别重要的两个神经网络:循环神经网络(RNN)和长短时记忆网络(LSTM),主要讲讲它们在自然语言处理里的应用。你想想,平常咱们用手机和别人聊天、看新闻、听语音助手说话,背后说不定就有 RNN 和 LSTM 在帮忙呢! 二、RNN 是什么? (一)…...

平板作为电脑拓展屏

有线串流&#xff08;速度更快&#xff09; spacedesk 打开usb对安卓的连接 用usb线直接连接电脑和平板 无线串流&#xff08;延迟高&#xff0c;不推荐&#xff09; todesk pc和手机端同时下载软件&#xff0c;连接后可以进行远程控制或扩展屏幕 spacedesk 连接到同一个…...

【Spring+MyBatis】留言墙的实现

目录 1. 添加依赖 2. 配置数据库 2.1 创建数据库与数据表 2.2 创建与数据库对应的实体类 3. 后端代码 3.1 目录结构 3.2 MessageController类 3.3 MessageService类 3.4 MessageMapper接口 4. 前端代码 5. 单元测试 5.1 后端接口测试 5.2 使用前端页面测试 在Spri…...

Redis的简单使用

1.Redis的安装Ubuntu安装Redis-CSDN博客 2.Redis在Spring Boot 3 下的使用 2.1 pom.xml <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifac…...

IDEA集成DeepSeek AI助手完整指南

在当今快速发展的软件开发领域,AI辅助编程工具正在成为开发者的重要助手。本文将详细介绍如何在IDEA中集成DeepSeek AI助手,帮助开发者提升编程效率。 一、环境准备 © ivwdcwso (ID: u012172506) 1.1 IDEA版本要求 在开始集成之前,需要确保你的IDEA版本满足要求: …...

rust学习笔记1-window安装开发环境

1.登录官网下载https://www.rust-lang.org/zh-CN/tools/install 下载 rustup-init.exe。 2.设置环境变量 &#xff08;1&#xff09;在指定路径新建.cargo和.rustup文件夹 CARGO_HOME RUSTUP_HOME &#xff08;2&#xff09;配置rustup下载源镜像 提高rust安装组件下载速…...

【钱包】【WEB3】【Flutter】一组助记词如何推导多个账号钱包

一、前言 一组助记词可以推导多个账户&#xff0c;是因为在区块链钱包中&#xff0c;助记词&#xff08;Mnemonic&#xff09;实际上是 BIP39 标准下生成的一个种子&#xff0c;该种子通过 BIP32/BIP44 标准可以派生出无限多个账户地址。 这里我将以太坊Ethereum为例&#xf…...

基于SSM+Vue的智能汽车租赁平台设计和实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...

Zotero PDF Translate插件配置百度翻译api

Zotero PDF Translate插件可以使用几种翻译api&#xff0c;虽然谷歌最好用&#xff0c;但是由于众所周知的原因&#xff0c;不稳定。而cnki有字数限制&#xff0c;有道有时也不行。其他的翻译需要申请密钥。本文以百度为例&#xff0c;进行申请 官方有申请教程&#xff1a; Zot…...

深度学习05 ResNet残差网络

目录 传统卷积神经网络存在的问题 如何解决 批量归一化BatchNormalization, BN 残差连接方式 ​残差结构 ResNet网络 ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出&#xff0c;斩获当年ImageNet竞赛中分类任务第一名&#xff0c;目标检测第一名。获得CO…...

【Python项目】文本相似度计算系统

【Python项目】文本相似度计算系统 技术简介&#xff1a;采用Python技术、Django技术、MYSQL数据库等实现。 系统简介&#xff1a;本系统基于Django进行开发&#xff0c;包含前端和后端两个部分。前端基于Bootstrap框架进行开发&#xff0c;主要包括系统首页&#xff0c;文本分…...

【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析④】

ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase04 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月17日 关键词&#xff1a;UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 TC11-004测试用例 用例ID测试场景验证要点参考条款预期结果TC…...

机器学习:k近邻

所有代码和文档均在golitter/Decoding-ML-Top10: 使用 Python 优雅地实现机器学习十大经典算法。 (github.com)&#xff0c;欢迎查看。 K 邻近算法&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;是一种经典的机器学习算法&#xff0c;主要用于分类和回归任务…...

Pytorch实现论文之一种基于扰动卷积层和梯度归一化的生成对抗网络

简介 简介:提出了一种针对鉴别器的梯度惩罚方法和在鉴别器中采用扰动卷积,拟解决锐梯度空间引起的训练不稳定性问题和判别器的记忆问题。 论文题目:A Perturbed Convolutional Layer and Gradient Normalization based Generative Adversarial Network(一种基于扰动卷积层…...