python操作MySQL、SQL注入问题、视图、触发器、事务、存储过程、函数、流程控制、索引(重点)

news2024/12/26 23:39:16

python操作MySQL(重要)

SQL的由来:

MySQL本身就是一款C/S架构,有服务端、有客户端,自身带了有客户端:mysql.exe
python这门语言成为了MySQL的客户端(对于一个服务端来说,客户端可以有很多)

操作步骤:
    1. 先链接MySQL
        host、port、username、password、charset、库等
    2. 在Python中书写SQL语句
    3. 开始执行SQL语句,拿到结果
    4. 在Python中做处理(进一步对数据做处理)
# 需要使用第三方一个模块: pymysql mysqldb  mysqlclient

1. 先链接MySQL

conn=pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='1234',
    db='db10',
    charset='utf8',
    autocommit=True
)

2. 获取游标

cur=conn.cursor(cursor=pymysql.cursors.DictCursor)

3. 写SQL语句

sql='select * from student'
sql='insert into teacher(tid, tname) values (7, "ly1")'

4. 开始执行SQL语句

affect_rows=cur.execute(sql) # 16 是影响的行数

需要执行二次确认: 除了查询之外都要二次确认提交
 conn.commit()
print(affect_rows)

5. 想获取到结果:

res=cur.fetchone()
res=cur.fetchall()
res=cur.fetchmany(5)
{'sid': 1, 'gender': '男', 'class_id': 1, 'sname': '理解'}
print(res) # (1, '男', 1, '理解')  元组类型

for i in res:
print(i.get("sid"))

SQL注入问题

import pymysql
# 连接MySQL服务端
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    database='db8_3',
    charset='utf8',
    autocommit=True  # 针对增 改 删自动二次确认
)
# 产生一个游标对象
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 编写SQL语句
username = input('username>>>:').strip()
password = input('password>>>:').strip()
sql = "select * from userinfo where name='%s' and pwd='%s'" % (name,pwd)
sql = "select * from userinfo where name=%s and pwd=%s"
cursor.execute(sql,(username,password))
data = cursor.fetchall()
if data:
    print(data)
    print('登录成功')
else:
    print('用户名或密码错误')


# 1.只需要用户名也可以登录
username:>>>   kevin111 " -- ddasfdfsdfdsfsdfsdfsdfdsfsdfsd
username:>>>   xxx " or 1=1 
# 2.不需要用户名和密码也可以登录
SQL注入的原因 是由于特殊符号的组合会产生特殊的效果
    实际生活中 尤其是在注册用户名的时候 会非常明显的提示你很多特殊符号不能用
        原因也是一样的
结论:设计到敏感数据部分 不要自己拼接 交给现成的方法拼接即可


 sql = 'insert into userinfo(name,pwd) values("jason","123"),("kevin","321")'
res = cursor.execute(sql)

print(res)

在使用代码进行数据操作的时候 不同操作的级别是不一样的
    针对查无所谓
    针对增 改 删都需要二次确认
        conn.commit()

视图

什么是视图

视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可

为什么要用视图

如果要频繁使用一张虚拟表,可以不用重复查询

如何用视图

create view teacher2course as
select * from teacher inner join course on teacher.tid = course.teacher_id;

创建好了之后 验证它的存在navicat验证 cmd终端验证
最后文件验证 得出下面的结论 视图只有表结构数据还是来源于之前的表
delete from teacher2course where id=1;

强调

1、在硬盘中,视图只有表结构文件,没有表数据文件

2、视图通常是用于查询,尽量不要修改视图中的数据

drop view teacher2course;

思考:开发过程中会不会去使用视图?

不会!视图是mysql的功能,如果你的项目里面大量的使用到了视图,那意味着你后期想要扩张某个功能的时候这个功能恰巧又需要对视图进行修改,意味着你需要先在mysql这边将视图先修改一下,然后再去应用程序中修改对应的sql语句,这就涉及到跨部门沟通的问题,所以通常不会使用视图,而是通过重新修改sql语句来扩展功能

触发器

在满足对某张表数据的增、删、改的情况下,自动触发的功能称之为触发器

为何要用触发器

触发器专门针对我们对某一张表数据增insert、删delete、改update的行为,这类行为一旦执行
就会触发触发器的执行,即自动运行另外一段sql代码

创建触发器语法

语法结构

create trigger 触发器的名字 before/after insert/update/delete on 表名 for each row
begin
    sql语句
end

针对插入

create trigger tri_after_insert_t1 after insert on 表名 for each row
begin
    sql代码。。。
end 
create trigger tri_after_insert_t2 before insert on 表名 for each row
begin
    sql代码。。。
end

针对删除

create trigger tri_after_delete_t1 after delete on 表名 for each row
begin
    sql代码。。。
end
create trigger tri_after_delete_t2 before delete on 表名 for each row
begin
    sql代码。。。
end

针对修改

create trigger tri_after_update_t1 after update on 表名 for each row
begin
    sql代码。。。
end
create trigger tri_after_update_t2 before update on 表名 for each row
begin
    sql代码。。。
end

需要注意 在书写sql代码的时候结束符是; 而整个触发器的结束也需要分号;
这就会出现语法冲突 需要我们临时修改结束符号
delimiter $$
delimiter ; 
该语法只在当前窗口有效  

案例

CREATE TABLE cmd (
    id INT PRIMARY KEY auto_increment,
    USER CHAR (32),
    priv CHAR (10),
    cmd CHAR (64),
    sub_time datetime, #提交时间
    success enum ('yes', 'no') #0代表执行失败
);

CREATE TABLE errlog (
    id INT PRIMARY KEY auto_increment,
    err_cmd CHAR (64),
    err_time datetime
);

delimiter $$  # 将mysql默认的结束符由;换成$$

create trigger tri_after_insert_cmd after insert on cmd for each row
begin
    if NEW.success = 'no' then  # 新记录都会被MySQL封装成NEW对象
        insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
    end if;
end $$

delimiter ;  # 结束之后记得再改回来,不然后面结束符就都是$$了

#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
    USER,
    priv,
    cmd,
    sub_time,
    success
)
VALUES
    ('egon','0755','ls -l /etc',NOW(),'yes'),
    ('egon','0755','cat /etc/passwd',NOW(),'no'),
    ('egon','0755','useradd xxx',NOW(),'no'),
    ('egon','0755','ps aux',NOW(),'yes');

查询errlog表记录
select * from errlog;
 删除触发器
drop trigger tri_after_insert_cmd;

事务(掌握重点)

什么是事务

开启一个事务可以包含一些sql语句,这些sql语句要么同时成功
要么一个都别想成功,称之为事务的原子性

事务的作用

保证了对数据操作的数据安全性

案例:用交行的卡操作建行ATM机给工商的账户转钱

事务的4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

原子性(atomicity)一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

怎么使用

# 先介绍事务的三个关键字 再去用表实际展示效果
start transaction;
commit;
rollback;

create table user(
id int primary key auto_increment,
name char(32),
balance int
);

insert into user(name,balance)
values
('jason',1000),
('egon',1000),
('tank',1000);

# 修改数据之前先开启事务操作
start transaction;

# 修改操作
update user set balance=900 where name='jason'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='tank'; #卖家拿到90元

# 回滚到上一个状态
rollback;

# 开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘
commit;
"""开启事务检测操作是否完整,不完整主动回滚到上一个状态,如果完整就应该执行commit操作"""

# 站在python代码的角度,应该实现的伪代码逻辑,
try:
    # 少了开事务...
    update user set balance=900 where name='jason'; #买支付100元
    update user set balance=1010 where name='egon'; #中介拿走10元
    update user set balance=1090 where name='tank'; #卖家拿到90元
except 异常:
    rollback;
else:
    commit;

存储过程

存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql,类似于python中的自定义函数

基本使用

delimiter $$
create procedure p1()
begin
    select * from user;
end $$
delimiter ;

# 调用
call p1()

三种开发模型

第一种

应用程序:只需要开发应用程序的逻辑
mysql:编写好存储过程,以供应用程序调用
优点:开发效率,执行效率都高
缺点:考虑到人为因素、跨部门沟通等问题,会导致扩展性差

第二种

应用程序:除了开发应用程序的逻辑,还需要编写原生sql
优点:比方式1,扩展性高(非技术性的)
缺点:
1、开发效率,执行效率都不如方式1
2、编写原生sql太过于复杂,而且需要考虑到sql语句的优化问题

第三种

应用程序:开发应用程序的逻辑,不需要编写原生sql,基于别人编写好的框架来处理数据,ORM
优点:不用再编写纯生sql,这意味着开发效率比方式2高,同时兼容方式2扩展性高的好处
缺点:执行效率连方式2都比不过

创建存储过程

# 介绍形参特点  再写具体功能

delimiter $$

create procedure p2(
    in m int,  # in表示这个参数必须只能是传入不能被返回出去
    in n int,  
    out res int  # out表示这个参数可以被返回出去
)
begin
    select tname from teacher where tid > m and tid < n;
    set res=0;  # 用来标志存储过程是否执行
end $$
delimiter ;


# 针对res需要先提前定义
set @res=10;  定义
select @res;  查看
call p1(1,5,@res)  调用
select @res  查看

如何用存储过程

 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用

 1、直接在mysql中调用
set @res=10  # res的值是用来判断存储过程是否被执行成功的依据,所以需要先定义一个变量@res存储10
call p1(2,4,10);  # 报错
call p1(2,4,@res);  

# 查看结果
select @res;  # 执行成功,@res变量值发生了变化

2、在python程序中调用
pymysql链接mysql
产生的游表cursor.callproc('p1',(2,4,10))  # 内部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10;
cursor.execute('select @_p1_2;')

3、存储过程与事务使用举例(了解)
delimiter //
create PROCEDURE p5(
    OUT p_return_code tinyint
)
BEGIN
    DECLARE exit handler for sqlexception
    BEGIN
        -- ERROR
        set p_return_code = 1;
        rollback;
    END;


  DECLARE exit handler for sqlwarning
  BEGIN
      -- WARNING
      set p_return_code = 2;
      rollback;
  END;

  START TRANSACTION;
      update user set balance=900 where id =1;
      update user123 set balance=1010 where id = 2;
      update user set balance=1090 where id =3;
  COMMIT;

  -- SUCCESS
  set p_return_code = 0; #0代表执行成功


END //
delimiter ;

函数

注意与存储过程的区别,mysql内置的函数只能在sql语句中使用!


CREATE TABLE blog (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR (32),
    sub_time datetime
);

INSERT INTO blog (NAME, sub_time)
VALUES
    ('第1篇','2015-03-01 11:31:21'),
    ('第2篇','2015-03-11 16:31:21'),
    ('第3篇','2016-07-01 10:21:31'),
    ('第4篇','2016-07-22 09:23:21'),
    ('第5篇','2016-07-23 10:11:11'),
    ('第6篇','2016-07-25 11:21:31'),
    ('第7篇','2017-03-01 15:33:21'),
    ('第8篇','2017-03-01 17:32:21'),
    ('第9篇','2017-03-01 18:31:21');


+----+--------------------------------------+---------------------+
| id | NAME                                 | sub_time            |  month
+----+--------------------------------------+---------------------+
|  1 | 第1篇                                | 2015-03-01 11:31:21 |  2015-03
|  2 | 第2篇                                | 2015-03-11 16:31:21 |  2015-03
|  3 | 第3篇                                | 2016-07-01 10:21:31 |  2016-07
|  4 | 第4篇                                | 2016-07-22 09:23:21 |  2016-07
|  5 | 第5篇                                | 2016-07-23 10:11:11 |  2016-07 
|  6 | 第6篇                                | 2016-07-25 11:21:31 |  2016-07
|  7 | 第7篇                                | 2017-03-01 15:33:21 |  2017-03
|  8 | 第8篇                                | 2017-03-01 17:32:21 |  2017-03
|  9 | 第9篇                                | 2017-03-01 18:31:21 |  2017-03
+----+--------------------------------------+---------------------+

select count(*) from blog group by month;

select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');
https://blog.csdn.net/GG_Bruse/article/details/131484538

流程控制

# if条件语句
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN
    
    declare i int default 0;
    if i = 1 THEN
        SELECT 1;
    ELSEIF i = 2 THEN
        SELECT 2;
    ELSE
        SELECT 7;
    END IF;

END //
delimiter ;

# while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN

    DECLARE num INT ;
    SET num = 0 ;
    WHILE num < 10 DO
        SELECT
            num ;
        SET num = num + 1 ;
    END WHILE ;

END //
delimiter ;

索引(重点)

索引就是一种数据结构,类似于书的目录。意味着以后再查数据应该先找目录再找数据,而不是用翻页的方式查询数据

索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。

  • primary key

  • unique key

  • index key

注意:上面三种key前两种除了有加速查询的效果之外还有额外的约束条件(primary key:非空且唯一,unique key:唯一),而index key没有任何约束功能只会帮你加速查询

本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

索引的影响:

         在表中有大量数据的前提下,创建索引速度会很慢(建表的时候,如果明显需要索引,就提前加上)

# 以后实际添加索引的时候,尽量在空表的时候添加,在创建表的时候就添加索引,此时添加索引是最快的
# 如果表中数据已经有了,还需要添加索引,也可以,只不过创建索引的速度会很慢,不建议这样做

         在索引创建完毕后,对表的查询性能会大幅度提升,但是写的性能会降低

# 但是,写的性能影响不是很大,因为在实际中,写的频率很少,大部分操作都是查询
# 如何添加索引?到底给哪些字段加索引呢?
'''没有固定答案,具体给哪个字段加索引,要看你实际的查询条件'''
select * from user where name='' and password='';
# 索引的使用其实是需要大量的工作经验,才能正确的判断出
'''不要一创建表就加索引,在一张表中,最多最多不要超过15个索引,索引越多,性能就会下降'''
# 如何数据量比较小,不需要加索引,100w一下一般不用加,mysql针对于1000w一下的数据,性能不会下降太多.

b+树

树------>二叉树 平衡树  b树  b+树 b-树...

只有叶子结点存放真实数据,根和树枝节点存的仅仅是虚拟数据

查询次数由树的层级决定,层级越低次数越少

一个磁盘块儿的大小是一定的,那也就意味着能存的数据量是一定的。如何保证树的层级最低呢?一个磁盘块儿存放占用空间比较小的数据项

# 以后加索引的时候,尽量给字段中存的是数字的列加,我们使用主键查询速度很快
select * from user where name = ''
select * from user where id = ''  # 主键查询的更快一些

思考我们应该给我们一张表里面的什么字段字段建立索引能够降低树的层级高度>>> 主键id字段

聚集索引(primary key)

聚集索引其实指的就是表的主键,innodb引擎规定一张表中必须要有主键。先来回顾一下存储引擎。

myisam在建表的时候对应到硬盘有几个文件(三个)?

innodb在建表的时候对应到硬盘有几个文件(两个)?frm文件只存放表结构,不可能放索引,也就意味着innodb的索引跟数据都放在idb表数据文件中。

特点:叶子结点放的一条条完整的记录

辅助索引(unique,index)

辅助索引:查询数据的时候不可能都是用id作为筛选条件,也可能会用name,password等字段信息,那么这个时候就无法利用到聚集索引的加速查询效果。就需要给其他字段建立索引,这些索引就叫辅助索引

特点:叶子结点存放的是辅助索引字段对应的那条记录的主键的值(比如:按照name字段创建索引,那么叶子节点存放的是:{name对应的值:name所在的那条记录的主键值})

select name from user where name='jack';

上述语句叫覆盖索引:只在辅助索引的叶子节点中就已经找到了所有我们想要的数据

select age from user where name='jack';

上述语句叫非覆盖索引,虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1139123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜维尔科技:Geomagic Touch X力反馈设备【开箱图真机测试】

将力反馈性能提升到一个新的水平&#xff0c;可提供更精确的定位输入和高保真力反馈输出。对于3D建模和设计、手术培训、虚拟装配等要求精确度较高的多种操作&#xff0c;TouchX是一个易于使用、经济实惠的选择。 Touch X 的功能 屡获殊荣的 Touch X 力反馈设备提供了经济实惠…

成集云 | 成集云-经销商返利系统集成金蝶云星辰 | 解决方案

方案介绍 成集云经销商返利系统通过线上平台来管理经销商返利活动&#xff0c;实现商品的销售、推广和返利的全过程管理。为企业解决了返利计算复杂、返利决策不清晰、返利发放不及时、无法跟踪经销商等多个难题。 金蝶云星辰是金蝶旗下的一款企业级SaaS管理云&#xff0c;其…

推荐一款适合科技行业的CRM系统

推荐您一款科技行业好用的CRM系统——Zoho CRM客户管理系统&#xff0c;旨在帮助企业管理客户数据、销售过程、营销活动以及服务支持&#xff0c;助力业务增长及数字化转型&#xff0c;实现“以客户为中心”的企业管理和运营模式。 近些年&#xff0c;随着政府鼓励政策的出台、…

Python字典-dict “ “ ---记一次查缺补漏“ “

文章目录 0x0 前言0x1 字典 &#xff08;Dictionary&#xff09;0x01 访问字典里的值0x02 修改字典0x03 删除字典元素0x04 判断字典是否包含指定key&#xff0c;用in或not in 运算符 0x2 字典键的特性0x010x2 0x3 字典内置函数&方法0x4 使用格式化字符串 0x0 前言 python没…

jmeter界面压测过程卡死解决思路

1、排查压测机的资源是否充足&#xff1b; 2、检查jmeter压测脚本&#xff0c;除聚合报告的所有组件关闭&#xff1b; 我在压测过程中出现频繁卡死&#xff0c;就是查看结果数和断言结果信息量过多导致&#xff1a; 3、直接用非gui界面形式&#xff0c;也就是脚本形式压测。

postgis ST_CoverageInvalidEdges使用说明

官方文档 函数说明 概要 geometry ST_CoverageInvalidEdges(geometry winset geom, float8 tolerance 0); 描述 一个窗口函数&#xff0c;用于检查窗口分区中的多边形是否形成有效的多边形覆盖范围。 它返回线性指示器&#xff0c;显示每个多边形中无效边&#xff08;如果…

判断对象a的值是否小于对象boperator.lt()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 判断对象a的值 是否小于对象b operator.lt() 选择题 下列代码执行输出的结果是? import operator print("【执行】print(operator.lt(3, 5))") print(operator.lt(3, 5)) print(&qu…

傅里叶级数系数的完整详细算法

傅里叶级数系数的完整详细算法 一、三角函数相关公式和定积分 在分析傅里叶级数之前&#xff0c;一定要先熟悉三角函数的相关公式&#xff0c;以及三角函数的积分。 1、两角和公式&#xff1a; sin(αβ) sin(α) * cos(β) cos(α) * sin(β) sin(α-β) sin(α) * co…

域名系统 DNS

DNS 概述 域名系统 DNS(Domain Name System)是因特网使用的命名系统&#xff0c;用来把便于人们使用的机器名字转换成为 IP 地址。域名系统其实就是名字系统。为什么不叫“名字”而叫“域名”呢&#xff1f;这是因为在这种因特网的命名系统中使用了许多的“域(domain)”&#x…

【数字IC验证半科班历程:芯片概括_2023.10.20】

前言 选择行业需深入了解&#xff1a;行业的前景&#xff0c;是否适合……在知乎浏览n多帖子&#xff0c;千人千面&#xff0c;褒贬不一&#xff0c;只能黑人问号脸。且帖子虽说明学习路线&#xff0c;但甚至面对缩写名词&#xff0c;百度后仍是一知半解&#xff0c;不知确切内…

el-form组件如何清除校验提示(前端技能提升)

错误效果 错误描述 在切换radio切换的时候校验提示提示出来了&#xff0c;本身不应该出来但是如何取消呢&#xff1f;因为在切换时候我们置空但是并没有取消校验&#xff0c;所以从通过到拒绝置空时候肯定会出现提示语&#xff0c;那么我们把提示校验的方法去掉就行了。 错误代…

启动两个线程,用另一个线程以通知的终止另一个线程

要求&#xff1a; 在main方法中启动两个线程第一个线程循环随机打印100以内的整数直到第二个线程从键盘读取了”Q“命令 实现代码如下&#xff1a; public class Homework01 {public static void main(String[] args) {THk tHk new THk();tHk.start();Thk2 thk2 new Thk2(…

【Linux】操作系统以及虚拟机的安装与配置

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Linux的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.操作系统的介绍 二.VMWare虚拟机的安装…

【算法题】割后面积最大的蛋糕

题目&#xff1a; 矩形蛋糕的高度为 h 且宽度为 w&#xff0c;给你两个整数数组 horizontalCuts 和 verticalCuts&#xff0c;其中&#xff1a; horizontalCuts[i] 是从矩形蛋糕顶部到第 i 个水平切口的距离 verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离 请你…

宏定义实现offsetof

在C语言中&#xff0c;有这样一个特殊的宏&#xff0c;叫offsetof&#xff0c;它的功能是啥呢&#xff1f; 我们来看看它的介绍 它的功能是&#xff1a;返回一个结构体的成员的大小&#xff08;相较于起始地址的偏移量&#xff09; 引用代码&#xff1a;http://t.csdnimg.cn…

CS224W1.1——图机器学习介绍

文章目录 1. 介绍2. 主要问题3. 深度学习如何应用在图结构中4. 课程大纲 学习一下斯坦福CS224W的图机器学习&#xff08;2021年&#xff09;&#xff0c;并做一下学习笔记&#xff0c;主要是研究方向与图神经网络相关。这次是第一次笔记&#xff0c;图片很多都是从斯坦福的PPT里…

【java学习—九】抽象类和抽象方法(3)

文章目录 1. 相关概念2. 如何定义抽象方法和抽象类3. 抽象类的作用4. 练习题4.1. 问题14.2. 问题2 1. 相关概念 抽象类&#xff1a;随着继承层次中一个个新子类的定义&#xff0c;类变得越来越具体&#xff0c;而父类则更一般&#xff0c;更通用。类的设计应该保证父类和子类能…

如何在群晖Synology+Office实现多人编辑一个文件?

使用群晖Synology Office提升生产力&#xff1a;多人同时编辑一个文件 文章目录 使用群晖Synology Office提升生产力&#xff1a;多人同时编辑一个文件本教程解决的问题是&#xff1a;1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制…

潮玩宇宙:大逃杀模式的利与弊

在当今的游戏市场中&#xff0c;潮玩宇宙的概念越来越受到关注。这个以潮流玩具为主题的宇宙&#xff0c;不仅包含了众多类型的玩具和收藏品&#xff0c;还融合了各种独特的文化形式和娱乐内容。其中&#xff0c;大逃杀模式作为一种流行的游戏模式&#xff0c;在潮玩宇宙中占据…

倒计时 1 天!神策 2023 数据驱动大会「参会指南」,请收藏

「新旅程、新经营&#xff0c;决胜数字化」&#xff0c;神策 2023 数据驱动大会明日召开&#xff01;大会聚焦客户经营与客户旅程主题&#xff0c;特邀数十位海内外专家、知名企业代表、资深投资人&#xff0c;分享行业观点与趋势洞察&#xff0c;共同推动中国企业数字化客户经…