SQL Server简介

news2025/7/18 9:43:56

SQL Server是微软的一款关系型数据库。某些平台吹得天花烂坠,今天第一次在自己的项目中使用了下,感觉不是那么好,特别是SQL语句的支持度还是很欠缺,如limit等都不支持,还有特别单双引号都是需要特别注意的,下面是SQL Server的安装和使用总结:
SQL Server安装:
1.到官网下载下载器:https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads ,如图:
在这里插入图片描述
2.新建一个文件夹并将下载好的下载器移动到这个文件夹中(可以不新建,个人习惯将软件归类管理,但是后面会发现微软的软件很多你是无法很好的管理,因为它会不受控制的安装到C盘去,即使自定义了安装目录,但是还是有很多文件是装到C盘去,吐槽微软!),之后双击下载器后选中基本即可,如:
在这里插入图片描述
3.双击基本后会再次弹出一个许可协议,接受后将安装路径修改为自己新建的文件夹,之后点击安装继续,如:
在这里插入图片描述
4.看到下面界面表示数据库已经安装成功,此时可以继续安装SSMS(SSMS是一款数据库管理软件,类似SQLyog,但是没有SQLyog好用的数据库管理软件),如:
在这里插入图片描述
5.点击完SSMS后会跳到新的网页中去,此时点击如图所示位置即可下载可视化管理软件(如果需要中文,可以继续到下面Available languages点击chinese即可安装中文版),如:
在这里插入图片描述
6.将下载好的SSMS下载器放到重新新建的文件夹,之后双击,并修改安装路径后继续点击install进行下载安装,如:
在这里插入图片描述
7.安装完成后点击Close即可,点击完CLose后,此时桌面可能没有快捷方式,此时你可以到自己应用中找到名为:azuredatastudio.exe的程序之后双击即可,通过文件所在位置可以看到文件是安装在了C盘,我C盘坚决不安装与系统相关的软件,因此我会将整个文件剪切到其它盘,之后创建快捷方式,打开管理软件如下(类似编辑器,如果想要更可视化的管理数据库,那么还得继续选择其中的工具):
在这里插入图片描述
其中的工具如:
在这里插入图片描述
**node.js中使用SQL Server: **

node.js中使用SQL Server可以通过第三方包:mssql,类似node.js连接mysql的包mysql一样,我项目中涉及分库分表存储数据,下面我将我项目中主要代码粘贴如下可供参考:

配置默认数据库:默认数据库用来查询项目基础数据,文件命名为:mssqldefaultconfig.js

// 默认数据库配置:
// 引入前先: npm i mssql 下载依赖包
const mssql = require('mssql')
// 默认数据库配置:
const option = {
  // sql server数据库所在服务器:
  server: '***.**.***.***', 
  // sql server数据库监听的端口号,默认1433:
  port: ****,
  // sql server数据库某个数据库名称:
  database: '********2021',
  // 用户名:
  user: '******',
  // 密码:
  password: '*********',
  options: {
    encrypt: false,  //加密
    enableArithAbort: false
  },
  pool: {
    min: 0,
    max: 10,
    idleTimeoutMillis: 3000
  }
}

// 创建默认数据库连接池:
const pool = new mssql.ConnectionPool(option)
pool.on('error', err => {
  console.log('数据库连接错误: ', err)
})
// 连接数据库:
const connection = pool.connect()

// 封装一个执行sql语句的方法,用来操作数据库:
const defaultDataBaseQuery = async (sql, callBack) => {  
  const ps = new mssql.PreparedStatement(await connection)
  ps.prepare(sql, err => {  
    if (err){  
      console.log('prepare错误:' + err)
      return
    }  
    ps.execute('', (err, result) => {  
      if (err){  
        console.log('execute错误:' + err)
        return
      }  
      ps.unprepare(err => {  
        if (err){  
          console.log('unprepare错误:' + err)
          callBack(err, null)
          return
        }  
        callBack(err, result)
      })
    })
  })
}

// 导出默认数据库:
module.exports = defaultDataBaseQuery

配置动态数据库 :动态数据库是指按规定的日期自动切换到某个数据,文件命名为:mssqlswitchconfig.js

// 动态库配置:
const mssql = require('mssql')
// 定时事务:一个第三方的包,类似定时器,可以设置某段代码多久执行一次(某个日期点执行某段代码)
const schedule = require('node-schedule')
// 引入默认数据库配置:动态库切换也是需要借助基础库的,因此需要引入基础库:
const defaultDataBaseQuery = require('./mssqldefaultconfig')

// 导出一个动态的数据库配置:按年份配置数据库
function createSqlServeOption() {
  let date = new Date()
  let yearstr = date.getFullYear()
  // 动态数据库配置:
  let optionObj = {
    server: '***.**.***.***', 
    port: ****,
    // 动态库命名最方便的就是前缀固定+后缀年份等
    database: '******' + yearstr,
    user: '*****',
    password: '************',
    options: {
      encrypt: false,  //加密
      enableArithAbort: false
    },
    pool: {
      min: 0,
      max: 10,
      idleTimeoutMillis: 3000
    }
  }
  return optionObj
}

// 程序启动配置当前年份动态库option:
let option = createSqlServeOption()
// 数据库连接变量
let pool;

// 程序启动连接当前年份动态库:
pool = new mssql.ConnectionPool(option)

// 每年1月1日自动切换到最新数据库:
schedule.scheduleJob('0 0 0 1 1 *', function () {
  const date = new Date()
  const yearstr = date.getFullYear()
  let dbStr = '******' + yearstr
  // 降低频率切换:因为此项目为老项目二开,数据库中数据和数据结构都是不动的,只提供使用权,这里动态创建新的数据库业务不在我项目,所以我无法创建数据库且不确定新的数据库是否已经创建好,因此只能不断的查询新的数据库是否存在,如果存在立马切换到新的数据库,否则持续每次降低频率的尝试查询数据库是否存在
  let count = 0
  // 如果新的一年数据库创建了那么立马切换到新创建的数据库,否则延迟递归切换
  function switchDB () {
    // SQL Server中无法使用:'SELECT table_name FROM `INFORMATION_SCHEMA`.`TABLES` WHERE table_schema = ******'+yearstr此sql语句查询某个数据库中是否有某表,只能通过下面数据查询到所有数据库,然后去判断数据库中是否有新的数据库名称
    let sql = 'select * From master.dbo.sysdatabases'
    defaultDataBaseQuery(sql,async (error,result) => {
      try {
        if (error) {
          throw error
        } else {
          const isExist = result.recordset.find(item => item.name == dbStr) // 不存在是返回undefined
          if (isExist) {
            option.database = dbStr
            // 动态切换新的数据库连接:如果将new mssql.ConnectionPool(option)提到最外面,这里我不能保证它会重新创建新连接,为了确保期间,我在这里重新创建一次
            pool = new mssql.ConnectionPool(option)
            // 存在的情况下return掉,否则继续延迟尝试切换:
            return
          } else {
            // 延迟重新判断是否存在数据库
            setTimeout(() => {
              count++
              switchDB()
            },1000 * count)
          }
        }
      } catch (err) {
        console.log('查询新创建数据库是否存在失败' + err)
      }
    })
  }
  switchDB()
})

// 连接池创建错误时:
pool.on('error', err => {
  console.log('数据库连接错误: ', err)
})

// 创建数据库连接:
const connection = pool.connect()

// 动态库查询方法:
const switchDataBaseQuery = async (sql, callBack) => {  
  const ps = new mssql.PreparedStatement(await connection)
  ps.prepare(sql, err => {  
    if (err){  
      console.log('prepare错误:' + err)
      return
    }  
    ps.execute('', (err, result) => {  
      if (err){  
        console.log('execute错误:' + err)
        return
      }  
      ps.unprepare(err => {  
        if (err){  
          console.log('unprepare错误:' + err)
          callBack(err, null)
          return
        }  
        callBack(err, result)
      })
    })
  })
}

// 导出动态数据库:
module.exports = switchDataBaseQuery 

查询页api接口路由文件

// 记录查询页:

// 引入日期格式化函数:
const {dataFormat} = require('../utils/utils')
// 引入路由模块:
const Router = require('koa-router')
// 引入默认数据库配置
const defaultDataBaseQuery = require('../config/mssqldefaultconfig')
// 引入动态数据库配置
const switchDataBaseQuery = require('../config/mssqlswitchconfig')
// 引入redis配置文件:
const redisClient = require('../config/redisconfig')
// 创建路由实例:
const router = new Router({prefix:'/api'})//里面可接收一个对象,可以设置些默认配置,如{prefix:'/api'}设置路由匹配前缀

// 在创建路由时默认加了前缀 /api ,下面router.post('/login', ()=>{})可直接匹配:'/api/login'路由

// 查实时值接口:
router.post('/getrealtime',async (ctx, next) => {
  let {id, ParaId} = ctx.request.body
  // 设备单位等参数redis缓存key
  let keys = 'equipmentunit' + ParaId
  return new Promise((resolve,reject) => {
    // 查仪表相关配置参数:
    function queryEquipOption() {
      // 判断是否存在key:存在走缓存,否则走数据库:
      return new Promise((resolve,reject) => {
        redisClient.exists(keys, (err, res) => {
          if (res == 0) {
            let sql1 = 'SELECT Name,Unit,Xh FROM Equipment_Para_Two WHERE FId= '+ParaId +' AND WeiXin=1'
            defaultDataBaseQuery(sql1, (error, result) => {
              if (error) {
                ctx.body = {cod: 201, msg: '查询错误!'}
                console.log('查询实时值sql1错误:' + error)
                reject()
              } else {
                if (result.recordset.length === 0) {
                  ctx.body = {cod: 200, msg: '无实时值!', resultList: [], time: dataFormat()}
                  resolve()
                  return
                }
                // 将查询到的数据存到redis中600秒过期:
                redisClient.setex(keys, 60 * 10, JSON.stringify(result))
                resolve(result)
              }
            })
          } else {
            redisClient.get(keys, (error,res) => {
              resolve(JSON.parse(res))
            })
          }
        })
      })
    }
    // 查实时值数据:
    async function queryTimeData() {
      const option = await queryEquipOption()
      // 要获取的通道
      const dnArray = [...new Set(option.recordset.map(it => 'D' + it.Xh))]
      // 要查询的通道值字段:
      const dnStr = dnArray.toString()
      // 查询时刻值:
      let sql2 = 'SELECT TOP 1 '+dnStr+', SubTime FROM Equipment_Data WHERE EqId = '+id+' order by id desc'
      switchDataBaseQuery(sql2, (error, result) => {
        if (error) {
          ctx.body = {cod: 201, msg: '查询错误!'}
          console.log('查询实时值sql2错误:' + error)
        } else {
          if (result.recordset.length === 0) {
            ctx.body = {cod: 200, msg: '无实时值!', resultList: [], time: dataFormat()}
            resolve()
            return
          }
          // 实时值数组
          let resultArray = []
          option.recordset.forEach(item => {
            resultArray.push({...item,...{value: result.recordset[0]['D' + item['Xh']]}})
          })
          ctx.body = {cod: 200, msg: '请求实时值数据成功!', resultList: resultArray, time: dataFormat(result.recordset[0].SubTime)}
          resolve()
        }
      })
    }
    queryTimeData()
  })
})

// 查历史值接口:
router.post('/gethistory', async (ctx, next) => {
  const {date1, date2, ParaId, id, page} = ctx.request.body
  const startYear = date1.slice(0,4)
  const endYear = date2.slice(0,4)
  if (startYear !== endYear) {
    ctx.body = {cod: 200, msg: '日期不能跨年!', resultList: []}
    return
  }
  // 设备单位等参数redis缓存key
  let keys = 'equipmentunit' + ParaId
  return new Promise((resolve, reject) => {
     // 查仪表相关配置参数:
     function queryEquipOption() {
      // 判断是否存在key:存在走缓存,否则走数据库:
      return new Promise((resolve,reject) => {
        redisClient.exists(keys, (err, res) => {
          if (res == 0) {
            let sql1 = 'SELECT Name,Unit,Xh FROM Equipment_Para_Two WHERE FId= '+ParaId +' AND WeiXin=1'
            defaultDataBaseQuery(sql1, (error, result) => {
              if (error) {
                ctx.body = {cod: 201, msg: '查询错误!'}
                console.log('查询实时值sql1错误:' + error)
                reject()
              } else {
                if (result.recordset.length === 0) {
                  ctx.body = {cod: 200, msg: '无实时值!', resultList: []}
                  resolve()
                  return
                }
                // 将查询到的数据存到redis中600秒过期:
                redisClient.setex(keys, 60 * 10, JSON.stringify(result))
                resolve(result)
              }
            })
          } else {
            redisClient.get(keys, (error,res) => {
              resolve(JSON.parse(res))
            })
          }
        })
      })
    }
    // 查历史值数据:
    async function queryHistoryData() {
      const option = await queryEquipOption()
      // 要获取的通道
      const dnArray = [...new Set(option.recordset.map(it => 'D' + it.Xh))]
      // 要查询的通道值字段:
      const dnStr = dnArray.toString()
      if (page < 1) {
        ctx.body = {cod: 200, msg: '页数无效!', resultList: []}
        return
      }
      let skip = (page - 1)*10
      // 查询历史值:
      const date = new Date()
      const currentYear = date.getFullYear()
      let sql2;
      // 如果查询日期是当前年份,则执行当前年份动态库,否则切换到对应的历史数据库查询数据:
      if (startYear == currentYear) {
        sql2 = "select top 10 "+dnStr+" ,SubTime,EqId from (select row_number() over(order by id desc) as rownumber, "+dnStr+" ,SubTime,EqId from Equipment_Data) temp_row where EqId = "+id+" and SubTime between '"+date1+"' and '"+date2+"' and rownumber > " +skip
      } else {
        sql2 = "select top 10 "+dnStr+" ,SubTime,EqId from (select row_number() over(order by id desc) as rownumber, "+dnStr+" ,SubTime,EqId from [YLinK"+startYear+"].[dbo].[Equipment_Data]) temp_row where EqId = "+id+" and SubTime between '"+date1+"' and '"+date2+"' and rownumber > " +skip
      }
      switchDataBaseQuery(sql2, (error, result) => {
        if (error) {
          ctx.body = {cod: 201, msg: '查询错误!'}
          console.log('查询历史值sql2错误:' + error)
        } else {
          if (result.recordset.length === 0) {
            ctx.body = {cod: 200, msg: '无历史值!', resultList: []}
            resolve()
            return
          }
          // 历史值数组
          let resultArray = []
          // 遍历历史值
          result.recordset.forEach(item => {
            // 二维数组子数组:
            let arr = []
            // 遍历单位数组:
            option.recordset.forEach(uitem => {
              // 遍历历史值对象:
              for (key in item) {
                if (key.slice(1,2) == uitem.Xh) {
                  arr.push({...uitem,value:item[key]})
                }
              }
            })
            resultArray.push({time: dataFormat(item.SubTime), ValueArray: arr})
          })
          ctx.body = {cod: 200, msg: '请求历史值数据成功!', resultList: resultArray}
          resolve()
        }
      })
    }
    queryHistoryData()
  })
})

// 查充值记录接口
router.post('/getpayrec', async (ctx, next) => {
  const {date1, date2, id, page} = ctx.request.body
  return new Promise((resolve,reject) => {
    // 查询充值记录:
    if (page < 1) {
      ctx.body = {cod: 200, msg: '页数无效!', resultList: []}
      resolve()
      return
    }
    let skip = (page - 1) * 10
    let sql = "select top 10 EquipmentId,SbTime,No,Amount from (select row_number() over(order by id desc) as rownumber,EquipmentId,SbTime,No,Amount from PayRec) temp_row where EquipmentId = "+id+" and SbTime between '"+date1+"' and '"+date2+"' and rownumber > " +skip
    defaultDataBaseQuery(sql, (error, result) => {
      if (error) {
        ctx.body = {cod: 201, msg: '查询错误!'}
        console.log('查充值记录sql错误:' + error)
      } else {
        result.recordset.map(item => {
          item.SbTime = dataFormat(item.SbTime)
        })
        ctx.body = {cod: 200, msg: '请求充值记录数据成功!', resultList: result.recordset}
        resolve()
      }
    })
  })
})

// 退款记录接口
router.post('/getrefund', async (ctx, next) => {
  const {date1, date2, id, page} = ctx.request.body
  return new Promise((resolve,reject) => {
    // 查询退款记录:
    if (page < 1) {
      ctx.body = {cod: 200, msg: '页数无效!', resultList: []}
      resolve()
      return
    }
    let skip = (page - 1) * 10
    let sql = "select top 10 EquipmentId,SbTime,No,Amount from (select row_number() over(order by id desc) as rownumber,EquipmentId,SbTime,No,Amount from Refund) temp_row where EquipmentId = "+id+" and SbTime between '"+date1+"' and '"+date2+"' and rownumber > " +skip
    defaultDataBaseQuery(sql, (error, result) => {
      if (error) {
        ctx.body = {cod: 201, msg: '查询错误!'}
        console.log('查退款记录sql错误:' + error)
      } else {
        result.recordset.map(item => {
          item.SbTime = dataFormat(item.SbTime)
        })
        ctx.body = {cod: 200, msg: '请求退款记录数据成功!', resultList: result.recordset}
        resolve()
      }
    })
  })
})


// 导出路由
module.exports = router

index启动文件

// 引入设置响应头的中间件:
const setResponseHeader = require('./middelware/setresponseheader')
// 引入解析请求体的中间件:koa-bodyparser
const bodyParser = require('koa-bodyparser')
// 导入查询页路由文件
const recordqueryserve = require('./serves/recordqueryserve')

const Koa = require('koa')
// 创建Koa实例对象:
const app = new Koa()

// 挂载设置响应头的中间件:
app.use(setResponseHeader)
// 挂载koa-bodyparser中间件:如果不配置的话在路由页就不能通过ctx.request.body拿到请求体
app.use(bodyParser())

// 挂载查询页接口路由:
app.use(recordqueryserve.routes())

// 绑定端口号:
app.listen(3000,() => {
  console.log('serve is running at 3000!')
})

提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者 删除。

笔者:苦海

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

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

相关文章

从0到1CTFer成长之路——1git(全网最详细)

1.1.2.1 git 泄露 (1) 常规git泄露 安装docker sudo apt-get update sudo apt-get install docker 安装容器 docker pull ubuntu:18.04 然后发现请求超时 我们需要阿里云的镜像加速器 我们按照要求配置文件 没有/etc/docker 就自己创建 sudo mkdir -p /etc/docker 然后写入…

Cookie与Session 以及给CBV添加装饰器

文章目录Cookie与Session1、Django操作cookie简单实现用户登录加入装饰器2、Django操作session设置session获取session过期时间清除sessionCBV添加装饰器Cookie与Session HTTP被设计为”⽆态”&#xff0c;也就是俗称“脸盲”。 这⼀次请求和下⼀次请求 之间没有任何状态保持&…

跨模态神经搜索实践VCED 环境准备

跨模态神经搜索实践 环境准备 本文基于WSL2及docker进行环境搭建 1. 安装和配置WSL2 Ubuntu发行版 1.1 安装WSL2 Ubuntu 相关安装命令&#xff1a; wsl --install&#xff1a;默认安装Ubuntu发行版wsl --list --online&#xff1a;查看可支持的发行版本wsl --install -d &…

如何将 wordfile 添加到 UltraEdit 或 UEStudio

UltraEdit 本身支持开箱即用的最常用编程和标记语言的语法突出显示。我们也有数百个其他语言的 wordfile&#xff0c;但是&#xff0c;很容易找到和添加您需要的语言&#xff01; 重要提示&#xff1a;此电源提示适用于运行 UltraEdit v15.00或 UEStudio v09.10及更高版本的用户…

Ubuntu18.04系统安装nginx

Ubuntu18.04系统安装nginx一、在线安装 Nginx二、离线安装 Nginx参考链接请确保以具有 sudo 权限的用户身份登录&#xff0c;并且您没有在端口 80 或 443 上运行 Apache 或任何其他 Web 服务器。 一、在线安装 Nginx 简介&#xff1a;Nginx (engine x) 是一个免费的&#xff0…

swift-类属性

了解属性之前&#xff0c;需要先了解前面的swift-类结构内容 - swift-类结构源码探寻 FieldDescriptor TargetClassDescriptor {var Flags: ContextDescriptorFlags // uint32var Parent: TargetRelativeContextPointer // Int32var Name: TargetRelativeDirectPointer // I…

Markdown还能这么玩?这款开源神器绝了!

Markdown是一款轻量级标记语言&#xff0c;由于它易读易写的特性&#xff0c;很多程序员用它来写项目文档。其实Markdown的功能不止于此&#xff0c;结合一些工具使用还可以用来做PPT&#xff0c;今天带大家使用Markdown来做一个PPT&#xff0c;看看到底有多炫酷&#xff01; S…

《springboot那些事》

注&#xff1a;static目录、主要用于存放非模板引擎渲染的资源。 ​ template目录&#xff0c;存放渲染引擎页面的资源。 一句话&#xff1a;用模板引擎的话&#xff0c;就放template目录、否则static目录。 一、使用thymeleaf 引入thymealeaf坐标 <dependency><…

22.11.15打卡 mysql学习笔记

学了DDL和DQL, 今天课太多, 没怎么学啊, 很烦躁, 还有3周要考试了 空格可以有一个或者多个 if not exists表示不存在则执行, 存在则不执行 方括号当中的都可 create database itcase; show databases;查看数据库 再次创建itcase数据库 加上if not exists就不会报错 字符集演示 …

DPDK LPM库(学习笔记)

1 LPM库 DPDK LPM库组件为32位的key实现了最长前缀匹配&#xff08;LPM&#xff09;表查找方法&#xff0c;该方法通常用于在IP转发应用程序中找到最佳路由匹配。 2 LPM API概述 LPM组件实例的主要配置参数是要支持的最大规则数。 LPM前缀由一对参数&#xff08;32位Key&…

React源码分析3-render阶段(穿插scheduler和reconciler)

本章将讲解 react 的核心阶段之一 —— render阶段&#xff0c;我们将探究以下部分内容的源码&#xff1a; 更新任务的触发更新任务的创建reconciler 过程同步和异步遍历及执行任务scheduler 是如何实现帧空闲时间调度任务以及中断任务的 触发更新 触发更新的方式主要有以下几…

Leetcode第21题:合并两个有序链表

生命无罪&#xff0c;健康万岁&#xff0c;我是laity。 我曾七次鄙视自己的灵魂&#xff1a; 第一次&#xff0c;当它本可进取时&#xff0c;却故作谦卑&#xff1b; 第二次&#xff0c;当它在空虚时&#xff0c;用爱欲来填充&#xff1b; 第三次&#xff0c;在困难和容易之…

面试官:你说说 Mysql 索引失效有哪些场景?

前言 SQL 写不好 加班少不了 日常工作中SQL 是必不可少的一项技术 但是很多人不会过多的去关注SQL问题。 一是数据量小&#xff0c;二是没有意识到索引的重要性。本文主要是整理 SQL失效场景&#xff0c;如果里面的细节你都知道&#xff0c;那你一定是学习能力比较好的人&am…

基于Docker的网络安全靶场搭建

背景介绍 在学习网络安全技术过程中,我们往往需要有一个自己的操作机与多个用来搭建环境的靶机,使用VM虚拟机模拟资源占用较大,成本高、局限性大且使用十分不便。 这时我们可以使用一台安装好Docker环境的linux虚拟机来完成桌面版操作机与WEB靶机的搭建与实验操作。 Docker…

Linux操作系统~进程替换,exec系列函数的使用

目录 1.概念/原理 &#xff08;1&#xff09;.替换原理 &#xff08;2&#xff09;.子进程调用execl执行程序替换&#xff0c;为什么父进程不受影响&#xff1f; &#xff08;3&#xff09;.exec*返回值 2.替换函数exec execl execv execlp execvp的&#xff08;execv…

Android Studio App开发之网络通信中使用POST方式调用HTTP接口实现应用更新功能(附源码 超详细必看)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一、POST方式调用HTTP接口 POST方式把接口地址与请求报文分开&#xff0c;允许使用自定义的报文格式&#xff0c;由此扩大了该方式的应用场景。POST请求与GET请求主要有三处编码差异 1&#xff1a;在调用setRequestMethod方…

Kafka 消息队列 ( 一 ) 基本概念

0.MQ(message queue) 消息中间件 生活中的问题 : 快递员 给 你 送东西, 你必须 在家等着, (效率低) 可以 把东西 放 指定 的 地方(菜鸟驿站) , 你自己去取 , 指定 的地点(菜鸟驿站) 就是 MQ 消息队列中间件 0.1.开发中的问题 0.1.1.异步问题 0.1.2.业务解耦 0.1.3.流量削…

2. 信息在计算机中存储的格式

目录 一、信息存储&#xff1a; 1. 空间大小定义 2. 不同进制的转换方法 3. 各种数据类型所占字节数 4. 字节顺序 5. 字符串存储 6. 代码的二进制表示 7. 布尔代数运算 8. 逻辑运算 9. 移位运算 二、 整数表示 1. 有符号与无符号表示 1.1 表示范围 1.2 补码编码的…

C语言日记 35 拷贝构造函数

书P132&#xff1a; 拷贝构造函数的作用是 用已存在的对象初始化另一对象&#xff0c;两对象类类型应一样 在这里我们可以看到&#xff0c; 他对被拷贝的对象的要求只有“已存在的对象&#xff0c;两对象类类型一样”&#xff0c;也就是说他这里也没有说我们不能跨区域&…

使用 Spring Cloud Loadbalancer 实现客户端负载均衡

使用 Spring Cloud Loadbalancer 实现客户端负载均衡 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;使用 Spring Cloud Loadbalancer 实现客户端负载均衡 CSDN&#xff1a;使用 Spring Cloud Loadbalancer 实现客户端负载均衡 背景 在Spring Cloud G 版…