JS图片多个上传,并压缩为Base64 - 跑着的小强 - 博客园

mikel阅读(299)

来源: JS图片多个上传,并压缩为Base64 – 跑着的小强 – 博客园

首先是JS 批量上传

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="Pic_pass">
           <p style="font-size: 20px;font-weight: bold;">请上传照片 </p>
           <p><span style="color: red">注:最多可以传3张</span></p>
           <div class="picDiv">
               <div class="addImages">
                   <input type="file" class="file" id="fileInput" multiple="" accept="image/png, image/jpeg, image/gif, image/jpg">
                   <div class="text-detail">
                       <span>+</span>
                       <p>点击上传</p>
                   </div>
               </div>
           </div>
       </div>

样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
.imageDiv {
          display:inline-block;
          width:160px;
          height:130px;
          -webkit-box-sizing:border-box;
          -moz-box-sizing:border-box;
          box-sizing:border-box;
          border:1px dashed darkgray;
          background:#f8f8f8;
          position:relative;
          overflow:hidden;
          margin:10px
      }
      .cover {
          position:absolute;
          z-index:1;
          top:0;
          left:0;
          width:160px;
          height:130px;
          background-color:rgba(0,0,0,.3);
          display:none;
          line-height:125px;
          text-align:center;
          cursor:pointer;
      }
      .cover .delbtn {
          color:red;
          font-size:20px;
      }
      .imageDiv:hover .cover {
          display:block;
      }
      .addImages {
          display:inline-block;
          width:160px;
          height:130px;
          -webkit-box-sizing:border-box;
          -moz-box-sizing:border-box;
          box-sizing:border-box;
          border:1px dashed darkgray;
          background:#f8f8f8;
          position:relative;
          overflow:hidden;
          margin:10px;
      }
      .text-detail {
          margin-top:40px;
          text-align:center;
      }
      .text-detail span {
          font-size:40px;
      }
      .file {
          position:absolute;
          top:0;
          left:0;
          width:160px;
          height:130px;
          opacity:0;
      }

JS代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
var userAgent = navigator.userAgent; //用于判断浏览器类型
         $(".file").change(function () {
             //获取选择图片的对象
             var cou = $('.imageDiv').length
             console.log(cou)
             var docObj = $(this)[0];
             var picDiv = $(this).parents(".picDiv");
             var fileList = docObj.files;
             console.log(fileList)
             console.log(fileList.length)
             console.log(picDiv)
             //循环遍历
             for (var i = 0; i < fileList.length; i++) {
                 //动态添加html元素
                 var picHtml = "<div class='imageDiv' > <img id='img" + fileList[i].name + "' /> <div class='cover'><i class='delbtn'>删除</i></div></div>";
                 picDiv.prepend(picHtml);
                 //获取图片imgi的对象
                 var imgObjPreview = document.getElementById("img" + fileList[i].name);
                 if (fileList && fileList[i]) {
                     formData.append("file", docObj.files[i]);
                     
                     //图片属性
                     imgObjPreview.style.display = 'block';
                     imgObjPreview.style.width = '160px';
                     imgObjPreview.style.height = '130px';
                     //imgObjPreview.src = docObj.files[0].getAsDataURL();
                     //火狐7以上版本不能用上面的getAsDataURL()方式获取,需要以下方式
                     if (userAgent.indexOf('MSIE') == -1) {
                         //IE以外浏览器
                         imgObjPreview.src = window.URL.createObjectURL(docObj.files[i]); //获取上传图片文件的物理路径;
                         
                         console.log(docObj.files[i]);
                         // var msgHtml = '<input type="file" id="fileInput" multiple/>';
                     else {
                         //IE浏览器
                         if (docObj.value.indexOf(",") != -1) {
                             var srcArr = docObj.value.split(",");
                             imgObjPreview.src = srcArr[i];
                             console.log(srcArr[i]);
                         else {
                             imgObjPreview.src = docObj.value;
                         }
                     }
                 }
             }
            
             $('#fliei1').click(function () {
                 console.log($(".file").files)
             })
             /*删除功能*/
             $(".delbtn").click(function () {
                 var _this = $(this);
                 _this.parents(".imageDiv").remove();
             });
         });
     })

效果

 

但是图片都是没有压缩的 、

1
 

 

本来JS 是没有办法压缩的 但是H5的画布可以 可以用画布压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
   function dealImage(path, obj) {
            var img = new Image();
            img.src = path;
            img.onload = function () {
                var that = this;
                var w = that.width,
                    h = that.height,
                    scale = w / h;
                w = obj.width || w;
                h = obj.height || (w / scale);
                var quality = 0.85; //压缩质量 1是不压缩
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                var anw = document.createAttribute("width");
                anw.nodeValue = w;
                var anh = document.createAttribute("height");
                anh.nodeValue = h;
                canvas.setAttributeNode(anw);
                canvas.setAttributeNode(anh);
                ctx.drawImage(that, 0, 0, w, h);
                if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
                    quality = obj.quality;
                }
                var base64 = canvas.toDataURL('image/jpeg', quality);
                //最后返回压缩后的base64编码
                console.log(base64)
            }
        }
<br>
<br>              var imgReaderI = new FileReader();<br>               //转换base64编码
                        imgReaderI.readAsDataURL(docObj.files[i]);
                        console.log(imgReaderI)
                        var size=docObj.files[i].size
                        imgReaderI.onloadend = function (evt) {
                            //压缩
                                dealImage(this.result, { width: 180 });
                            }
                        }

有一点 docObj.files[i] 这个表示选择的图片可以传到后台直接保存 但是没有压缩。

 

1个1.9M 压缩过后28.2K 还是特别客观的 接下来 我们就可以吧这个字符串通过AJAX方式传入后台。进行保存或者直接放入数据库,下一篇 我会写后台保存方法MVC 保存到服务器 返回相对路径

前端图片上传使用,base64直接上传,base64转化成file上传,form表单直接上传文件,element-ui上传图片_base64 如何上传 fs-CSDN博客

mikel阅读(312)

来源: 前端图片上传使用,base64直接上传,base64转化成file上传,form表单直接上传文件,element-ui上传图片_base64 如何上传 fs-CSDN博客

最近项目中使用到了图片上传功能,作为前端开发对此应该不陌生,正常来说图片会有一个单独存储的服务,例如现在公司使用minio统一集中管理,直接部署在docker上面非常方便,下面记录一下使用经历过的图片上传

1.base64直接上传
这种base64直接上传给后端,然后后端拿到数据之后就能自行处理,一般前端会对base64数据前面拼接 “data:image/jpeg;base64,” + base64数据;代表图片格式,其余后端自行处理,相对来说这种方式对前端更加友好,上传方式跟普通数据上传完全相同,然后后端返回图片存储的相对路径,前端进行拼接ip前缀就能正常展示;如下面代码:

$.ajax({
url: uploadFea,
type: “POST”,
dataType: “JSON”,
processData: false,
beforeSend: function () {
console.log(“正在上传特征值文件,请稍候”);
},
headers: {
“Content-Type”: “application/json;charset=UTF-8”,
},
data: {
platform: “web”,
uploadFile: feaFile,
name: fileName + “_” + guid(),
},
success: (res) => {
console.log(res.fileSuccess);

},
});
2.form表单方式的提交
这种是类似于form表单提交,这样其实是类似于element-ui中的上传,本质就是表单上传,而且方法提供的非常全面直接复制就行,这样一般也会有几种情况;

一种是直接提交给后端,一种是传base64数据给后端,还一种情况是前端获取到的图片数据是硬件提供的数据(例如身份证读卡器)一般是直接给你base64数据,但是后端接口不支持直接传base64,这样就需要前端童鞋处理一下base64数据了,然后再以表单提交文件形式传给后端了

1.直接提交给后端就是如下:

<form action=”http://192.168.10.94:3050/serverData/upload” method=”POST” enctype=”multipart/form-data”>
<input type=”file” name=”tupian” multiple=”multiple”>
<input type=”text” name=”id” id=”name”>
<input type=”submit”value=”提交”id=”btnn”>
</form>
这是自己本地使用node做的一个简单图片上传接口,接口能接收到文件数据,然后通过重命名移动等操作将处理后的图片文件保存到对应服务器目录,后端能直接获取到文件名称后缀以及数据等信息,自习看下element-ui其实本质就是一个封装好的表单提交,如下:

<el-upload class=”avatar-uploader” :style=”styles” :http-request=”uploadImg” :on-progress=”uploadVideoProcess” :disabled=”isDisabled”>
<el-progress type=”circle” v-show=”videoFlag” :percentage=”videoUploadPercent” class=”circle”></el-progress>

</el-upload>
2.element-ui中提供了 :http-request 方法我们能够使用,可以直接上传文件或者上传base64数据如:

//后端不需要base64
uploadImg (file) {
//这里file其实就是上传的文件,如果后端需要此类上传我们就能直接使用
$.ajax({
type: ‘post’,
url: upLodUrl,
data: file,
dataType: ‘text’,
processData: false, // bu要去处理发送的数据
contentType: false, //不要去设置Content-Type请求头
success: function(res) {
url = res.data
}
})
}

//后端需要base64,就需要对获取到的数据进行处理
uploadImg (file) {
let reader = new FileReader()
reader.readAsDataURL(file.file)
reader.onload =()=>{
let dataURL = reader.result // 获取到base64编码 包括前缀data:image/jpeg;base64,
}
//此时可以使用最上面直接上传base64的方式进行上传了
}
3.最后一种是最坑的一种,由于图片数据是硬件获取到的,或者是通过摄像头拍照拿到的数据,一般都是base64数据,恰好后端又不支持前端直接上传图片,此时就需要前端对base数据处理,转化成能直接上传的file,就类似于转化成 new FormData()

let bytes = window.atob(base64)
let ab = new ArrayBuffer(bytes.length)
let ia = new Uint8Array(ab)
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
let imgs = new File([ab], name, { type: ‘image/jpg’ })
const formData = new FormData()
formData.append(‘file’, imgs)

//上传操作 下面是前面几篇文章中讲的axios封装的方法,并无不同
const data =await upload(formData)
console.log(data)
//此处上传无论是直接使用ajax还是axios上传都一样,直接把formData放到data那里就行,不需要键值对形势
//ajax上传就类似于第二步中的 $.ajax上传,formData就是file,直接使用即可
最后第三种需要注意点,let imgs = new File([ab], name, { type: ‘image/jpg’ }) 中的name指的是你自己定义图片的名称,然后生成的formData就包含name以及自己定义的type:’image/jpg’ ,一般直接form表单上传name是包含后缀名的,例如图片.jpg等,后端可能会根据后缀去定义图片格式,前端上传命名时候需要注意点,可以自己随意添加后缀名或者直接让后端从type中去取,或者是让后端自己随便定义即可

补充直接上传二进制文件

let fileData = file.file; // 拿到file后,转为FormData格式,这样再发送给后端就可以了
let formData = new FormData();
formData.append(“img”, fileData);
api_upload(formData) // 发起请求
.then((res)=>{
console.log(res)
})
.catch((err)=>{
console.log(err)
})

//此处直接上传file.file 为二进制文件,不需要将数据转成字符串或其他

————————————————
版权声明:本文为CSDN博主「一梦成回忆」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/H_Elie/article/details/115471125

JS,base64编码的图片上传_js res.photobase64 如何上传-CSDN博客

mikel阅读(295)

来源: JS,base64编码的图片上传_js res.photobase64 如何上传-CSDN博客

公司的项目要拍照上传图片,但用了第三方平台,拍照接口返回的是照片的base64编码,如何把base64编码的图片上传到服务器呢?思路上来说:首先,要将base64编码转换成file,再将file塞到from中,提交到后台即可。直接上代码

/**
* imageURI为图片的base64编码,不包含头部部分:data:img/jpg;base64,
**/
var fileName=(new Date()).getTime()+”.jpeg”; //随机文件名
var imgfile=convertBase64UrlToImgFile(imageURI,fileName,’image/jpeg’); //转换成file
var formData = new FormData();
formData.append(‘file’, imgfile); //放到表单中,此处的file要和后台取文件时候的属性名称保持一致
$.ajax({
url:上传文件的后台处理url,
type:”POST”,
cache:false,
data:formData,
processData:false, //不对参数进行转换序列号
contentType:false, //fromData上传文件时将其设置为false
success:function(data){
//成功执行的代码逻辑
},
error:function(data){
//失败执行的代码逻辑
}
});
其中convertBase64UrlToImgFile函数代码如下:

/**
* 有些浏览器(如edge)不支持new File,所以为了兼容,base64要先转换成blob再设置type,name,lastModifiedDate
* 属性间接转换成文件,而不推荐直接new File()的方式
**/
function convertBase64UrlToImgFile(urlData,fileName,fileType) {
var bytes = window.atob(urlData); //转换为byte
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
var ia = new Int8Array(ab);
var i;
for (i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
//转换成文件,添加文件的type,name,lastModifiedDate属性
var blob=new Blob([ab], {type:fileType});
blob.lastModifiedDate = new Date();
blob.name = fileName;
return blob;
}
但在调用时,后台始终获取不到设置的filename,一直是blob。查资料发现,需要在formdata.append时加上文件名,如下:

formData.append(‘file’, imgfile,fileName);
如此,问题解决。
————————————————
版权声明:本文为CSDN博主「southArbor」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010295735/article/details/89029399

JS实现本地图片预览的两种方式_js图片预览-CSDN博客

mikel阅读(266)

来源: JS实现本地图片预览的两种方式_js图片预览-CSDN博客

方式一:

第一种是用window.URL.createObjectURl方法对选择的图片数据(可以勉强理解为input的value)生成一个blob对象路径。

<template>
<div>
<input multiple type=”file” id=”file” @change=”handleChange”>
<div id=”imagebox”></div>
</div>
</template>

<script>
export default {
data() {
return {};
},
methods: {
handleChange() {
var file = document.getElementById(“file”).files[0]; // 获取input上传的图片数据;
var img = new Image();
var url = window.URL.createObjectURL(file); // 得到bolb对象路径,可当成普通的文件路径一样使用,赋值给src;
img.src = url;
document.getElementById(“imagebox”).appendChild(img);
},
},
};
</script>
方式二:

第二种是用获取 FileReader读取器。

用FileRader对像读取文件可分为四步;1、创建FileReader对像;2、调用readAsDataURL方法读取文件;3、调用onload事件监听,我们一需要拿到完整的数据,但我们又不知道文件何时读完,所以需要第三步监听;4、通过FileRader对像r的result属性拿到读取结果。

<template>
<div>
<input multiple type=”file” id=”file” @change=”handleChange”>
<div id=”imagebox”></div>
</div>
</template>

<script>
export default {
data() {
return {};
},
methods: {
handleChange() {
var file = document.getElementById(“file”).files[0]; // 获取input上传的图片数据;
var read = new FileReader(); // 创建FileReader对像;
read.readAsDataURL(file); // 调用readAsDataURL方法读取文件;
read.onload = function() {
var url = read.result; // 拿到读取结果;
var img = new Image();
img.src = url;
document.getElementById(“imagebox”).appendChild(img);
};
},
},
};
</script>
————————————————
版权声明:本文为CSDN博主「雪花女神」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46279019/article/details/119417948

C#中使用设置(Settings.settings) Properties.Settings.Default .(配置文件相当重要) - newlives - 博客园

mikel阅读(257)

来源: C#中使用设置(Settings.settings) Properties.Settings.Default .(配置文件相当重要) – newlives – 博客园

 

在设计时创建新设置的步骤

在“Solution Explorer”(解决方案资源管理器)中,展开项目的“Properties”(属性)节点。

在“Solution Explorer”(解决方案资源管理器)中,双击要在其中添加新设置的 .settings 文件。此文件的默认名称是 Settings.settings。

 

 

为设置键入新值,然后保存该文件。

在运行时使用设置

 

运行时应用程序可以通过代码使用设置。具有应用程序作用域的设置值能够以只读方式进行访问,而用户作用域设置的值可以进行读写。在 C# 中可以通过 Properties 命名空间使用设置。

在运行时读取设置

可在运行时使用 Properties 命名空间读取应用程序作用域及用户作用域设置。Properties 命名空间通过Properties.Settings.Default 对象公开了项目的所有默认设置。编写使用设置的代码时,所有设置都会出现在 IntelliSense 中并且被强类型化。因此,举例来说,如果设置的类型为 System.Drawing.Color,则无需先对其进行强制类型转换即可使用该设置,如下例所示:

this.BackColor = Properties.Settings.Default.myColor;

在运行时保存用户设置

应用程序作用域设置是只读的,只能在设计时或通过在应用程序会话之间修改 <AssemblyName>.exe.config 文件来进行更改。然而,用户作用域设置却可以在运行时进行写入,就像更改任何属性值那样。新值会在应用程序会话持续期间一直保持下去。可以通过调用 Settings.Save 方法来保持在应用程序会话之间对用户设置所做的更改。这些设置保存在 User.config 文件中。

在运行时写入和保持用户设置的步骤

访问用户设置并为其分配新值,如下例所示:

Properties.Settings.Default.myColor = Color.AliceBlue;
如果要保持在应用程序会话之间对用户设置所做的更改,请调用 Save 方法,如以下代码所示:

Properties.Settings.Default.Save();

 

 

 

=========================================================================================================================================================================================================================================================================================================================================================================================================

 

 

1、定义

 

在Settings.settings文件中定义配置字段。把作用范围定义为:User则运行时可更改,Applicatiion则运行时不可更改。可以使用数据网格视图,很方便;

2、读取配置值

text1.text = Properties.Settings.Default.FieldName;
//FieldName是你定义的字段

3、修改和保存配置

Properties.Settings.Default.FieldName = “server”;

Properties.Settings.Default.Save();//使用Save方法保存更改

4、也可以自己创建

创建一个配置类FtpSetting。在WinForm应用程序里,一切配置类都得继承自 ApplicationSettingsBase 类。

sealed class FtpSettings : ApplicationSettingsBase

{
[UserScopedSetting]
[DefaultSettingValue(“127.0.0.1”)]
public string Server
{
get { return (string)this[“Server”]; }
set { this[“Server”] = value; }
}
[UserScopedSetting]
[DefaultSettingValue(“21”)]
public int Port
{
get { return (int)this[“Port”]; }
set { this[“Port”] = value; }
}
}

使用上述配置类,可以用:

private void button2_Click(object sender, EventArgs e)
{
FtpSettings ftp = new FtpSettings();
string msg = ftp.Server + “:” + ftp.Port.ToString();
MessageBox.Show(msg);
}

我们在使用上述FtpSetting 配置时,当然要先进行赋值保存,然后再使用,后面再修改,再保存,再使用。
private void button2_Click(object sender, EventArgs e)
{
FtpSettings ftp = new FtpSettings();
ftp.Server = “ftp.test.com”;
ftp.Port = 8021;
ftp.Save();
ftp.Reload();
string msg = ftp.Server + “:” + ftp.Port.ToString();
MessageBox.Show(msg);
}
嗯。已经Save了,你可能会在应用程序文件夹里找不到它到底保存到哪里去了。由于我们是用UserScope的,所以其实该配置信息是保存到了你的Windows的个人文件夹里去了。比如我的就是 C:\Documents and Settings\brooks\Local Settings\Application Data\TestWinForm目录了。

 

 

=========================================================================================================================================================================================================================================================================================================================================================================================================

 

 

例:

using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Configuration;

namespace 设置文件读写测试
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Properties.Settings.Default.name = this.textBox1.Text;
Properties.Settings.Default.Save();
this.label1.Text = Properties.Settings.Default.name;
}

private void button2_Click(object sender, EventArgs e)
{
this.label1.Text = Properties.Settings.Default.name;
}

private void button3_Click(object sender, EventArgs e)
{
FtpSettings ftp = new FtpSettings();
string msg = ftp.Server + “:” + ftp.Port.ToString();
this.label2.Text = msg;
}

private void button4_Click(object sender, EventArgs e)
{
FtpSettings ftp = new FtpSettings();
ftp.Server = this.textBox2.Text ;
ftp.Port = Convert.ToInt32(this.textBox3.Text);
ftp.Save();
//ftp.Reload();
string msg = ftp.Server + “:” + ftp.Port.ToString();
this.label2.Text = msg;
}
}

sealed class FtpSettings : ApplicationSettingsBase
{
[UserScopedSetting]
[DefaultSettingValue(“127.0.0.1”)]
public string Server
{
get { return (string)this[“Server”]; }
set { this[“Server”] = value; }
}
[UserScopedSetting]
[DefaultSettingValue(“21”)]
public int Port
{
get { return (int)this[“Port”]; }
set { this[“Port”] = value; }
}
}
}

SQL Server查看库、表占用空间大小 - 郭大侠1 - 博客园

mikel阅读(336)

来源: SQL Server查看库、表占用空间大小 – 郭大侠1 – 博客园

查询数据文件与日志文件占用情况,查看数据大小,查看库大小

1. 查看数据文件占用(权限要求较大)

DBCC showfilestats

2. 查看日志文件占用

dbcc sqlperf(logspace) 

复制代码
USE master
go
--简易版
SELECT 
Name,
physical_name,
Size/128.0 AS [Size(MB)],
FILEPROPERTY(Name,'SpaceUsed')/128.0 AS [SpaceUsed(MB)],
STR(FILEPROPERTY(Name,'SpaceUsed')*1.0/Size*100,6,3) AS [SpaceUsed(%)] 
FROM master.sys.database_files
复制代码
复制代码
--详细版
SELECT a.name [文件名称] ,cast(a.[size]*1.0/128 as decimal(12,1)) AS [文件设置大小(MB)] ,
    CAST( fileproperty(s.name,'SpaceUsed')/(8*16.0) AS DECIMAL(12,1)) AS [文件所占空间(MB)] ,
    CAST( (fileproperty(s.name,'SpaceUsed')/(8*16.0))/(s.size/(8*16.0))*100.0 AS DECIMAL(12,1)) AS [所占空间率%] ,
    CASE WHEN A.growth =0 THEN '文件大小固定,不会增长' ELSE '文件将自动增长' end [增长模式] ,CASE WHEN A.growth > 0 AND is_percent_growth = 0 
    THEN '增量为固定大小' WHEN A.growth > 0 AND is_percent_growth = 1 THEN '增量将用整数百分比表示' ELSE '文件大小固定,不会增长' END AS [增量模式] ,
    CASE WHEN A.growth > 0 AND is_percent_growth = 0 THEN cast(cast(a.growth*1.0/128as decimal(12,0)) AS VARCHAR)+'MB' 
    WHEN A.growth > 0 AND is_percent_growth = 1 THEN cast(cast(a.growth AS decimal(12,0)) AS VARCHAR)+'%' ELSE '文件大小固定,不会增长' end AS [增长值(%或MB)] ,
    a.physical_name AS [文件所在目录] ,a.type_desc AS [文件类型] 
FROM sys.database_files a 
INNER JOIN sys.sysfiles AS s  ON a.[file_id]=s.fileid 
LEFT JOIN sys.dm_db_file_space_usage b ON a.[file_id]=b.[file_id] ORDER BY a.[type]
复制代码

 

转自:https://www.cnblogs.com/nikyxxx/archive/2012/10/08/2715423.html

SQL server查看所有表大小、所占空间

基于T-SQL

复制代码
SELECT 
   db_name() as DbName,
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS 总共占用空间MB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 0
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    总共占用空间MB desc
复制代码

 

基于存储过程(exec sp_spaceused)

–主要原理:
exec sp_spaceused ‘表名’ –取得表占用空間
exec sp_spaceused ”–數據庫所有空間

复制代码
复制代码
create table #Data(name varchar(100),row varchar(100),reserved varchar(100),data varchar(100),index_size varchar(100),unused varchar(100)) 
 
declare @name varchar(100) 
declare cur cursor  for 
    select name from sysobjects where xtype='u' order by name 
open cur 
fetch next from cur into @name 
while @@fetch_status=0 
begin 
    insert into #data 
    exec sp_spaceused   @name 
    print @name 
 
    fetch next from cur into @name 
end 
close cur 
deallocate cur 
 
create table #DataNew(name varchar(100),row int,reserved int,data int,index_size int,unused int) 
 
insert into #dataNew 
select name,convert(int,row) as row,convert(int,replace(reserved,'KB','')) as reserved,convert(int,replace(data,'KB','')) as data, 
convert(int,replace(index_size,'KB','')) as index_size,convert(int,replace(unused,'KB','')) as unused from #data  
 
select * from #dataNew order by data desc
复制代码
复制代码

 

 

查看索引大小

复制代码
--查看索引大小
如果您想要表的每个索引的大小,请使用以下两个查询中的一个:

SELECT
    i.name                  AS IndexName,
    SUM(s.used_page_count) * 8   AS IndexSizeKB
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.indexes                AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
WHERE s.[object_id] = object_id('dbo.TableName')
GROUP BY i.name
ORDER BY i.name

---第2种方法
SELECT
    i.name              AS IndexName,
    SUM(page_count * 8) AS IndexSizeKB
FROM sys.dm_db_index_physical_stats(
    db_id(), object_id('dbo.TableName'), NULL, NULL, 'DETAILED') AS s
JOIN sys.indexes AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
GROUP BY i.name
ORDER BY i.name
结果通常略有不同,但在1%之内。
复制代码

 

 查看堆表及数据量超过10W行的

复制代码
select * from (
SELECT tables.NAME, 
       (SELECT rows 
        FROM   sys.partitions 
        WHERE  object_id = tables.object_id 
               AND index_id = 0 -- 0 is for heap 
               -- 1 is for clustered index 
                And rows >=100000
       )AS numberofrows 
FROM   db_tank.sys.tables tables 
WHERE  Objectproperty(tables.object_id, N'TableHasClustIndex') = 0
)t where numberofrows is not null
复制代码

 

 

查看表数据行数

但这种办法不是实时的,是SQL server定时做的统计操作,执行下面代码可进一步精确

DBCC UpdateUSAGE(DatabaseName,[TABLENAME])WITH ROW_COUNTS

复制代码
SELECT   a.name, b.rows
FROM      sysobjects AS a INNER JOIN
                 sysindexes AS b ON a.id = b.id
WHERE   (a.type = 'u') AND (b.indid IN (0, 1))
ORDER BY b.rows DESC

复制代码

SSMS 实用小技巧_ssms 格式化sql_郑小晨的博客-CSDN博客

mikel阅读(266)

来源: SSMS 实用小技巧_ssms 格式化sql_郑小晨的博客-CSDN博客

一、怎么看Table在哪被用到
选中表→右键→查看依赖关系(V),就可以看到有哪些地方用到这个表。

 

二、SQL格式化
SQL Pretty Printer:SSMS的SQL格式化小插件,对于那些很长的SP,真的挺好用。

下载链接:https://www.dpriver.com/dlaction.php

下载下来后安装,重启SSMS就可以用了。

 

点击SQL Beautifier

1、选择Format All SQL 格式化当前文档所有SQL语句。

2、选择Format Selected SQL格式化选中的SQL语句。

简单好用。。。

最重要的是它还可以设置SQL的格式

SQL Beautifier→SQL Formatter Options

 

三、执行计划
SQL优化一个很好用的东西,可以看到执行耗时,是否有走索引啊。。。

对于懒得去记那么多东西的人来说,超友好

 

四、查看最近执行的SQL
选择 当前连接→活动和监视器(M)

选择其中一条,右键→编辑查询文本

就可以看到执行的SQL语句了

————————————————
版权声明:本文为CSDN博主「郑小晨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012835032/article/details/118994774

IIS 错误解决:当前标识没有对 Temporary ASP.NET Files 的写访问权限 - 独立观察员 - 博客园

mikel阅读(283)

来源: IIS 错误解决:当前标识没有对 Temporary ASP.NET Files 的写访问权限 – 独立观察员 – 博客园

完整错误:

当前标识 (IIS APPPOOL\.NET v4.5) 没有对”C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files” 的写访问权限

 

其中的标识 “.NET v4.5” 是指你的应用程序池,所以每个人可能不一样;后面的路径也可能不一样,比如不是 “Framework” 而是 “Framework64” 之类的。

 

那么这个问题如何解决呢?我们需要使用 Windows PowerShell 来执行 “ASP.NET 注册选项”,具体地说,应该是使用 Aspnet_regiis.exe 程序的相关命令来” 为指定的用户或用户组授予权限,使其可以访问 IIS 元数据库和 ASP.NET 使用的其他目录”。我用网上(https://blog.csdn.net/qq_36981814/article/details/84997624 )提供的方法,在 PowerShell 中输入如下命令:

 

这个其实有点问题,网上的说法是出现这个界面就成功了,其实并不是,出现这种界面一般是命令有误,相关程序输出了帮助信息。不过也好,我们可以看到我们需要的 “-ga” 命令选项,右边是对其的解释 —— 为指定的用户或用户组授予权限,使其可以访问 IIS 元数据库和 ASP.NET 使用的其他目录。

 

那么正确的命令是什么呢?应该将用户或用户组用单引号引起来,如下(注意按实际情况修改):

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Aspnet_regiis.exe -ga ‘IIS APPPOOL\.NET v4.5’

 

还有要用管理员权限的 PowerShell,不然会有如下错误:

 

所以,我们右键 win10 开始菜单,点击 “Windows PowerShell (管理员)(A)”:

 

然后输入命令并回车,即可得到正确结果,问题解决:

vs出现错误,无法启动 Visual Studio。StreamJsonRpc.ConnectionLostException:在请求完成之前,与远程的JSON-RPC连接已丢失_客服专区-CSDN问答

mikel阅读(684)

来源: vs出现错误,无法启动 Visual Studio。StreamJsonRpc.ConnectionLostException:在请求完成之前,与远程的JSON-RPC连接已丢失_客服专区-CSDN问答

这个错误通常是由于Visual Studio的某些组件损坏或缺失导致的。你可以尝试以下方法来解决这个问题:

重置Visual Studio设置:在Visual Studio中,选择“工具”>“导入和导出设置”>“重置所有设置”,然后重新启动Visual Studio。
修复Visual Studio:在Visual Studio安装器中,选择“修改”,然后选择“修复”。
重新安装Visual Studio:如果以上两种方法都无法解决问题,则可以尝试重新安装Visual Studio。
此外,你可以尝试使用Developer Command Prompt for VS2019打开Visual Studio。如果这种方法也不起作用,你可以尝试使用以下命令打开Visual Studio:devenv /nosplash。

🔥🔥微服务架构:软件开发的革命还是短暂潮流? - 努力的小雨 - 博客园

mikel阅读(286)

来源: 🔥🔥微服务架构:软件开发的革命还是短暂潮流? – 努力的小雨 – 博客园

引言

从今天开始,我们将深入探讨服务网格(Service Mesh)这个领域的知识。尽管在我们的工作中可能还没有广泛应用,但服务网格确实是一种趋势。如果你还没有听说过这个概念,我希望你能够跟随我的步伐,一起了解这个特殊而重要的技术。首先,我将为大家介绍微服务的发展历程,从过去到现在,逐渐引入服务网格的概念,帮助大家全面理解这个领域的重要性。

微服务架构的特点

围绕业务构建团队

image

随着技术的不断发展,从最初的单体架构演变为现在的微服务架构。在单体架构中,页面、服务模块和数据库连接操作等都集中在一个系统中,尽管现在一些先进的公司已经将UI层剥离出来,但整体架构仍然相对单一。而微服务架构则将各个模块拆分成独立的微服务,每个微服务都有专门的开发人员负责,使得团队可以根据业务需求,组成几个人的小团队来开发单独的模块。这样的架构特点带来了更高的灵活性和扩展性,使得团队可以更加专注于各自负责的模块,提高开发效率和业务的可维护性。

去中心化的数据管理

image

去中心化的数据管理是微服务架构的一个重要特点。在传统的单体应用中,所有的业务数据都集中在一个数据库中。而在微服务架构中,每个微服务都可以拥有自己独立的数据库,负责维护自身所需的业务数据。这种去中心化的数据管理方式带来了一些优势。它可以提升数据库性能、增强系统的灵活性和可扩展性,同时也提高了系统的可维护性。这里我们不详细赘述了。

微服务架构的优势

微服务架构在团队层面和产品层面都带来了许多优势。

在团队层面,微服务架构鼓励团队内部的内聚性。每个微服务都专注于处理特定的业务功能,团队成员可以更加专注于自己负责的微服务开发和维护。这种独立开发业务的方式,使得团队成员可以更好地理解和掌握自己负责的业务领域,提高了开发效率和质量。

此外,由于每个微服务都是独立的,彼此之间没有直接的依赖关系。这意味着团队可以并行开发不同的微服务,不受其他团队的影响。团队成员之间的沟通和协作也更加简单和高效。

在产品层面,微服务架构的一个重要特点是服务的独立性。每个微服务都是一个独立的服务单元,可以独立部署和运行。这意味着当需要更新或修复某个微服务时,只需要针对该微服务进行部署,而不会影响其他微服务的正常运行。这样可以减少系统的停机时间和风险,提高了系统的可用性和容错性。

此外,由于每个微服务彼此独立,系统可以更加灵活地进行扩展。当某个微服务面临高并发或大数据量的情况时,可以单独对该微服务进行水平扩展,而不需要对整个系统进行扩展。这样可以避免资源的浪费,并且能够更好地应对系统的负载压力。

但是微服务是软件开发的最好选择吗?

微服务面临的问题

image

微服务架构中,服务间的网络调用是一个常见且容易出现问题的挑战。相较于单体架构,在微服务架构中,由于服务的细粒度拆分,服务调用链变得更加复杂。这意味着每个服务可能需要与其他多个服务进行通信,而每个网络调用都有可能引发潜在的故障或延迟。

为何网络通信是微服务的痛点

在微服务架构中,网络通信是一个常见的痛点,这是因为分布式计算中存在着一些被称为”分布式计算的8个谬论”(Fallacies of Distributed Computing)的观念误区。

网络是可靠的:实际上网络是容易受到各种因素干扰和故障的,如硬件故障、网络拥塞等,这可能导致服务之间的通信中断或延迟。

带宽是无限的:实际上网络带宽是有限的资源,当服务之间的数据传输量增加时,带宽可能变得紧张,导致网络通信的性能下降。

网络拓扑从不改变:实际上在分布式系统中,网络拓扑可能会因为硬件故障、网络设备调整等原因而发生变化,这会对服务之间的通信产生影响。

传输成本是0:实际上进行网络通信是需要消耗资源的,如网络带宽、计算能力等,因此进行大量的网络通信可能会导致成本增加。

网络延迟是0:实际上网络通信中存在着传输延迟,这取决于网络拓扑、网络负载、数据包大小等因素,这会对服务之间的通信性能产生影响。

还有一些观念误区,如网络是安全的、只有一个管理员、网络是同构的。

如何管理和控制网络间的通信

在微服务架构中,管理和控制网络间的通信是至关重要的。以下是一些常用的方法和策略:

  1. 服务注册/发现:通过服务注册和发现机制,服务可以在网络中注册自己的信息,并由其他服务发现和使用。这样可以实现动态的服务发现和调用,减少了对服务之间硬编码的依赖。
  2. 路由、流量转移:通过使用路由和流量转移机制,可以将请求从一个服务路由到另一个服务。这对于实现负载均衡、故障转移和容错是非常重要的。例如,可以使用负载均衡器来将请求分发到多个实例,以提高系统的性能和可靠性。
  3. 弹性能力(熔断、超时、重试):在网络通信中,存在各种故障和不可靠的情况。为了提高系统的弹性和容错能力,可以实现熔断、超时和重试机制。例如,当一个服务不可用或响应时间过长时,可以暂时关闭对该服务的请求,以避免系统的级联故障。
  4. 安全:网络通信中的安全性是非常重要的。可以使用各种安全措施,如身份验证、授权和加密,来保护服务之间的通信和数据的安全性。例如,可以使用HTTPS来加密网络通信,以防止信息被窃听或篡改。
  5. 可观测性:为了更好地管理和监控网络通信,可以引入可观测性的机制。这包括日志记录、指标收集和分析、分布式追踪等。通过收集和分析这些数据,可以获得对网络通信的实时和历史视图,以便进行故障排查、性能优化和系统监控。

如果你和我一样是以Java为主要开发语言,那么对于这些策略可能并不陌生,因为我们有一些成熟的开源框架可以用来解决这些问题。然而,问题来了,如果我们的系统不仅限于纯Java系统,还包含其他的业务系统,那么我们应该如何应对呢?

总结

在本文中,我们详细讲解了从单体架构到微服务的演变过程,并在阐述微服务的优势时也指出了微服务所面临的问题。接下来的章节中,我将带领大家深入了解服务网格是如何解决这些问题的。我们将探讨服务网格的核心概念、架构设计以及它如何提供弹性、可观察性和安全性等关键特性。