系统设计 --- 对数据库的并发操作导致数据重复插入
对数据库的并发操作导致数据重复插入
- 日常开发的过程中遇到这样一个问题, 代码需要根据某个字段是否存在来判断是添加数据还是更新数据.
- 换个生活中的例子就是, 两个用户同时注册账号, 如果用户名已存在则注册失败, 不存在则注册成功
- 这类问题的代码处理逻辑通常是:
- 查询数据库, 判断用户名是否已经在数据库里
- 根据查询结果进行判断注册成功还是注册失败
- 但是如果两个用户同时进行注册操作, 则两个用户第一步的查询结果都会为不存在, 最后导致数据库出现重复数据
使用唯一索引解决
- 唯一索引是数据库中一种特殊类型的索引,用于确保索引列中的值是唯一的。
- 在唯一索引下,数据库系统会强制要求索引列中的每个值都是唯一的,这意味着你无法在索引列中插入或更新具有与现有行中相同值的新行
- 这样在插入数据的时候就可以避免重复数据, 还可以提高查询性能
SQL
-- 连接到数据库
USE YourDatabaseName;
-- 创建用户表
CREATE TABLE Users (
UserID INT PRIMARY KEY IDENTITY(1,1),
Username NVARCHAR(50) UNIQUE,
Phone NVARCHAR(20),
Email NVARCHAR(100),
Address NVARCHAR(255)
);
MongDB
using System;
using MongoDB.Driver;
namespace MongoDBExample
{
class Program
{
static void Main(string[] args)
{
// 连接到MongoDB数据库
MongoClient client = new MongoClient("mongodb://localhost:27017");
IMongoDatabase database = client.GetDatabase("mydatabase");
Console.WriteLine("Database connected successfully");
// 获取或创建用户表(集合)
IMongoCollection<User> usersCollection = database.GetCollection<User>("users");
// 创建用户名字段的唯一索引
// indexKeysDefinition 是一个索引对象, mongdb中需要指明是升序索引还是降序索引
var indexKeysDefinition = Builders<User>.IndexKeys.Ascending(u => u.Username);
var indexOptions = new CreateIndexOptions { Unique = true };
var indexModel = new CreateIndexModel<User>(indexKeysDefinition, indexOptions);
usersCollection.Indexes.CreateOne(indexModel);
// 插入示例数据
var user = new User
{
Username = "john_doe",
Phone = "1234567890",
Email = "john@example.com",
Address = "123 Main St, City, Country"
};
usersCollection.InsertOne(user);
Console.WriteLine("Inserted user: {0}", user.Username);
// 关闭连接
client.Close();
}
}
public class User
{
public string Username { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
}
延申: 订票系统会遇到的并发问题
To be continued