MySQL45讲之用户关注案例

本文介绍 MySQL45 讲中提到的一个用户关注的案例,并记录下可行的处理方案。

业务背景

业务上有这样的需求,A、B两个用户,如果互相关注,则成为好友。存在两个表,
关系(relation)表:

CREATE TABLE relation (
  id int NOT NULL AUTO_INCREMENT,
  user_id int NOT NULL,
  liker_id int NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY uk_user_id_liker_id (user_id,liker_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

好友(friend)表:

CREATE TABLE friend (
  id int NOT NULL AUTO_INCREMENT,
  friend1_id int NOT NULL,
  friend2_id int NOT NULL,
  PRIMARY KEY (id),
  KEY uk_friend (friend1_id,friend2_id) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

以A关注B为例:
第一步,先查询对方有没有关注自己(B有没有关注A)
select * from relation where user_id = B and liker_id = A;

如果有,则成为好友
insert into friend;

不,这只是一段单向的关系。

[En]

No, it’s just an one-way relationship.

insert into like;

现在存在的问题是, 如果 A 和 B 同时关注对方,在第一步判断对方没有关注自己,则只记录单向关注关系,然而实际上应该记录成好友的

锁定记录就能解决吗?否,由于该记录不存在,行锁无法生效。

[En]

Can it be solved by locking the records? No, because the record does not exist, the row lock cannot take effect.

解决方案

将两条记录合并到一条,这样就可以充分利用唯一索引。此外,再新增一个字段来记录状态。

关系表新增一个 relation_ship 字段,tinyint 类型。当 A 关注 B 且 A < B 时,

INSERT INTO (user_id, liker_id, relation_ship) values(A, B, 1);

当 A 关注 B 且 B < A 时,

INSERT INTO (user_id, liker_id, relation_ship) values(B, A, 2);

当 relation_ship = 3,表示 A 和 B 互相关注。

执行逻辑如下

begin;
1. 插入记录或者更新 relation_ship
INSERT INTO relation(user_id, liker_id, relation_ship) values(A, B, 1) on duplicate key update relation_ship = (relation_ship | 1);
2. 查询 relation_ship
SELECT relation_ship FROM relation WHERE user_id = A AND liker_id = B;
3. 在业务逻辑中,如果 relation_ship = 3,则创建好友关系
INSERT INTO friend(friend1_id, friend2_id) values(A, B);
commit;

当两个用户同时关注对方时,对先执行到达的事务会成功插入关系记录,得到的 relation_ship 值为 1 或 2,不创建好友关系;而后到来的事务,因为重复不插入关系记录,而更新 relation_ship = 1 | 2 或者 2 | 1,总之结果都是 3,于是它会创建好友关系。

通过这种方式,解决了业务中存在的问题,主要是借助唯一索引。

[En]

In this way, the problems existing in the business are solved, mainly with the help of unique index.

Original: https://www.cnblogs.com/flowers-bloom/p/mysql45-relation-sample.html
Author: flowers-bloom
Title: MySQL45讲之用户关注案例

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508134/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 了解HTML/CSS/JS/JQuery/ajax等前端知识

    什么是HTML 超文本标记语言 浏览器通过识别相应的标签来加载页面 通过HTTP协议传输,不是编程语言 HTML常用标签 title script style link meta …

    数据库 2023年6月16日
    0137
  • MySQL隐式转换的坑

    MySQL以以下规则描述比较操作如何进行转换: 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 实际使用中经研究发现字符串和数字比较时,优先把字符串转换为…

    数据库 2023年6月9日
    075
  • 设计模式之工厂方法

    一、工厂方法:简单工厂违背了单一职责原则,而且不利于扩展,于是衍生了工厂方法模式,该模式能很好地解决对扩展开放、对修改关闭的需求。 二、实现思路 :对每一个对象都创建一个对应的工厂…

    数据库 2023年6月14日
    0116
  • Decorator 装饰(结构型)

    Decorator 装饰 (结构型) 一:描述: Decorator 装饰模式是动态地给一个对象增加一些额外的功能职责特性。 来替换以前使用的继承来静态扩展对象的功能,避免子类的增…

    数据库 2023年6月11日
    082
  • Mysql 的Innodb引擎和Myisam数据结构和区别

    先大体看一下MySQL的SQL layer层的一个架构流程: 简要介绍一些关键模块: [En] Give a brief description of some key modul…

    数据库 2023年5月24日
    090
  • springboot~用正则表达式提取bearer token

    前后一体的应用,是这样进行认证的 用户向服务端发送验证信息(用户名、密码); 服务端验证成功就向用户返回一个sessionid; 服务端保存了这个session_id对应的信息,并…

    数据库 2023年6月6日
    0100
  • 绿色安装MySQL5.7版本—-配置my.ini文件注意事项

    简述绿色安装MySQL5.7版本以及配置my.ini文件注意事项 前言 由于前段时间电脑重装,虽然很多软件不在C盘,但是由于很多注册表以及关联文件被删除,很多软件还需要重新配置甚至…

    数据库 2023年5月24日
    0100
  • SqlSessionFactory工具类抽取

    多次SqlSessionFactory创建对象问题解决 SqlSessionFactory工具类抽取 问题描述: 当我们多次使用SqlSessionFactory创建并获取对象时会…

    数据库 2023年6月16日
    076
  • 利用VBS循环弹窗

    VBScript是Visual Basic Script的简称,即 Visual Basic 脚本语言,有时也被缩写为VBS。 将以下代码复制到文本文档中,保存后修改文件后缀名称为…

    数据库 2023年6月11日
    0135
  • 2021长安杯wp

    案件背景 2021年4月25日,上午8点左右,警方接到被害人金某报案,声称自己被敲诈数万元;经询问,昨日金某被嫌疑人诱导果聊,下载了某果聊软件,导致自己的通讯录和果聊视频被嫌疑人获…

    数据库 2023年6月11日
    076
  • my2sql工具之快速入门

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。 my2sql工具之快速入门 1….

    数据库 2023年5月24日
    095
  • docker-compose部署rocketmq

    docker-compose安装: Ubuntu下载docker-compose文件 sudo&#xA0;curl&#xA0;-L&#xA0;https:/…

    数据库 2023年6月11日
    084
  • [LeetCode]14. 最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入: [“flower”,&…

    数据库 2023年6月9日
    086
  • Oracle培训-介绍与体系架构

    1979年,公司推出Oracle 2,这是计算机软件史上第一个由纯软件公司开发的商用关系型数据库管理系统。公司改名为”关系软件公司” (Relational…

    数据库 2023年6月11日
    0105
  • JMeter接口自动化发包与示例

    JMeter接口自动化发包与示例 近期需要完成对于接口的测试,于是了解并简单做了个测试示例,看了看这款江湖上声名远播的强大的软件-Jmeter靠不靠谱。官网:https://jme…

    数据库 2023年6月6日
    063
  • 实现一个简单的Database1(译文)

    “What I cannot create, I do not understand.” – Richard Feynman I’m build…

    数据库 2023年6月11日
    0107
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球