关于node.js:Nodejs开发心路历程

3次阅读

共计 56306 个字符,预计需要花费 141 分钟才能阅读完成。

一、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 是一个数组,可选择性的仅蕴含数组指定的属性。```js
    1. 转换值如果有 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,仅会序列化可枚举的属性。```
    
  • 例子:

```js
JSON.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 返回 nullundefined,则删除成员。
  • 返回值:
    一个对象或数组。

    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 实例

   
```js
const 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-element
    2. 增加全局资源:指令 / 过滤器 / 适度等。如:vue-touch
    3. 通过全局混入来增加一些组件选项。如: vue-router
    4. 增加 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 = 2
obj1.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,能够写 %,本地写 localhost

grant 权限(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 
      字段            3
from
      表名            1
where
      条件                2
order 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 e
    12.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 columns
    13. 子查问
       什么是子查问?子查问都能够呈现在哪里?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 = expr2
THEN 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_name1
UNION ALL
SELECT 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 束缚。

汇集索引 基于数据行的键值 ,在 表内排序和存储这些数据行。每个表只能有一个汇集索引,应为数据行本分只能按一个顺序存储。

在汇集索引中,表中各行的物理程序与索引键值的逻辑 (索引) 程序雷同 。汇集索引通常可放慢UPDATEDELETE操作的速度,因为这两个操作须要读取大量的数据。创立或批改汇集索引可能要花很长时间,因为执行这两个操作时要在磁盘上对表的行进行重组。

  • 非汇集索引

因为一个表中只能有一个汇集索引,如果须要在表中建设多个索引,则能够创立为非汇集索引。表中的数据并不依照非汇集索引列的顺序存储,但非汇集索引的索引行中 保留了非汇集键值 行定位器 ,能够快捷 地依据非汇集键的值来定位记录的存储地位

无论是汇集索引,还是非汇集索引,都能够是惟一索引。在 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 add
    git 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 操作系统简略分类

  1. Windows: 目前最风行的集体桌面操作系统,不做多的介绍,大家都分明。
  2. Unix: 最早的多用户、多任务操作系统 . 依照操作系统的分类,属于分时操作系统。Unix 大多被用在服务器、工作站,当初也有用在集体计算机上。它在创立互联网、计算机网络或客户端 / 服务器模型方面施展着十分重要的作用。

  3. 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 依据原生水平,分为两种:

  1. 内核版本: Linux 不是一个操作系统,严格来讲,Linux 只是一个操作系统中的内核。内核是什么?内核建设了计算机软件与硬件之间通信的平台,内核提供零碎服务,比方文件治理、虚拟内存、设施 I / O 等;
  2. 发行版本: 一些组织或公司在内核版根底上进行二次开发而从新发行的版本。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 目录的操作命令(增删改查)

  1. mkdir 目录名称 减少目录
  2. ls 或者 ll(ll 是 ls - l 的缩写,ll 命令以看到该目录下的所有目录和文件的详细信息):查看目录信息
  3. 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"
  4. mv 目录名称 新目录名称 批改目录的名称(改)

    留神:mv 的语法不仅能够对目录进行重命名而且也能够对各种文件,压缩包等进行 重命名的操作。mv 命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。前面会介绍到 mv 命令的另一个用法。

  5. mv 目录名称 目录的新地位 挪动目录的地位 — 剪切(改)

    留神:mv 语法不仅能够对目录进行剪切操作,对文件和压缩包等都可执行剪切操作。另外 mv 与 cp 的后果不同,mv 如同文件“搬家”,文件个数并未减少。而 cp 对文件进行复制,文件个数减少了。

  6. cp -r 目录名称 目录拷贝的指标地位 拷贝目录(改),- r 代表递归拷贝

    留神:cp 命令不仅能够拷贝目录还能够拷贝文件,压缩包等,拷贝文件和压缩包时不 用写 - r 递归

  7. rm [-rf] 目录: 删除目录(删)

    留神:rm 不仅能够删除目录,也能够删除其余文件或压缩包,为了加强大家的记忆,无论删除任何目录或文件,都间接应用rm -rf 目录 / 文件 / 压缩包

4.3 文件的操作命令(增删改查)

  1. touch 文件名称: 文件的创立(增)
  2. 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 监控 文 件的变动

  3. vim 文件 批改文件的内容(改)

    vim 编辑器是 Linux 中的弱小组件,是 vi 编辑器的加强版,vim 编辑器的命令和快捷方式有很多,但此处不一一论述,大家也无需钻研的很透彻,应用 vim 编辑批改文件的形式根本会应用就能够了。

    在理论开发中,应用 vim 编辑器次要作用就是批改配置文件,上面是个别步骤:

    vim 文件 ——> 进入文件 —–> 命令模式 ——> 按 i 进入编辑模式 —–> 编辑文件 ——-> 按 Esc 进入底行模式 —–> 输出:wq/q!(输出 wq 代表写入内容并退出,即保留;输出 q! 代表强制退出不保留。)

  4. 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,咱们每次开机到要求其主动启动该怎么办?

  1. 新建一个脚本 zookeeper
  2. 为新建的脚本 zookeeper 增加可执行权限,命令是:chmod +x zookeeper
  3. 把 zookeeper 这个脚本增加到开机启动项外面,命令是:chkconfig --add zookeeper
  4. 如果想看看是否增加胜利,命令是: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 <==> yarn
npm install taco --save <==> yarn add taco
npm uninstall taco --save <==> yarn remove taco
npm install taco --save-dev <==> yarn add taco --dev
npm 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 的版本信息,即阐明环境配置胜利

正文完
 0