一、Node.js 全栈开发材料
1、前端入门根底
- 慕课网HTML +CSS入门
- 慕课网JS入门
- javascript进阶篇
- 菜鸟教程html局部
- 菜鸟教程CSS局部
- 阮一峰js入门
- 阮一峰es6教程
- html中文网
- JavaScript中文网
2、node 后端入门根底
- node入门
- Linux基础知识
- mysql数据库常识
- 数据库事务
- sequelize中文文档
- Express框架官网文档
- Koa官网文档
- koa框架教程
- Egg.js官网
3、深入浅出Node.js-朴灵
- 链接:https://pan.baidu.com/s/1Aemx...
- 提取码:nbso
4、vue学习材料
- vue官网文档
- 视频教程 )
- vuex官网文档
- vue-router官网文档
- axios中文文档
- ElementUI官网文档
- webpack官网文档
- webpack5视频教程
5、flex布局
- flex 布局教程:语法篇
- Flex 布局教程:实例篇
- flexb布局视频教程
二、JSON
1、JSON教程
2、JSON.stringfy() 和 JSON.parse()
2.1 JSON.stringfy() 将对象、数组转换成 JSON字符串
概述:
JSON.stringfy()办法是将一个JavaScript值(对象或者数组)转换为一个 JSON 字符串,如果指定了replacer是一个函数,则能够选择性的替换值,或者如果指定了replacer是一个数组,可选择性的仅蕴含数组指定的属性。 ```js1.转换值如果有toJSON()办法,该办法定义什么值将被序列化。2.非数组对象的属性不能保障以特定的程序呈现在序列化后的字符串中。3.布尔值、数字、字符串的包装对象在序列化过程中会主动转换成对应的原始值。4.undefined 任意的函数以及 symbol 值,在序列化过程中会被疏忽(呈现在非数组对象的属性值中时)或者被转换成 null(呈现在数组中时)。函数、undefined被独自转换时,会返回undefined,JSON.stringify(function(){}) or JSON.stringify(undefined).5.对蕴含循环援用的对象(对象之间互相援用,造成有限循环)执行此办法,会抛出谬误。6.所有以 symbol 为属性键的属性都会被齐全疏忽掉,即使 replacer 参数中强制指定蕴含了它们。7.Date日期调用了toJSON()将其转换为了string字符串(同Date.toISOString()),因而会被当做字符串解决。8.NaN和Infinity格局的数值及null都会被当做null。9.其余类型的对象,包含Map/Set/weakMap/weakSet,仅会序列化可枚举的属性。```
- 例子:
```jsJSON.stringify({}); // '{}'JSON.stringify(true); // 'true'JSON.stringify("foo"); // '"foo"'JSON.stringify([1, "false", false]); // '[1,"false",false]'JSON.stringify({ x: 5 }); // '{"x":5}'JSON.stringify({x: 5, y: 6}); // "{"x":5,"y":6}"JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); // '[1,"false",false]'
JSON.stringify({x: undefined, y: Object, z: Symbol("")}); // '{}'
JSON.stringify([undefined, Object, Symbol("")]); // '[null,null,null]'
JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'
JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]);// '{}'
JSON.stringify(
{[Symbol.for("foo")]: "foo"}, function (k, v) { if (typeof k === "symbol"){ return "a symbol"; } });
// undefined
// 不可枚举的属性默认会被疏忽:
JSON.stringify(
Object.create( null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } } ));// "{"y":"y"}"```
语法:JSON.stringfy(value [,replacer] [,space])
- value 是必选字段,就是输出对象,比方数组,类等。
replacer: 可选的,它又分为2种形式,一种是数组,一种是办法
replacer参数能够是一个函数或者一个数组。作为函数,它有两个参数,键(key)值(value)都会被序列化。1.如果返回一个 Number, 转换成相应的字符串被增加入JSON字符串。2.如果返回一个 String, 该字符串作为属性值被增加入JSON。3.如果返回一个 Boolean, "true" 或者 "false"被作为属性值被增加入JSON字符串。4.如果返回任何其余对象,该对象递归地序列化成JSON字符串,对每个属性调用replacer办法。除非该对象是一 个函数,这种状况将不会被序列化成JSON字符串。5.如果返回undefined,该属性值不会在JSON字符串中输入。留神: 不能用replacer办法,从数组中移除值(values),如若返回undefined或者一个函数,将会被null取 代。
状况一:
replacer为数组时,它是和第一个参数value有关系的。一般来说,序列化后的后果是通过键值对来进行表 示的。所以,如果此时第二个参数的值在第一个存在,那么就以第二个参数的值做key,第一个参数的值为 value进行示意,如果不存在,就疏忽。1、第二个参数的值在第一个存在var str = {"name" : "张三", "site": "http://www.baidu.com"}const str_pretty1 = JSON.stringify(str, ["name","site"])console.log(str_pretty1)输入后果:{"name":"张三","site":"http://www.baidu.com"}2、第二个参数的值在第一个不存在var str = {"name" : "张三", "site": "http://www.baidu.com"}const str_pretty1 = JSON.stringify(str, ["username","address"])console.log(str_pretty1)输入后果:{}3、不写第二个参数var str = {"name" : "张三", "site": "http://www.baidu.com"}const str_pretty1 = JSON.stringify(str)console.log(str_pretty1)输入后果:{"name":"张三","site":"http://www.baidu.com"}
状况二:
replacer为办法时,那很简略,就是说把序列化后的每一个对象(记住是每一个)传进办法外面进行解决。function replacer(key, value) { if (typeof value === "string") { return undefined } return value }const foo = { name: "张三", age: 18, sex: "女", address: "吉祥村" }const jsonString = JSON.stringify(foo, replacer)console.log(jsonString)JSON序列化的后果为: {"age":18}
space: 就是用什么来做宰割符的。
1.如果省略的话,那么显示进去的值就没有分隔符,间接输入来 。 2.如果是一个数字的话,那么它就定义缩进几个字符,当然如果大于10 ,则默认为10,因为最大值为10。3.如果是一些转义字符,比方“\t”,示意回车,那么它每行一个回车。4.如果仅仅是字符串,就在每行输入值的时候把这些字符串附加下来。当然,最大长度也是10个字符。
```js const strSpace = JSON.stringify({ a: 1, b: 2 }, null, '\t') console.log(strSpace) 输入后果: { "a": 1, "b": 2 } ``` - 返回值: 一个给定值的 JSON 字符串
2.2 JSON.parse() 将JSON字符串转换成JavaScript对象
- 概述
JSON通常用于与服务端替换数据,在接管服务端数据时个别是字符串,
咱们能够应用 JSON.parse()办法将数据转换为 JavaScript 对象。 - 语法:JSON.parse(text [, reviver])
参数
- text 必须。 一个无效的 JSON 字符串。
- reviver
可选。 一个转换后果的函数。将为对象的每个成员调用此函数。如果成员蕴含嵌套对象,则先于父对象转换 嵌套对象。对于每个成员,会产生以下状况:如果 reviver 返回一个有效值,则成员值将替换为转换后的 值。如果 reviver 返回它接管的雷同值,则不批改成员值。如果 reviver 返回 null 或 undefined,则删除成员。
返回值:
一个对象或数组。var string = { "name" : "张三", "sex" : "女", "address" : "吉祥村" }var obj = JSON.parse('{ "name" : "张三", "sex" : "女", "address" : "吉祥村" }')console.log(obj)输入后果: { name: '张三', sex: '女', address: '吉祥村' }留神:解析前要确保你的数据是规范的 JSON 格局,否则会解析出错
3、toJSON()
3.1定义和用法
- toJSON()办法能够将 Date 对象转换为字符串,并格式化为 JSON 数据格式 - JSON 数据用同样的格局就像x ISO-8601 规范: YYYY-MM-DDTHH:mm:ss.sssZ
3.2实例
```jsconst d = new Date()const a = d.toJSON()console.log(a)输入后果: 2022-01-01T11:40:13.147Z```
如果一个被序列化的对象领有 toJSON 办法,那么该 toJSON 办法就会笼罩该对象的序列化行为:不是那个对象被序列化,而是调用 toJSON 办法后的返回值会被序列化。
例如:
var obj = { foo: 'foo', toJSON: function() { return 'bar' }}const stringFy = JSON.stringify(obj)console.log(stringFy) // "bar"const string = JSON.stringify({ x: obj })console.log(string) // {"x":"bar"}
4、localStorage/sessionStorage/Cookie的区别及用法
4.1webstorage
webstorage是本地存储,存储在客户端,包含 localStorage和sessionStorage
4.2localStorage
localStorage生命周期是永恒,这意味着除非用户显示在浏览器提供的UI上革除localStorage信息,否则这些信息将永远存在。存放数据大小为个别为5MB,而且它不仅在客户端(即浏览器)中保留,不参加和服务器的通信。
4.3sessionStorage
sessionStorage仅在以后会话下无效,敞开页面或浏览器后被革除。存放数据大小为个别为5MB,而且它仅在客户端(即浏览器)中保留,不参加和服务器的通信。源生接口能够承受,亦可再次封装来对Object和Array有更好的反对。
localStorage和sessionStorage应用时应用雷同的API:
localStorage.setItem("key","value");//以“key”为名称存储一个值“value”localStorage.getItem("key"); //获取名称为“key”的值localStorage.removeItem("key"); //删除名称为“key”的信息。localStorage.clear(); //清空localStorage中所有信息
- 作用域不同
不同浏览器无奈共享localStorage或sessionStorage中的信息。雷同浏览器的不同页面间能够共享雷同的 localStorage(页面属于雷同域名和端口),然而不同页面或标签页间无奈共享sessionStorage的信息。这里须要留神的是,页面及标签页仅指顶级窗口,如果一个标签页蕴含多个iframe标签且他们属于同源页面,那么他们之间是能够共享sessionStorage的。
- Cookie
生命期为只在设置的cookie过期工夫之前始终无效,即便窗口或浏览器敞开。存放数据大小为4K左右。有个数限度(各浏览器不同),个别不能超过20个。与服务器端通信:每次都会携带在HTTP头中,如果应用cookie保留过多数据会带来性能问题。但Cookie须要程序员本人封装,源生的Cookie接口不敌对(http://www.jb51.net/article/6...\
)。
//Cookie办法<script src="../js/cookie.js"></script> //Cookie函数本人封装引入function foo(){ if(getCookie("isClose")){ $(".header").hide(); }else{ $(".header").show(); } $(".close").click(function(){ $(".header").fadeOut(1000); setCookie("isClose", "1","s10"); }) } foo();
cookie的长处:具备极高的扩展性和可用性
1.通过良好的编程,管制保留在cookie中的session对象的大小。2.通过加密和平安传输技术,缩小cookie被破解的可能性。3.只有在cookie中寄存不敏感的数据,即便被盗取也不会有很大的损失。4.管制cookie的生命期,使之不会永远无效。这样的话盗窃者很可能拿到的就是一个过期的cookie。
cookie的毛病:
1.cookie的长度和数量的限度。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB。否则会被截掉。2.安全性问题。如果cookie被人拦掉了,那个人就能够获取到所有session信息。加密的话也不起什么作用。3.有些状态不可能保留在客户端。例如,为了避免反复提交表单,咱们须要在服务端保留一个计数器。若吧计数器保留在客户端,则起不到什么作用。
- localStorage、sessionStorage、Cookie共同点:都是保留在浏览器端,且同源的。
- 应用 JSON.stringify 联合 localStorage 的例子
一些时候,你想存储用户创立的一个对象,并且,即便在浏览器被敞开后仍能复原该对象。上面的例子是 JSON.stringify 实用于这种情景的一个样板:
// 创立一个示例数据var session = { 'screens': [], 'state': true};session.screens.push({"name":"screenA", "width":450,"height":250})session.screens.push({"name":"screenB", "width":650, "height":350})session.screens.push({"name":"screenC", "width":750,"height":120})// 应用 JSON.stringify 转换为 JSON 字符串// 而后应用 localStorage 保留在 session 名称里localStorage.setItem('session', JSON.stringify(session));// 而后是如何转换通过 JSON.stringify 生成的字符串,该字符串以 JSON 格局保留在 localStorage 里var restoredSession = JSON.parse(localStorage.getItem('session'));// 当初 restoredSession 蕴含了保留在 localStorage 里的对象console.log(restoredSession);
三、Vue.js
1、vue 脚手架我的项目搭建
- 全局装置脚手架
npm install -g @vue/cli-低版本装置npm install -g @vue/cli-init
- 在想要创立我的项目的目录下关上cmd命令行(抉择须要装置的一个版本即可)
注:hello-word是我要装置的我的项目名,依据理论需要更改我的项目名(1) 3.X版本装置(不会看到webpack的配置文件)vue create hello-world
- 装置步骤
(1)3.X装置步骤: ①、零碎将提醒您抉择预设: 能够抉择根本Babel + ESLint设置附带的默认预设,也能够抉择“手动抉择性能”以抉择所需的性能 (举荐抉择第二个,手动抉择) ②、依据集体须要抉择配置项(抉择办法:空格即可) ③、路由是否抉择history模式(举荐抉择 y,如果抉择n,路由将默认为hash模式) ④、selint语法抉择(举荐抉择eslint+standard config:规范模式) ⑤、检测形式(举荐抉择lint on sava) ⑥、文件类型(举荐应用json) ⑦、保留以后的配置为预设,以供将来应用(举荐应用 y) ⑧、保留预设并命名(2)低版本装置步骤: 后面四步都能够一路回车,第五步询问是否装置vue-router,抉择是,第六步应用eslint代码查看,依据集体状况抉择是或否,第七步设置单元测试,抉择否,第八步测试监听,抉择否,第九步抉择npm即可,期待装置实现 (其实装置都没有固定的步骤,齐全依据集体我的项目需要,这里只是举荐大众化的步骤) 链接:https://juejin.cn/post/6844904037674909709
- 文件夹详解
(1)、src文件夹搁置所有的资源文件,个别会被webpack用来打包 ①assets文件夹搁置资源文件,如:css,js,fonts ②components文件夹搁置所有的子组件,即每个页面级组件的子组件,例如:index页面级组件,把它分为header、content、footer三局部,只有在components文件夹下新建一个index文件夹(为了辨别其余组件),放入对应的子组件 ③pages文件夹搁置所有的页面级组件 ④router文件夹中index用来配置路由信息 ⑤main.js是入口文件,可在此引入公共的款式等 (2)、static搁置的资源文件不会最终被weback打包(个别搁置图片文件和本地模仿的json数据)├── node_modules\├── public\│ ├── favicon.ico: 页签图标\│ └── index.html: 主页面\├── src\│ ├── assets: 寄存动态资源\│ │ └── logo.png\│ │── component: 寄存组件\│ │ └── HelloWorld.vue\│ │── App.vue: 汇总所有组件\│ │── main.js: 入口文件\├── .gitignore: git版本管制疏忽的配置\├── babel.config.js: babel的配置文件\├── package.json: 利用包配置文件\├── README.md: 利用形容文件\├── package-lock.json:包版本控制文件
- 更改配置
(1)、更改App.vue文件 <template> <div id="app"> <img src="/static/logo.png"> <router-view/> </div> </template> 更改为:(目标:插入一个路由插槽,进行页面的跳转,显示不同的路由) <template> <router-view></router-view> </template>(2)、更改main.js文件 new Vue({ el: '#app', router, components: { App }, template: '<App/>' }) 更改为:(目标:以app做为根组件,每次在路由插槽渲染页面)(如果有语法报错,禁用eslint查看即可) new Vue({ el: '#app', router, render(h){ return h(App) } })(3)、更改router文件夹的index文件(依据我的项目需要,引入对应页面,配置路由信息,进行页面跳转)( / 代表跟门路) import Vue from 'vue' import Router from 'vue-router' // import HelloWorld from '@/components/HelloWorld' // 首页 import Index from "../pages/Index"; // 登录 import Login from "../pages/Login" Vue.use(Router); export default new Router({ linkExactActiveClass: "act", mode: "history", routes: [ { path: '/Index', name: 'Index', component: Index }, { path: '/', name: 'Login', component: Login } ] })
- 我的项目启动形式
(1)3.X版本启动形式 npm run serve(2)低版本启动形式 npm run dev
2、插件
概念
插件通常用来为 vue 增加全局性能。插件的性能范畴没有严格的限度,个别有上面几种:1.增加全局办法或者属性。如:vue-custom-element2.增加全局资源:指令/过滤器/适度等。如:vue-touch3.通过全局混入来增加一些组件选项。如: vue-router4.增加 Vue 实例办法,通过把它们增加到 Vue.prototype 上实现。5.一个库,提供本人的 API,同时提供下面提到的一个或多个性能。如: vue-router
应用办法
通过全局办法 Vue.use() 应用插件。它须要在你调用 new Vue() 启动利用之前实现:```js// 调用 MyPlugin.install(Vue)Vue.use(MyPlugin)new Vue({
// ...组件选项
})```
为避免屡次注册同一个组件:咱们能够传递一个可选的对象
Vue.use(MyPlugin, { someOption: true })
Vue.use会主动阻止屡次注册雷同插件,届时即便屡次调用也只会注册一次该插件
留神点:
Vue.js 官网提供的一些插件 (例如 vue-router) 在检测到 Vue 是可拜访的全局变量时会主动调用 Vue.use()。然而在像 CommonJS 这样的模块环境中,你应该始终显式地调用 Vue.use():```js// 用 Browserify 或 webpack 提供的 CommonJS 模块环境时var Vue = require('vue')var VueRouter = require('vue-router')// 不要忘了调用此办法Vue.use(VueRouter)```
2.1 nextTick
- 语法
this.$nextTick(回调函数)
- 作用
在下一次 DOM 更新完结后执行其指定的回调。什么时候用:当扭转数据后,要基于更新后的新DOM进行某些操 作时,要在nextTick所指定的回调函数中执行。
3、flex布局
3.1 flex 布局体验
传统布局与 flex 布局
传统布局
1.兼容性好2.布局繁琐3.局限性,不能在挪动端很好的布局
flex 布局
1.操作不便,布局极为简略,挪动端利用很宽泛2.PC 端浏览器反对状况较差3.IE 11 或更低版本,不反对或仅局部反对
- 初体验
- 初体验
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 80%; height: 300px; background-color: pink; justify-content: space-around; } div span { /* width: 150px; */ height: 100px; background-color:purple; margin-right: 5px; flex: 1; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> </div></body></html>
3.2 flex 布局原理
- 布局原理
flex 是 flexible Box 的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性,任何一个容器都能够 指定为 flex 布局。
1.当咱们为父盒子设为 flex 布局当前,子元素的 float、clear 和 vertical-align 属性将生效。2.伸缩布局 === 弹性布局 === 伸缩盒布局 === 弹性盒布局 === flex 布局
采纳 Flex 布局的元素,称为 Flex 容器 (flex container),简称“容器”。它的所有子元素主动成为容器成员, 称为 Flex 我的项目(flex item), 简称“我的项目”
1.体验中 div 就是 flex 父容器2.体验中 span 就是 子容器 flex 我的项目3.子容器能够横向排列也能够纵向排列
总结 flex 布局原理:就是通过给父盒子增加 flex 属性,来管制子盒子的地位和排列形式
3.3 flex 布局父项常见属性
- 常见父项属性
以下有6个属性是对父元素设置的
1.flex-direction: 设置主轴的方向2.justify-content: 设置主轴上的子元素排列形式3.flex-warp: 设置子元素是否换行4.align-content: 设置侧轴上的子元素的排列形式(多行)5.align-items: 设置侧轴上的子元素排列形式(单行)6.flex-flow: 复合属性,相当于同时设置了 flex-direction 和 flex-warp
flex-direction 设置主轴的方向
主轴与侧轴
在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有:行和列、x 轴和 y 轴1.默认主轴方向就是 x 轴方向,程度向右2.默认侧轴方向就是 y 轴方向,程度向下
- 属性值
flex-direction属性决定主轴的方向(即我的项目的排列方向)
留神:主轴和侧轴是会变动的,就看 flex-direction设置为主轴,剩下的就是侧轴,而咱们的子元素是跟着主轴来排列的
属性值 | 阐明 |
---|---|
row | 默认值从左到有 |
row-reverse | 从右到左 |
column | 从上到下 |
column-reverse | 从下到上 |
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { /* 给父级增加 flex 属性 */ display: flex; width: 800px; height: 300px; background-color: pink; /* 默认的主轴是 x 轴 行 row 那么 y 轴就是侧轴*/ /* 咱们的元素是跟着主轴来排列的 */ /* flex-direction: row; */ /* 翻转 */ /* flex-direction: row-reverse; */ /* 主轴设置为 y 轴,那么 x 轴就成了侧轴 */ flex-direction: column; } div span { width: 150px; height: 100px; background-color: purple; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> </div></body></html>
- justify-content 设置主轴上的子元素排列形式
1.justify-content 属性定义了我的项目在主轴上的对齐形式留神:应用这个属性之前肯定要确定好主轴是那个
属性值 | 阐明 |
---|---|
flex-start | 默认值从头部开始 如果主轴是 x 轴,则从左到右 |
flex-end | 从尾部开始排序 |
center | 在主轴居中对齐(如果主轴是x轴则程度居中) |
space-around | 平分残余空间 |
space-between | 先两边贴边 再平分残余空间(重要) |
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 80%; height: 300px; background-color: pink; /* 默认的主轴是 x 轴 row */ flex-direction: row; /* justify-content: 是设置主轴多行子元素的排列形式 */ /* justify-content: flex-start */ /* justify-content: end; */ /* 让子元素居中对齐 */ /* justify-content: center; */ /* 平分残余空间 */ /* justify-content: space-around; */ /* 先两边贴边,在调配残余空间 */ justify-content: space-between; } div span { width: 150px; height: 100px; background-color:purple; margin-right: 5px; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> <span>4</span> </div></body></html>
- flex-warp 设置子元素是否换行
默认状况下,我的项目都排在一条线上(又称"轴线")上,flex-warp属性定义,flex 布局中默认是不换行的。
属性值 | 阐明 |
---|---|
nowrap | 默认值,不换行 |
wrap | 换行 |
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 600px; height: 400px; background-color: pink; /* flex 布局中,默认的子元素是不换行的,如果装不开,会放大子元素的宽度,放到父元素外面 */ /* flex-wrap: nowrap; */ flex-wrap: wrap; } div span { width: 150px; height: 100px; background-color:purple; color: #fff; margin: 10px; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </div></body></html>
- align-items 设置侧轴上的子元素排列形式(单行)
该属性是管制子项在侧轴(默认是 y 轴)上的排列形式,在子项为单项的时候应用
属性值 | 阐明 |
---|---|
flex-start | 默认值 从上到下 |
flex-end | 从下到上 |
center | 挤在一起居中(垂直居中) |
stretch | 拉伸 |
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 800px; height: 400px; background-color: pink; /* 默认的主轴是 x 轴 row */ flex-direction: column; justify-content: center; /* 须要一个侧轴居中 */ align-items: center; /* 拉伸,然而子盒子不要给高度 */ /* align-items: stretch; */ } div span { width: 150px; height: 100px; background-color:purple; color: #fff; margin: 10px; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> </div></body></html>
- align-content 设置侧轴上的子元素的排列形式(多行)
设置子项在侧轴上的排列形式并且只能用于子项呈现换行的状况(多行),在单行下是没有成果的。
属性值 | 阐明 |
---|---|
flex-start | 默认值在侧轴的头部开始排列 |
flex-end | 在侧轴的尾部开始排列 |
center | 在侧轴两头显示 |
space-around | 子项在侧轴平分残余空间 |
space-between | 子项在侧轴先散布在中间,再平分残余空间 |
stretch | 设置子项元素高度平分父元素高度 |
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 800px; height: 400px; background-color: pink; /* 换行 */ flex-wrap: wrap; /* 因为有了换行,此时咱们侧轴上管制子元素的对齐形式咱们用 align-content */ /* align-content: flex-start; */ /* align-content: center; */ /* align-content: space-between; */ align-content: space-around; } div span { width: 150px; height: 100px; background-color:purple; color: #fff; margin: 10px; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> <span>6</span> </div></body></html>
align-content 和 align-items 区别
1.align-items 实用于单行状况下,只有上对齐、下对齐、居中和拉伸2.align-content 实用于换行(多行)的状况下(单行状况下有效),能够设置上对齐、下对其、居中、拉伸以及平均分配残余空间等属性值3.总结就是单行找 align-items 和多行找 align-content
- flex-flow
flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 600px; height: 400px; background-color: pink; /* flex-direction: column; flex-wrap: wrap; */ /* 把设置主轴方向和是否换行(换列)简写*/ flex-flow: column wrap; } div span { width: 150px; height: 100px; background-color:purple; color: #fff; margin: 10px; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> <span>6</span> </div></body></html>
3.4 flex 布局子项常见属性
1.flex 子项目占的份数2.align-self管制子项本人在侧轴的排列形式3.order 属性定义子项的排列程序(前后程序)
flex 属性定义子项目调配残余空间,用 flex 来示意占多少份数
.item { flex: <number>; /* default 0 */}
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> section { display: flex; width: 60%; height: 200px; background-color: pink; margin: 0 auto; } section div { height: 150px; flex: 1; margin: 10px; background-color: sienna; } section div:nth-child(6) { height: 150px; flex: 2; background-color: sandybrown; margin: 10px; } p { display: flex; width: 60%; height: 200px; background-color: rosybrown; margin: 100px auto; } p span { flex: 1; } p span:nth-child(2) { flex: 2; background-color: seagreen; } </style></head><body> <section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </section> <p> <span>1</span> <span>2</span> <span>3</span> </p></body></html>
- align-self 管制子项本人在侧轴上的排列形式
align-self属性容许单个我的项目有与其余我的项目不一样的对齐形式,可笼罩 align-items 属性。默认值为 auto,示意继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch - order 属性定义我的项目的排列程序
数值越小,排列越靠前,默认为 0。留神:和 z-index 不一样
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { display: flex; width: 60%; height: 300px; background-color: pink; /* 让三个子盒子沿着侧轴底侧对齐 */ /* align-items: flex-end; */ /* 想只让3号盒子下来底侧 */ } div span { width: 20%; height: 100px; background-color: plum; margin-right: 10px; } div span:nth-child(2) { /* 默认是0, -1 比 0 小所以在后面 */ order: -1; } div span:nth-child(3) { align-self: flex-end; } section { display: flex; width: 60%; height: 400px; background-color: pink; margin-top: 100px; /* 默认的主轴是 x 轴 row */ flex-direction: row; justify-content: center; /* 须要一个侧轴居中 */ align-items: center; } section span { flex: 1; height: 150px; background-color: powderblue; margin: 10px; } section span:nth-child(2) { flex: 2; } </style></head><body> <div> <span>1</span> <span>2</span> <span>3</span> </div> <section> <span>1</span> <span>2</span> </section></body></html>
4、refs、emit、props三中的传参形式区别和应用
4.1 $refs的应用
- 父组件
<!-- 父组件 --><template> <div> <h1>我是父组件!</h1> <child ref="msg"></child> </div></template><script> import Child from '../components/child.vue' export default { components: {Child}, mounted: function() { console.log(this.$refs.msg) this.$refs.msg.getMessage('我是子组件一!') } }</script>
- 子组件
<!-- 子组件 --><template> <h3>{{ message }}</h3></template><script> export default { data() { return { message: '' } }, methods: { getMessage(m) { this.message = m } } }</script>
通过 ref = 'msg' 能够将子组件 child 的实例指给 $refs,并且通过 .msg.getMessage() 调用到子组件的 getMessage 办法, 将参数传递给子组件。
4.2 $emit的应用形式
$emit 绑定一个自定义事件 event,当这个语句被执行到的时候,就会将参数 arg 传递给父组件,父组件通过 @event 监听并承受参数。
- 父组件
<template> <div> <h1>我是父组件</h1> <child message="我是子组件一!"></child> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <child v-bind:message="a+b"></child> <!-- 用一个变量进行动静赋值。--> <child v-bind:message="msg"></child> <other-child @getMessage="showMsg"></other-child> <h1>{{ content }}</h1> </div></template><script> import Child from '../components/child.vue' import OtherChild from '../components/otherChild.vue' export default { data () { return { a: '我是子组件二!', b: 112233, msg: '我是子组件三!' + Math.random(), content: '' } }, methods: { showMsg(title) { this.content = title } } }</script>
- 子组件
<template> <h3>我是子组件!</h3></template>export default { mounted: function() { this.$emit('getMessage', '我是子组件传给父组件的参数!') }}
4.3 props的应用形式
子组件的 props 选项可能承受来自父组件数据
性能:让组件接管内部传过来的数据传递数据:`<Demo name="xxx"/>`接收数据:第一种形式(只接管):`props:['name']`第二种形式(限度类型):`props:{name:String}`第三种形式(限度类型、限度必要性、指定默认值):props:{ name:{ type:String, //类型 required:true, //必要性 default:'老王' //默认值 }}备注:props是只读的,Vue底层会监测你对props的批改,如果进行了批改,就会收回正告,若业务需要的确须要批改,那么请复制props的内容到data中一份,而后去批改data中的数据。
- 父组件(这里采纳的是动静传递)
<!-- 父组件 --> <template> <div> <h1>我是父组件!</h1> <child message="我是子组件一!"></child> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <child v-bind:message="a+b"></child> <!-- 用一个变量进行动静赋值。--> <child v-bind:message="msg"></child> </div> </template><script> import Child from '../components/child.vue' export default { components: {Child}, data () { return { a: '我是子组件二!', b: 112233, mas: '我是子组件三!' + Math.random() } } }</script>
- 子组件
<template> <h3>{{ message }}</h3></template><script> export default { props: ['message'] }</script>
4.4 三者的应用场景和区别
- $refs
$refs用于数据之间的传递,如果ref用在子组件上能通过$refs获取到子组件节点、事件、数据、属性,次要还是父组件向子组件通信$refs 着重于索引,次要用来调用子组件里的属性和办法,其实并不善于数据传递。而且ref用在dom元素的时候,能使到选择器的作用,这个性能比作为索引更常有用到。
- $emit
$emit用于事件之间的传递, 能够实现子组件传参给父组件$emit次要是能够在子组件中触发父组件外面的办法
- props
props用于父组件向子组件传递数据信息,传参形式是单向传输,只能父组件传给子组件,不能实现子组件传参给父组件.props 着重于数据的传递,它并不能调用子组件里的属性和办法。像创立文章组件时,自定义题目和内容这样的应用场景,最适宜应用prop。
4.5 父组件向子组件传值
- 父组件向子组件传值步骤:
在这里先定义一下,绝对本案例来说:App.vue是父组件,Second-module.vue是子组件。
1.首先,值必定是定义在父组件中的,供所有子组件共享。所以要在父组件的data中定义值:
2.其次,父组件要和子组件有契合点:就是在父组件中调用、注册、援用子组件:**调用: import Secondmodule from './components/Second-module'注册: components: { // 部分注册组件这里,可能会定义多个组件,所以 component 这个单词加上 ‘s’ SecondModule }援用: <!-- 实现父组件给子组件传值 --> <second-module v-bind:newLists="newLists" v-bind:secondList="secondList"></second-module>
3.接下来,就能够在父组件和子组件链接的中央(即援用子组件的标签上),把父组件的值绑定给子组件: <!-- 实现父组件给子组件传值 --> <second-module v-bind:newLists="newLists" v-bind:secondList="secondList"></second-module>
这里绑定了两个值,一个是数组,一个是字符串。
总的来说父传子就是这三个步骤:父组件中定义值、调用子组件并援用、在援用的标签上给子组件传值。
然而留神是要用 v-bind: 绑定要传的值,不必v-bind间接把值放到标签上,会被当成html的节点属性解析的。
4.最初,子组件外部必定要去承受父组件传过来的值:props(小道具)来接管:**
5.这样,子组件外部就能够间接应用父组件的值了。
然而有要**留神**的点:**子组件承受的父组件的值分为——援用类型和一般类型两种,**一般类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)**援用类型:数组(Array)、对象(Object)**其中,一般类型是能够在子组件中更改,不会影响其余兄弟子组件内同样调用的来自父组件的值,然而,援用类型的值,当在子组件中批改后,父组件的也会批改,那么结果就是,其余同样援用了改值的子组件外部的值也会跟着被批改。除非你有非凡的要求这么去做,否则最好不要这么做。父组件传给子组件的值,在子组件中千万不能批改,因其数据是专用的,改了所有援用的子组件就都改了。
(6)Object.assign()的应用
- Object.assign()对象的拷贝
Object.assign() 办法用于将所有可枚举的值从一个或多个源对象复制到指标对象。它将返回指标对象。Object.assign(target, ...sources) [target: 指标对象],[source: 源对象(可多个)]案列: const object1 = { a: 1, b: 2, c: 3 } const object2 = Object.assign({ c: 4, d: 5 }, object1) console.log(object2) // { c: 3, d: 5, a: 1, b: 2 }留神:1.如果指标对象中的属性具备雷同的键,则属性将被源对象中的属性笼罩。前面的源对象的属性将相似地笼罩后面的源对象的属性2.Object.assign 办法只会拷贝源对象本身的并且可枚举的属性到指标对象。该办法应用源对象的[[Get]]和指标对象的[[Set]],所以它会调用相干 getter 和 setter。因而,它调配属性,而不仅仅是复制或定义新的属性。如果合并源蕴含getter,这可能使其不适宜将新属性合并到原型中。为了将属性定义(包含其可枚举性)复制到原型,应应用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
- Object.assign()对象的深拷贝
1.针对深拷贝,须要应用其余方法,因为 Object.assign()拷贝的是属性值。如果源对象的属性值是一个对象的援用,那么它也只指向那个援用。 const obj1 = { a: 0, b: { c: 1 } } const obj2 = Object.assign({}, obj1) console.log(obj2) // { a: 0, b: { c: 1 } } const obj3 = JSON.stringify(obj2) console.log(obj3) // {"a":0,"b":{"c":1}} obj1.a = 2 console.log(JSON.stringify(obj1)) // {"a":2,"b":{"c":1}} console.log(JSON.stringify(obj2)) // {"a":0,"b":{"c":1}} obj2.a = 3 console.log(JSON.stringify(obj1)) // {"a":2,"b":{"c":1}} console.log(JSON.stringify(obj2)) // {"a":3,"b":{"c":1}} obj2.b.c = 4 console.log(JSON.stringify(obj1)) // {"a":2,"b":{"c":4}} console.log(JSON.stringify(obj2)) // {"a":3,"b":{"c":4}}最初一次赋值的时候,b的值是对象的援用,只有批改一次,其余的也会影响2.深拷贝const obj1 = {a: 1, b: { c: 1 }}const obj2 = JSON.parse(JSON.stringify(obj1))console.log(obj2) // { a: 1, b: { c: 1 } }obj1.a = 2obj1.b.c = 2;console.log(JSON.stringify(obj2)) // {"a":1,"b":{"c":1}}3.如何辨别深拷贝与浅拷贝,简略点来说,就是假如B复制了A,当批改A时,看B是否会发生变化,如果B也跟着变了,阐明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。 根本数据类型有哪些,**number,string,boolean,null,undefined,symbol**以及将来ES10新增的**BigInt**(任意精度整数)七类。
- 对象的合并
const o1 = { a: 1 }const o2 = { b: 2 }const o3 = { c: 3 }const obj1 = Object.assign(o1,o2,o3)console.log(obj1) // { a: 1, b: 2, c: 3 }console.log(o1) // { a: 1, b: 2, c: 3 } 留神指标对象本身也会扭转其实就是对象的拷贝,o1就是指标对象,前面的是源对象,前面的属性等会拷贝到指标对象
- 合并具备雷同属性的对象
const o1 = { a: 1, b: 1, c: 1 };const o2 = { b: 2, c: 2 };const o3 = { c: 3 };const obj = Object.assign({}, o1, o2, o3);console.log(obj); // { a: 1, b: 2, c: 3 }1.属性被后续参数中具备雷同属性的其余对象笼罩。2.指标对象的属性与源对象的属性雷同,源的会笼罩指标的属性
- 继承属性和不可枚举属性是不能拷贝的
const obj = Object.create({foo: 1}, { // foo 是个继承属性。 bar: { value: 2 // bar 是个不可枚举属性。 }, baz: { value: 3, enumerable: true // baz 是个本身可枚举属性。 }});创建对象时,如果没有设置enumerable的值,默认为false(不可枚举属性),设置为true,则为可枚举属性const copy = Object.assign({}, obj);console.log(copy); // { baz: 3 }
- 原始类型会被包装为对象
const v1 = "abc";const v2 = true;const v3 = 10;const v4 = Symbol("foo")const obj = Object.assign({}, v1, null, v2, undefined, v3, v4); // 原始类型会被包装,null 和 undefined 会被疏忽。// 留神,只有字符串的包装对象才可能有本身可枚举属性。console.log(obj); // { "0": "a", "1": "b", "2": "c" }
- 异样会打断后续拷贝工作
const target = Object.defineProperty({}, "foo", { value: 1, writable: false}); // target 的 foo 属性是个只读属性。Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});// TypeError: "foo" is read-only// 留神这个异样是在拷贝第二个源对象的第二个属性时产生的。console.log(target.bar); // 2,阐明第一个源对象拷贝胜利了。console.log(target.foo2); // 3,阐明第二个源对象的第一个属性也拷贝胜利了。console.log(target.foo); // 1,只读属性不能被笼罩,所以第二个源对象的第二个属性拷贝失败了。console.log(target.foo3); // undefined,异样之后 assign 办法就退出了,第三个属性是不会被拷贝到的。console.log(target.baz); // undefined,第三个源对象更是不会被拷贝到的。
四、CSS
1、margin
margin是外边距的意思,当一个元素款式属性里有margin:0 auto时,并且父元素的宽度是确定的,意思是这个元素处于其父元素的居中地位,并且这个元素的高低外边距为0。
margin还有其余配置类型:
1.margin-bottom:设置元素的下外边距。2.margin-left:设置元素的左外边距。3.margin-right:设置元素的右外边距。4.margin-top:设置元素的上外边距。
五、SQL
1、sql、DB、DBMS
- DB
DataBase(数据库,数据库实际上在硬盘上以文件的模式存在)
- DBMS
DataBase Management System(数据库管理系统,常见的有:MySQL Oracle DB2 Sybase SqlServer...)
- SQL
结构化查询语言,是一门规范通用的语言。规范的sql适宜于所有的数据库产品。
SQL属于高级语言。只有能看懂英语单词的,写进去的sql语句,能够读懂什么意思。
SQL语句在执行的时候,实际上外部也会先进行编译,而后再执行sql。(sql语句的编译由DBMS实现。)
DBMS负责执行sql语句,通过执行sql语句来操作DB当中的数据。DBMS -(执行)-> SQL -(操作)-> DB
2、表
- 表:table
表:table是数据库的根本组成单元,所有的数据都以表格的模式组织,目标是可读性强。 一个表包含行和列: 行:被称为数据/记录(data) 列:被称为字段(column) 学号(int) 姓名(varchar) 年龄(int) ------------------------------------ 110 张三 20 120 李四 21 每一个字段应该包含哪些属性? 字段名、数据类型、相干的束缚。
3、SQL 语句分类
- DQL(数据查询语言): 查问语句,但凡select语句都是DQL。
- DML(数据操作语言):insert delete update,对表当中的数据进行增删改。
- DDL(数据定义语言):create drop alter,对表构造的增删改。
- TCL(事务管制语言):commit提交事务,rollback回滚事务。(TCL中的T是Transaction)
- DCL(数据管制语言): grant受权、revoke撤销权限等。
4、导入数据
第一步:登录mysql数据库管理系统 dos命令窗口:mysql -uroot -p333 第二步:查看有哪些数据库 show databases; (这个不是SQL语句,属于MySQL的命令。)第三步:创立属于咱们本人的数据库 create database powernode; (这个不是SQL语句,属于MySQL的命令。)第四步:应用 powernode 数据 use powernode; (这个不是SQL语句,属于MySQL的命令。)第五步:查看以后应用的数据库中有哪些表? show tables; (这个不是SQL语句,属于MySQL的命令。)第六步:初始化数据 mysql> source D:\course\05-MySQL\resources\powernode.sql
5、sql脚本
当一个文件的扩展名是.sql,并且该文件中编写了大量的sql语句,咱们称这样的文件为sql脚本。留神:间接应用source命令能够执行sql脚本。sql脚本中的数据量太大的时候,无奈关上,请应用source命令实现初始化。
6、MySql 根本命令
6.1根底命令
mysql -uroot -p 明码; (也能够不带明码,输出之后)本地登录mysql -h 登录 ip -p 端口(通常 3306 ) -uroot -p明码; 近程登录desc 表名; 查看表的各个字段的属性,以及自增键mysqldump -u 用户 -p 数据库名 > xx.sql; 导出数据库文件,保留mysql -u 用户名 -p 明码 数据库名 < xx.sql; 导入数据库文件(也能够抉择登录进去,在抉择数据库后,应用 source 命令导入数据)select database(); 查看以后应用的是哪个数据库select version(); 查看mysql的版本号。\c 命令,完结一条语句。exit 命令,退出mysql。show create table emp;查看创立表的语句:
6.2创立命令
create user '用户名' @ 'ip' identified by '明码'; 创立用户ip 是指用户登录 mysql 的电脑 ip,能够写 %,本地写 localhostgrant 权限(select/insert/updata/all priveleges) on 表/数据库名 to '用户'@'ip' identified by '明码'; 用户受权drop user 用户名@ip 删除用户show databases; 查数据库use databases; 应用数据库drop database powernode; 删除数据库1.创立表 建表语句的语法格局: create table 表名( 字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型, .... );2.对于MySQL当中字段的数据类型?以下只说常见的 int 整数型(java中的int) bigint 长整型(java中的long) float 浮点型(java中的float double) char 定长字符串(String) varchar 可变长字符串(StringBuffer/StringBuilder) date 日期类型 (对应Java中的java.sql.Date类型) BLOB 二进制大对象(存储图片、视频等流媒体信息) Binary Large OBject (对应java中的Object) CLOB 字符大对象(存储较大文本,比方,能够存储4G的字符串。) Character Large OBject(对应java中的Object) ......3.char和varchar怎么抉择? 在理论的开发中,当某个字段中的数据长度不产生扭转的时候,是定长的,例如:性别、生日等都是采纳char。 当一个字段的数据长度不确定,例如:简介、姓名等都是采纳varchar。4.BLOB和CLOB类型的应用? 电影表: t_movie id(int) name(varchar) playtime(date/char) haibao(BLOB) history(CLOB) ---------------------------------------------------------------------------------------- 1 蜘蛛侠 2 3 表名在数据库当中个别倡议以:t_或者tbl_开始。5.insert语句插入数据 语法格局: insert into 表名(字段名1,字段名2,字段名3,....) values(值1,值2,值3,....) 要求:字段的数量和值的数量雷同,并且数据类型要对应雷同。 须要留神的中央: 当一条insert语句执行胜利之后,表格当中必然会多一行记录。 即便多的这一行记录当中某些字段是NULL,前期也没有方法在执行 insert语句插入数据了,只能应用update进行更新。 字段能够省略不写,然而前面的value对数量和程序都有要求。 一次插入多行数据 insert into t_student (no,name,sex,classno,birth) values (3,'rose','1','gaosi2ban','1952-12-14'),(4,'laotie','1','gaosi2ban','1955-12-14');6.表的复制 语法: create table 表名 as select语句; 将查问后果当做表创立进去。7.将查问后果插入到一张表中? insert into dept1 select * from dept;
6.3查表命令
条件查问
提醒:
1.任何一条sql语句以 “;” 结尾。 2.sql语句不辨别大小写。 3.规范sql语句中要求字符串应用单引号括起来。尽管mysql反对双引号,尽量别用。 4.as关键字能够省略(起别名) 5.语法格局: select 字段,字段... from 表名 where 条件; 执行程序:先from,而后where,最初select
select * from 表名;select 列名···from 表名;select 列名 from 表名 where 列名(id等) >/</!= value;select 列名,常量 from 表名; 减少一个常量列select 列名 from 表名 where 列名 in/not in/between and value;select 列名 from 表名 where 条件1 and 条件2;非凡的:select 列名 from 表名 where 列名 in (select 列名(只能一列) from 表名);select 列名 from 表名 where 列名 like 'xx%'/'%xx'/"xx_"; 查问以xx结尾/xx结尾 %代表任意位,_代表一位
分页
1.limit是mysql特有的,其余数据库中没有,不通用。(Oracle中有一个雷同的机制,叫做rownum)2.limit取后果集中的局部数据,这是它的作用。3.语法机制: limit startIndex, length startIndex示意起始地位,从0开始,0示意第一条数据。 length示意取几个 案例:取出工资前5名的员工(思路:降序取前5个) select ename,sal from emp order by sal desc; 取前5个: select ename,sal from emp order by sal desc limit 0, 5; select ename,sal from emp order by sal desc limit 5;4.limit是sql语句最初执行的一个环节: select 5 ... from 1 ... where 2 ... group by 3 ... having 4 ... order by 6 ... limit 7 ...;5.通用的标准分页sql? 每页显示3条记录: 第1页:0, 3 第2页:3, 3 第3页:6, 3 第4页:9, 3 第5页:12, 3 每页显示pageSize条记录: 第pageNo页:(pageNo - 1) * pageSize, pageSize pageSize是什么?是每页显示多少条记录 pageNo是什么?显示第几页 select 列名 from 表名 limit num; 显示num个select 列名 from 表名 limit num1,num2; 从num1后取num2行数据,num1是起始地位,num2 是个数select 列名 from 表名 limit num1 offset num2; 从num2后取num1行数据,num2是起始地位,num1 是个数
排序
默认是升序。select 字段 3from 表名 1where 条件 2order by .... 4 order by是最初执行的。select * from 表名 order by 列名 desc; 从大到小排序select * from 表名 order by 列名 asc; 从小到大排序select * from 表名 order by 列名1 desc 列名2 asc; 首先遵循列1从大到小排序,遇到雷同数据时, 按列2从小到大排序
分组
1.分组函数count 计数sum 求和avg 平均值max 最大值min 最小值 分组函数一共5个。 分组函数还有另一个名字:多行处理函数。 多行处理函数的特点:输出多行,最终输入的后果是1行。 分组函数主动疏忽NULL。2.count(*)和count(具体的某个字段),他们有什么区别? count(*):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关) count(comm): 示意统计comm字段中不为NULL的数据总数量。select count/sum/max/min/avg(列名1),列名2 from 表名 group by 列名(通常是列名2); 分组操作select count/sum/max/min/avg(列名1),列名2 from 表名 group by 列名(通常是列名2)having 条件;分组操作后筛选3.单行处理函数 什么是单行处理函数? 输出一行,输入一行。 计算每个员工的年薪? select ename,(sal+comm)*12 as yearsal from emp; 重点:**所有数据库都是这样规定的,只有有NULL参加的运算后果肯定是NULL**。 应用ifnull函数: select ename,(sal+ifnull(comm,0))*12 as yearsal from emp; ifnull() 空处理函数? ifnull(可能为NULL的数据,被当做什么解决) : 属于单行处理函数。 select ename,ifnull(comm,0) as comm from emp;
group by 和 having
group by : 依照某个字段或者某些字段进行分组。having : having是对分组之后的数据进行再次过滤。 案例:找出每个工作岗位的最高薪资。 select max(sal),job from emp group by job; +----------+-----------+ | max(sal) | job | +----------+-----------+ | 3000.00 | ANALYST | | 1300.00 | CLERK | | 2975.00 | MANAGER | | 5000.00 | PRESIDENT | | 1600.00 | SALESMAN | +----------+-----------+留神:分组函数个别都会和group by联结应用,这也是为什么它被称为分组函数的起因。并且任何一个分组函数(count sum avg max min)都是在group by语句执行完结之后才会执行的。当一条sql语句没有group by的话,整张表的数据会自成一组。select ename,max(sal),job from emp group by job;以上在mysql当中,查问后果是有的,然而后果没有意义,在Oracle数据库当中会报错。语法错误。Oracle的语法规定比MySQL语法规定谨严。记住一个规定:**当一条语句中有group by的话,select前面只能跟分组函数和参加分组的字段。**
总结一个残缺的DQL语句
select 5 ..from 1 ..where 2 ..group by 3 ..having 4 ..order by 6 ..
对于查问后果集的去重
distinct关键字去除重复记录。select distinct job from emp记住:distinct只能呈现在所有字段的最后面。
6.4连贯查问
什么是连贯查问
在理论开发中,大部分的状况下都不是从单表中查问数据,个别都是多张表联结查问取出最终的后果。在理论开发中,个别一个业务都会对应多张表,比方:学生和班级,起码两张表。stuno stuname classno classname-----------------------------------------------------------------------------------1 zs 1 北京大兴区亦庄经济技术开发区第二中学高三1班2 ls 1 北京大兴区亦庄经济技术开发区第二中学高三1班...学生和班级信息存储到一张表中,后果就像下面一样,数据会存在大量的反复,导致数据的冗余。
连贯查问的分类
1.依据语法呈现的年代来划分的话,包含: SQL92(一些老的DBA可能还在应用这种语法。DBA:DataBase Administrator,数据库管理员) SQL99(比拟新的语法)2.依据表的连贯形式来划分,包含: 内连贯: 等值连贯 非等值连贯 自连贯 外连贯: 左外连贯(左连贯) 右外连贯(右连贯) 全连贯3.在表的连贯查问方面有一种景象被称为:笛卡尔积景象。(笛卡尔乘积景象) 笛卡尔积景象:当两张表进行连贯查问的时候,没有任何条件进行限度,最终的查问后果条数是两张表记录条数的乘积。 案例:找出每一个员工的部门名称,要求显示员工名和部门名。 EMP表 +--------+--------+ | ename | deptno | +--------+--------+ | SMITH | 20 | | ALLEN | 30 | | WARD | 30 | | JONES | 20 | | MARTIN | 30 | | BLAKE | 30 | | CLARK | 10 | | SCOTT | 20 | | KING | 10 | | TURNER | 30 | | ADAMS | 20 | | JAMES | 30 | | FORD | 20 | | MILLER | 10 | +--------+--------+ DEPT表 +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+ select ename,dname from emp,dept; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | ACCOUNTING | | SMITH | RESEARCH | | SMITH | SALES | | SMITH | OPERATIONS | | ALLEN | ACCOUNTING | | ALLEN | RESEARCH | | ALLEN | SALES | | ALLEN | OPERATIONS | ............ 56 rows in set (0.00 sec) 笛卡尔积景象:当两张表进行连贯查问的时候,没有任何条件进行限度,最终的查问后果条数是两张表记录条数的乘积。4.对于表的别名: select e.ename,d.dname from emp e,dept d; 表的别名有什么益处? 第一:执行效率高。 第二:可读性好。5.怎么防止笛卡尔积景象?当然是加条件进行过滤。 思考:防止了笛卡尔积景象,会缩小记录的匹配次数吗? 不会,次数还是56次。只不过显示的是无效记录。6.内连贯之等值连贯:最大特点是:条件是等量关系。 7.内连贯之非等值连贯:最大的特点是:连贯条件中的关系是非等量关系。8.自连贯:最大的特点是:一张表看做两张表。本人连贯本人。9.外连贯 什么是外连贯,和内连贯有什么区别? 内连贯: 假如A和B表进行连贯,应用内连贯的话,但凡A表和B表可能匹配上的记录查问进去,这就是内连贯。 AB两张表没有主副之分,两张表是平等的。 外连贯: 假如A和B表进行连贯,应用外连贯的话,AB两张表中有一张表是主表,一张表是副表,次要查问主表中 的数据,捎带着查问副表,当副表中的数据没有和主表中的数据匹配上,副表主动模拟出NULL与之匹配。 外连贯的分类: 左外连贯(左连贯):示意右边的这张表是主表。 右外连贯(右连贯):示意左边的这张表是主表。 左连贯有右连贯的写法,右连贯也会有对应的左连贯的写法。 外连贯最重要的特点是:主表的数据无条件的全副查问进去。 10.连表操作 select * from 表1 left join 表2 on 表1.列名=表2.列名; 左连贯 select * from 表1 right join 表2 on 表1.列名=表2.列名; 右连贯 select * from 表1 inner join 表2 on 表1.列名=表2.列名; 内连贯 留神:如果超过3个表联合操作,如果其中两个表操作时曾经扭转了表构造,应该将这两个表操作的后果作为一个长期表再与第三个表联合操作。11.长期表 (select * from 表名)as e12.union (能够将查问后果集相加) 案例:找出工作岗位是SALESMAN和MANAGER的员工? 第一种:select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN'; 第二种:select ename,job from emp where job in('MANAGER','SALESMAN'); +--------+----------+ | ename | job | +--------+----------+ | ALLEN | SALESMAN | | WARD | SALESMAN | | JONES | MANAGER | | MARTIN | SALESMAN | | BLAKE | MANAGER | | CLARK | MANAGER | | TURNER | SALESMAN | +--------+----------+ 第三种:union select ename,job from emp where job = 'MANAGER' union select ename,job from emp where job = 'SALESMAN'; +--------+----------+ | ename | job | +--------+----------+ | JONES | MANAGER | | BLAKE | MANAGER | | CLARK | MANAGER | | ALLEN | SALESMAN | | WARD | SALESMAN | | MARTIN | SALESMAN | | TURNER | SALESMAN | +--------+----------+ 两张不相干的表中的数据拼接在一起显示? select ename from emp union select dname from dept; +------------+ | ename | +------------+ | SMITH | | ALLEN | | WARD | | JONES | | MARTIN | | BLAKE | | CLARK | | SCOTT | | KING | | TURNER | | ADAMS | | JAMES | | FORD | | MILLER | | ACCOUNTING | | RESEARCH | | SALES | | OPERATIONS | +------------+ mysql> select ename,sal from emp -> union -> select dname from dept; ERROR 1222 (21000): The used SELECT statements have a different number of columns13.子查问 什么是子查问?子查问都能够呈现在哪里? select语句当中嵌套select语句,被嵌套的select语句是子查问。 子查问能够呈现在哪里? select ..(select). from ..(select). where ..(select).
6.5批改、删除数据
批改
1.语法格局: update 表名 set 字段名1=值1,字段名2=值2... where 条件;2.批改表构造 alter table 表名 auto_increment=value;设置自增键起始值; alter table 表名 drop 列名; 删除列 alter table 表名 add 列名 数据类型 束缚; 减少列 alter table 表名 change 旧列名 新列名 数据类型; 批改字段类型 alter table 表名 modify 列名 数据类型; 批改数据类型 alter table 旧表名 rename 新表名; 批改表名 alter table 表名 drop primary key; 删除表中主键 alter table 表名 add 列名 数据类型 primary key; 增加主键 alter table 表名 add primary key(列名); 设置主键 alter table 表名 add column 列名 数据类型 after 列名; 在某一列后增加主键
删除
语法格局: delete from 表名 where 条件;留神:没有条件全副删除。 删除10部门数据? delete from dept1 where deptno = 10; 删除所有记录? delete from dept1; 怎么删除大表中的数据?(重点) truncate table 表名; // 表被截断,不可回滚。永恒失落。 删除表? drop table 表名; // 这个通用。 drop table if exists 表名; // oracle不反对这种写法。delete from 表名; 革除表(如果有自增id,id 不会从新开始)delete from 表名 where 条件;革除特定数据truncate table 表名; 革除表(如果有自增id,id 会从新开始)
7、罕用 SQl 语句
7.1 case when 行转列、列转行
行转列,列转行是咱们在开发过程中常常碰到的问题。行转列个别通过CASE WHEN 语句来实现,也能够通过 SQL SERVER 2005 新增的运算符PIVOT来实现。用传统的办法,比拟好了解。档次清晰,而且比拟习惯。 然而PIVOT 、UNPIVOT提供的语法比一系列简单的SELECT...CASE 语句中所指定的语法更简略、更具可读性。上面咱们通过几个简略的例子来介绍一下列转行、行转列问题。
行转列
mysql> create table t_student_scores( -> id int(10) primary key AUTO_INCREMENT, -> user_name varchar(255), -> subject varchar(255), -> score int(10));insert into t_student_scores values(1,'Jack', '语文', 80), (2,'Rose', '语文', 80), (3,'张三','数学',98), (4, '李四','英语',78), (5, '王五', '物理', 89), (6, '赵六','化学',78);mysql> select * from t_student_scores;+----+-----------+---------+-------+| id | user_name | subject | score |+----+-----------+---------+-------+| 1 | Jack | 语文 | 80 || 2 | Rose | 语文 | 80 || 3 | 张三 | 数学 | 98 || 4 | 李四 | 英语 | 78 || 5 | 王五 | 物理 | 89 || 6 | 赵六 | 化学 | 78 |+----+-----------+---------+-------+6 rows in set (0.00 sec)案例: 想晓得每位学生的每科问题,而且每个学生的全副问题排成一行,这样不便我查看、统计,导出数据mysql> select user_name, -> max(case subject when '语文' then score else 0 end) as '语文', -> max(case subject when '数学' then score else 0 end) as '数学', -> max(case subject when '英语' then score else 0 end) as '英语', -> max(case subject when '物理' then score else 0 end) as '物理', -> max(case subject when '化学' then score else 0 end) as '化学', -> max(case subject when '生物' then score else 0 end) as '生物' -> from t_student_scores -> group by user_name;+-----------+--------+--------+--------+--------+--------+--------+| user_name | 语文 | 数学 | 英语 | 物理 | 化学 | 生物 |+-----------+--------+--------+--------+--------+--------+--------+| Jack | 80 | 0 | 0 | 0 | 0 | 0 || Rose | 80 | 0 | 0 | 0 | 0 | 0 || 张三 | 0 | 98 | 0 | 0 | 0 | 0 || 李四 | 0 | 0 | 78 | 0 | 0 | 0 || 王五 | 0 | 0 | 0 | 89 | 0 | 0 || 赵六 | 0 | 0 | 0 | 0 | 78 | 0 |+-----------+--------+--------+--------+--------+--------+--------+6 rows in set (0.00 sec)
- 列转行
次要通过 UNION ALL 来实现
mysql> select user_name, subject as items, score from t_student_scores -> union all -> select user_name, score as scores, subject from t_student_scores;+-----------+--------+--------+| user_name | items | score |+-----------+--------+--------+| Jack | 语文 | 80 || Rose | 语文 | 80 || 张三 | 数学 | 98 || 李四 | 英语 | 78 || 王五 | 物理 | 89 || 赵六 | 化学 | 78 || Jack | 80 | 语文 || Rose | 80 | 语文 || 张三 | 98 | 数学 || 李四 | 78 | 英语 || 王五 | 89 | 物理 || 赵六 | 78 | 化学 |+-----------+--------+--------+12 rows in set (0.00 sec)
7.2 concat()函数
性能:将多个字符串连接成一个字符串。语法:concat(str1, str2,...)返回后果为连贯参数产生的字符串,如果有任何一个参数为null,则返回值为null。mysql> select user_name, concat(t.subject, t.score) items from t_student_scores t;+-----------+----------+| user_name | items |+-----------+----------+| Jack | 语文80 || Rose | 语文80 || 张三 | 数学98 || 李四 | 英语78 || 王五 | 物理89 || 赵六 | 化学78 |+-----------+----------+6 rows in set (0.01 sec)
- concat_ws()函数
性能:和concat()一样,将多个字符串连接成一个字符串,然而能够一次性指定分隔符~(concat_ws就是concat with separator)语法:concat_ws(separator, str1, str2, ...)阐明:第一个参数指定分隔符。须要留神的是分隔符不能为null,如果为null,则返回后果为null。mysql> select user_name, concat_ws('|', t.subject, t.score) items from t_student_scores t;+-----------+-----------+| user_name | items |+-----------+-----------+| Jack | 语文|80 || Rose | 语文|80 || 张三 | 数学|98 || 李四 | 英语|78 || 王五 | 物理|89 || 赵六 | 化学|78 |+-----------+-----------+6 rows in set (0.00 sec)
- group_concat()函数
性能:将group by产生的同一个分组中的值连接起来,返回一个字符串后果。语法:group_concat( [distinct] 要连贯的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )阐明:通过应用distinct能够排除反复值;如果心愿对后果中的值进行排序,能够应用order by子句;separator是一个字符串值,缺省为一个逗号。
7.3 ifNull()、isNull(),nullif()
- isnull(expr) 的用法
如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0。
mysql> select user_name, score from t_student_scores where isnull(score);Empty set (0.00 sec)应用= 的null 值比照通常是谬误的。isnull() 函数同 is null比拟操作符具备一些雷同的个性。请参见无关is null 的阐明。**** ISNULL()**用处:应用指定的替换值替换返回值为NULL语法:ISNULL(check_expression,replacement_value)参数:check_expression,将被查看是否为NULL的表达式,能够为任意类型的。replacement_value,在check_expression为NULL时返回的表达式。必须与check_expression雷同类型。返回类型:返回与check_expression雷同的类型正文:如果check_expression不为NULL,那么返回该表达式的值;否则返回replacement_value'
- IFNULL(expr1,expr2)的用法
如果expr1不为null(),则IFNULL()的返回值为expr1;否则其返回值为expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所应用的语境。mysql> select ifnull(1,0);+-------------+| ifnull(1,0) |+-------------+| 1 |+-------------+1 row in set (0.01 sec)mysql> select ifnull(null,10);+-----------------+| ifnull(null,10) |+-----------------+| 10 |+-----------------+1 row in set (0.00 sec)IFNULL(expr1,expr2)的默认后果值为两个表达式中更加“通用”的一个,程序为STRING、REAL或INTEGER。假如一个基于表达式的表的状况,或MySQL必须在内存储器中贮存一个长期表中IFNULL()的返回值:CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;在这个例子中,[测试](http://lib.csdn.net/base/softwaretest)列的类型为 CHAR(4)。
- NULLIF(expr1,expr2)的用法
如果expr1 = expr2成立,那么返回值为NULL,否则返回值为expr1。这和CASE WHEN expr1 = expr2THEN NULL ELSE expr1 END雷同。mysql> select user_name, case when subject='物理' then subject else null end from t_student_scores;+-----------+-------------------------------------------------------+| user_name | case when subject='物理' then subject else null end |+-----------+-------------------------------------------------------+| Jack | NULL || Rose | NULL || 张三 | NULL || 李四 | NULL || 王五 | 物理 || 赵六 | NULL |+-----------+-------------------------------------------------------+6 rows in set (0.11 sec)
7.4 trim()
问题形容: 在数据库中,批量导入数据的时候,没有留神字段数据的空格,造成导入数据库里的数据开端有空格。解决方案: trim() 函数介绍: trim 函数能够移除字符串的**首尾信息**。最常见的用法为移除字符首尾空格。trim() 函数应用: mysql> update t_student_scores -> set subject=trim(subject) -> where subject = '物理'; Query OK, 0 rows affected (0.12 sec) Rows matched: 1 Changed: 0 Warnings: 0
7.5 union和 union all
- SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的后果集。请留神,UNION 外部的 SELECT 语句必须领有雷同数量的列。列也必须领有类似的数据类型。同时,每条 SELECT 语句中的列的程序必须雷同。SQL UNION 语法 SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2 正文:默认地,UNION 操作符选取不同的值。如果容许反复的值,请应用 UNION ALL。
- SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1UNION ALLSELECT column_name(s) FROM table_name2另外,UNION 后果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
(6)row_number() over (partition by)
row_number 语法ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其间断的编号。在查问时利用了一个排序规范后,只有通过编号才可能保障其程序是统一的,当应用ROW_NUMBER函数时,也须要专门一列用于事后排序以便于进行编号partition by关键字是剖析性函数的一部分,它和聚合函数不同的中央在于它能返回一个分组中的多条记录,而聚合函数个别只有一条反映统计值的记录,partition by用于给后果集分组,如果没有指定那么它把整个后果集作为一个分组,分区函数个别与排名函数一起应用。
8、索引和主键
8.1 索引
个别学习编程语言都是从c语言开始,c语言外面有个东东叫"指针",都晓得c语言外面指针用的不好会带来不安全性,学习java的时候都晓得java外面没有指针。Java外面还有相似指针的中央,java外面叫做索引。索引指向的是对象在jvm外面调配的内存地址,因为中距离了一层jvm,所以安全性有保障。
MySQL官网对于索引的定义为:索引是帮忙MySQL高效获取数据的数据结构。
数据库查问是数据库最次要的性能之一,咱们都心愿查问数据的速度尽可能的快,因而数据库系统的设计者会从查问算法的角度进行优化。最根本的查问算法当然是程序查找,当然这种工夫复杂度为O(N)的算法在数据量很大时显然是蹩脚的,于是有了二分查找O(log N) 、二叉树查找等。然而二分查找要求被检索数据有序,而二叉树查找只能利用于二叉查找树,然而数据自身的组织构造不可能齐全满足各种数据结构。所以,在数据之外,数据库系统还保护着满足特定查找算法的数据结构,这些数据结构以某种形式援用数据,这样就能够在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
插曲:大O表示法。查看长度为n的列表,二分查找最坏的状况须要执行log N次操作,应用大O表示法来示意算法的运行工夫,也就是O(log N) 。括号外面指算法须要执行的操作次数。
创立表时,不能在同一个字段上建设两个索引(主键默认建设惟一索引),在须要 常常查问的字段上建设索引(如:deal_id曾经是主键,不能再次执行:create index tmp_table_index on tmp_table(deal_id), 会报错);
- 主键:该字段没有反复值,且不容许为空
惟一索引:该字段没有反复值,但容许空值(该字段能够有多个null值)
一张table只容许一个主键,但能够创立多个unique index
比方,表中有5行,ID的值是12345,就能够作为主键
但如果ID的值是1234 NULL NULL,则能够建设惟一索引,不能作为主键
- 能够为 多个字段建设惟一索引:
create unique index unique_index01 on search_result_tmp(deal_id,compare_flag);
建设惟一索引当前,只容许插入一条如下记录,插入两条时会违反unique index束缚
Insert into search_result_temp values(1,null);
- 删除索引:drop index unique_index01;
函数索引
如果在咱们的查问条件应用了函数,那么索引就不可用了。
能够用建设函数索引的形式,来解决这个问题
例如: select * from product where nvl(price,0.0)>1000.0 ;
这里,nvl(price,0.0)应用了函数,索引不能利用price字段上做的索引了ok,咱们来创立函数索引
create index index_price on product(nvl(price,0.0));
其余:
惟一索引能极大的进步查问速度,而且还有惟一束缚的作用
个别索引,只能进步30%左右的速度
常常插入,批改,应在查问容许的状况下,尽量减少索引,因为增加索引,插入,批改等操作,须要更多的工夫
A、主键肯定是唯一性索引,唯一性索引并不一定就是主键。B、 一个表中能够有多个唯一性索引,但只能有一个主键。C、主键列不容许空值,而唯一性索引列容许空值。 D、索引能够进步查问的速度。
主键和索引都是键,不过主键是逻辑键,索引是物理键,意思就是主键不理论存在,而索引理论存在在数据库中
(1)劣势 相似大学图书馆建书目索引,进步数据检索效率,升高数据库的IO老本。 通过索引对数据进行排序,升高数据排序的老本,升高了CPU的耗费。(2)劣势 实际上索引也是一张表,该表保留了主键与索引字段,并指向实体表的记录,所以索引列也是要占空间的。 尽管索引大大提高了查问速度,同时确会升高更新表的速度,如对表进行INSERT、UPDATE、DELETE。 因为更新表时,MySQL不仅要保留数据,还要保留一下索引文件每次更新增加了索引列的字段。
8.2 索引的数据结构
在关系数据库中,索引是一种对数据库表中的值进行排序的存储构造。索引的作用相当于图书的目录,能够依据目录中的页码疾速找到所需的内容。
索引提供指向存储在表的指定列中的数据值的指针,而后依据您指定的排序程序对这些指针排序。数据库应用索引以找到特定值,而后顺指针找到蕴含该值的行。这样能够使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。
什么样的信息能力成为索引
在关系型数据库中,主键,惟一键,一般键,都能够作为数据库的索引。
- 索引的数据结构
如图是一个二叉查找树,在二叉查找树中,咱们能够应用二分查找法,去检索须要的数据。
那为什么不必二叉树去作为索引的数据结构呢?如图所示的二叉树,如果咱们删除了数据为6的节点,减少一个数据为10的节点,那此二叉树便成为了一个线形二叉树。也就是说,在插入删除的过程中,二叉树可能调演变成线性构造,线性构造会明显降低查问的效率;同时,二叉树在数据较多时,深度狠深,也不利于数据的查找。
- 咱们再来看一下B树。
什么是B树呢,B树,又称B-树,它具备以下特点:
(1)排序形式:所有节点关键字是按递增秩序排列,并遵循左小右大准则;(2)它是一个多阶树,他的叶子节点和非叶子节点都记录有关键字;(3)所有叶子节点均在同一层、叶子节点除了蕴含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指 针地址都为null。
B树的这些规定保障了关键字信息的顺序排列,并且在B树中进行删除减少操作时,b树依然会放弃树形构造。
显然B树相较于均衡二叉树,更加适宜做索引的数据结构,然而呢,咱们罕用的mysql用的却并不是B树,而是更适宜的B+树。
B+树
B+树是B树的一个升级版,绝对于B树来说B+树更充沛的利用了节点的空间,让查问速度更加稳固,来看下B+树:
B+树具备以下特点:
1)B+跟B树不同B+树的非叶子节点不保留关键字记录的指针,只进行数据索引;2)B+树叶子节点保留了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点能力获取到。所以每次数据查问的次数都一样;3)B+树叶子节点的**关键字从小到大有序排列**,右边结尾数据都会保留左边节点开始数据的指针。
所以,用B+树作为索引构造,有着以下长处:
1)B+树的两头节点不保留数据,是纯索引,然而B树的两头节点是保留数据和索引的,相对来说,B+树在磁盘页中能包容更多节点元素。2)B+树每次查问都要从根节点始终查到叶节点,所以查问效率更加稳固。3)因为每个叶子节点都寄存了指向下一个节点的指针,且要害数据有序排列,所以在范畴查找中,B+树更占优势。4)增删节点时,效率更高,因为B+树的叶子节点蕴含所有关键字,并以有序的链表构造存储。
咱们罕用的Mysql 就是默认采纳了B+树作为索引构造。
在咱们创立索引时,能够看到mysql也是反对hash索引构造的,咱们再来简略介绍下hash 索引。
哈希索引就是采纳肯定的哈希算法,把键值换算成新的哈希值,检索时不须要相似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立即定位到相应的地位,速度十分快。
听起来很吊,然而hash索引尽管再等值查问时占有肯定的劣势,然而它相比于B+tree却有一些无法弥补的毛病:
1)它仅仅能满足等值查问,不反对范畴查问。2)无奈进行数据的排序操作。3)不反对多列联结索引的最左匹配规定。因为hash索引的联结索引,是把多个键值房子一起算hash值的。4)遇到大量hash值相等的状况后性能降落。
综上,mysql采纳了默认B+tree作为索引构造,也反对hash构造作为索引的形式。
8.3 惟一索引和聚合索引(汇集索引)
(1)一个表只能有一个主索引-PRIMARY,且只有是数据库表才有主索引,后缀为 .CDX,索引关键字是不能够反复的.哪怕是空记录也只能够有一条.(2)候选索引能够有很多个,索引关键字同样不能够反复,同样只存在于数据库表.(3)惟一索引,能够存在于自在表,但索引关键字不能够反复.(4)一般索引简略的了解就是只起排序作用.索引关键字是能够反复的.可存在于自在表.CREATE UNIQUE **INDEX** test_UniqueKey **ON** test (UniqueKey);
主键与惟一索引的区别
主键是一种束缚,惟一索引是一种索引,两者在实质上是不同的。 主键创立后肯定蕴含一个唯一性索引,唯一性索引并不一定就是主键。 唯一性索引列容许空值,而主键列不容许为空值。 主键列在创立时,曾经默认为空值 + 惟一索引了。 主键能够被其余表援用为外键,而惟一索引不能。 一个表最多只能创立一个主键,但能够创立多个惟一索引。 主键更适宜那些不容易更改的惟一标识,如主动递增列、身份证号等。 在 RBO 模式下,主键的执行打算优先级要高于惟一索引。 两者能够进步查问的速度。
汇集索引:
决定物理程序,所以一个表只能有一个汇集索引、
对有程序或自增列更无效 eg:日期等、
对值只有惟一值的列效率更高、
对常常排序的列效率高、
◆应用汇集索引如果插入新数据会进行从新排序
create clustered index CLU_ABC on abc(A)
◆删除汇集索引,会发现表的程序不会产生扭转。
create nonclustered index NONCLU_ABC on abc(A)
一种索引,该索引中键值的逻辑程序决定了表中相应行的物理程序。 \
汇集索引确定表中数据的物理程序。汇集索引相似于电话簿,后者按姓氏排列数据。因为汇集索引规定数据在表中的物理存储程序,因而一个表只能蕴含一个汇集索引。但该索引能够蕴含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。 \
汇集索引对于那些常常要搜寻范畴值的列特地无效。应用汇集索引找到蕴含第一个值的行后,便能够确保蕴含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查问常常检索某一日期范畴内的记录,则应用汇集索引能够迅速找到蕴含开始日期的行,而后检索表中所有相邻的行,直到达到完结日期。这样有助于进步此类查问的性能。同样,如果对从表中检索的数据进行排序时常常要用到某一列,则能够将该表在该列上汇集(物理排序),防止每次查问该列时都进行排序,从而节省成本。 \
当索引值惟一时,应用汇集索引查找特定的行也很有效率。例如,应用惟一雇员 ID 列 emp_id 查找特定雇员的最疾速的办法,是在 emp_id 列上创立汇集索引或 PRIMARY KEY 束缚。
汇集索引基于数据行的键值,在表内排序和存储这些数据行。每个表只能有一个汇集索引,应为数据行本分只能按一个顺序存储。
在汇集索引中,表中各行的物理程序与索引键值的逻辑(索引)程序雷同。汇集索引通常可放慢UPDATE和DELETE操作的速度,因为这两个操作须要读取大量的数据。创立或批改汇集索引可能要花很长时间,因为执行这两个操作时要在磁盘上对表的行进行重组。
- 非汇集索引:
因为一个表中只能有一个汇集索引,如果须要在表中建设多个索引,则能够创立为非汇集索引。表中的数据并不依照非汇集索引列的顺序存储,但非汇集索引的索引行中保留了非汇集键值和行定位器,能够快捷地依据非汇集键的值来定位记录的存储地位。
无论是汇集索引,还是非汇集索引,都能够是惟一索引。在SQL Server中,当唯一性是数据自身的特点时,可创立惟一索引,但索引列的组合不同于表的主键。例如,如果要频繁查问表Employees(该表主键为列Emp_id)的列Emp_name,而且要保障姓名是惟一的,则在列Emp_name上创立惟一索引。如果用户为多个员工输出了雷同的姓名,则数据库显示谬误,并且不能保留该表。
- 深刻检出了解索引构造
实际上,您能够把索引了解为一种非凡的目录。微软的SQL SERVER提供了两种索引:汇集索引(clustered index,也称聚类索引、簇集索引)和非汇集索引(nonclustered index,也称非聚类索引、非簇集索引)。上面,咱们举例来说明一下汇集索引和非汇集索引的区别:\
其实,咱们的汉语字典的注释自身就是一个汇集索引。比方,咱们要查“安”字,就会很天然地打开字典的前几页,因为“安”的拼音是“an”,而依照拼音排序汉字的字典是以英文字母“a”结尾并以“z”结尾的,那么“安”字就天然地排在字典的前部。如果您翻完了所有以“a”结尾的局部依然找不到这个字,那么就阐明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最初局部,因为“张”的拼音是“zhang”。也就是说,字典的注释局部自身就是一个目录,您不须要再去查其余目录来找到您须要找的内容。咱们把这种注释内容自身就是一种依照肯定规定排列的目录称为“汇集索引” 。\
如果您意识某个字,您能够疾速地从主动中查到这个字。但您也可能会遇到您不意识的字,不晓得它的发音,这时候,您就不能依照方才的办法找到您要查的字,而须要去依据“偏旁部首”查到您要找的字,而后依据这个字后的页码间接翻到某页来找到您要找的字。但您联合“部首目录”和“检字表”而查到的字的排序并不是真正的注释的排序办法,比方您查“张”字,咱们能够看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的下面是“驰”字,但页码却是63页,“张”的上面是“弩”字,页面是390页。很显然,这些字并不是真正的别离位于“张”字的上下方,当初您看到的间断的“驰、张、弩”三字实际上就是他们在非汇集索引中的排序,是字典注释中的字在非汇集索引中的映射。咱们能够通过这种形式来找到您所须要的字,但它须要两个过程,先找到目录中的后果,而后再翻到您所须要的页码。咱们把这种目录纯正是目录,注释纯正是注释的排序形式称为“非汇集索引” 。\
通过以上例子,咱们能够了解到什么是“汇集索引”和“非汇集索引”。进一步引申一下,咱们能够很容易的了解:每个表只能有一个汇集索引,因为目录只能依照一种办法进行排序。
汇集:返回一个区间的列、值小数目不同、不要频繁更新*
非汇集索引 : 能够频繁更新、值大数目不同\
事实上,咱们能够通过后面汇集索引和非汇集索引的定义的例子来了解上表。如:返回某范畴内的数据一项。比方您的某个表有一个工夫列,恰好您把聚合索引建设在了该列,这时您查问2004年1月1日至2004年10月1日之间的全副数据时,这个速度就将是很快的,因为您的这本字典注释是按日期进行排序的,聚类索引只须要找到要检索的所有数据中的结尾和结尾数据即可;而不像非汇集索引,必须先查到目录中查到每一项数据对应的页码,而后再依据页码查到具体内容。**
在进行数据查问时都离不开字段的是“日期”还有用户自身的“用户名”。既然这两个字段都是如此的重要,咱们能够把他们合并起来,建设一个复合索引(compound index)。
9、MySql的存储引擎
9.1 Innodb引擎
Innodb引擎当初是MySQL的默认引擎。Innodb引擎提供了对数据库ACID事务的反对,并且实现了SQL规范的四种隔离级别(mysql数据库默认的隔离级别是:可反复读。读未提交,读已提交,可反复读,串行化读) 。该引擎还提供了行级锁和外键束缚,它的设计指标是解决大容量数据库系统,它自身其实就是基于MySQL后盾的残缺数据库系统,MySQL运行时Innodb会在内存中建设缓冲池,用于缓冲数据和索引。然而该引擎不反对FULLTEXT类型的索引,而且它没有保留表的行数,当SELECT COUNT() FROM TABLE时须要扫描全表。当须要应用数据库事务时,该引擎当然是首选。因为锁的粒度更小,写操作不会锁定全表,所以在并发较高时,应用Innodb引擎会晋升效率。然而应用行级锁也不是相对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范畴,InnoDB表同样会锁全表。*
9.2 MyISAM引擎
在MySQL5.1之前,MyISAM是MySQL默认的引擎,它没有提供对数据库事务的反对,也不反对行级锁和外键,因而当INSERT(插入)或UPDATE(更新)数据时即写操作须要锁定整个表,效率便会低一些。不过和Innodb不同,MyISAM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只须要间接读取曾经保留好的值而不须要进行全表扫描。如果表的读操作远远多于写操作且不须要数据库事务的反对,那么MyIASM也是很好的抉择。
9.3 InNoDB与MyISAM异同
InnoDB 反对事务,反对行级别锁定,反对 B-tree、Full-text (InNoDB从1.2.X版本开始反对全文搜寻的技术)等索引,不反对 Hash 索引,然而给了又有一个非凡的解释:InnoDB存储引擎 是反对hash索引的,不过,咱们必须启用,hash索引的创立由InnoDB存储引擎引擎主动优化创立,是数据库本身创立并应用,DBA(数据库管理员)无奈干涉;
MyISAM 不反对事务,反对表级别锁定,反对 B-tree、Full-text 等索引,不反对 Hash 索引;
Memory 不反对事务,反对表级别锁定,反对 B-tree、Hash 等索引,不反对 Full-text 索引;
MyISAM引擎不反对外键,InnoDB反对外键
MyISAM引擎的表在大量高并发的读写下会经常出现表损坏的状况
对于count()查问来说MyISAM更有劣势,MyISAM间接通过计数器获取,MyISAM会有一个空间转专门又来存储行数。InnoDB须要通过扫描全副数据,尽管InNoDB存储引擎是反对行级别锁,InNoDB是行级别锁,是where对他主键是无效,非主键的都会锁全表的
MyISAM 引擎的表的查问、更新、插入的效率要比InnoDB高,如果你的数据量是百万级别的,并且没有任何的事务处理,那么用MyISAM是性能最好的抉择。并且MyISAM能够节俭很多内存,因为MyISAM索引文件是与数据文件离开搁置,并且索引是有压缩,内存使用率进步不少平台承载的大部分我的项目是读多写少的我的项目,MyISAM读性能比InNoDB强很多
9.4 两种引擎的抉择
大尺寸的数据集趋向于抉择InnoDB引擎,因为它反对事务处理和故障复原。数据库的大小决定了故障复原的工夫长短,InnoDB能够利用事务日志进行数据恢复,这会比拟快。
主键查问在InnoDB引擎下也会相当快,不过须要留神的是如果主键太长也会导致性能问题,因为在检索索引树的时候不论是主键索引还是辅助键索引最终都是会通过比拟主键来进行检索进而获得行数据的,如果逐步太长,那么比拟主键的操作也会变简单。
少量的INSERT语句(在每个INSERT语句中写入多行,批量插入)在MyISAM下会快一些
然而UPDATE语句在InnoDB下则会更快一些,尤其是在并发量大的时候。
六、git基础知识
1、用户名和邮箱设置
$ git config --global user.name "输出用户名" (自定义)$ git config --global user.email "输出email" (自定义)
2、git提交代码
- 创立近程仓库(GitHub,Gitee,coding...)
如果没有本地仓库
echo "# toutiao-publish-admin" >> README.md
初始化本地仓库
git init
把文件增加到暂存区
git add README.md
把暂存区文件提交到本地仓库造成历史记录
git commit -m "first commit"
增加近程仓库地址到本地仓库
git remote add origin https://github.com/hyjAdmin/t...
推送到近程仓库
git push -u origin master
如果已有本地仓库
VueCli 在创立我的项目的时候主动帮咱们初始化了Git仓库,并且基于初始化代码默认执行了一次提交
git remote add origin https://github.com/hyjAdmin/t...
- -u 记住本次推送的信息,下次就不必写推送信息了,能够间接 git push
git push -u origin master
之后如果代码有变动须要提交
git addgit commit
推送到近程仓库
git push
我的项目批改 git 近程仓库地址
(1)查看所有近程仓库,个别默认近程仓库名为origin git remote(2)批改以后我的项目近程地址为 http://192.168.1.88:9090/test/git_test.git git remote set-url origin http://192.168.1.88:9090/test/git_test.git(3)更改地址后,须要提交初始代码到近程库 git push
3、git创立和合并分支命令
查看分支:git branch创立分支:git branch <name>切换分支:git checkout <name>创立+切换分支:git checkout -b <name>合并某分支到以后分支:git merge <分支名> 合并分支时,加上--no-ff参数就能够用一般模式合并,合并后的历史有分支,能看进去已经做过合并,而不加--no-ff合并就看不出来已经做过合并。例git merge --no-ff -m "具体解释" 分支删除分支:git branch -d <name>查看分支合并图: git log --graph
4、gitlib配置SSH Key
在持续浏览后续内容前,请自行注册GitLab账号(个别进公司,配置管理员或者组长会给你创立账户的)。因为你的本地Git仓库和GitLab仓库之间的传输是通过SSH加密的,所以,须要以下设置:
4.1 第1步:
创立SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果曾经有了,可间接跳到下一步。如果没有,关上Shell(Windows下关上Git Bash),创立SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
你须要把邮件地址换成你本人的邮件地址,而后一路回车,应用默认值即可,因为这个Key也不是用于军事目标,所以也无需设置明码。\
如果一切顺利的话,能够在用户主目录里找到.ssh目录,外面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露进来,id_rsa.pub是公钥,能够释怀地通知任何人。
4.2 第2步:
登陆GitLab,关上“settings”,“SSH Keys”页面:\
而后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:
点“Add Key”,你就应该看到曾经增加的Key:
为什么GitLab须要SSH Key呢?因为GitLab须要辨认出你推送的提交的确是你推送的,而不是他人假冒的,而Git反对SSH协定,所以,GitLab只有晓得了你的公钥,就能够确认只有你本人能力推送。\
当然,GitLab容许你增加多个Key。假设你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只有把每台电脑的Key都增加到GitLab,就能够在每台电脑上往GitLab推送了。\
其余的操作就和GitHub是一样的了.
七、Linux基础知识
1、从意识操作系统开始
1.1 操作系统简介
我通过以下四点介绍什么操作系统:
- 操作系统(Operation System,简称OS)是治理计算机硬件与软件资源的程序,是计算机系统的内核与基石;
- 操作系统实质上是运行在计算机上的软件程序 ;
- 为用户提供一个与零碎交互的操作界面 ;
- 操作系统分内核与外壳(咱们能够把外壳了解成围绕着内核的应用程序,而内核就是能操作硬件的程序)。
1.2 操作系统简略分类
- Windows: 目前最风行的集体桌面操作系统 ,不做多的介绍,大家都分明。
Unix: 最早的多用户、多任务操作系统 .依照操作系统的分类,属于分时操作系统。Unix 大多被用在服务器、工作站,当初也有用在集体计算机上。它在创立互联网、计算机网络或客户端/服务器模型方面施展着十分重要的作用。
- Linux: Linux是一套收费应用和自在流传的类Unix操作系统.Linux存在着许多不同的Linux版本,但它们都应用了 Linux内核 。Linux可装置在各种计算机硬件设施中,比方手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。严格来讲,Linux这个词自身只示意Linux内核,但实际上人们曾经习惯了用Linux来形容整个基于Linux内核,并且应用GNU 工程各种工具和数据库的操作系统。
2、初探Linux
2.1 Linux简介
咱们下面曾经介绍到了Linux,咱们这里只强调三点。
- 类Unix零碎: Linux是一种自在、开放源码的相似Unix的操作系统
- Linux内核: 严格来说,Linux这个词自身只示意Linux内核
- Linux之父: 一个编程畛域的传奇式人物。他是Linux内核的最早作者,随后发动了这个开源我的项目,负责Linux内核的首要架构师与我的项目协调者,是当今世界最驰名的电脑程序员、黑客之一。他还发动了Git这个开源我的项目,并为次要的开发者。
2.2 Linux诞生简介
- 1991年,芬兰的业余计算机爱好者Linus Torvalds编写了一款相似Minix的零碎(基于微内核架构的类Unix操作系统)被ftp管理员命名为Linux 退出到自由软件基金的GNU打算中;
- Linux以一只可恶的企鹅作为标记,象征着敢作敢为、热爱生活。
2.3 Linux的分类
Linux依据原生水平,分为两种:
- 内核版本: Linux不是一个操作系统,严格来讲,Linux只是一个操作系统中的内核。内核是什么?内核建设了计算机软件与硬件之间通信的平台,内核提供零碎服务,比方文件治理、虚拟内存、设施I/O等;
发行版本: 一些组织或公司在内核版根底上进行二次开发而从新发行的版本。Linux发行版本有很多种(ubuntu和CentOS用的都很多,初学倡议抉择CentOS),如下图所示:
3、Linux文件系统概览
3.1 Linux文件系统简介
在Linux操作系统中,所有被操作系统治理的资源,例如网络接口卡、磁盘驱动器、打印机、输入输出设施、一般文件或是目录都被看作是一个文件。
也就是说在LINUX零碎中有一个重要的概念:一切都是文件。其实这是UNIX哲学的一个体现,而Linux是重写UNIX而来,所以这个概念也就传承了下来。在UNIX零碎中,把所有资源都看作是文件,包含硬件设施。UNIX零碎把每个硬件都看成是一个文件,通常称为设施文件,这样用户就能够用读写文件的形式实现对硬件的拜访。
3.2 文件类型与目录构造
Linux反对5种文件类型 :
Linux的目录构造如下:
Linux文件系统的构造档次显明,就像一棵倒立的树,最顶层是其根目录:
常见目录阐明:
- /bin: 寄存二进制可执行文件(ls,cat,mkdir等),常用命令个别都在这里;
- /etc: 寄存系统管理和配置文件;
- /home: 寄存所有用户文件的根目录,是用户主目录的基点,比方用户user的主目录就是/home/user,能够用~user示意;
- /usr : 用于寄存零碎应用程序;
- /opt: 额定装置的可选利用程序包所搁置的地位。个别状况下,咱们能够把tomcat等都装置到这里;
- /proc: 虚构文件系统目录,是零碎内存的映射。可间接拜访这个目录来获取零碎信息;
- /root: 超级用户(系统管理员)的主目录(特权阶级^o^);
- /sbin: 寄存二进制可执行文件,只有root能力拜访。这里寄存的是系统管理员应用的零碎级别的治理命令和程序。如ifconfig等;
- /dev: 用于寄存设施文件;
- /mnt: 系统管理员装置临时文件零碎的装置点,零碎提供这个目录是让用户长期挂载其余的文件系统;
- /boot: 寄存用于零碎疏导时应用的各种文件;
- /lib : 寄存着和零碎运行相干的库文件 ;
- /tmp: 用于寄存各种临时文件,是专用的临时文件存储点;
- /var: 用于寄存运行时须要扭转数据的文件,也是某些大文件的溢出区,比方说各种服务的日志文件(系统启动日志等。)等;
- /lost+found: 这个目录平时是空的,零碎非正常关机而留下“无家可归”的文件(windows下叫什么.chk)就在这里。
4、Linux根本命令
上面只是给出了一些比拟罕用的命令。举荐一个Linux命令快查网站,十分不错,大家如果忘记某些命令或者对某些命令不了解都能够在这里失去解决。
Linux命令大全:man.linuxde.net/
4.1 目录切换命令
cd usr
: 切换到该目录下usr目录cd ..(或cd../)
: 切换到上一层目录cd /
: 切换到零碎根目录cd ~
: 切换到用户主目录cd -
: 切换到上一个所在目录
4.2 目录的操作命令(增删改查)
mkdir 目录名称
: 减少目录ls或者ll
(ll是ls -l的缩写,ll命令以看到该目录下的所有目录和文件的详细信息):查看目录信息find 目录 参数
: 寻找目录(查)示例:
- 列出当前目录及子目录下所有文件和文件夹:
find .
- 在
/home
目录下查找以.txt结尾的文件名:find /home -name "*.txt"
- 同上,但疏忽大小写:
find /home -iname "*.txt"
- 当前目录及子目录下查找所有以.txt和.pdf结尾的文件:
find . ( -name "*.txt" -o -name "*.pdf" )
或find . -name "*.txt" -o -name "*.pdf"
- 列出当前目录及子目录下所有文件和文件夹:
mv 目录名称 新目录名称
: 批改目录的名称(改)留神:mv的语法不仅能够对目录进行重命名而且也能够对各种文件,压缩包等进行 重命名的操作。mv命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。前面会介绍到mv命令的另一个用法。
mv 目录名称 目录的新地位
: 挪动目录的地位---剪切(改)留神:mv语法不仅能够对目录进行剪切操作,对文件和压缩包等都可执行剪切操作。另外mv与cp的后果不同,mv如同文件“搬家”,文件个数并未减少。而cp对文件进行复制,文件个数减少了。
cp -r 目录名称 目录拷贝的指标地位
: 拷贝目录(改),-r代表递归拷贝留神:cp命令不仅能够拷贝目录还能够拷贝文件,压缩包等,拷贝文件和压缩包时不 用写-r递归
rm [-rf] 目录
: 删除目录(删)留神:rm不仅能够删除目录,也能够删除其余文件或压缩包,为了加强大家的记忆, 无论删除任何目录或文件,都间接应用
rm -rf
目录/文件/压缩包
4.3 文件的操作命令(增删改查)
touch 文件名称
: 文件的创立(增)cat/more/less/tail 文件名称
文件的查看(查)cat
: 只能显示最初一屏内容more
: 能够显示百分比,回车能够向下一行, 空格能够向下一页,q能够退出查看less
: 能够应用键盘上的PgUp和PgDn向上 和向下翻页,q完结查看tail-10
: 查看文件的后10行,Ctrl+C完结
留神:命令 tail -f 文件 能够对某个文件进行动静监控,例如tomcat的日志文件, 会随着程序的运行,日志会变动,能够应用tail -f catalina-2016-11-11.log 监控 文 件的变动
vim 文件
: 批改文件的内容(改)vim编辑器是Linux中的弱小组件,是vi编辑器的加强版,vim编辑器的命令和快捷方式有很多,但此处不一一论述,大家也无需钻研的很透彻,应用vim编辑批改文件的形式根本会应用就能够了。
在理论开发中,应用vim编辑器次要作用就是批改配置文件,上面是个别步骤:
vim 文件------>进入文件----->命令模式------>按i进入编辑模式----->编辑文件 ------->按Esc进入底行模式----->输出:wq/q! (输出wq代表写入内容并退出,即保留;输出q!代表强制退出不保留。)
rm -rf 文件
: 删除文件(删)同目录删除:熟记
rm -rf
文件 即可
4.4 压缩文件的操作命令
1)打包并压缩文件:
Linux中的打包文件个别是以.tar结尾的,压缩的命令个别是以.gz结尾的。
而个别状况下打包和压缩是一起进行的,打包并压缩后的文件的后缀名个别.tar.gz。 命令:tar -zcvf 打包压缩后的文件名 要打包压缩的文件
其中:
z:调用gzip压缩命令进行压缩
c:打包文件
v:显示运行过程
f:指定文件名
比方:退出test目录下有三个文件别离是 :aaa.txt bbb.txt ccc.txt,如果咱们要打包test目录并指定压缩后的压缩包名称为test.tar.gz能够应用命令:tar -zcvf test.tar.gz aaa.txt bbb.txt ccc.txt
或:tar -zcvf test.tar.gz /test/
2)解压压缩包:
命令:tar [-xvf] 压缩文件
其中:x:代表解压
示例:
1 将/test下的test.tar.gz解压到当前目录下能够应用命令:tar -xvf test.tar.gz
2 将/test下的test.tar.gz解压到根目录/usr下:tar -xvf xxx.tar.gz -C /usr
(- C代表指定解压的地位)
4.5 Linux的权限命令
操作系统中每个文件都领有特定的权限、所属用户和所属组。权限是操作系统用来限度资源拜访的机制,在Linux中权限个别分为读(readable)、写(writable)和执行(excutable),分为三组。别离对应文件的属主(owner),属组(group)和其余用户(other),通过这样的机制来限度哪些用户、哪些组能够对特定的文件进行什么样的操作。通过 ls -l
命令咱们能够 查看某个目录下的文件或目录的权限
示例:在随便某个目录下ls -l
第一列的内容的信息解释如下:
上面将具体解说文件的类型、Linux中权限以及文件有所有者、所在组、其它组具体是什么?
文件的类型:
- d: 代表目录
- -: 代表文件
- l: 代表链接(能够认为是window中的快捷方式)
Linux中权限分为以下几种:
- r:代表权限是可读,r也能够用数字4示意
- w:代表权限是可写,w也能够用数字2示意
- x:代表权限是可执行,x也能够用数字1示意
文件和目录权限的区别:
对文件和目录而言,读写执行示意不同的意义。
对于文件:
权限名称 | 可执行操作 |
---|---|
r | 能够应用cat查看文件的内容 |
w | 能够批改文件的内容 |
x | 能够将其运行为二进制文件 |
对于目录:
权限名称 | 可执行操作 |
---|---|
r | 能够查看目录下列表 |
w | 能够创立和删除目录下文件 |
x | 能够应用cd进入目录 |
在linux中的每个用户必须属于一个组,不能独立于组外。在linux中每个文件有所有者、所在组、其它组的概念。
所有者
个别为文件的创建者,谁创立了该文件,就人造的成为该文件的所有者,用ls ‐ahl命令能够看到文件的所有者 也能够应用chown 用户名 文件名来批改文件的所有者 。
文件所在组
当某个用户创立了一个文件后,这个文件的所在组就是该用户所在的组 用ls ‐ahl命令能够看到文件的所有组 也能够应用chgrp 组名 文件名来批改文件所在的组。
其它组
除开文件的所有者和所在组的用户外,零碎的其它用户都是文件的其它组
咱们再来看看如何批改文件/目录的权限。
批改文件/目录的权限的命令:chmod
示例:批改/test下的aaa.txt的权限为属主有全副权限,属主所在的组有读写权限, 其余用户只有读的权限
chmod u=rwx,g=rw,o=r aaa.txt
上述示例还能够应用数字示意:
chmod 764 aaa.txt
补充一个比拟罕用的货色:
如果咱们装了一个zookeeper,咱们每次开机到要求其主动启动该怎么办?
- 新建一个脚本zookeeper
- 为新建的脚本zookeeper增加可执行权限,命令是:
chmod +x zookeeper
- 把zookeeper这个脚本增加到开机启动项外面,命令是:
chkconfig --add zookeeper
- 如果想看看是否增加胜利,命令是:
chkconfig --list
4.6 Linux 用户治理
Linux零碎是一个多用户多任务的分时操作系统,任何一个要应用系统资源的用户,都必须首先向系统管理员申请一个账号,而后以这个账号的身份进入零碎。
用户的账号一方面能够帮忙系统管理员对应用零碎的用户进行跟踪,并管制他们对系统资源的拜访;另一方面也能够帮忙用户组织文件,并为用户提供安全性爱护。
Linux用户治理相干命令:
useradd 选项 用户名
:增加用户账号userdel 选项 用户名
:删除用户帐号usermod 选项 用户名
:批改帐号passwd 用户名
:更改或创立用户的明码passwd -S 用户名
:显示用户账号密码信息passwd -d 用户名
: 革除用户明码
useradd命令用于Linux中创立的新的零碎用户。useradd可用来建设用户帐号。帐号建好之后,再用passwd设定帐号的明码.而可用userdel删除帐号。应用useradd指令所建设的帐号,实际上是保留在/etc/passwd文本文件中。
passwd命令用于设置用户的认证信息,包含用户明码、明码过期工夫等。零碎管理者则能用它管理系统用户的明码。只有管理者能够指定用户名称,个别用户只能变更本人的明码。
4.7 Linux零碎用户组的治理
每个用户都有一个用户组,零碎能够对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同,如Linux下的用户属于与它同名的用户组,这个用户组在创立用户时同时创立。
用户组的治理波及用户组的增加、删除和批改。组的减少、删除和批改实际上就是对/etc/group文件的更新。
Linux零碎用户组的治理相干命令:
groupadd 选项 用户组
:减少一个新的用户组groupdel 用户组
:要删除一个已有的用户组groupmod 选项 用户组
: 批改用户组的属性
4.8 其余常用命令
pwd
: 显示以后所在位置grep 要搜寻的字符串 要搜寻的文件 --color
: 搜寻命令,--color代表高亮显示ps -ef
/ps aux
: 这两个命令都是查看以后零碎正在运行过程,两者的区别是展现格局不同。如果想要查看特定的过程能够应用这样的格局:ps aux|grep redis
(查看包含redis字符串的过程)留神:如果间接用ps((Process Status))命令,会显示所有过程的状态,通常联合grep命令查看某过程的状态。
kill -9 过程的pid
: 杀死过程(-9 示意强制终止。)先用ps查找过程,而后用kill杀掉
网络通信命令:
- 查看以后零碎的网卡信息:ifconfig
- 查看与某台机器的连贯状况:ping
- 查看以后零碎的端口应用:netstat -an
shutdown
:shutdown -h now
: 指定当初立刻关机;shutdown +5 "System will shutdown after 5 minutes"
:指定5分钟后关机,同时送出正告信息给登入用户。reboot
:reboot
: 重开机。reboot -w
: 做个重开机的模仿(只有纪录并不会真的重开机)。
八、npm 和 yarn
标签: nodejs 电脑 yarn环境变量 yarn装置
Yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的JS 包管理工具 ,正如官网文档中写的,Yarn 是为了补救 npm 的一些缺点而呈现的。yarn和npm一样,都能够用来增加和删除某个软件包,但yarn比npm装置软件包的速度更快,装置语法也更简洁。
命令比照如下:
npm install <==> yarnnpm install taco --save <==> yarn add taconpm uninstall taco --save <==> yarn remove taconpm install taco --save-dev <==> yarn add taco --devnpm update --save <==> yarn upgrade
上面介绍在win10平台上,yarn工具的装置和环境配置。
1、应用PowerShell的管理员形式装置yarn工具
1.1 按Win+R,输出:powershell–>回车,弹出第一个蓝色的PowerShell,在外面输出命令:
Start-Process powershell -Verb runAs
1.2 在第二个弹出的蓝色框框里,持续输出如下命令:
set-ExecutionPolicy RemoteSigned
1.3 输出yarn的全局装置命令:
npm install -g yarn
2、配置yarn环境变量
这里以node的默认门路,即C:\Program Files为例进行阐明。当然,如果你的node装置在其余盘,将其改成node的理论门路即可。
2.1 在零碎环境变量里,增加一个NODE_PATH变量,如下:\
点击[我的电脑] -->属性–> 高级零碎变量 -->环境变量 --> 零碎变量 -->新建:\
变量名:NODE_PATH\
门路:C:\Program Files\nodejs\node_global\node_modules;
图(1) 增加NODE_PATH零碎变量
2.2 同时,将下面的C:\Program Files\nodejs\node_global\node_modules门路,也增加到[用户变量]的Path里,如图(2)所示:
图(2) 在用户变量Path里也增加一份雷同的门路
2.3 设置node软件包的全局装置目录和缓存目录,在powershell管理员的蓝色框框里,输出如下2个命令即可:
npm config set prefix "C:\Program Files\nodejs\node_global"npm config set cache "C:\Program Files\nodejs\node_cache"
2.4设置淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
3、重启电脑
4、进入powershell的蓝色框框,输出如下命令:
yarn -v
若有版本信息打印,阐明yarn的环境变量设置胜利,即yarn命令能被零碎辨认。如图(3)所示:
图(3) 能打印yarn的版本信息,即阐明环境配置胜利