Mycat 中间件:sql语句的路由器
insert语句写入mycat,mycat根据生成全局主键并根据类型写入到对应数据库中
在线修改表结构
【使用Percona-Toolkit工具】
详细使用说明:
https://blog.csdn.net/wsk1103/article/details/80960300
-
安装第三方依赖包
yum install -y perl-DBI yum install -y perl-DBD-mysql yum install -y perl-IO-Socket-SSL yum install -y perl-Digest-MD5 yum install -y perl-TermReadKey
-
安装Percona-Toolkit
#进入到Percona-Tookit离线文件所在的目录 rpm -ivh *.rpm
-
更改mysql8.0登录方式为老的登录方式
alter user 'root'@'%' identified by 'password' password expire never; alter user 'root'@'%' identified with mysql_native_password by 'abc123456';
-
把客户收货地址表中的name字段改成VARCHAR(20)
pt-online-schema-change --host=192.168.58.129 --port=3306 --user=root --password=password --alter "MODIFY name VARCHAR(20) NOT NULL COMMENT '收货人'" D=neti,t=t_customer_address --charset=utf8 --print --execute
生成流水号
配置好java,和Maven环境,用Maven构建java项目
package dev.demo.test1;
import java.util.concurrent.ThreadLocalRandom;
public class Demo1 {
public static String createOrderCode(String type,String organizationId,
String spgId,String date) {
StringBuffer buffer=new StringBuffer();
buffer.append(type);
buffer.append(organizationId);
buffer.append(spgId);
buffer.append(date);
ThreadLocalRandom.current().ints(0,9).limit(10).forEach((one)->{
buffer.append(one);
});
return buffer.toString();
}
public static void main(String[] args) {
String code=createOrderCode("S", "000012", "11002", "20180514");
System.out.println(code);
}
}
物理删除
- 真的从硬盘中删除了,误删除恢复数据,需要停掉数据库
- binlog日志记录执行的sql语句,用程序分析binlog日志,找出错误的sql,剔除掉,删掉数据库所有记录,执行所有OK的sql
- 给一个数 据库复制延时节点,延时24小时,数据同步,24小时内,从备份节点进行恢复
- 物理删除造成主键不连续,查询变慢,因为主键有索引,用where比limit快
逻辑删除
逻辑删除就是在数据表添加一个字段(is_deleted),用字段值标记该数据已经逻辑删除,查询的时候跳过这些数据
为每张表添加逻辑删除
alter table t_brand add is_delete tinyint(1) unsigned not null default 0 comment '逻辑删除';
为每张表 创建历史表,在后半夜负载小时,转移存放 主表中逻辑删除的历史数据
复制表
CREATE TABLE t_backstock_history like t_backstock;
快速分页查询商品
select * from table limit (start-1)*pageSize,pageSize
每页20条数据,查询第7页
limit (7-1)*20,20
limit 120,20
1. 主键连续
select t.id, t.val from t_test where id>100000 and id<100000
+100;
2. 主键不连续:先用主键索引加速,再用表连接获取具体数据
select t.id, t.val from t_test t join
(select id from t_test limit 100000,10) tmp
on t.id=tmp.id;
3. 业务上限定,不允许查询太早的数据,比如百度只能查76页的数据
业务场景
1. 读少写多
- 价值低的数据,用非关系数据库NoSQL ,没有表结构、约束、事务机制,没有redo,undo日志
- 价值高的数据,大规模写入的数据,TokuDB引擎,写入速度是 InnoDB 9~20倍
2. 写多读多
- NoSQL,比如存储离线消息的微信数据库
数据库集群优点,支持更多并发访问,存储更多数据,InnoDB引擎,单表超过2000万条数据,性能会降低
锁
InnoDB 是 行级锁
- 共享锁(读锁)
- 获取共享锁以后的事务,只能读
- 其他事务:只能读,不能写
- 不同事物可以对数据重复添加
事物 提交 或 回滚 后共享锁会消失
begin;
select * from t_test where id<10 LOCK IN SHARE MODE;
commit;
- 排它锁(写锁)
- 获取排它锁以后的事务,能读能写
- 其他事务:只能读,不能写
- 一个数据只能有一个排他锁
事物 提交 或 回滚 后排他锁会消失
执行删除,添加,更改时自动添加
如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。
select加锁是为了等待锁释放之后查询,保证数据一致
begin;
select * from t_test where id<10 FOR UPDATE;
commit;
select * from t for update 会等待行锁释放之后,返回查询结果。
select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果
select * from t for update wait 5 等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果
select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录
在select…for update之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数据表中加锁
把复杂的SQL语句变成短小的SQL语句,会减少并发锁冲突
- 乐观锁:
为数据表增加version字段,读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一,
此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号等于数据库表当前版本号,则予以更新,否则认为是过期数据。
由于乐观锁机制是在我们的系统中实现,来自外部系统的用户余额更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径,而不是将数据库表直接对外公开)。
需要同时修改一条数据的字段,加乐观锁,比如库存表
很多Java开发者,持久层会选择MyBatis,如果想使用乐观锁,可以先用Maven引用一下 MaBatis Plus插件,然后利用该插件内置的乐观锁机制就能实现乐观锁功能了,当然了也需要数据库里面有对应的版本号字段;
实战
https://blog.csdn.net/liyantianmin/article/details/50752102
系统内部业务图片存储方案
使用图床服务器,Nginx或云存储
MongoDB 的 GridFS 搭建 集群图床服务器
架设本地图床服务器
-
设置Nginx安装源
rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install -y nginx
-
防火墙开放80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload
-
在/usr/share/nginx/html目录下创建文件夹,上传图片即可