mysql用户管理_MySQL实战45讲

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

MySQL45讲之用户关注案例 - flowers

前言

本文介绍 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;

没有,则只是单向关注关系
insert into like;

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

那通过对记录上锁可以解决么?不行的,因为记录不存在,行锁无法生效。

解决方案

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

关系表新增一个 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,于是它会创建好友关系。

这样就解决了业务上存在的问题,主要借助了唯一索引来实现。

参考

  • [1] 答疑文章(一):日志和索引相关问题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/5842.html

(0)
上一篇 2023-04-22 18:00
下一篇 2023-04-22 19:00

相关推荐

  • mongodb如何新建用户

    mongodb如何新建用户在mongo shell里执行简单命令就可以创建用户 第一步 选择数据库 use [database] 第二步 创建用户名密码 db.createUser({user:'root&apos…

    2023-04-10
    168
  • Anaconda是Python工程师必备工具之一

    Anaconda是Python工程师必备工具之一Python语言火热发展,吸引了大量的程序员加入。然而,Python开发中需要用到的各种工具及其安装配置实际上还是一个很麻烦的事情。比如,虚拟环境、第三方库、各种IDE等,各种工具和开发环境需要一个一个地去装和配置,费时费力。这时候,Anaconda应运而生,成为了Python编程中的一大利器,并成为Python工程师们必备的开发工具之一。

    2024-06-07
    53
  • MySQL8开启ssl加密

    MySQL8开启ssl加密1 概述 MySQL从5.7开始默认开启SSL加密功能,进入MySQL控制台后输入status可以查看ssl的状态,出现下图表示在使用ssl: 另外,ssl加密需要密钥与证书,可以使用openssl…

    2023-02-10
    245
  • MySQL事务和锁——《MySQL DBA工作笔记》

    MySQL事务和锁——《MySQL DBA工作笔记》MySQL事务 事务存在的原因 事务存在的目的:保证用户对数据操作对数据是安全的。(比如说银行卡余额) 事务的特性——ACID 原子性:一个事务要么全部执行,要么不执行 一致性:事务开始和结束时,数据

    2022-12-17
    141
  • sql按时间戳查询_js日期转时间戳

    sql按时间戳查询_js日期转时间戳需求:有一张域名浏览记录表,有字段warning浏览次数,字段updatetime创建时间,现在需要获取,按创建时间的降序,浏览量的降序,获取域名列表。就是说,同一天创建的域名,如果谁的浏览量大,谁就

    2023-03-12
    145
  • sql server decode函数_怎么将时间转化为字符串

    sql server decode函数_怎么将时间转化为字符串一.字符串函数 参数character_expression:由字符数据组成的字母数字表达式,可以是常量或变量,也可以是字符列或二进制数据列 参数integer_expression:是正整数,如果

    2022-12-30
    142
  • jQuery的find方法查找包含在标签中的标题

    jQuery的find方法查找包含在标签中的标题jQuery是一种流行的JavaScript库,可以方便地操作HTML文档。find()方法是jQuery中最有用的方法之一,能够非常容易地查找在指定DOM元素内的子元素。在本文中,我们将探讨使用jQuery的find()方法来查找包含在h1标签中的标题,帮助您快速定位并操作这些元素。

    2024-05-20
    68
  • 多项测试第一!腾讯云图数据库TGDB中标中国农行图数据库项目

    多项测试第一!腾讯云图数据库TGDB中标中国农行图数据库项目7月20日,中国农业银行发布图数据库资源配置项目中标公告,腾讯云中标。根据公告,腾讯云将为中国农业银行提供图数据库系统及客户化开发服务。此前腾讯云企业级分布式数据库TDSQL也中标了中国农业银行的分布

    2023-04-19
    179

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注