python九周周末总结
UDP协议
udp协议的交互模式服务端不需要考虑客户端是否退出,你发多少那么他就会按照你发的东西直接去传输给客户端不存在黏包现象
服务端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
while True:
msg,address = server.recvfrom(1024)
print('msg>>>:%s'% msg.decode('utf-8'))
print(f'address>>>:{address}')
res = input('请输入您需要输入的内容')
server.sendto(res.encode('utf-8'),address)
客户端:
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server_address = ('127.0.0.1',8080)
while True:
res = input('请输入您需要输入的内容')
client.sendto(res.encode('utf-8'),server_address)
msg,address = client.recvfrom(1024)
print('msg>>>:%s'%msg.decode('utf-8'))
print(f'address>>>:{address}')
计算机三大核心硬件
五大核心硬件
计算器,运算器,存储器,输入设备,输出设备
三大核心硬件
cpu,内存,外存(硬盘)
操作系统发展史
穿孔卡带:cup利用率极低
练级批处理系统:稍微提升cpu利用率但是还是很低
脱机批处理系统:又提升了一些利用率,是现代计算的雏形
多道技术
io模式:其实就是进程进入输入,输出,程序睡眠,读取文件和保存文件的过程就是进入了io模式
单道技术:当A程序在执行的时候遇到io状态就会停下来等待,直到执行完程序才会继续往下走,执行程序B这种情况叫做单道技术
多道技术:当A程序进入io状态程序会自动跳向程序B开始执行程序B的内容,这种情况叫做多道技术
进程理论
什么是进程:
进程:其实就是我们的代码在被运行,这个代码就被叫做进程态
程序:当我们代码就是一堆数据并没有被运行的情况那么我们就可以叫他是一个程序或者是死代码
进程的调度
先来先去算法:其实就是我这个进程先开始运行那么就全力运行它直到程序结束开始运行下一个,这种的运行对短运行时间的程序不太友好
短作业有限算法:就是运行速度快的程序优先运行,慢的延后,这种运行对那种运行时间长的程序非常不友好
时间片轮转法和多级反馈队列:将时间平均分配给所有的程序,然后同时运行,如果一段时间这个程序没有被运行完那么就会给她更多的时间片,但是时间片越多那么这个程序的优先级则越低。
进程的并行与并发
并行:并行其实就是多个cpu同时运行多个程序那么我们就叫这种情况为并行
并发:并发其实就是多个进程运行起来看起来像是同时执行的情况我们叫做并发,并行有时候我们也可以叫做并发
进程的三状态
就绪态:当我们进程只要开始执行那么他就绝对会先进入就绪态
阻塞态:当我们的程序遇到io操作的时候那么就会进入阻塞态,当阻塞态完成io那么就会重新进入就绪态
运行态:就是完完整整的运行完这个程序那么就会叫做运行态
同步和异步
同步:其实就是程序进行运行的时候进入io状态cpu就会停下等待直到程序结束才会进入下一个进程那么这种情况我们就叫做同步
异步:当我们的程序进入io的话那么我们的cpu就会直接进入其他的程序先运行其他的程序做到不停的情况那么我们就可以称他为异步操作
阻塞与非阻塞
阻塞态:其实就是程序进入io状态,那么我们就叫它为阻塞
非阻塞:程序没有进入io的状态那么我们就叫他为非阻塞
同步异步与阻塞非阻塞
同步阻塞:最慢的运行一旦遇到io就会停下等待
同步非阻塞:不会进入io状态因为没有
异步阻塞;遇到阻塞就会跳到别的地方执行
异步非阻塞:执行最快
创建进程的多种方式
其实就是调用模块利用函数创建多进程
from multiprocessing import Process
import time
def task(name):
print(f'子进程{name}正在运行')
time.sleep(3)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p = Process(target=task, args=('joseph',)) # 创建一个进程对象
p.start() # 开始子进程执行
print('主进程执行')
调用模块利用类的方式执行多进程
from multiprocessing import Process
import time
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('joseph')
obj.start()
print('正在执行主进程')
TCP开发
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p1.start() # 开始执行子进程
p1.join() # 主进程等待子进程结束后再运行
print('主进程') # 最后执行
join方法
其实就是让我们的主进程在子进程结束后然后再继续执行的方法
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p2 = Process(target=task, args=('alice', 2))
p3 = Process(target=task, args=('trump', 5))
start_time = time.time()
p1.start() # 开始执行子进程
p1.join() # 主进程等待子进程结束后再运行
p2.start()
p2.join()
p3.start()
p3.join()
end_time = time.time() - start_time
print(end_time)
print('主进程')
# 如果等待它一次执行那么执行时间就会很长,8.649637937545776
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p2 = Process(target=task, args=('alice', 2))
p3 = Process(target=task, args=('trump', 5))
start_time = time.time()
p1.start() # 开始执行子进程
p2.start()
p3.start()
p1.join() # 主进程等待子进程结束后再运行
p2.join()
p3.join()
end_time = time.time() - start_time
print(end_time)
print('主进程') # 只要调换下位置让他们先开始执行那么结果就是同时运行进入io态,结束
进程数据之间的关系
各进程之间要是想要数据交互那么可能就需要通道进行传输也叫队列
from multiprocessing import Process
count = 999
def task():
global count
count = 666
print('子进程打印的money', count) # 666
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print('主进程', count) # 999
print(count) # 999
生产者和消费者模型
其实就是生产者只和缓冲区进行交互,而消费者也只和缓冲区进行交互,有缓冲区来协调两者的平衡关系不能两者直接进行交互,然后要是内部东西没有了那么就需要生产者进行补充吗,然后消费者才能购买
进程的相关方法
from mlutprocessing import Queue
q = Queue (3) # 这个数字是路i当以的我们可以设置一共可以产生多少个队列的阀值
q.put() # 向队列中增加值
p.pull() # 查看队列是否已经存满
q.get() # 从队列中进行取值
q.empty() # 查看队列是否已经被取空
q.get_nowait() # 取值 如果没有可以取的值那么就会直接报错
p.terminate() # 销毁该进程
p.is_alive() # 查看该进程是否还存活
current_process().pid # 查看进程号
os.getpid # 查看进程号
os.getppid # 查看父进程号
IPC机制
子进程和父进程进行数据交互
from multiprocessing import Queue, Process
def procedure(q):
q.put('子进程procedure往列队中添加了数据')
def consumer(q):
print('子进程consumer往列队中添加了数据', q.get())
if __name__ == '__main__':
q = Queue()
# q.put('主进程向对列中添加了新的数据')
p1 = Process(target=procedure, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start() # 子进程consumer往列队中添加了数据
# 子进程procedure往列队中添加了数据主进程执行
p1.join()
p2.start()
p2.join()
print('主进程执行')
守护进程
其实就是我们可以定义这个进程守护另一个进程只要被守护进程结束那么该进程就会直接结束
from multiprocessing import Process
import time
def task(name):
print(f'子进程{name}正在运行')
time.sleep(3)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p = Process(target=task, args=('joseph',)) # 创建一个进程对象
p.daemon = True # 将子进程设置成父进程的守护进程,只要父进程一结束那么就立即结束
p.start() # 开始子进程执行
# p.join()
print('主进程执行')
僵尸进程和孤儿进程
僵尸进程其实就是我们的子进程结束没有返回值或者返回了但是父进程没有接收到然后导致父进程无法正常关闭那么就会产生一个僵尸进程,僵尸进程危害电脑的运行所有要尽量避免有僵尸进程
孤儿进程:其实就是父进程意外暴毙,没有父进程接收返回值那么这个进程就会变成一个孤儿进程,但是我们有一个进程福利院来接收这样的孤儿进程叫做init
互斥锁
互斥锁其实就是将并发变成串行的一种锁,使进程数据不会错乱
from multiprocessing import Process,Lock
import time
import json
import random
def search(name):
with open(r'data.json','r',encoding='utf-8')as f:
data = json.load(f)
print('%s正在查票,当前余票为:%s'% (name,data.get('ticket_num')))
def buy(name):
with open(r'data.json','r',encoding='utf-8')as f:
data = json.load(f)
time.sleep(random.randint(1,5))
if data.get('ticket_num') > 0:
data['ticket_num'] -= 1
with open(r'data.json','w',encoding='utf-8')as f:
json.dump(data,f)
print('%s成功购买前往理想乡的车票'% name)
else:
print('%s很遗憾买不到票,今晚都睡不着了'% name)
def run(name,mutex):
search(name)
mutex.acquire() # 枪锁
buy(name)
mutex.release() # 施放锁
if __name__ == '__main__':
mutex = Lock()
l1 = ['joseph','Alice','Trump','Jason']
for i in l1:
p = Process(target=run,args=('用户名%s'% i,mutex))
p.start()
线程理论
进程:进程是资源单位,负责在内部拿去相应的所有资料就像是一个工厂
线程:就相当于车间中的流水线,只需要拿取自己的数据即可然后就可以运行
进程下至少拥有一条线程,如果没有那么他就没有存在的必要
创建线程的两种方式
还是和创建进程以一样一种是以函数来创建而另一种则是类的方法
方式一:
from threading import Thread
import time
def task(name):
print(f'{name}正在执行')
time.sleep(3)
print(f'{name}执行结束')
t = Thread(target=task,args=('joseph',))
t.start() # 两个都可以执行,但是最好写上下方的启动代码,以增加兼容性和规范性
print('主线程')
if __name__ == '__main__':
t = Thread(target=task, args=('joseph',))
t.start()
print('主线程')
"""
开设线程不需要完整的拷贝代码,所以无论什么系统都不会出现反复草早的情况,也不需要像启动进程时一样使用启动脚本,但是为了兼容性和规范性我们最好也写上启动脚本
"""
方式二:
from threading import Thread
import time
class MyThred(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 = MyThred('jsoeph')
obj.start()
print('主线程')
线程join方法
和进程一样就是当使用join的子进程结束后那么父进程才会继续运行
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=('joseph',))
t.start()
t.join()
print('主线程')
同一个进程下线程的数据共享
在进程中我们的多进程之间并不能直接数据交互必须要有通道和队列才可以进行数据交互,然而在进程与进程之间就可以做到数据自由交互,子进程和父进程之间可以进程数据交互
from threading import Thread
count = 999
def func():
global count
count = 666
t = Thread(target=func)
t.start()
t.join()
print(count) # 666
线程对象相关方法
1.进程号
在同一个进程下的多个线程都拥有同一个进程的进程号
2.线程名
from threading import Thread,current_thread
from threading import Thread
count = 999
def func():
global count
count = 666
print(current_thread().name) # Thread-1
t = Thread(target=func)
t.start()
t.join()
print(current_thread().name) # MainThread
print(count) # 666
3.进程下的线程数
active_count()
守护线程
守护线程其实就是和守护进程一样都是,都是被守护线程一旦结束那么守护他的线程就会跟着直接结束
from threading import Thread
import time
def task():
print('子进程运行task函数')
time.sleep(3)
print('子进程运行task函数结束')
t = Thread(target=task)
t.daemon = True
t.start()
print('主进程')
GIL全局解释器锁
本质上也是一种互斥锁,但是是一款在Cpython中自带的一种全局解释器锁,在全局解释器锁的情况下将并发变成串行依次运行使数据不会被垃圾回收机制所回收掉
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.)
验证GIL存在
from threading import Thread
count = 100
def task():
global count
count -= 1
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 0
GIL特点
在数据中存在io的情况下那么就会变成并发状态那么我们的GIL就不能触发,所以就会导致数据错乱的风险那么这种时候就需要我们自己去给她加锁
from threading import Thread
import time
count = 100
def task():
global count
num = count
time.sleep(0.1)
count = num - 1
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 99
"""
自己给自己加锁来完成统计
"""
from threading import Thread,Lock
import time
count = 100
mutex = Lock()
def task():
mutex.acquire()
global count
num = count
time.sleep(0.1)
count = num - 1
mutex.release()
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 0
验证多线程的作用
-
多种验证方法
- 单cpu
- io密集型操作
- 计算密集型操作
- 多cpu
- io密集型操作
- 计算密集型操作
- 单cpu
-
单CPU操作
1.io密集型的多进程 需要在内存中多次申请额外的内存空间,需要消耗更多的时间和资源 2.io密集型的多线程 只需要在进程中申请自己所需要的代码即可,只需要通过多道的技术那么就可以实现多线程操作,消耗的资源和时间较少 3.计算密集型的多进程 同样需要在内存中申请额外的内存空间,然后消耗更多的时间和资源(总计算耗时和申请内存空间的时间,拷贝代码的时间再加上各个进程之间切换的时间) 4.计算密集型的多线程 只需要在进程中申请自己所需要的代码即可,并且通过多道技术直接执行(总计算消耗的时间和切换到各线程的时间) 5.总结 所以说在单cup中python的多线程还是非常有用的,即节省内存空间又速度较快
-
多CPU操作
1.io密集型的多进程
总耗时(单个进程的耗时+IO操作的耗时+申请内存空间的耗时+拷贝代码的耗时)
2.io密集型的多线程
总耗时(单个线程的耗时+IO操作的耗时)
3.计算密集型的多进程
总耗时(单个进程的耗时)
4.计算密集型的多线程
总耗时(多个进程的耗时总和,但是由于内部有优化代码,所以实际上没有那么长的时间进行计算)
5.总结
在多CUP进行密集型计算时由于多进程可以有多个核进行计算所以计算时间会非常短所以在多CPU多计算模型的情况下多进程占据主要又是,也可以称之为完胜,而多线程因为没有办法享用多cpu的好处所以只能一个CPU慢慢计算。
- 多CPU代码展示
1.小知识使用代码查看自己电脑是几核处理
import os
print(os.cpu_count()) # 12
2.展示多计算状态的运行
from threading import Thread
from multiprocessing import Process
import os
import time
def work():
res = 1
for i in range(1,100000):
res *= i
if __name__ == '__main__':
start_time = time.time()
p_list = []
for i in range(12):
p = Process(target=work)
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('总耗时:%s'%(time.time() - start_time)) # 总耗时:5.136746883392334
if __name__ == '__main__':
start_time = time.time()
t_list = []
for i in range(12):
t = Thread(target=work)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print('总耗时:%s' % (time.time() - start_time)) # 总耗时:27.33429765701294
死锁现象
其实就是在线程中,两个并发的线程都拿到了对方需要拿的锁那么就会形成死锁状态
from threading import Thread,Lock
import time
mutexA = Lock()
mutexB = Lock()
class MyThread(Thread):
def run(self):
self.func1()
self.func2()
def func1(self):
mutexA.acquire()
print(f'子进程{self.name}获取A锁')
time.sleep(3)
mutexB.acquire()
print(f'子进程{self.name}获取B锁')
mutexB.release()
print(f'子进程{self.name}获取B锁')
mutexA.release()
print(f'子进程{self.name}获取A锁')
def func2(self):
mutexB.acquire()
print(f'子进程{self.name}获取B锁')
time.sleep(3)
mutexA.acquire()
print(f'子进程{self.name}获取A锁')
mutexA.release()
print(f'子进程{self.name}获取A锁')
mutexB.release()
print(f'子进程{self.name}获取B锁')
for i in range(10):
t = Thread()
t.start()
信号量
信号量其实就是我们可以限定可以产生多少把锁
from threading import Thread,Semaphore
import time
import random
SP = Semaphore(3) # 设置信号量为3也就是三把锁
class MyThread(Thread):
def run(self):
SP.acquire()
print(self.name)
time.sleep(random.randint(1,3))
SP.release()
for i in range(20):
t = MyThread()
t.start()
event事件
event就像是等红绿灯只有在被等待程序执行到的时候那么等待程序才会执行
from threading import Thread,Event
import time
import random
event = Event()
def light():
print('比赛准备开始,本场次有黑哨请所有人启动赛车听到自己的指令出发')
time.sleep(random.randint(1,5))
print('预备,鸣发动机,let GO!GO!GO!')
event.set() # 发送指令
def car(name):
print(f'{name}正在启动赛车')
event.wait() # 等待指令
print(f'{name}发动机轰鸣后出发了')
t = Thread(target=light)
t.start()
l1 = ['Joseph','Alice','Trump','kdi','jason']
for i in l1:
t = Thread(target=car,args=(f'选手{i}',))
t.start()
进程池与线程池
在我们呢的进程和线程中既然我们做服务的时候可以产生很多的进程和线程同时运行也就是并发的结果,但是由于我们的硬件跟不上我们创建的应用过程所以受到硬件水平的限制我们必须要设置一共可以产生多少个进程和线程来限制产生
进程池与线程池操作
"""
进程池和线程池本质上就是帮它定了一个阀值,让他只能在这个阀值内运行多了那么对不起,你等着吧
"""
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread
import os
import time
pool1 = ProcessPoolExecutor(3)
pool2 = ThreadPoolExecutor(3)
def task(n):
print(current_thread().name)
print(os.getpid())
print(os.getppid())
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(5):
res = pool1.submit(task,123)
print(res.result())
pool1.submit(task,123).add_done_callback(func)
if __name__ == '__main__':
for i in range(5):
res = pool2.submit(task,123)
print(res.result())
pool2.submit(task,123).add_done_callback(func)
pool2.submit(task,123).add_done_callback(func)
协程简介
进程:资源单位
线程:执行单位
协程:单个线程的并发
携程:一款旅行软件,住酒店看携程
协程在单线程下帮助我们的代码实现并发,帮我们在到io状态的时候立即捕获然后让cpu去执行别的欺骗cpu一直跑
from gevent import monkey;monkey.patch_all() # 就是这样写的,我也不知道为什么(猴子补丁)
from gevent import spawn
import time
def func1():
print('func1 正在执行')
time.sleep(3)
print('func1 执行完毕')
def func2():
print('func2 正在执行')
time.sleep(6)
print('func2 执行完毕')
if __name__ == '__main__':
start_time = time.time()
# func1()
# func2() # 9.022636413574219
s1 = spawn(func1) # 一旦遇到io操作那么就立即跳到别的地方执行,如果都在io那么久反复横跳
s2 = spawn(func2) # # 6.01244044303894
s1.join()
s2.join()
print(time.time() - start_time)
协程的实际作用
1.服务端
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-8'))
sock.send(data.upper())
def get_server():
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
sock,address = server.accept()
spawn(communication,sock)
s1 = spawn(get_server)
s1.join()
2.客户端
import socket
from threading import Thread,current_thread
def get_client():
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
client.send(f'good night {current_thread().name}'.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
for i in range(20):
t = Thread(target=get_client)
t.start()
数据存取史
- 起源······文本文件
- 在最开始使用计算机都没有相应的规范我们的数据一般都是自己起一个名字然后就根据这个路径存储数据并且存储数据的格式也都五花八门就产生了很多奇奇怪怪的方式
- 文件路径C:xxx.txt,D:xxx.txt, E:xxx.txt, F:xxx.txt等
- 数据存储格式:joseph|321, Alice¥520等
- 发展······软件开发目录规范
- 我们渐渐的创造出一些默认的软件开发目录规范,让存储数据不再变得那么难以查找,并且一看某些文件夹就知道内部文件大概是什么,但是针对数据的存储格式还是没有完全统一
- 规定了文件存储大概位置:db文件夹内
- 数据存储格式:json格式和picket格式等存储格式还是繁多
- 现阶段·····数据库服务
- 针对上方的情况我们也搞出了解决方法既然大家存储格式都不太一样那么我就发明一种足够吸引你使用的存储格式和地方,然后大家就一起使用统一的存储格式那么就方便互相之间的交互
- 统一了存取位置和数据与格式
数据库软件应用史
- 单机模式
- 在不同计算机上的相同程序,数据无法共享因为数据库的存储服务全是在本机上完成也就是本地存储,无法分享,满足个人需求
- 联机交互模式
- 不同计算机上的相同程序,数据可以共享,数据库并不存储在本地而是存储在网络架构上方的远程数据库上,我们只需要联网就可以去那个地方拿取到我们自己的数据
- 远程数据库
- 数据库服务是构建一个数据库集群,但是为了我们的数据的安全性和服务器的负载效率我们一般让数据存储分备份存储在不同地方以防出现数据丢失或者物理丢失的情况,所以就有了一句话,贵州山脉服务器集群,水冷设备降温除虫。远离病虫害。(自己瞎编的)
数据库的本质
- 数据库的表达角度
- 站在底层原理的角度来说数据库是指专用于操作数据的进程,就是指运行在内存中的代码
- 而站在显示应用的角度来说,数据库其实本质上就是一种拥有操作界面的应用程序
- 数据库的本质
- 其实数据库本质上来说就是一款应用程序,理论上我们是个程序员都可以自己编写数据库应用程序,他其实也是一款CS架构的应用程序。
数据库的分类
-
关系型数据库
- 数据的组织方式有明确的表结构,甚至我们可以将他直接看成是存储在表格中
id name password 1 joseph 123 2 jason 520 - 表与表之间可以建立数据库层面的关系,只需要获取到用户表中的一条数据那么我们就可以获取到与之相关的其他表的数据
SQL 形态 介绍 MySQL 开源 使用最为广泛,数据库学习必学,现在安全程度也变得越来越高 PsotgreSQL 开源 支持二次开发 MariaDB 开源 与MySQL是同一个作者,用法也极其相似,名称是以自己女儿名字命名 Oracle 收费 安全性极高,各大银行和重要机关使用 sqlite 小型数据库 主要是用于本地测试在django中自带的一个数据库 db2 开源 转为中型和大型商业机构设计开发 sql server 开源 使用集成的商业智能(BI)工具提供了企业级的数据管理 -
非关系型数据库
-
数据结构没有明确的表的形式去表述,一般是以字典的K:V键值对的形式去组织存储
{'name':'jsoeph'}{'username':'Alice','password':'520'}
-
数据之间无法直接建立数据库层面的关系
SQL 形态 介绍 redis 目前来说最火的非关系数据库 使用频率最好的缓存型数据库 mongoDB 稳定型数据库 最像是关系型数据库的非关系数据库,有Java那味了 memcache GG GG -
MySQL简介
- 前言
- 虽然说数据库类型也是繁多复杂的但是就底层操作来收几乎都差不多,只要学会一个的话那么学别的就会特别快,MySQl一般来说都是第一个学习使用的数据库
- 版本
- 5.6.x 前几年使用频率最高的版本
- 5.7.x 最近几年在迁移的版本使用频率正在逐步上升
- 8.0.x 最新版本,功能非常强大,但是线上环境也就是公司中一般不会去使用这个版本,因为公司宁可使用十多年前的版本也要追求稳定性,否则一旦出事很难收拾,我们自己在个人使用的时候开源尝试使用8.0.x
- 版本之间虽然有所不同但是操作上基本没有什么改变
- 下载及其安装详情
- 访问官网 https://www.mysql.com/
- 点击DOWNLOADS https://www.mysql.com/downloads/
- 在下方点击GPL MySQL Community (GPL) Downloads »
- 点击community server https://dev.mysql.com/downloads/mysql/
- 点击archives https://downloads.mysql.com/archives/community/
- 点击download 一般选择64位的即可
- 安装使用管理员安装和登录并且设置自己的密码即可
- 重要文件介绍
- bin文件夹
- mysqld.exe 服务端
- mysql.exe 客户端
- data文件夹
- 存储数据
- my-default.ini
- 默认的配置文件
- bin文件夹
MySQL基本使用
- 先启动服务器
- 可能会有两种报错:寻找关键信息到浏览器寻找解决方式,一般为缺失文件,下个补丁应该就可以了
- 查找MySQL文件位置
- 打开一个cmd窗口输入 cd+文件路径 进入登录然后保持这个状态不动充当服务端即可
- 再次打开新的cmd窗口
- 进入MySQL直接回车就可以进入阉割的游客模式,但是功能很少
- 用户登录
- 输入mysql -u用户名 -p密码 ;就可以登录了
- 一般第一次的话直接输默认的账号密码即可 mysql -uroot 空密码即可登录
- 退出
- quit 退出
- exit 退出
系统服务制作
- 添加环境变量
- 找到我们系统的环境变量然后点击path将我们的mysql的bin文件夹的绝对路径添加进去即可
- 讲MySQL服务端设置成自动启动
- 以管理员身份进入cmd窗口,执行mysqld --install命令
- 然后有两种方式一种是使用系统服务命令 services.msc 调出系统设置找到MySQL然后启动
- 另一种方法是使用命令的方式 net start mysql
- 关闭服务器和移除系统服务
- 关闭服务器 net stop mysql
- 先确保服务已经关闭然后执行移除命令 mysqld --remove
密码相关操作
-
修改密码
mysqladmin命令 通用命令: mysqladmin -u用户名 -p原密码 password 新密码 第一次修改 mysqladmin -uroot -p(这里为空就好因为默认密码为空,如果安装时你已经设置密码那么直接输你密码即可) password xxx 低版本修改简便方式: # 但是需要先登录 set password=PASSWORD(新密码)即可
-
忘记密码
-
把系统内存储你密码的那三个文件删除然后让你朋友将他的三个文件发你粘贴到那三个文件的地址上你用他的账号密码登录,然后你再更改
-
先关闭服务器,然后就不需要校验用户身份及逆行启动,再去修改安装正常方式启动
1.net stop mysql 2.mysqld --skip-grant-tabes 3.mysql -uroot -p 4.update mysql.user set password=password(xxx) where HOST='localhost' and User='root' 5.net stop mysql 6.net start mysql
-
SQL和NOSQL
- 兼容性
- 由于数据库是为了支持各种语言充当客户端,但是各种语言的区别有很大为了解决这个问题我们就像如何做到让所有的语言都可以使用我们的数据库那么就出现了两种方式
- 一种是服务端也就是数据库进行兼容所有语言,但是那样就会使服务端变得臃肿所以我们就应该使用另一种方式
- 自己制定一套标准所有的都遵循我的标准来执行那么就可以做到我的服务器又好用,还快,但是就是需要学一下我的简单语句就可以使用SQL语句和NoSQL语句两种
- 由于数据库是为了支持各种语言充当客户端,但是各种语言的区别有很大为了解决这个问题我们就像如何做到让所有的语言都可以使用我们的数据库那么就出现了两种方式
- 语法区别
- SQL语句的意思就是操作关系型数据库的语法
- NoSQL则是操作非关系型数据库
- 所以有时候SQL也被指为关系型数据库而NoSQL则指为非关系型数据库
数据库重要概念
数据库 | 操作 | 作用 | 帮助理解 |
---|---|---|---|
库 | show databases; | 查看所有的数据库 | 文件夹 |
表 | show tables; | 查看所有的表 | 文件夹中的文件 |
记录 | select * from mysql.user; | 查看user表中的所有记录 | 文件中的数据 |
数据库补充知识
符号 | 作用 |
---|---|
;(分号) | SQL语句中的结束符 |
\c | 取消SQL语句执行 |
针对数据区基本SQL语句
操作 | 代码 | 作用 |
---|---|---|
增 | create database 库名; | 增加一个新的库 |
查 | show databases; |show create database 库名; | 查询这个库下的数据 |
该 | alter database 库名 charset='gbk'; | 更改这个库下的数据 |
删 | drop database 库名; | 删除这个库 |
查看所在库名 | select database(库名); use 库名; | 如果没有的话默认为NULL |
针对表的基本SQL语句
操作 | 代码 | 作用 |
---|---|---|
增 | create table 表名(字段名 字段类型) | 增加表内数据 |
查 | show tables;|show create table 表名; |descrlbe 表名;|desc 表名; | 查看表内的内容 |
改 | alter table 旧表名 rename 新表名; | 改表名 |
删 | drop table 表名; | 删除表 |
针对记录的基本SQL语句
操作 | 代码 | 作用 |
---|---|---|
增 | insert into 表名 values(数据,数据); |insert into 表名 values(数据,数据); | 增加表内的数据 |
查 | select * from 表名; |select 字段1,字段2 from 表名; | 查看表内的所有字段 |
改 | updata 表名 set 字段名=新数据 where 筛选条件; | 修改表内的数据 |
删 | defete from 表名;|defete from 表名 where 筛选条件; | 删除表中所有数据和按条件删除数据 |