V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Tinet
V2EX  ›  问与答

操作数据库中的一个情景

  •  
  •   Tinet · 2014-04-18 13:28:11 +08:00 · 3203 次点击
    这是一个创建于 3654 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有一个表,有多个进程同时在读这个表中的数据,现在加了一项任务,每过一段时间就会由另一个专门的进程往表里添加很多数据,并根据某个域的值对整个表进行排序(此时可能正好有进程在从表中读数据),那么在这种情况下,Mysql是怎么处理的呢?
    17 条回复    1970-01-01 08:00:00 +08:00
    liprais
        1
    liprais  
       2014-04-18 13:55:30 +08:00
    关键词:锁
    Tinet
        2
    Tinet  
    OP
       2014-04-18 14:04:21 +08:00
    @liprais 添加数据并排序所有数据会被加锁?然后读数据阻塞?或者反过来
    thinkif
        3
    thinkif  
       2014-04-18 14:08:45 +08:00
    不知道具体场景, 不过排序结果放在缓存里会不会有帮助?
    tobyzw
        4
    tobyzw  
       2014-04-18 14:16:55 +08:00
    排序没有影响吧?!
    Tinet
        5
    Tinet  
    OP
       2014-04-18 14:18:29 +08:00
    @thinkif 我这个问题本身就有问题,进行排序貌似对其他进程读数据没有什么影响
    Tinet
        6
    Tinet  
    OP
       2014-04-18 14:19:06 +08:00
    @tobyzw 应该是的,是独立的。
    Tinet
        7
    Tinet  
    OP
       2014-04-18 14:21:34 +08:00
    @thinkif 在where子句里面这样写:flag=0 limit 1,如果满足条件的数据有很多条的话,是取在数据库中存储最靠前的吗?
    lu18887
        8
    lu18887  
       2014-04-18 17:07:09 +08:00
    这是有专业的术语的,叫事务隔离级别 isolation level 。你可以查查相关的信息
    lu18887
        9
    lu18887  
       2014-04-18 17:07:59 +08:00
    这个可不一定的,得看数据库的实现的。
    @Tinet 在where子句里面这样写:flag=0 limit 1,如果满足条件的数据有很多条的话,是取在数据库中存储最靠前的吗?
    Tinet
        10
    Tinet  
    OP
       2014-04-18 20:48:38 +08:00
    @lu18887 嗯,我去查查
    Tinet
        11
    Tinet  
    OP
       2014-04-18 21:12:44 +08:00
    @lu18887 类似于这种需求:有一个表存储“激活码”,每1小时就有1万条数据插入,同时每秒钟会有1000个人在请求查询"激活码表",查询到后修改其状态为已使用(状态1)。
    msg7086
        12
    msg7086  
       2014-04-18 21:18:31 +08:00
    @Tinet 事务
    Tinet
        13
    Tinet  
    OP
       2014-04-18 21:51:07 +08:00
    @msg7086 得恶补一下数据库基础了
    mikej
        14
    mikej  
       2014-04-18 23:04:40 +08:00
    关系数据库标准中的4个事务隔离级别

    #未提交读(read uncommitted): 允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
    #提交读(read committed): 只能读取到已经提交的数据。oracle等多数数据库默认都是该级别
    #可重复读(repeated read): 可重复读。在同一个事务内的查询都是事务开始时刻一致的,innodb的默认级别。(在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读)
    #串行读(serializable): 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

    这里有很好的解释: http://blog.chinaunix.net/uid-21879027-id-3124330.html
    lu18887
        15
    lu18887  
       2014-04-19 00:39:36 +08:00
    @Tinet 我所知道的,ORACLE有“序列” 查一次,序列+1,你可以这样子做,激活码先生成几百万条,然后每个激活码,对应一个ID,这样你每次只要查那个序列就可以了,查出序列的值(一个数字ID),然后去读取激活码表对应的激活码就可以了。映射。这样就简单很多了。
    Tinet
        16
    Tinet  
    OP
       2014-04-19 10:46:59 +08:00
    @lu18887 你的意思是有两个表,一个表存激活码的ID(唯一值),然后程序去读这个表,再根据读到的ID,到另一个真正存激活码的表中去取激活码?
    lu18887
        17
    lu18887  
       2014-04-22 17:32:41 +08:00
    @Tinet 对的!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2780 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 12:18 · PVG 20:18 · LAX 05:18 · JFK 08:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.