zoukankan      html  css  js  c++  java
  • 数据库

    * 多表查询 * 索引 * python 操作数据库 * mysql主从复制 * 总结

    概念

    数据 data
    数据库 database
    数据库管理系统 DBMS
    数据库管理员 DBA

    数据库的分类

    关系型: mysqloracle sqlite sql server 适合我们在存取数据的时候 字段不确定的情况下
    非关系型: redismongdb 我们总是用一个固定的字段来获取某些信息 并且对数据的存取速度要求都非常高

    区别

    1)mysql :关系型数据库,用于持久化的存储数据到硬盘,功能强大,但读取速度较慢

    2)redis :非关系型数据库,也是缓存数据库,用于存储使用 较为频繁的数据 到缓存中,读取速度快 ,持久化是使用AOF和rdb方式,支持事务,存储小量的数据

    3)mongodb: 不支持事务,支持查询的语言比较多(json,xml,bson),适合大数据量的存储

    应用场景

    redis:数据量较小的更性能操作和运算上
    MongoDB:主要解决海量数据的访问效率问题

    redis 和memcache的区别

    1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例                    如图片、视频等等。 
    2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。 
    3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘 
    4、过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10 
    5、分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从 
    6、存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化) 
    7、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复 
    8、Redis支持数据的备份,即master-slave模式的数据备份。
    

    总结
    有持久化需求或者对数据结构和处理有高级要求的应用,选择redis,其他简单的key/value存储,选择memcache。

    mysql客户端的启动:
    1. 在cmd里执行

      mysql -uroot -p
      Enter password:
      root默认的用户 权限相对大

    2. 在mysql的客户端执行

      mysql> exit # 退出客户端

    3. 在cmd中执行的 服务端的启停:

      net start mysql
      net stop mysql

    mysql 导入 导出

    导出(备份)所有

    语法:mysqldump -u root -p  库名 > 路劲/新名字 (注:路经后边不能有中文)
    mysqldump -u root -p --all-databases > /tmp/db.dump
    

    导出db1、db2两个数据库的所有数据

    mysqldump -uroot -proot --databases db1 db2 >/tmp/user.sql
    mysqldump -uroot -p -B db1 db2 >/tmp/user.sql
    

    导入

    Mysql -uroot -p < /opt/all db.sql
    mysql>source /data/all.sql;
    

    其实导出的是库里面的表,要想导入,先建一个database库,进入库里边后再source.


    存储引擎

    1. Innodb:默认使用mysql5.6

    特点: 支持事务行级锁外键

    事务: 事务由单独单元的一个或者多个sql语句组成,在这个单元中,每个mysql语句时相互依赖的。而整个单独单元作为一个不可分割的整体,
    n句sql是一个完整的事件,这n句sql要么一起成功,要么一起失败(转账)
    事务的四个特性:
    原子性(Atomicity):所有操作要么全部成功,要么全部失败回滚
    一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态
    隔离性(Isolation):一个事务的执行不能让其它事务干扰
    持久性(Durability):事务一旦结束,数据就持久到数据库

    行级锁: 优点: 能够支持更多的修改数据的并发操作; 缺: 修改的行数太多,效率会受影响

    表级锁:
         缺点: 不支持并发的修改同一张表中的数据;
         优:不需要加很多锁,,效率高

    外键: 在本表中有一个字段 关联 外表中的另一个字段

    为什么要用innodb做存储引擎?
    因为他是mysql5.6 以上默认使用的,考虑到程序今后的扩展,我要用支持事务的inndb,并且并发的删除和修改的效率比其他引擎高一些

    1. myisam: 默认使用mysql5.5
      特点:表级锁

    3)memory: 缓存的存储方式 内存
    特点:读取快,不能完成数据的持久化存储,断电数据就会消失

    4)blackhole :黑洞
    特点: 集群(多台mysql服务,提供高可用的时候涉及到的一种存储引擎) 多级主从复制中的一台机器上的数据库常用的存储引擎

    创建表

    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    );
    

    例:

    mysql> create table staff_info (id int,name char(10),age int(3),sex enum('male', 'female'), phone char(11),job char(12));
    
    2) 查看表结构
    desc (describe) 表名;   查看表的基础信息
    show create table 表名 G;  查看表的详细信息(编码 和 存储引擎)
    
    3)修改表结构

    基础数据类型

    1) 数值类型
    Int 整型的长度约束,实际没效果
    Float 小数: float(n,m) 这个数据总长度n,小数点后为m 如:(126,45)

    2) 日期时间类型
    now()

    datetime : 允许为空,没有默认值,能够表示的时间范围大
    timestamp :不允许为空,默认值是当前时间,能够表示的时间范围小,超出范围表示为 0000-00-00 00:00:00
    如果同一个表中有两个该字段,只有第一个字段会被表示为默认当前时间

    3) 字符串格式
    char: 定长,存储相对浪费空间,存取速度快,不管你存储什么样的数据,他都会帮你把数据的空格在显示的时候去掉
    varchar: 变长,相对节省空间,存取效率相对慢
    检验:

    concat(ch,'+')字符串格式
    

    4) ENUM和SET类型
    enum 枚举 单选+不能选不在枚举范围里的
    set 集合 多选+去重+不能选不在集合里的

    create table t9 (name char(20),gender enum('female','male'))
    # 多选框--程序中 勾选
    create table t10 (name char(20),hobby set('抽烟','喝酒','烫头','翻车'))
    
    5) 表的约束

    (1)Not null 非空
    unique 唯一:不能重复输入非空的内容,但可以输入多个null

    (2) primary key 主键:非空+唯一 一张表只能有一个主键,其他的还是维持原来的约束

    6) 外键

    外键(foreign key)所关联的外表中的那个字段必须是唯一的,建议关联外表的主键
    创建外键

    create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id)             references departments(dep_id));
    

    增加外键

    语法:alter table 表名 add constraint FK_ID foreign key(你的外键字段名) REFERENCES 外表表名(对应的表的主键字段名);  //FK_ID是外键的名称
    alter table book add constraint fk_id foreign key(press_id) references press(id);
    

    删除外键

    语法: ALTER TABLE 表名 DROP FOREIGN KEY 外键字段名;
    
    7) 设置自增字段
    unique auto_increment  至少是唯一的才可以
    default 关键字   # 设置一个默认值
    

    例 删除某个字段

    方式一:删除class里某一个字段

    create table class (id int,class_name char(12)); 
    alter table class modify id int unique;  关联外键,字段至少唯一
    create table stu (id int,stu_name char(20),class_id int,foreign key (class_id) 
    references class(id));
    

    先删除stu里所关联class的id的字段
    delete from class where id =1;
    才能删class里对应的字段:
    delete from class id=1;

    方式二:删除外键所关联的多个字段(直接删除)
    加上on update cascade on delete cascade(连级删除或更新)

    create table class (id int  primary key,class_name char(12)); 
    

    关联外键,字段至少唯一

    create table stu (id int  primary key,stu_name char(20),class_id int,foreign key (class_id)   references class(id) on update cascade  on delete  cascade);
    

    数据的增删改查

    1)增加数据

    insert into 表名 value (1,'alex',83,'不详');  一次插入一条数据
    insert into 表名 values (1,'alex',83,'不详'),(2,'wusir',74,'male'); 支持一次写入多条数据
    insert into 表名 (name,age,sex) values ('alex',83,'不详');
    

    2) 修改数据

    update 表名 set 字段名=值 where 条件
    update 表名 set(修改成啥) 字段名1=值1,字段名2=值2 where 条件(在那一行)
    

    3) 删除数据

    delete from 表 where 条件;
    delete from 表;  清空表
    auto_increment 自增字段 至少是(int unique)
    

    4)单表查询 select

    select * from 表名; * 表示所有的内容
    select 字段1,字段2 from 表;  表示查指定的列的内容
    select distinct 字段名 from 表; distinct关键字表示去重
    在select字段可以使用四则(加减乘除)运算
    select 字段*12 from 表
    select 字段 as 新字段名 from 表   给字段重命名
    

    两个格式化函数

    concat()  concat_ws()
    concat('自己想拼的内容',字段,'你想拼的内容');
    Select concat('姓名:',emp_name,'年薪:',salary) AS annual_salary from employee;
    concat_ws(':',字段1,字段2)
    

    Case语句

    SELECT
       (
           CASE
           WHEN emp_name = 'jingliyang' THEN
               emp_name
           WHEN emp_name = 'alex' THEN
               CONCAT(emp_name,'_BIGSB')
           ELSE
               concat(emp_name, 'SB')
           END
       ) as new_name
     FROM
        employee;
    

    where条件
    对表当中的数据进行一个条件的筛选
    对一个值的判断 = > < != <> >= <=
    对一个范围的判断 between 小的值 and 大的值 [小的值,大的值]

    select emp_name,salary from employee where salary between 10000 and 20000;
    

    关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)

    select emp_name,post_comment from employee where post_comment is not null;
    

    **模糊匹配 **
    like '%a_'
    regext :字段名 ‘^d{15}$’
    'a'的名字
    '%a'以a结尾,'a%'表示以a开头,'%a%'表示匹配中间带个a的字符串
    '%'通配符 匹配任意长度的任意内容

    SELECT * FROM employee 
         WHERE emp_name LIKE 'eg%';
    

    'a' 表示任意的一个字符a,'a_'以a开头后面是任意的两个字符
    '_' 匹配一个长度的任意内容

    逻辑运算符
    and 两个条件必须都成立 才算成立
    or 只要有一个条件成立就成立
    not 非

    SELECT emp_name,salary FROM employee 
        WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
    
    SELECT emp_name,salary FROM employee 
        WHERE salary IN (3000,3500,4000,9000) ;
    
    SELECT emp_name,salary FROM employee 
        WHERE salary NOT IN (3000,3500,4000,9000) ;
    

    group by 分组(带去重的功能)
    1) select 数据 from 表 where 条件 group by 分组

    select post from employee where depart_id > 1;
    

    结果 是 有多少个部门 就有多少条数据
    2) GROUP BY关键字和GROUP_CONCAT()函数一起使用

    select post,group_concat(emp_name) from employee where depart_id<3 group by post; 结果是符合条件里的部门的所有人名字
    

    聚合函数
    count(字段) 统计有多少条记录是符合条件的 只统计字段不为空的那一行数据

    count(*) # count(1)	# min  # max  # avg  # sum
    

    order by 排序
    默认是升序
    降序 从大到小排 desc

    SELECT * FROM employee ORDER BY salary DESC;
    

    limit限制
    limit n 取n个
    limit m,n 从m +1 开始 取n条
    limit n offset m 从m+1开始 取n个

    **having **
    对group by 分组后的结果进行过滤和筛选
    能够 使用聚合函数
    Having: 如果是group by 用到的关键字, select 当中用到的名字 聚合函数要用到的名字

    优先级

    FROM 表名
        WHERE 条件
        GROUP BY field
        HAVING 筛选
    ORDER BY field
        LIMIT 限制条数
    

    .多表查询

    Select * from 表一,表二
    
    1.连表查询:

    用的是on连接
    1) 内连接 (inner join) :只有两张表中条件互相匹配上的项才能被显示出来

    select 字段 from 表1 inner join 表2 on 条件
    select * from class inner join stu on stu.class_id = class.id;
    

    等同于
    Select * from class,stu where stu.class_id = class.id

    2) 外链接
    左外链接(left join):会完整的显示左表,根据条件显示右表

    select 字段 from 表1 left join 表2 on 条件
    

    右外链接(right join):会完整的显示右表,根据条件显示左表

    select 字段 from 表1 right join 表2 on 条件
    

    全外链接
    用union连接

    from 表1 left join 表2 on 条件 union 表1 right join 表2 on 条件
        select * from employee as emp left join department as dep on emp.dep_id = dep.id
    union
        select * from employee as emp right join department as dep on emp.dep_id = dep.id;
    
    2.子查询 (效率比连表查询低)

    在一条sql中两个select,并且一个select的结果是另一个select的条件
    用的是 in 连接

    select * from 表1 where 字段 = (select 字段 from 表2 where 条件 = 值)
    select * from 表1 where 字段 in (select 字段 from 表2 where 条件 = 值)
    

    索引

    1.索引原理

    索引的目的在于提高查询效率

    有什么好处坏处:占空间,拖慢写的速度

    本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据
    索引越多,占用磁盘空间越大,修改表时对索引 的重构和更新很麻烦

    2.对哪些字段添加索引
        1、表的主键、外键必须有索引; 
        2、数据量超过300的表应该有索引; 
        3、经常与其他表进行连接的表,在连接字段上应该建立索引; 
        4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引; 
        5、索引应该建在选择性高的字段上; 
        6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引; 
        7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替: 
        A、正确选择复合索引中的主列字段,一般是选择性较好的字段; 
        B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引; 
        C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引; 
        D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段; 
        E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引; 
        8、频繁进行数据操作的表,不要建立太多的索引; 
        9、删除无用的索引,避免对执行计划造成负面影响
    

    创建索引:

    Create index age on student(age)
    

    删除索引

    drop index 索引名字 on索引的表
    

    1.b+树 以平衡树为基础的
    1).所有的非叶子结点不存储真实的数据
    2).所有的叶子结点之间都被添加了双向链表

    2. innodb和myisam的索引的存储方式

    innodb 内部 有一个 聚集索引(聚簇索引),非聚集索引
    myisam 内部 没有聚集索引 ,所有索引都是非聚集索引

    3. 索引的种类

    primary key: 除了约束 非空 + 唯一之外 还有其他的作用 聚集索引
    unique: 约束 唯一 非聚集索引的作用
    index: 没有约束的作用 普通的非聚集索引
    联合唯一索引
    联合主键索引
    联合索引

    4. 正确使用索引

    1.条件必须是已经创建了索引的列
    2.如果在条件中对索引列使用了范围,并且这个范围很大,速度就很慢  >   <  !=  between and   not in
    3.like条件 后面 必须是 'abc%'  ,如果 like '%abbasff'
    4.确认使用的索引列的区分度 选择区分度低的列作为索引实际上并不能有加速查找的效果
    5.索引列在条件中不能参与计算
    6.and和or
    and/or
        使用and条件的时候 mysql在优化查询的时候会有限选择区分度高的列先查询,来缩小其他条件要查询的范围
    or 只会从左到右依次进行判断
     所有条件中出现的列区分度都需要很高
     对每一个字段都要添加索引
    

    **5.联合索引(重复值比较多时用它)
    联合索引是指对表上的多个列合起来做一个索引

    create index 索引名 on 表名(字段1,字段2...);
    create index name_email on s1(name,email);
    

    最左前缀原则
    # s1(name,email)
    # sql语句中条件必须含有name这个字段**

    6.覆盖索引

    InnoDB存储引擎支持覆盖索引(covering index,或称索引覆盖),即从辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。(不需要再回表查了)
    例子:

    s elect name from 表 where id =10000  # 用到索引了 ,但是不是覆盖索引
    select id from 表 where id =10000  # 用到索引了 ,也是覆盖索引
    

    mysql 连接数据库

    1.在终端提交事务

    begin;  # 开启事务
    select * from emp where id = 1 for update;  # 查询id值,for update添加行锁;
    update emp set salary=10000 where id = 1; # 完成更新
    commit; # 提交事务
    

    2.使用python 操作mysql数据库

    import pymysql
    
        conn = pymysql.connect(
            host='localhost', user='root', password="root",
            database='db', port=3306, charset='utf-8', )
        cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
        创建一个游标对象
        # 游标里什么都不写是元祖形式,写上.cursors.DictCursor 就是字典形式
    
        sql2 = 'select sname from student for update;', 添加一个锁
        cursor.execute('select * from s1  where email="eva2300@oldboy" or email="eva6666@oldboy"')
        ret = cursor.fetchmany(2)  # 取几就打印几个
        fetchall()  # 全取     
        fetchone() #只取一个
        print(ret)
        conn.commit()  # 提交到数据库
        conn.close()
    

    简述mysql主从复制原理?

    (1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
    (2) slave将master的binary log events拷贝到它的中继日志(relay log);
    (3) slave重做中继日志中的事件,将改变反映它自己的数据。
    

    总结:

    查
      单表查
         select distinct * from 表 where 条件 group by 字段 having 过滤条件 order by 字段 limit n,m;
         聚合函数 : sum avg max min count
         分组聚合 : 求某个商品的平均价格,总销量,求部门的最高工资,求本月平均打卡时间最早的
      多表查
         多表查询
            连表查询
               inner join
               left join
               right join
            子查询
               在一条sql中两个select,并且一个select的结果是另一个select的条件
         推荐连表查询的效率高
    

    四, mongodb与MySQL的不同有哪些
    爱喝马黛茶的安东尼爱喝马黛茶的安东尼2020-01-03 11:03:12原创4175

    MySQL与MongoDB都是开源的常用数据库,但是MySQL是传统的关系型数据库,MongoDB则是非关系型数据库,也叫文档型数据库,是一种NoSQL的数据库。它们各有各的优点,关键是看用在什么地方。所以我们所熟知的那些SQL语句就不适用于MongoDB了,因为SQL语句是关系型数据库的标准语言。

    一、关系型数据库-MySQL

    1、在不同的引擎上有不同的存储方式。

    2、查询语句是使用传统的sql语句,拥有较为成熟的体系,成熟度很高。

    3、开源数据库的份额在不断增加,mysql的份额页在持续增长。

    4、缺点就是在海量数据处理的时候效率会显著变慢。

    二、非关系型数据库-MongoDB

    非关系型数据库(nosql ),属于文档型数据库。先解释一下文档的数据库,即可以存放xml、json、bson类型系那个的数据。这些数据具备自述性,呈现分层的树状数据结构。数据结构由键值(key=>value)对组成。

    1、存储方式:虚拟内存+持久化。

    2、查询语句:是独特的MongoDB的查询方式。

    3、适合场景:事件的记录,内容管理或者博客平台等等。

    4、架构特点:可以通过副本集,以及分片来实现高可用。

    5、数据处理:数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存中,将数据存储在物理内存中,从而达到高速读写。

    6、成熟度与广泛度:新兴数据库,成熟度较低,Nosql数据库中最为接近关系型数据库,比较完善的DB之一,适用人群不断在增长。

    三、MongoDB优势与劣势

    优势:

    1、在适量级的内存的MongoDB的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快。

    2、MongoDB的高可用和集群架构拥有十分高的扩展性。

    3、在副本集中,当主库遇到问题,无法继续提供服务的时候,副本集将选举一个新的主库继续提供服务。

    4、MongoDB的Bson和JSon格式的数据十分适合文档格式的存储与查询。

    劣势:

    1、 不支持事务操作。MongoDB本身没有自带事务机制,若需要在MongoDB中实现事务机制,需通过一个额外的表,从逻辑上自行实现事务。

    2、 应用经验少,由于NoSQL兴起时间短,应用经验相比关系型数据库较少。

    3、MongoDB占用空间过大。

    四、对比

    TOP PERCENT 实例

    使用百分比作为参数
    例: SQL 语句从 websites 表中选取前面百分之 50 的记录

    SELECT TOP 50 PERCENT * FROM Websites;
    

    使用 SQL [charlist] 通配符

    MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
    下面的 SQL 语句选取 name 以 "G"、"F" 或 "s" 开始的所有网站:

    SELECT * FROM Websites
    WHERE name REGEXP '^[GFs]';
    

    带有文本值的 NOT BETWEEN 操作符实例

    下面的 SQL 语句选取 name 不介于 'A' 和 'H' 之间字母开始的所有网站:
    实例

    SELECT * FROM Websites
    WHERE name NOT BETWEEN 'A' AND 'H';
    

    UNION 操作

    UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
    请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

    SQL UNION 语法

    SELECT column_name(s) FROM table1
    UNION
    SELECT column_name(s) FROM table2;
    

    注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

    SQL UNION ALL 语法

    SELECT column_name(s) FROM table1
    UNION ALL
    SELECT column_name(s) FROM table2;
    

    注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。


    {{uploading-image-259436.png(uploading...)}}

    insert into select 语句

    INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响

    insert into selec 语法

    我们可以从一个表中复制所有的列插入到另一个已存在的表中:

    INSERT INTO table2
    SELECT * FROM table1;
    

    或者我们可以只复制希望的列插入到另一个已存在的表中:

    INSERT INTO table2
    (column_name(s))
    SELECT column_name(s)
    FROM table1;
    

    select into from 和 insert into select from和create table as select * from 都是用来复制表

    select into from不是用在sql 的
    两者的主要区别为:
    select into from 和 create table as select * from 要求目标表不存在,因为在插入时会自动创建;insert into select from 要求目标表存在。所以我们除了插入源表source_table的字段外,还可以插入常量,如sql语句:
    1.新表不存在
    复制表结构即数据到新表

    create table new_table
    select * from old_talbe;
    

    这种方法会将old_table中所有的内容都拷贝过来,用这种方法需要注意,new_table中没有了old_table中的primary key,Extra,auto_increment等属性,需要自己手动加,具体参看后面的修改表即字段属性.
    只复制表结构到新表

    # 第一种方法,和上面类似,只是数据记录为空,即给一个false条件
    create table new_table
    select * from old_table where 1=2;
     
    # 第二种方法
    create table new_table like old_table;
    

    2.新表存在
    复制旧表数据到新表(假设两个表结构一样)

    insert into new_table
    select * from old_table;
    

    复制旧表数据到新表(假设两个表结构不一样)

    insert into new_table(field1,field2,.....)
    select field1,field2,field3 from old_table;
    

    复制全部数据

    select * into new_table from old_table;
    

    只复制表结构到新表

    select * into new_talble from old_table where 1=2;
  • 相关阅读:
    linux的ip配置
    脚本抓取mongoDB慢查询进程,生成kill语句,快速恢复mongodb CPU打满情况
    python脚本生成sql分库分表语句
    脚本获取rds慢日志
    问题反馈小平台实现 ----python练习
    python脚本 监控MySQL slave 状态
    传统复制的复制结构之间转换
    python判断合法IP并区分内网和外网地址
    ELK单台日志收集系统的搭建
    网站程序文件增量更新脚本
  • 原文地址:https://www.cnblogs.com/xm-179987734/p/12322738.html
Copyright © 2011-2022 走看看