Mysql 内外链接,索引,事务,用户管理以及用C语言链接Mysql

news2024/11/19 23:23:25

文章目录

    • 内外链接
    • 索引
      • 索引的相关操作
      • 全文索引
    • 事务
      • 事务的操作
      • 事务的隔离级别
      • 隔离级别
      • 3个记录隐藏列字段
    • 用户管理
      • 权限修改
    • 使用C语言链接数据库

内外链接

两张表直接做笛卡尔积为内连接,之前使用的都是内连接
两张表:stu和exam
image.png

将两张表进行连接:
image.png
内连接:

select * from 表1 inner join 表2 on 约束条件

表与表之间用inner join连接,之后用on表示内连接的约束条件
外连接:左外连接

select * from  表1 left join 表2 on 约束条件

以左表为主,根据约束显示右表的信息,若左表没有对应右表的信息,那么右表显示null
image.png
右外连接

select * from  表1 right join 表2 on 约束条件

以右表为主,根据约束显示左表的信息,若右表没有对应左表的信息,那么左表显示null


索引

根据冯诺依曼体系,mysql中的所有操作,本质上都是对内存的操作,在一段时间后,mysql会将数据刷新到磁盘中(进行持久化操作)
mysql的所有操作都会被转换成对文件系统的操作,最终转换成对硬件的操作
所以数据库的底层依赖于文件系统,要了解数据库必须要先了解文件系统
读取文件就意味着读取磁盘,相比于读取内存,读取磁盘非常慢,所以在进行文件查找时,尽可能地减少随机查找次数(减少IO次数)是关键

总之,索引以降低增删改的速度为代价,提高了查询速度。索引用于支持海量数据的查询

磁盘的基本单位为512字节,mysql的innodb引擎使用16KB进行IO交互,这个基本单位由mysql自己维护,通过以下命令查看mysql交互的基本单位

show global status like 'innodb_page_size';

image.png

主键的特性:若建表时指定主键,那么所有的记录都会按照主键的大小进行排序
image.png

为什么要排序?为了之后的索引做准备

主键索引

  1. 具有主键的表,每张表有一个B+树
  2. 若没有主键,mysql会生成隐藏主键(可以认为所有的数据都是线性组织的,隐藏主键的索引效率低,因为主键隐藏,所以无法根据主键进行查找)
  3. B+树也是按需加载到内存的

B+树vsB树
B+树的路上节点没有保存实际数据,而只保存目录信息,这是为了使这颗树更加矮胖
B+树的叶子节点相连,利于范围查找
聚簇vs非聚簇
B+树和数据耦合在一起,这种索引被成为聚簇索引,典型引擎Innodb
非聚簇索引,如MyISAM,叶子节点存储数据的起始地址,根据地址进行二次寻址

选择索引的两个原则:1. 列的使用频率高 2. 重复的数据较少(对于非主键索引)
InnoDB中,对于非主键索引,B+树叶子节点存储记录的主键值,先通过非主键索引查询该记录的主键,再进行回表,通过主键索引查询整条记录
为什么非主键索引只存储主键值?相比于存储整条记录,更节约空间(时间换空间)
MyISAM中,创建一个索引就构建一颗B+,和InnoDB一样,但是其叶子节点存储的是数据文件的地址指针,不是主键值,因为MyISAM是非聚簇索引

索引的相关操作

主动创建索引

alter table 表名 add index(列名); // 对表中的列建立索引

image.png

被动创建方式
添加主键约束后,自动生成主键索引
建表时,添加主键约束

create table 表名(id int primary key, name varchar(30));
create table 表名(id int, name varchar(30), primary key(id));

建表后,添加主键约束

alter table 表名 add primary key(id);
create index 索引名 on 表名(列名)

建表后,删除主键约束

alter table 表明 drop primary key:

唯一索引,添加unique约束后,自动添加唯一索引(普通索引)
删除普通索引:`

alter table drop index 含有索引的列名/索引名

普通索引Key属性显示为:MUL
image.png

查看表的索引

show index from 表名 \G

image.png

其中:key_name为索引名,除了主键索引,其他索引的名字都是列名(用alter创建的索引)
image.png

用create可以创建自定义的索引名,不过不建议这样
创建复合索引时,需要注意,索引名为第一个索引的名字
image.png

全文索引

创建全文索引

alter table 表名 add fulltext 索引名(列名);

MyISAM支持全文索引,而InnoDB不支持
有大量的查找需要时,使用MyISAM引擎(博客系统),大量的修改需要时,使用InnoDB引擎(购物系统)
全文索引是指:当列信息很大时,where(模糊)筛选该列的效率变得很低,因为每个数据都很大,此时就需要使用全文索引

select * from 要搜索的表名 where match(包含文本的列名) against('用来搜索的内容');

事务

一个或者多个sql语句的集合就是事务

(直接输入的一条命令也是事务)
事务这个概念不是数据库天然具有的,而是后续引入的,目的是为了简化上层的编程逻辑

InnoDB支持事务,MyISAM不支持事务

为什么需要事务?保证操作的原子性
事务的四个属性:

  1. 原子性:事务要么执行完,要么没有被执行,不存在中间态,若事务在执行过程中发生错误,将进行回滚,回滚到事务执行前的状态
  2. 持久性:事务处理完成后,对数据的修改是永久(持久)的,即数据刷新到磁盘,若系统故障也不会影响之前的事务
  3. 隔离性:事务之间互相独立,互不影响
  4. 一致性:事务开始之前与结束的时候,数据库的完整性不会被破坏,即事务的行为是可预测的

前三个特性由数据库实现,最后一个特性——一致性是实现前三个特性后的表现,也是一个上层概念
从技术上看,其他三个性质保证了一致性。但是从数据上看,一致性由业务逻辑决定,只有业务的逻辑保证了数据的一致,才能体现一致性

事务的操作

开启事务:begin或者start transaction
结束事务:commit
设置保存点:savepoint 保存点名字
回滚事务:rollback,默认回滚到最开始,即使存在很多保存点
回滚到指定保存点:rollback to 保存点名字
事务被提交后,不能rollback
若事务执行过程中,客户端崩溃,事务自动回滚到最开始

其中事务分为手动提交和自动提交两种方式
查看自动提交是否开启

show variables like 'autocommit'

关闭自动提交

set autocommit=0

begin启动事务后,无论是否设置自动提交autocommit,之后的语句都不会提交,只有执行commit后才会提交事务。若commit之前发生异常,那么未commit的语句将被撤销
自动提交只影响单语句(不使用begin)的sql事务,若关闭自动提交,执行完事务一定要记得commit

事务的隔离级别

隔离级别有三类:全局隔离级别、会话隔离级别、默认隔离级别
隔离级别的查看

select @@global.tx_isolation;   // 查看全局隔离级别
select @@session.tx_isolation;  // 查看会话隔离级别
select @@tx_isolation;          // 查看当前隔离级别

每次会话时,隔离级别的初始化顺序:全局隔离级别->会话隔离级别->默认隔离级别
隔离级别的设置

set global transction isolation level 隔离级别;   // 设置全局隔离级别
set session transaction isolation level 隔离级别; // 设置会话隔离级别
set transaction isolation level 隔离级别;         // 设置默认隔离级别

隔离级别为:read uncommitted、read committed、repeatable read或 serializable中的一个

会话隔离级别指的是:本次与mysql连接(会话)设置的隔离级别,不会影响下一次会话
全局影响会话和默认,会话影响默认,但不影响全局隔离级别

设置全局隔离级别后,需要退出重新登录,此时会话隔离级别和默认隔离级别才会被修改
设置会话隔离级别后,直接影响默认隔离级别

隔离级别

  • 读未提交(read uncommitted):一个客户端的事务执行到一半,另一个客户端能看到你未提交的数据。隔离级别最低,等价于没有隔离,容易引起并发问题,读到其他客户端“读未提交”的数据时,被称为“脏读”
  • 读提交(read committed):也叫不可重复读,一个客户端的事务提交后,不论其他客户端是否在事务中,都能看到提交的数据。若事务未提交,其他客户端无法看到未提交的数据。该隔离级别下,不同时间点读取的数据可能会不同
  • 可重复读(repeatable read):只要当前事务不提交,无论何时读取到的数据都是一样的。有些数据库在可重复读状态下,无法屏蔽其他事务的insert提交,此时读取到的数据与之前相比增加了,这种现象称为幻读。而mysql解决了幻读问题
  • 串行化(serializable):除了读取语句select之外,其他事务都会串行执行,不允许并发,即一个事务未提交之前,其他事务的更新或者插入操作都将被阻塞,直到该事务提交

RR在并发访问时,多个客户端进行修改操作,只要不更新出相同主键的记录或者同时修改同一条记录就不会导致阻塞

3个记录隐藏列字段

向表插入记录时,还插入了一些不可见的数据

  • DB_TRX_ID:6 byte,最近修改/插入的事务ID
  • DB_ROLL_PTR:7 byte,回滚指针,执行这条记录的上一个版本,一般在undo log中
  • DB_ROW_ID:6 byte,隐含的自增ID(隐藏主键),若没有指定主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
  • 还有一个隐藏字段flag:用来表示数据是否被删除

日志不仅仅是执行记录,mysql中的日志具有功能性和数据保存能力
以下说法不准确,但是好理解:
修改(update)记录时,加锁,将数据拷贝到undo log中,原数据的DB_ROW_PTR指向undo log中拷贝记录的地址,修改原数据的DB_TRX_ID为修改其的事务ID,并修改该记录
若其他事务或者当前事务再修改该记录,那么undo log中的拷贝记录和被修改记录之间就会形成一条版本链,由DB_ROW_PTR链接
那么回滚的本质就是用版本链中的记录覆盖当前记录

但undo long保存的是与修改语句相反的语句(不是上一条记录),回滚操作就是不断执行相反操作
这些相反操作为版本链中的一个个版本,也被称为快照
若当前事务commit,所有快照被清理

insert不会形成版本链,update和delete会形成版本链
为select维护版本链没有意义,但是select读取的是什么时候的数据?
读取分为两种:当前读与快照读。当前读需要加锁,而增删改也是一种特殊的当前读
由隔离级别决定当前读与快照读,快照读时,可以做到读写分离,提高并发性
虽然事务的执行顺序可能交织在一起,但事务的到来时间有先有后,事务到来的先后顺序由事务ID体现,越新的事务,ID越大
理论上说,先来的事务不应该看到后来事务的修改,后来的事务应该要看到先来事务的修改,让不同事务看到该看的内容。但让不同事务看到什么程度,由隔离级别决定

事务在读取时,会生成一个Read View类的对象,用来决定事务的可见版本
几乎同时启动的事务,后者能否看到前者修改并且提交的记录,取决于后者什么时候进行快照读(Read View对象何时生成)
Read View中存在这几个成员变量:

m_ids;          // 保存Read View生成时,mysql中活跃(begin但未commit)的事务ID
up_limit_id;    // 保存m_ids中的最小值
low_limit_id;   // 保存Read View生成时,系统尚未分配的最小事务ID,即已经分配过的事务ID+1
creator_trx_id; // 创建该Read View的事务ID

在RR隔离级别下,第一次select操作将形成快照,生成Read View对象。接着select将根据记录的历史版本链(含有对该记录操作过的事务ID),读取最近可见事务ID的修改记录
可见ID:

  • ID小于up_limit_id(比活跃ID的最小值还小)
  • ID大于等于low_limit_id(比活跃ID的最大值还大)
  • m_ids为空(形成快照时,没有活跃事务)
  • ID没有出现在m_ids(不是活跃ID)

在所有可见ID中选择最近(最后一次修改该记录)的版本读取
所以在RR隔离级别下,select快照读读取的是哪个版本的记录,取决于第一次select的时间
而RR和RC的区别在于是否会重复形成Read View

  • RC隔离级别下,每一次select都会形成快照
  • RR隔离级别下,只有第一次select会形成快照

正是因为RC每次select时都会形成快照,所以每次读取的数据不同(每次的活跃ID不同,可见范围随之变化),产生了不可重复读问题
而RR只有第一次select时才会形成快照,所以没有不可重复读问题


用户管理

mysql自带一个名为mysql的数据库,其中存在一张名为user的表,里面存储了当前mysql下的用户信息
进入名为mysql的数据库,输入

select * from user\G

可查看所有的用户信息
image.png
user:用户名
host:用户的登录IP,localhost表示本机(127.0.0.1)
authentication_string:经过md5摘要后,用户的登录密码

所以,所有对用户的管理工作,本质就是对user表进行的增删查改
我们可以直接insert,以添加用户,但是这样要设置很多其他的字段同时容易写错,不推荐这样做

mysql提供了一系列的语法以更快的添加/管理用户

创建用户

create user '用户名'@'登陆主机/ip' identified by '密码';

image.png
ip可以是localhost,也可以是%(所有IP),也可以是具体的IP

若添加用户失败,则执行刷新当前权限

flush privileges

删除用户

drop user '用户名'@'主机名'

修改用户密码

set password for '用户名'@'主机名'=password('新的密码') 
alter user '用户名'@'主机名'identified by '新的密码'  // 推荐使用

权限修改

grant 权限列表 on 库名.表名 to '用户名'@'主机名' [identified by '密码'](可省略)

表名用*代替,表示该库下的所有表
若权限列表有多个权限,那么权限之间用,分隔,用all代替权限列表,表示所有权限
关于具体的权限,大概列举几个:
image.png

显示用户权限

show grants for '用户名@主机名'

回收用户权限

revoke 权限列表 on 库.对象名 from '用户名'@'主机名';

执行以下命令,使修改生效

flush privileges

使用C语言链接数据库

搜索linux发行版本+安装C语言连接mysql的API库,下载相关环境
rpm -qa | grep mysqldpkg -l | grep mysql以查看系统中是否已经安装了相关安装包
ls /usr/include/mysql,查看相关库的头文件

连接mysql之前需要初始化MYSQL结构体,与FILE类似
MYSQL *msql = mysql_init(NULL),参数一般是空指针
若函数返回NULL,表示是初始化失败
mysql_close(MYSQL *msql),不需要该结构体时,要释放该结构体

初始化MYSQL后,连接mysql

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
								const char *user,
								const char *passwd,
								const char *db,
								unsigned int port,
								const char *unix_socket,
								unsigned long clientflag);
  • mysql:初始化成功的MYSQL结构体
  • host:mysql服务端所在的IP地址
  • user,passwd:用来登录的用户名与密码
  • port:mysql对外开放的端口号
  • unix_socket,clientflag:相应地设置为nullptr和0即可
    函数返回空指针表示连接失败
mysql_set_character_set(MYSQL *mysql, char *charset)

有时会遇到字符集(编码格式)不匹配的情况,连接成功后需要设置当前字符集,通常设置为utf8,mysql_set_character_set(msql, "utf8");

mysql_query(MYSQL *mysql, char *query*)

query:需要执行的sql语句,与命令行操作输入的语句相同
函数返回0表示语句执行成功
使用mysql_query进行增删改时,通过返回值是否为0判断操作是否成功即可
但是使用mysql_query进行查操作(如select)时,就比较麻烦
查操作时,若mysql_query成功,那么查询结果将保存到一开始初始化的MYSQL结构体中

MYSQL_RES *res = mysql_store_result(MYSQL *mysql);

以该结构体指针作为参数调用mysql_store_result函数,将查询结果保存到MYSQL_RES结构体中

int rowcnt = mysql_num_rows(MYSQL_RES *res);
int fieldcnt = mysql_num_fields(MYSQL_RES *res);

以该结构体指针为参数调用mysql_num_rowsmysql_num_fields,返回查询结果的行数与列数

MYSQL_FIELD *fname = mysql_fetch_fields(res);

以该结构体指针为参数调用mysql_fetch_fields函数,列属性的名称将被保存到MYSQL_FIELD结构体中,fname相当于一个数组,数组成员为MYSQL_FIELD,该结构体中的name字段为列属性的名称,即fname[j].name表示第j列的列名

MYSQL_ROW row = mysql_fetch_row(res); // 注意参数名的row没有s

以该结构体指针为参数调用mysql_fetch_row函数,将行信息保存到结构体MYSQL_ROW中,这里用结构体对象接受函数返回值,可以将MYSQL_ROW看成一个数组,长度为列的数量,row[j]第j个成员为第j列的数据,以字符串的形式保存


以下是一个简单使用的demo,该程序将读取标准输入的数据,若是select语句,则将结果打印到标准输出中

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <mysql/mysql.h>
using namespace std;

string host = "127.0.0.1";
string user = "root";
string password = "xx557223";
string db = "test_db";
unsigned int port = 3306;

int main()
{
    // cout << "version: " << mysql_get_client_info() << endl;
    MYSQL *msql = mysql_init(nullptr);
    if (msql == nullptr)
    {
        cerr << "init fail\n";
        return 0;
    }
    if (mysql_real_connect(msql, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "登陆失败\n";
        return 0;
    }
    mysql_set_character_set(msql, "utf8");
    // string sql = "insert into class_tb values(22, '一年b班', 'xxx')";
    // string sql =  "select * from class_tb";
    char str[1024];
    while (true)
    {
        cout << "mysql> ";
        fgets(str, sizeof str, stdin);
        int t = mysql_query(msql, str);
        if (strcasestr(str, "select") && t == 0)
        {
            MYSQL_RES *res = mysql_store_result(msql);
            int rows = mysql_num_rows(res);
            int fields = mysql_num_fields(res);

            MYSQL_FIELD *fname = mysql_fetch_fields(res);
            for (int j = 0; j < fields; ++ j) cout << fname[j].name << "\t|\t";
            cout << "\n";
            MYSQL_ROW line;
            for (int i = 0; i < rows; ++ i)
            {
                line = mysql_fetch_row(res);
                for (int j = 0; j < fields; ++ j)
                    cout << line[j] << "\t|\t";
                cout << "\n";
            }
        }
    }
    // 关闭
    mysql_close(msql);
    return 0;
}

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

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

相关文章

Arya碎碎念 | 我的创作纪念日——写在成为创作者的第1095天

前言 打开博客创作者页面&#xff0c;发现CSDN发送过来一条私信&#xff0c;提醒我3年前发了第一篇博客。3年的时间里&#xff0c;大家都经历了很多事情&#xff0c;疫情 . . . . . 本篇博客是一些碎碎念&#xff0c;作为一个成为1095天创作者的纪念博客。 一、个人优质博客汇…

I2C的硬件实现

因为I2C是同步的&#xff0c;所以相对来说I2C更好用软件来实现&#xff0c;硬件却相对来说没这么好&#xff0c;但是硬件I2C通信也是有其优点的 我们是通过软件写入控制寄存器CR和数据寄存器DR&#xff0c;读取状态寄存器SR来了解外设电路当前处于什么状态&#xff0c;来实现I…

jvm实现的锁优化

目录 轻量级锁 轻量级锁的工作流程 轻量级锁的解锁 偏向锁 偏向锁的流程&#xff1a; 偏向锁和轻量级锁机区别&#xff1a; 其他优化 自旋锁和自适应自旋锁 锁消除 锁粗化 轻量级锁 “轻量级” 是相对于使用操作系统互斥量来实现的传统锁而言的&#xff0c;因此传统的…

Java学习笔记(四)——程序控制结构

一、顺序控制 二、分支控制 &#xff08;一&#xff09;单分支 &#xff08;二&#xff09;双分支 &#xff08;三&#xff09;多分支 &#xff08;四&#xff09;嵌套分支 &#xff08;五&#xff09;switch分支结构 &#xff08;六&#xff09;if和switch的选择 三、循…

Android Studio快速实现Flutter应用的国际化和多语言支持

文章目录 Flutter实现国际化和多语言支持添加依赖库Android Studio 安装flutter Intl插件项目初始化增加语言app中使用国际化在应用中切换语言&#xff1a;运行应用 总结easy_localization 插件intl 包Flutter GetX 包flutter_i18n 插件JSON 文件 Flutter实现国际化和多语言支持…

利用ArcGIS获取每一个冰川的中心位置经纬度坐标:要素转点和要素折点转点的区别

问题概述&#xff1a;下图是天山地区的冰川的分布&#xff0c;我们可以看到每一条冰川是一个面要素&#xff0c;要求得到每一个冰川&#xff08;面要素&#xff09;的中心经纬度坐标。 1.采用要素转点功能 选择工具箱的【数据管理工具】-【要素】-【要素转点】。完成之后再采用…

疯狂堆料!技嘉钛雕Z790 AORUS PRO X主板图赏

技嘉推出了钛雕Z790 AORUS PRO X主板。 现在这款新品已经来到了我们评测室&#xff0c;下面为大家带来图赏。 技嘉钛雕Z790 AORUS PRO X主板采用新一代超耐久显卡插槽&#xff0c;约58KG承重能力、内衬保护显卡PCB。 其采用1812相供电设计&#xff0c;4根双通道DDR5内存插槽&am…

药物滥用第四篇介绍

OXY&#xff1a; 羟考酮&#xff08;Oxycodone&#xff0c;OXY&#xff09;&#xff0c;分子式为C18H21NO4&#xff0c;是一种半合成的蒂巴因衍生物。羟考酮为半合成的纯阿片受体激动药&#xff0c;其作用机制与吗啡相似&#xff0c;主要通过激动中枢神经系统内的阿片受体而起镇…

FastAdmin框架实现数据表的增删改查

目录 简介 增加数据 修改数据 控制器&#xff08;controller&#xff09;代码&#xff1a; 查询数据 控制器&#xff08;controller&#xff09;代码&#xff1a; 模型&#xff08;model&#xff09;代码&#xff1a; 删除数据 控制器&#xff08;controller&#xff0…

2023年农村市场风口新商机:互联网+认养模式商业模式解析

背景&#xff1a;随着城市化进程的不断加快&#xff0c;人们对物质生活的要求和品质日益增高&#xff0c;特别是在疫情过亲身经历过病痛的折磨后&#xff0c;大家对自己的更加爱惜了&#xff0c;今天&#xff0c;微三云营销总监胡佳东发现一套2023年创业新项目新商机&#xff1…

选型销售管理软件要注意哪些问题?

近些年来&#xff0c;创新型企业大量涌现成为国内经济增长的新动能。同时管理者发现很快就遇到了发展瓶颈&#xff0c;为了保证业务的快速开展&#xff0c;引入销售管理软件的需求十分强烈。那么&#xff0c;选型销售管理软件要注意哪些问题? 一、直指痛点的功能 对于多数企…

APP开发成本的影响因素

在温州或中国任何地方开发APP的成本取决于多个因素&#xff0c;包括应用的规模、功能、设计、复杂性以及所需的技术和人力资源。以下是一些可能影响APP开发成本的主要因素&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xf…

风电机浪涌保护器的防雷作用和意义

风电是一种利用风能转化为电能的清洁新能源&#xff0c;具有节约资源、减少污染、降低碳排放等优点。随着风电技术的发展和应用&#xff0c;风电场的规模和数量也不断增加&#xff0c;为人类提供了可持续的电力供应。然而&#xff0c;风电场也面临着一些挑战和风险&#xff0c;…

KingBase库模式表空间和客户端认证(kylin)

库、模式、表空间 数据库 数据库基集簇与数据库实例 KES集簇是由单个KES实例管理的数据库的集合KES集簇中的库使用相同的全局配置文件和监听端口、共享相关的进程和内存结构同一数据库集簇中的进程、相关的内存结构统称为实例 数据库 数据库是一个长期存储在计算机内的、有…

PDF编辑阅读 PDF Expert v3.5.2

PDF Expert是由Readdle开发的一款专业的PDF编辑和阅读工具。它可以帮助用户在Mac、iPad和iPhone等设备上查看、注释、编辑、填写和签署PDF文档。 以下是PDF Expert的特点&#xff1a; PDF编辑&#xff1a;PDF Expert提供了丰富的PDF编辑功能&#xff0c;包括添加、删除、移动…

学习pytorch14 损失函数与反向传播

神经网络-损失函数与反向传播 官网损失函数L1Loss MAE 平均MSELoss 平方差CROSSENTROPYLOSS 交叉熵损失注意code 反向传播在debug中的显示code B站小土堆pytorch视频学习 官网 https://pytorch.org/docs/stable/nn.html#loss-functions 损失函数 L1Loss MAE 平均 import to…

2022年亚太杯APMCM数学建模大赛A题结晶器熔剂熔融结晶过程序列图像特征提取及建模分析求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 A题 结晶器熔剂熔融结晶过程序列图像特征提取及建模分析 原题再现&#xff1a; 连铸过程中的保护渣使钢水弯液面隔热&#xff0c;防止钢水在连铸过程中再次氧化&#xff0c;控制传热&#xff0c;为铸坯提供润滑&#xff0c;并吸收非金属夹杂物…

基于Java的旅游网站系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

Linux下等待队列、定时器、中断综合应用——按键控制LED

本文通过按键控制LED的亮灭&#xff0c;按键每按一次&#xff0c;LED的状态就发生一次变化。 等待队列是为了在按键有动作发生时再读取按键值&#xff0c;而不是一直读取按键的值&#xff0c;使得CPU的占用率很高。 定时器在本实验中引入是为了按键消抖&#xff0c;在键值稳定了…

Node.js中常用的设计模式有哪些?

本文由葡萄城技术团队首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可复用解决方案&#xff0c;它提…