索引:
主键索引:表的id (唯一 且 不能为空)
唯一索引:表User 假设有account 字段 ,用户名不重复 (唯一 可以为空)
复合索引:where() 的条件 用户名,密码 (无要求,无要求)
锁:
悲观锁:悲观锁的核心思想是假设在最坏的情况下,多个并发操作都会试图修改同一数据。因此,悲观锁会在操作数据之前先加锁,确保在解锁之前不会有其他线程或进程修改数据。这样,锁持有的期间,其他线程或进程无法访问该数据,直到锁被释放。(两个人同时想要去上厕所 只有一个厕所 , 只能A,B中的一个先上厕所即事务, 当上厕所的人 解决了后 剩下的人才能使用厕所)
例子:
假设商品ID为1的商品只剩下一件库存。用户A和用户B几乎同时发起购买这个商品的请求。
用户A开始一个事务,并执行SELECT * FROM products WHERE id = 1 FOR UPDATE;这个SQL语句。这个语句锁住了商品ID为1的记录,其他事务不能修改这个记录直到用户A的事务结束。
用户B开始一个事务,并试图执行同样的操作。但是,由于用户A已经加锁了该商品,用户B的查询会被阻塞,直到用户A释放锁。
悲观锁确保了用户A和用户B不会同时获得这件商品的购买资格,只有一个用户能够成功购买。
乐观锁:乐观锁的核心思想是假设大多数情况下,多个并发操作不会冲突。乐观锁不会在操作数据前加锁,而是在数据更新时检查是否有其他线程或进程同时修改了数据。(在车站进站的时候,检票机【商城或者商品 】 在检测到用户 刷省份证的后 会进行 放行的行动 这个时候 A用户【大人】 B用户 【未成年 无身份证】 同时进入 。 在商品来讲就是超卖 原始库存10 即两个请求同时进行 在商品的数据的库存中-1 但是只会减1 【此时的库存为9】 )
用户A开始一个事务,并读取了商品ID为1的记录,此时不加锁。记录显示有10件库存。
用户B也开始一个事务,并读取了同样的记录,同样不加锁。记录也显示有10件库存。
用户A更新商品ID为1的记录的stock_quantity减1,并尝试提交事务。
用户B也更新商品ID为1的记录的stock_quantity减1,并尝试提交事务。
在用户A和用户B都尝试提交事务时,数据库会检查stock_quantity字段的值是否有冲突。由于两个人都减少了1件库存,现在库存量为9件。数据库会检查自事务开始以来数据是否有过变更。在这个例子中,由于两个人读取的数据是一样的,所以他们都认为库存量是10件,并且都进行了减1的操作。因此,他们都会成功提交事务,并不会因为库存量为9件而失败。
商品超卖问题 使用easyswoole 的消息队列来解决。
事务:事务是数据库中的一个重要功能,它允许一组数据库操作要么全部成功,要么全部失败。
rabbitmq:
RabbitMQ 是一个开源的消息队列系统,它实现了高级消息队列协议(AMQP)。AMQP 是一种消息传递中间件的标准协议,它定义了消息的传输、路由和队列机制。RabbitMQ 提供了跨语言和跨平台的客户端库,支持多种消息传递模式,包括点对点(Point-to-Point)、发布/订阅(Publish/Subscribe)和路由(Routing)
memache:
异步和同步是消息传递和数据处理中的两种常见模式,它们在不同的使用场景中有不同的优势和应用。
异步
使用场景:
高并发处理:当系统需要处理大量并发请求时,异步处理可以避免阻塞,提高系统吞吐量。
非实时性要求:对于不要求实时响应的场景,如日志收集、数据分析等,异步处理可以background执行,不影响主线程。
解耦合:异步通信可以减少系统组件之间的耦合,使得系统更加模块化和灵活。
扩展性:异步模式便于扩展,可以通过增加消费者来处理更多的消息。
优点:
提高系统响应速度和吞吐量。
减少资源占用,因为多个操作可以并行处理。
增强系统的伸缩性,可以通过增加处理线程或实例来处理更多的任务。
缺点:
可能会引入复杂性,如消息队列的管理、消费者数量的调整等。
需要处理消息的顺序性和一致性问题。
可能会增加系统的复杂性,如错误处理、重试逻辑等。
同步
使用场景:
实时性要求高:如在线交易处理、实时通信等,需要立即得到响应。
操作重要:对于关键操作,需要确保执行完毕才能进行后续操作。
数据一致性要求高:在需要确保数据一致性的场景中,同步操作可以保证操作的顺序性和一致性。
优点:
保证操作的顺序性和一致性。
易于理解和实现,尤其是对于简单的单向操作。
适合需要即时反馈的场景。
缺点:
可能会降低系统的并发能力,因为一个操作可能会阻塞其他操作。
资源占用较大,因为操作需要依次执行。
系统的伸缩性较差,因为增加负载通常需要增加服务器资源。
新建目录后,要执行的
php easyswoole.php server start
composer dump-autoload
composer dump-autoload
bstract class 和 class 在 PHP 中都是用来定义类的关键字,但它们之间有一些重要的区别: 抽象类 (abstract class): 不能被实例化。 必须被继承。 可以用 abstract 关键字定义没有实现体的方法(即纯虚方法)。 目的是为了给出子类必须实现的方法规范。 普通类 (class): 可以被实例化。 可以不用被继承。 必须实现所有公共方法和属性(除非它们被声明为 static)。 从你提供的代码片段来看,你已经在使用 abstract 类了。在这个上下文中: abstract class Base extends Controller 表明 Base 是一个抽象类,它继承自 Controller 类。 abstract function onRequest(?string $action): ?bool 表明 onRequest 是一个抽象方法,它没有具体的实现,子类必须实现这个方法。 抽象的使用方法: 定义接口:当你想要定义一组方法,让继承你的类的子类必须实现这些方法时。 代码复用和规范:当你有一组类共享同样的结构和行为,但具体实现不同的时候。 基类:你可以创建一个抽象类作为其他类的基类,提供通用的方法和属性。
第一范式(1NF): 第一范式的主要要求是属性原子性,也就是说,表中的每个字段都应该是不可再分的最小数据单位。这与主键或外键的概念无关。1NF确保了字段内的数据是单一的,不包含多个值或者字符串集合。 假设我们有一个表叫做Students,它包含学生的信息。在1NF的要求下,每个字段都应该包含一个不可再分的值。例如,如果我们想要存储学生的全名,我们不能将名字和姓氏分开存储,而应该有一个字段FullName来存储完整的名字。 复制 Students +--------+------------+------+ | ID | FullName | ... | +--------+------------+------+ | 1 | John Doe | ... | | 2 | Jane Smith | ... | +--------+------------+------+ 在这个例子中,FullName字段包含的是学生的完整名字,它是一个不可再分的值。 第二范式(2NF) 第二范式在第一范式的基础上增加了唯一性的要求,即表中的每条记录都应该有一个唯一的主键,并且表中的所有非主键字段都必须完全依赖于主键,而不是仅依赖于主键的一部分(即组合键)。这里的“依赖于”意味着如果删除某条记录,那么与这条记录相关的所有其他记录都应该被删除,以保持数据的引用完整性。第二范式与外键的概念相关,因为它涉及到表之间的引用关系,但它们并不是相同的事物。
(学生表和课程表 ,在课程表中 想要知道某学生和他的课程 学生相关信息的字段依赖于课程的字段,每个学生的课程都因该与特定的课程关联 比如说学生的课程 web开发 特定的课程 web开发 xx老师授课 )
现在,让我们假设我们还有一个表叫做Courses,它包含学生选修的课程信息。在2NF的要求下,每个表都应该有唯一的主键,并且表中的所有非主键字段都必须完全依赖于主键。 复制 Courses +--------+---------+------+ | Course | Student | ... | +--------+---------+------+ | Math | 1 | ... | | Physics| 1 | ... | | History| 2 | ... | +--------+---------+------+ 在这个例子中,Student字段依赖于Course字段,因为每个学生选修的课程都应该与特定的课程关联。这里我们可以给Courses表添加一个主键,比如CourseID。 第三范式(3NF) 最后,3NF要求表中的所有字段不仅依赖于主键,而且它们的值不能被其他字段所派生。这意味着表中的每个字段都应该是独立的,不应该包含可以从其他字段计算得出的数据。 假设我们想要存储每个课程的教师信息。如果我们有一个Teachers表,它包含教师的详细信息,我们不能在Courses表中重复教师的详细信息。 Teachers +--------+---------+------+ | Teacher| Course | ... | +--------+---------+------+ | Smith | Math | ... | | Brown | Physics | ... | | Jones | History | ... | +--------+---------+------+ 在这个例子中,Courses表中的Teacher字段依赖于Teachers表中的Teacher字段。因此,我们应该在Courses表中使用一个外键TeacherID来引用Teachers表的主键TeacherID。 通过遵循这三个范式,我们可以确保数据库中的数据是规范化的,这样可以减少数据冗余,提高数据的一致性和完整性。
MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
1:硬件方面: 增加cpu ,内存,硬盘
2:使用redis减少 对数据库的查询。
3:使用合适的数据库引擎 InnoDb 。
4:设置索引,优化索引 ,优化sql
5:分区,分表。
6:读写分离。
对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?
1:限流:
令牌桶算法,漏桶算法,。
2:采用分布式系统。
3:队列处理。
4:数据库缓存。
use think\facade\Redis;
// 实例化 Redis 对象
$redis = Redis::instance();
// 连接到 Redis 服务器
$redis->connect('127.0.0.1', 6379, 1); // 1秒超时
// 开始事务
$redis->multi();
// 执行事务中的命令
$redis->set('key1', 'value1');$redis->set('key2', 'value2');
// 执行事务
$result =$redis->exec();
// 检查事务执行结果
if ($result) {
// 所有命令成功执行
echo "Transaction successful.";
} else {
// 事务中有命令执行失败
echo "Transaction failed.";
}
// 关闭 Redis 连接
$redis->close();