第九周内容回顾

第九周内容回顾

1、UDP协议

UDP不需要考虑黏报问题 (UDP多用于短消息交互)
服务端不需要考虑客户端异常退出

服务端

import socket
server = socket.socket(type = socket.sock_DGRAM)
server.bind(('127.0.0.1,8080'))
msg,address = server.recvfrom(1024)
print ('msg>>>:%s'%msg.decode('utf8'))
print('address>>>',address)
server.sendto('我是服务端 你好'.encode('utf'),address)

客户端

import socket
client = socket.socket(type = socket.sock_DGRAM)
serverr_address = ('127.0.0.1',8080)
client.sendto('我是客户端,我不好',encode('utf'),server_address)
msg,address = client.recvfrom(1024)
print('msg>>>:%s'%msg.decode('utf'))
print('address>>>:',address)

说明
开发编程前期学习阶段理论居多,后期才会有操作(调模块)
学习并发编程就是在学习操作系统发展史
也可称之为并发编程发展史

2、多道技术

前提:一个核/一个CPU/一个真正干活的
单道技术
所有程序排列执行 总耗时是所有程序耗时之和

多道技术
计算机利用空间时间 提前准备好了一些数据 提高效率总耗时较短

切换+保存状态

  1. 程序两种情况会切换(去执行其他程序)

    1. 陈旭自身进入io操作

      IO操作:输入输出操作

      1. 获取用户输入
      2. time.sleeo()
      3. 读取文件
      4. 保存文件
    2. 程序长时间占用CPU

  2. 保存在状态

    1. 每次切换之前要记录当前执行状态 之后切换回来基于当前状态继续执行

形象比喻
做饭耗时 50min
洗衣耗时 30min

单道技术:50-30-10
多道技术:50

3、进程理论

如何理解进程
程序:一堆躺在文件上的死代码
进程:正在被运行的程序

进程调度算法

  1. 未来先服务算法

    针对耗时比较短的程序不友好

  2. 短作业优先调度

    针对耗时比较长的程序不友好

  3. 时间片轮转法+多级反馈队列

    将固定的时间均分成很多份 所有的程序来了都公平的分一份

    分配多次之后如果 还有程序需要运行 则将其分到下一层

    越下表示程序总耗时越长 每次分的时间片越多,但是优先级越低

3.1、进程的并行与并发

并发
多个进程同时执行
单个CPU肯定无法实现 并行 必须要有多个CPU (并行是真正的共同执行)

并发
多个进程看上去像同时执行就可以称之为并发
单个CPU完全可以实现并发效果 如果是并行那么肯定也属于并发

描述一个网址 非常牛逼能够同时服务很多人的话术

  1. 我这个网址很牛逼 能够支持14亿并行量(高并行)
    不合理 不可能有这么多CPU (集群也不现实)
  2. 我们这个网址 很牛逼 能够支持14亿并发量(高并发)
    非常合理!!!,国内最牛逼的网站>>>12306

3.2、进程的三状态

  1. 所有进程要想被运行 必须要先经过就绪态
  2. 运行过程中如果 出现了IO操作 则进入阻塞态
  3. 运行过程中如果时间片用完 则继续进入就绪态
  4. 阻塞态想要进入运行态 必须先经过就绪态

3.3、同步和异步

主要用于描述任务的提交状态

同步
提交完任务之后 原地等待任务的结果 期间不做任何事

异步
提交完任务之后 不原地等待 直接去做其他事 结果自动提醒

3.4、阻塞与非阻塞

用于描述进程的执行状态

阻塞
阻塞态

非阻塞
就绪态、运行态

3.5、同步异步与阻塞非阻塞

同步阻塞: 在银行排队 并且在队列中什么事情都不做
同步非阻塞: 在银行排队 并且在队伍中做点其他事情
异步阻塞: 取号 在旁边座位上等着叫号 期间不做任何事
异步非阻塞: 在旁边座位上等着叫号 期间为所欲为

4、代码创建进程

创建进程的本质:在内存中申请一块内存空间用于运行相应的程序代码

创建进程的方式
鼠标双击桌面一个应用启动一个应用 就是会启动和创建一些进程
代码创建

在不同的操作系统创建进程的要求不一样
在windows中创建进程是以倒模块的方式进行 所以创建进程的代码必须写在__main__ 子代码中
否则会直接报错 因为在无限制创建进程(进入死循环)
在linux和mac中创建进程是直接拷贝一份源代码然后执行 不要写__main__ 子代码中

#第一种创建进程的方式
import time
from multiprocessing import Porcess

#创建一个函数
def task(name):
    print('%s is runing' % name)
    time.sleep(3)
    print('%s is over'%name)
    
if __name__ == '__main__':
    #创建一个进程对象
    P = Process(target = task,args=('kk',))
    #告诉操作系统创建一个新的进程
    p。start()
    print('主进程')
    
#第二种创建进程的方式
from multiprocessing import Process
import time

#创建一个类继承 Process父类 来使用其中的方法
class Myprocess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print(f'{self.name}正在运行')
        time.sleep(3)
        print(f'{self.name}运行结束')
        
if __name__ =='__main__':
    #创建一个进程对象
    obj = Myprocess('kk')
    #告诉操作系统船舰了一个进程
    obj.start()

4.1、join方法

join: 主进程等待子进程 运行结束之后再运行

推导:

  1. 直接再主进程代码中添加 time.sleep()让主进程延时 至子进程运行结束

不合理 因为无法准确的把握子进程的执行时间

  1. 利用join方法
import time
from multiprocessing import Process
def task(name,n):
    print(f'{name}正在运行')
    time。sleep(n)
    print(f'{name}运行结束')
    
    
if __name__ == '__main__':
    #创建一个进程对象
    p1 = Process(target = task,args=('kk',3))
    p2 = Process(target = task,args = ('jj',2))
    t1 = time.time()
    #创建一个进程
    p1.start()
    #这里 通过join方法 将两个进程一个个运行
    p1.join()
    p2.start()
    #等子进程运行完 再继续执行主进程
    p2.join()
    end_time = time.time()-t1
    print(f'程序的运行时间{end_time}')
    print('主进程')

4.2、进程之间数据默认隔离

多个进程数据彼此之间默认是相互隔离的
如果想要交互 需要借助于 管道 队列

from multiprocessing import Process
money = 100
def task():
    global money
    money = 666
    print(f'子进程有{money}')
    
    
if __name__ == '__main__':
    p1 = Process(target = task)
    P1.start()
    p1.join()
    print(f'父进程有{money}')

4.3、进程间通信(IPC机制)

from multiprocessing import Queue

#先创建队列列表
q= Queue(3) #默认可容纳数据个数为2147483647
#往队列添加数据
q.put(111)

#判断队列是否已经存满
print(q.full())
q.put(222)
q.put(333)
print(q.full())
#如果超出存放限制 那么程序 一直处于阻塞态

#从队列中获取数据
print(q.get())  # 取不到进入阻塞态
q.put(444)
print(q.get())
print(q.get_nowait()) #如果被取完了 那么会直接报错
#判断队列是否已经空了
print(q.empty())

下列方法再多进程中不能精确使用

q.full() #判断队列中是否已经存满 可能刚判断完里面数据就被改动了 下列方法也是
q.empyt() #判断 队列是否已经空了
q.get_nowait() #如果独立额里为空 再取会直接报错
4.3.1、IPC机制

主进程与子进程通信
子进程与子进程通信

from multiprocessing import Queue,Process
def procedure(q):
    q.put('子进程Procedure 往队列中添加的数据')
def consumer(q):
    print('子进程的consumer 从队列中获取数据',q.get())
    
if __name__ == '__main__':
    #在主进程中 产生q对象 确保所有的子进程使用的是相同的q
    q = Queue()
    p1 = Process(target = procedure,args=(q,))
    p2 = Process(target = consumer,args=(q,))
    p1.start()
    p2.start()
    print('主进程')

4.4、生产者消费者模型

生产者
产生数据

消费者
处理数据

  • 生产者:获取网页数据代码(函数)
  • 消费者:从网页数据中筛选出符合条件的数据(函数)
    • 筛选

完整的生产者 消费者模型至少还有三个部分
生产者
消息队列
消费者

4.5、进程的相关方法

查看进程号

#通过 curent_process:
from multiprocessing import current_process
print(current_process()) #查看当前进程号
#通过os 模块
import os
print(os.getpid()) #查看当前进程号
print(os.getpid()) #查看它的父进程 进程号 即主进程号

销毁子进程

p1.erminate()

判断 进程是否存货

#我们都是跟操作系统打交道的 都是异步操作 所以代码运行速度很快 操作系统运行没有反应那么快
p1.is_alive

4.6、守护进程

如何理解守护进程
伴随着守护对象的 存活而存活 死亡而死亡

from multiprocessing import Process

import time 

def task(name):
    print('大内总管:%s存货'%name)
    time.sleep(3)
    print('大内总管 %s 挂了'% name)
    
if __name__ == '__main__':
    p = Process(target=task ,args=('kk',))
    # 将子进程设置为守护进程:主进程代码结束 子进程立刻结束
    p.daemon = True
    p.start()
    print('主进程')

4.7、僵尸进程与孤儿进程

僵尸进程
进程已经运行结束了 但是相关的资源并没有瓦努请安的清空
需要父进程参与回收

孤儿进程
父进程意外死亡 子进程正常运行 该子进程就称之为孤儿进程
孤儿进程 也不是没有人管 操作系统 会自动分配福利院接收

5、互斥锁

多个程序同时操作一份数据的时候 很容易产生数据错乱!
所以为了避免数据错乱,我们要使用互斥锁

互斥锁
将并发变成 串行 虽然牺牲了 程序的执行效率 但是保证了数据安全

使用方法

#互斥锁 也时multiprocessing 模块中的类 我们可以在创建进程 倒模块时一起倒入
from multiprocessing import Process,Lock
mutex = Lock()
#抢锁
mutex。acquire()
#释放锁
mutex。release()

注意
互斥锁 只应该出现在多个程序操作数据的地方 其他位置尽量不要加

6、线程

线程是资源单位
进程相当于是车间 进程负责给颠部的线程提供相应的资源

线程是执行单位
线程相当于是车间里面的流水线 线程负责执行真正的功能

一个进程至少含有一个线程

多进程与多线程区别
多进程
需要申请内存空间 需要拷贝全部代码 资源消耗大

多线程
不要申请内存空间 也不需要拷贝全部代码 资源消耗小

同一进程下 多个线程之间资源共享

6.1、创建线程的两种方式

开设线程不用完整的拷贝代码 所以无论什么系统都不会出现反复操作的情况 也不需要在启动脚本执行 但是为了兼容性 和统一性 习惯在脚本编写

线程的创建 与进程创建 代码步骤相似
方式一:

from threading import Thread
import time

def task(name):
    print(f'{name}正在运行')
    time.sleep(3)
    print(f'{name}运行结果)
          
if __name__ == '__main__':
    #创建线程对象
    t = Thread(target=task, args=('kk',))
    t.start()
    print('主线程')

方式二:

import time
from threading import Thread

class My_Thread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name
        
   	def run (self):
        print(f'{self.name} 正在运行')
        time.sleep(3)
        print(f'{self.name}运行结束')

obj = My_Thread('jason')
obj.start()
print('主线程')

6.2、多线程实现TCP 服务端并发

比进程更加简单 方便 消耗的资源更少
server

import socket
from threading import Thread
def get_server():
    server = socket.socket()
    server.bind(('127.0.0.1,8080'))
	server.listen(5)
    return server

def talk(sock):
    while True:
        data = sock.recv(1024)
        print (data.decode('utf8'))
		sock.send(data.upper())

if __name__ == '__main__':
    server = get_server()
    while True:
        sock,addr = server.accept()
        #开设进程取完完成数据交互
        t = Thread(target= talk,args=(sock,))
        t.start()

client

import socket

client = socket.socket()
client. connect(('127.0.0.1',8080))

for i in rangge(10000):
    client.send(b'hello baby)
                data = client.recv(1024)
                print(data.decode('utf'))

6.3、join方法

主线程 等到子线程运行结束之后再运行

from threading import Thread
import time 

def task():
    print('正在执行')
    time.sleep(3)
    print('运行结束')

t=Thread(targe = task)
t.stat()
t.join()
print('主线程')

6.4、同一进程下线程之间数据共享

线程创建不会去另外开设空间 就在进程下运行 所以数据公用

from threading import Thread

money = 10000

def func():
    global money
    money = 888

if __name__ == '__main__':
    t = Thread(target=func)
    t.start()
    # 确保线程运行完毕 再查找 money 结果更具有说服性
    t.join()
    print(money)

6.5、线程对象相关方法

进程号
同一进程下开设多个线程拥有相同的进程号

查看线程名、线程号

from threading import Thread,current_thread
import os 
#查看 主线程
print(current_thread().name)
#查看 线程号
print(os.getpid())

def task(name):
    print(f'{name}正在运行')
    #查看子线程
    print(current_thread().name)
    #查看子线程号
    print(os.getpid())
    time.sleep(3)
    print(f'{name}y运行结束')
主;MainThread  子:Thread:N

统计线程数

from threading import active_count()

6.6、守护线程

守护线程 伴随着被守护的线程的结束 而结束
子线程守护主线程 伴随主线程结束 而结束

进程下锁有非守护线程结束 主线程 (主进程)才能结束

from threading import Thread
import time
def task():
    print('子线程 运行 task函数')
    time。sleep(3)
    print('子线程运行task结束')
    
t = Thrad(target = task)
# t线程为守护线程
# t.daemon = True
print('主线程')

7、GIL全局解释器

储备知识

python 解释器 也是由编程语言写出来的
Cpython 用c写出来的
Jpython 用Jave写的
Pypython 用python写出来的
最常用的就是C python(默认)

官方文档GIL的解释器

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

  1. GIL的研究是Cpyhon 解释器的特点 不是python语言的特点
  2. Gil本质也是一把互斥锁
  3. GIL的存在使得同一进程下的多个线程无法同时执行(关键)
    言外之意:单进程下的多线程无法利用多核优势 效率低!
  4. GIL的存在 主要是因为Cpython解释器中垃圾回收机制 不是线程安全的
  5. 误解: python的线程是垃圾 利用不到多核优势
    python的线程确实无法使用多核优势 但是在IO密集型的任务下是有用的
  6. 误解: 既然由GIL 那么以后我们写代码都不需要加互斥锁
    不对 GIL只确保解释器层面数据 不会错乱(垃圾回收机制)
    针对 程序自己的数据应该自己加锁处理
  7. 锁有的解释型编程语言 都没办法做倒同一个进程下 多个线程同时执行
    我们平时在写代码的时候 不需要考虑GIL 只在学习和面试阶段才考虑

7.1验证GIL的存在

我们通过代码来验证 GIL的存在

通过 创建一百个线程,正常来说这是异步操作 他们一时间取代的都是100,但是 因为有GIL的机制 让他们抢锁 所以就不是真正意义上的同时运行 而是串行

from threading import Thread

money = 100
def task():
    global money
    money -=1
    
t_list=[]
#创建100个线程
for i in range(100):
    t = Thread(target = task)
    t.start()
    #将线程添加进列表
    t_list.append(t)
    
#将锁有创建的线程 都让他们能够运行完
for i in t_list:
    t.join()
    
#等待 锁有的线程运行结束 查看 money 是多少
print(money)
>>>>>
0

7.2、GIL的特点

单进程多线程中 当一个线程 先拿到锁 取到公共数据后 进入io操作 那么 会释放解释器 让各线程 都能被轮流拿到锁 去取公共数据 而第一个拿到锁的 没有机会 在这之前 将数据实时更新

所以我们就算有解释器锁 在面对 io操作下 同线程 创建情况 我们还是要添加互斥锁

from threading import Thread
import time
muetx = Lock()
money = 100

def task():
    giobal money
    #先取money
    price = money
    #io 操作 使其释放锁
    time.sleep(0.0.1)
    money = print -1
    #释放锁
    mutex.release()
    
    
t_list = []
#创建 100个线程
t1 = time.time
for i in range(100):
    t = Thread(target = task)
    t.start()
    t.join()
    #将线程添加进列表
    t_list.append(t)
    
#将锁有创建的线程都让他能够运行完
for i in t_list:
    t.join()
    
#等待 锁有的线程运行结束 查看money 是多少
print(time.time()-t1)
print(money)

8、验证python多线程 是否有用

分情况

  1. cpu情况

    1. 单个cpu
    2. 多个cpu
  2. 代码情况

    1. io密集型(代码有io操作)
    2. 计算密集型(代码没有io)
  3. 单个cpu

    1. io密集型

      1. 多进程

        总耗时(单进程的耗时+io +申请空间+拷贝代码)

      2. 多线程

        总耗时(单进程的耗时+io)

      多线程有优势

    2. 计算密集型

      1. 多进程

        申请而外的空间 消耗 更多的资源(总耗时+申请的空间+拷贝的代码+切换)

      2. 多线程

      3. 耗时资源相对较少 通多多道计数(总耗时+切换)

      多线程有优势

  4. 多个cpu

    1. io密集型

      1. 多进程

        总耗时(单个进程的耗时)

      2. 多线程

        总耗时(单进程耗时+io)

      多线程有优势

    2. 计算密集型

      1. 多进程

        总耗时(单个进程的耗时)

      2. 多线程

        总耗时(多个进程的综合)

      多进程完胜

9、信号量

信号量本质也是 互斥锁 只不过它是多把锁

强调:
信号量在不同的知识体系中 意思可能有区别
在django 中信号量指的是达到某个条件自动触发(中间件)

我们之前使用Lock产生的是单把锁
类似于单间厕所
信号量相当于一次性 创建多间厕所
类似于公共厕所

from threading import Thread,semaphore
import time

#一次性 产生五把锁
sp = Semaphore(5)

class Mythread(Thread):
    def run(self):
        sp.acquire()
        print(self.name)
        time.sleeo(2)
        sp.release()
        
        
for i in range(20):
    t= mythread()
    t.start()
#一磁性进去五个 然后再出取五个 依次类推

10、event事件

子进程:子线程之间 可以彼此等待彼此
子A运行倒某一个代码位置 发信号告诉B开始运行

from threading import Thread,Event
import time

#类似于 造另一个红绿灯
event = Event()

def light():
    print('红灯亮着的 所有人都别动')
    #进入io操作 等待两秒
    time.sleep(2)
    print('绿灯亮了 冲')
    event.set()
    
def car(name):
    print('%s等红灯'%name)
    #等待 等light执行到 set发送信号 就会继续执行
    event.wait()
    print('%s加油门 飙车' %name)
    
#异步操作 进入io就转到下面创建进程
t = Thread(target=light)
t.start()
for i in range(20):
    t = Thread(target=car,args=(i,))
    t.start()

11、进程池和线程池

多进程 多线程
在实际应用中 是不是可以无限制的开进程和线程
肯定 不可以! 会造成内存溢出 受限于硬件水平

我们在开设多进程或线程的时候 还需要考虑硬件的承受范围


降低程序的执行效率 保证计算机硬件的安全

进程池
提前创建好固定个数的进程供程序使用 后续不会再创建

线程池
提前创建好 固定个数的线程提供程序使用 后续不会再创建

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from threading import current_thread
import os
import time

pool = ThreadPoolExecutor(5)  # 固定产生五个线程


def task(n):
    # print(os.getpid())
    print(current_thread().name)
    print(n)
    time.sleep(1)
    return '返回的结果'

# 这边会 被异步回调 传参执行
def func(*args, **kwargs):
    print('func', args, kwargs)
    print(args[0].result())

if __name__ == '__main__':
    for i in range(20):
        #给池子提交任务
        pool.submit(task, 123)
        # 异步回调:异步任务 执行完成后有结果就会自动触发该机制
        # pool.submit(task,123).add_done_callback(func)

12、协程

进程:资源单位

线程:执行单位

协程:单线程下实现并发(效率极高)
在代码层面 欺骗cpu 让cpu觉得我们的代码里面没有io操作
实际上 在io操作被我们自己写的代码监测 一旦有 立刻让代码执行别的
该技术 完全是程序员 自己弄出来的 名字也是程序员 自己起的

核心:自己写代码完全切换+保存状态

import time
from gevent import monkey;
#固定 编写 用于监测 所有io操作(猴子补丁)用来补全一些监测不到的io操作
money。patch)_all()
from gevent import spawn

def func1():
    print('func1 running')
    time.sleep(3)
    pirnt('func1 over')
    
def func2():
    print('func2 running')
    time.sleep(5)
    print('func2 over')
    
if __name__ == '__main__':
    start_time = time.time()
    s1 = spawn(func1)
    s2 = spawn(func2)
    s1.join()
    s2.join()
    print(time.time() - start_time)

12.1、协程实现TCP服务端 并发

import socket
from gevent import monkey;monkey.patch_all()
from gevent import spawn

#循环 收发
def communication(sock):
    while True:
        data = sock.recv(1024)
        print(data.decode('utf'))
        sock.send(data.upper())

def get_server():
    server = socket.socket()
    server.bind(('127.0.0.1',8080))
    server.listen(5)
    while True:
        #等待 客户端访问 网络请求
        sock,addr = server.accept()
        #监测 communication的io操作
        spawn(communication,sock)
#监测 get_server 的io操作 然后io操作
s1 = spawn(get_server)
s1.join()

13、数据存取演变史

文本文件
文件路径不一致
数据格式不一致

软件开发目录规范
规定了数据文件的大致存储位置:db文件
针对 数据格式还是没有完全统一 :比如统一 json 文件但是内部键值 对不同

数据服务
统一 了存取位置 也统一了数据格式(完全统一)

14、数据库软件应用史

单机游戏
不同计算机上 的相同程序 数据无法共享
数据库服务全部再本地完成

网络游戏
不同计算机上的相同程序 数据可以共享
数据库 服务单独再网络架设(远程数据库 服务)

远程数据库服务
数据库集群

  • 数据安全 性问题
  • 服务器 负载问题

让多台服务器 运行相同的数据库服务

15、数据库本质

数据库三字在不同角度下描述的意思不一样

  1. 站在底层原理角度
    数据库指的是专用用于操作数据的进程
    ​ 运行在内存中的代码
  2. 站在现实应用的角度
    数据库指的是拥有操作界面的应用程序
    ​ 用于操作进程的界面

我们不做特殊说明的前提下数据库其实是在指数据库软件
我们也称数据库软件本质是一款cs架构的应用程序
言外之意所有的程序员理论上都可以编写>>>:市面上已经有很多数据库软件

16、数据库分类

16.1、关系型数据库

  1. 数据 的组织 方式有明确的表结构

    id name password

    关系型数据库存取数据的方式可以看成是表格

  2. 表与表之间可以进阿里数据层面的关系
    eg: 用户表 房屋表
    只要获取到用户表的一条数据 就可以获取到与之相关的其他数据

  3. MySQL、PostgreSQL、MariaDB、Oracle、sqlite、db2、sql、server

    1. MySQL: 开源 使用最为广泛 数据库学习必学
    2. PostgreSQL: 开源 支持二次开发
    3. MariaDB: 开锁 与MySQL 是同一个作者 用法也极其相似
    4. Oracle: 收费 安全性极高 主要用于银行及各大重要机关
    5. sqlite: 小型数据库 主要用于本地测试(django框架自带该数据库)

16.2、非关系型数据库

  1. 数据的组织方式没有明确的表结构 是以k:v键值对的形式组织的
    {'name':'jason'}
    {'username':'kevin','pwd':'123'}
  2. 数据之间无法直接建立数据库层面关系
  3. redis、mongoDB、memcache
    1. redis: 目前最火 使用频率最高的缓存型数据库
    2. mongoDB: 稳定型数据库 最像关系型的非关系型 主要用于爬虫、大数据
    3. memcache:已经被redis淘汰

17、MySQL简介

虽然数据库软件很多 但是底层操作几乎一致 学会一个其他都可以快速上手

学了MySQL基本就可以快速上手所有的关系型数据库甚至非关系型数据库

  1. MySQL版本问题

    5.6X: 前几年使用频率最高的版本

    5.7X: 最近尝试迁移的版本(频率+)

    8.0X: 最新版本 功能很强大 但是线上环节几乎不用(本地自己用非常好用)

    虽然版本有区别 但是操作几乎没有区别 主要体现在底层运作

  2. 下载与安装

    1. 访问官网
    2. 点击DOWNLOADS
    3. 点击 GPL
    4. 点击 community server
    5. 点击 archives
    6. 点击 down load
  3. 解压安装

    上述方式下载的压缩包里含有服务端和客户端 支持本地操作

  4. 主要文件介绍

    1. bin文件夹

      mysqld.exe 服务端 mysql.exe客户端

    2. data 文件夹

      存取数据

    3. my-default.ini

      默认配置文件

18、基本使用

先启动服务器
可能会报错;拷贝关键信息去百度
两种报错

查找mysqld文件位置
mysqld
cmd 窗口就是服务端 不要关闭

再次开启新的cmd窗口
mysql
查找回车 会以游客模式进入 功能很少

用户名密码登录
mysql -u 用户名 -p密码
mysql 默认管理员账号 用户名是root 密码是空

退出
exit
quit

18.1、系统服务制作

如何解决每次都需要切换路径查找文件的缺陷
添加环境变量

将mysql服务端制作成系统服务(随着计算机的开启便启动 关闭而结束)

  1. 以管理员身份打开cmd窗口

  2. 执行系统服务命令

    mysqld–install

  3. 启动服务端

    1. 右键直接点击启动

    2. 命令启动

      net start mysql

查看系统服务的命令
servoces.msc

关闭mysql服务器
net stop mysql

移除系统服务
先确保服务已经关闭
执行移除命令
mysqld ==remove

18.2、密码相关操作

18.2.1、修改密码

mysql admin命令

  1. 通用方式:直接在cmd中写命令
    mysqladmin -uroot -p原密码 password 新密码

    第一次修 原密码直接不输

    第二次修改

    mysqladmin -uroot =p123 password 321

  2. 偏门方式(有些版本无法使用):#需要先登录

    set(password=PASSword(新密码)

18.2.2、忘记密码

直接重装\拷贝对应文件
先关闭服务端 然后以不需要校验用户身份的方式启动 再修改 最后再按照正常方式启动

  1. net stop mysql
  2. mysqld --skip-skip-grant-tables
  3. mysql - uroot -p
  4. update mysql.user set password=password(123) where Host='localhost' and User='root'
  5. net stop mysql
  6. net start mysql

19、SQL与NoSQL

数据库的服务端支持各种语言当客户端
以MySQL服务端为例
MySQL客户端 python代码编写的客户端 java 代码编写的客户端
为了能够兼容 所有类型的客户端 有两种策略

  1. 服务端兼容
    不合理 消耗数据库服务端资源
  2. 指定统一标准
    SQL语句、NoSQL语句

SQL与NoSQL
SQL 语句的意思是操作关系型数据库的语法
NoSQL语句的意思操作非关系型数据库的语法
SQL有时候也用来表示关系型数据库、NoSQL也用来表示非关系型数据库

20、数据库重要概念

下述概念 缺乏仅仅为了更快的理解 缺乏严谨性

库 文件夹

表 文件夹里面的文件

记录 文件里一行行的数据

show databases; 查看所有数据库
show tables; 查看所有的表
select * from mysql.user; 查看user表里面所有的记录

SQL语句结束是英文分号 ;

取消SQL 语句的执行 \C

21、基本SQL语句

21.1、针对库的基本SQL语句

create database 库名; #数据库

show databases; #查看 所有库
show create database 库名; #查看指定库信息

alter database jp01 charset = 'gbk' #改库下的编码

drop database 库名;#删除指定库

21.2、针对表的基本SQL语句

查看当前所在的库名

select database(); #如果 没有切换在任何库下 那么默认是NULL
use 库名; #进入到某库下

create table 表名(字段名 字段类型,字段名 字段类型);

show tables; 3查看所有表

show create table 表名 ; #查看指定表信息
describe 表名; #简写 desc 表名;

alter table 旧表名;改表名

drop table 表名;

21.3、针对记录的基本SQL语句

既然想操作记录 那么肯定先有库和表

insert into 表名 values(数据,数据);

insert into 表名 values(数据,数据),(数据,数据),(数据,数据)

select * from 表名; # * 表示查看所有字段

select 字段1, 字段2 from 表名; #查看表中数据
#如果 表中字段 出现错误 可以结尾写\G

update 表名 set 字段=新数据 where 筛选 条件;

delete from 表名 #删除 表中 所有数据

delete from 表名 where 筛选条件; 按照筛选条件删除数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值